环境:DVWA靶场
难度:low
bool型盲注基本原理
何为盲注入?
在页面中不会显示数据库信息,一般情况下只会显示对与错的内容。这种情况下就不能直接通过页面的返回信息来获取数据库中的数据内容,只能用一些间接的方式获取,而这种方式称之为:盲注。
盲注有两种方式:一种是布尔型盲注入,另外一种是延时型盲注入。
如何判断是否为盲注?
输入 SQL 注入检测语句 判断页面是否不一样,如果不一样大概会存在 SQL 注入漏洞 1'and '1'='1 一样 1'and '1'='2 不一样,如果输入检测语句页面没有任何改 变可以使用延时语句进行检测 1'and sleep(10)--+ 函数 sleep() 在 mysql 是延时 返回的意思 以秒为单位 sleep(10) 即延时 10 秒执行。通过这两种方法可以判断是否为盲注入。本文主要使用bool型盲注入。
bool型盲注入
由于页面不会返回任何数据库内容,所以不能使用联合查询将敏感信息显示在页面,但是可以通过构造 SQL 语句,获取数据。
布尔型盲注入用到得 SQL 语句 select if(1=1,1,0) if()函数在 mysql 是判断,第一 个参数是表达式,如果条件成立,会显示 1,否则显示 0。1=1 表达式可以换成构造的 SQL 攻击语句。
1' and if(1=1,1,0)--+ 页面返回正常,这个语句实际上是 1’and 1,真 and 真 结果 为真,1 是存在记录的。所以返回正确页面
1' and if(1=2,1,0)--+ 页面返回错误,这个语句就是 1’and 0 ,真 and 假 结果为 假,整个 SQL ID 的值也是 0 所以没有记录,返回错误页面。
bool型盲注获取数据库敏感信息
在黑盒的环境下,通过构造 SQL 注入语句,根据页面的特征确定获取敏感信息。
布尔型盲注入用到的函数:
- SUBSTRING()字符串截取,第一个参数是要截取的字符串,第二个参数是开始截取位置,第三个参数是截取的长度。
- select database()查询当前数据库名称。
接着再用 if 函数进行构造 select if(SUBSTRING(database(),1,1)='d',1,0) 判断数据 库第一个字是不是字符 d,如果是返回 1 否则返回 0
接着判断第二个字符。将 substring 第二个参数写成 2 因为要截取第二个字符 select if(SUBSTRING(database(),2,1)='v',1,0) 第二个字符为 v。如此类推。最后拼接所有字符就是完整的库名。
在黑盒测试中bool型注入
上文介绍了bool型盲注的基本原理,下面介绍黑盒测试中bool型盲注的流程。
首先判断注入,判断完注入就获取数据库的长度,得到长度再查询库名,通过库名再查询表,接着通过表查询字段,最后查询某表指定的数据。
查询长度
要查询当前库名,首先确定要查询数据库的长度,再通过截取字符进行对比。
使用的指令为1' and if(length(database())=4,1,0)--+
这个指令表示,如果数据库名长度为4,就返回1,否则返回0.
上图中返回存在,说明数据库名长度为4,接下来获取数据库名。
这里使用指令1' and if(substring(database(),1,1)='d',1,0)来判断数据库的名称,如果数据库第一个字面是d就会返回id存在,否则返回id不存在。为了方便,我在这里用burp suite进行抓包爆破。
可以看到,返回存在,说明第一个字母为d,接下来我们抓包爆破试试。
下面设置变量1
设置变量2
完成之后就可以开始攻击了
得到库名获取表名
这里使用这个指令
if(substring((select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA=database() limit 0,1),1,1)='g',1,0)--+
再抓个包爆破一波
从上面的结果可以得知表名,很明显,一般情况下,我们对users表的内容更感兴趣,下面我们来获取它里面的字段,看看里面有些什么东西
得到表名获取字段名
这里使用这个指令
if(substring((select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME='users' and TABLE_SCHEMA=database() limit 0,1),1,1)='u',1,0)--+
通过上面的结果可以得知,字段名分别为:user_id,first_name,last_name,user,password,avatar,last_login,failed_login。很明显,我们好奇user,和password字段里面存的有什么,下面来获取里面的内容。
获取账号和密码
首先判断查询账号和密码的长度
if(substring((select CONCAT(user,0x3a,PASSWORD) from users limit 1),1,1)='a',1,0)--+
0x3a是冒号:的十六进制表示,这里可以让结果更人性化
现在来抓个包试试
最后整理结果得出 admin:5f4dcc3b5aa765d61d8327deb882c