《Remote Code Execution from SSTI in the Sandbox Automatically Detecting and Exploiting Template Escape Bugs》论文笔记
最后更新时间:
Remote Code Execution from SSTI in the Sandbox:Automatically Detecting and Exploiting Template Escape Bugs
前置
模板引擎
适用于前后端不分离的架构,后端接收请求数据后,将数据通过
模板引擎
解析渲染成视图后再返回给前端,由前端展示。可以简单理解为访问一个URL后直接得到html页面模板引擎的作用就是实现逻辑与数据的分离,最终可将模板文件和数据通过模板引擎的渲染生成最终的HTML代码
SSTI 漏洞成因
服务端接收了攻击者的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的一部分,
模板引擎
在进行目标编译渲染的过程中(一般可以执行各种表达式),执行了攻击者插入的可以破坏模板结构的语句(恶意Payload
),因而可能导致了敏感信息泄露、代码执行、GetShell等问题如何挖掘和判定?
利用模板表达式常用的特殊字符来尝试 fuzz 模板
怎么判断是哪种模板引擎?
- 报错信息
根据执行结果(依赖于不同模板语言特性)
模板逃逸漏洞
主要发生在基于设计的渲染引擎渲染过程中,由于模板代码的内容可控,可以在生成PHP代码的过程中逃离原本的语义,注入PHP代码造成 RCE
Abstract
模板引擎在 web 应用中可以简化用户接口的开发,它所提供的强大能力可以被攻击者利用 SSTI 注入发起服务端的攻击,包括 RCE,因此现代模板引擎通常会提供沙箱机制作防御。
作者从一个模板引擎被忽视的沙箱绕过漏洞入手(模板逃逸),研究并解决了其利用手法对于模板引擎语法和渲染逻辑的依赖问题,结合最新技术开发出 TEFuzz 自动化检测利用工具,可应用于 PHP 的7款模板引擎上。
研究动机
从一个 CVE 入手
公开的关于模板逃逸的漏洞很少,然而模板转换过程涵盖了模板代码解析和PHP代码生成两个部分,这涉及到大量复杂的字符串操作,因此模板逃逸漏洞在现实中不应该是罕见的,值得研究
Introduction
模板逃逸漏洞概述
大部分模板引擎在渲染过程中采用基于生成的设计方案,即会在渲染过程中将模板文件转换成 PHP 文件,并执行。同时,通过缓存生成的 PHP 文件,渲染过程可以达到近乎原始PHP代码的执行性能。
由于模板引擎一些不恰当的实现,模板代码在渲染过程中可以逃离模板的语义导致注入PHP代码到生成的PHP文件当中。
威胁模型:
敌手的能力:
- 直接形式的模板注入
- 利用其它类型的漏洞如文件上传,造成模板文件被修改控制
- 滥用 Web 应用的正常功能(如模板文件编辑功能)
研究目标:开发一款自动化的工具来检测模板逃逸漏洞并检测它们的可利用性
面临的挑战:
- 漏洞的根源——模板渲染逻辑,与语法分析紧密关联,难以理解和自动化推断
- 输入 POC 很难构造,EXP 更难构造。需要调整 payload 以适应 PHP 文件中转义点(EP)的语义环境(EC)
- 模板逃逸漏洞是基于语义层面的 bug ,很难去识别
提出:针对模板逃逸漏洞设计的模糊测试框架 TEFuzz
动态测试结合了 Fuzz 的优势,避免了对于复杂模板语法的理解,并且利用了生成的 PHP 代码来方便检测漏洞和利用
技术问题转变到Fuzz的技术问题上:如何平衡探索和利用,即如何保证测试的代码覆盖率同时减少冗余的测试样例。
![Untitled](Remote%20Code%20Execution%20from%20SSTI%20in%20the%20Sandbox%20Aut%207020c30e8f32462281b933608ffc7d25/Untitled%204.png)
解决方案设计
针对如何检测模板逃逸 bugs
Fuzz 原则1:平衡探索和利用。探索阶段:识别更多的 interesting testcases;利用阶段:将 interesing testcases 转换为 PoC
阶段1:基于探测的 Interesting Testcase 识别
magic string 插入,推断哪一部分被带入到了 PHP 代码中
阶段2:PHP语法引导的PoC生成
观察:payload 触发模板漏洞通常伴随着打破了原生成的 PHP 代码的结构
利用:包含一些 PHP 语法字符来打破代码结构(判断依据)
Fuzz 原则2:提高代码覆盖率同时避免冗余测试。
技术1:利用错误反馈自适应调整测试用例
观察:错误反馈信息通常会传达如何修复引起错误的测试样例;错误反馈信息种类较少
利用:半自动化的测试用例适配技术
技术2:利用运行时信息聚合测试用例
现有的 fuzz 框架的度量(代码覆盖 、调用栈信息) + 拓展
针对如何利用模板逃逸 bugs
挑战:PoC 可能会在不同的上下文(EC)中破坏PHP代码结构,并且每个破坏的PHP代码结构都必须以其特定的方式修复
解决:上下文敏感的漏洞利用
- 识别出 PHP 代码中 PoC 的转义上下文 EC
调整 PoC 来保证注入的 PHP 代码符合对应的转义上下文
贡献:总结了模板逃逸 bugs 的转义语义以及 payload 调整方法
实现细节
阶段一:Seed Collection
为每个模板引擎初始化测试样例。
Interesting Testcase Identification
探测技术创建测试样例 + 错误反馈调整;聚合类似的 interested testcases
聚合的困难:聚合方法不应该依赖于模板语法的先验知识
提出语法无关的测试用例聚合技术,判断点1 相似的 interesting testcases 应该拥有相同的代码占用空间 ⇒ 代码覆盖率相同;判断点2 相同的 EP 点 ⇒ magic string 出现在 PHP 文件中的行号一样
PoC 生成
语法制导测试样例突变技术 + 错误反馈调整 + PoC 聚合
PoC 聚合:覆盖相似性评估 覆盖行号的 Jaccard index;EP相似性 包含 EP 点的 PHP 代码行之间的 edit distance
How to fix the TE Error?
人工收集错误信息并编写对应的修正规则:
- File Adaption 创建对应文件并赋予可读权限
- Grammar Adaption missing params or attrs; unclosed symbols; unclosed tags
- Attribute Adaption 改变属性类型
EXP 合成
识别生成 PHP 文件的转义上下文,调整 PoC 使其包含在 EC 中(闭合语句)
如何识别转义上下文 EC
分类五种 EC:
在 AST 层面判断,Poc 本身会破坏 AST 结构难以定位 EP 点;用良性输入替换生成 PHP 文件的 AST ,对比识别出 EP 点及其归属的 EC
EXP 失效问题根源:忽略掉了模板代码解析过程????
如何正确闭合 PoC 在不同的 EC 中
- 利用 EC 和 EP 来寻找对应的闭合 payload (闭合了 EP 之前的语句)
- 闭合EP 之后的语句:单行注释符;同样依据 EC 和 EP 去寻找 payload
- 在闭合语句中间插入 RCE 代码
实验评测
TE 数据集
拥有沙箱机制/不支持直接执行PHP代码;基于生成PHP式的模板渲染引擎;知名度
编写 TE 驱动;抽离每个TE的分界符;编写自适应规则
种子收集
爬虫爬取文档中源代码相关的模板样例,正则编写抽取模板代码
性能评估
模板逃逸漏洞的普遍性和严重性
从 PoC 中可以总结出漏洞的成因:
- 模板代码解析过程中验证不严
PHP代码生成过程中过滤不严
并总结了容易产生漏洞的模板引擎特征:
复杂的模板语法
- 模板变量直接映射为PHP变量
- “乐观”的模板代码解析原则
- 生成PHP代码过程缺少过滤
对比试验
与一款 SSTI 扫描器:tplmap 进行对比
角度1:tplmap 能否发现模板逃逸漏洞?
角度2:TEFuzz能否指导 tplmap 进行 RCE ?
真实世界 Web 应用的漏洞挖掘能力
针对已知漏洞
分析现存 CVE 中的 SSTI 漏洞的成因,评估其是否符合本文所构建的威胁模型,验证可行性;
针对实验中涉及到的存在漏洞的模板引擎,利用TEFuzz进行RCE利用探索。通过成功对 CMS 造成 RCE ,来证实模板逃逸漏洞的严重性
针对 0day 漏洞
对比试验
SSTI 扫描器 0 产出 ⇒
检测依赖于 HTTP 相应,无法识别二次注入;固定的 payload 字典无法自适应不同的注入点上下文语义环境
手动找 SSTI 注入(根据威胁模型)+ TEFuzz RCE
TEFuzz 设计的性能评估
测试基于种子和 interesting case 样例生成的有效性、聚合的能力以及错误修复能力
评估测试样例自适应模块带来的有效性
针对 EXP 合成模块的探究:
exp失效的原因:
模板解析错误。过度闭合转义点上下文语义,导致模板解析过程已经无法通过
模板验证错误。标签解析后元素格式不符规定
寻求模板解析验证和 EXP 合成之间的平衡(调整使其通过模板解析验证功能,不可避免地需要去知道模板语法是什么??)
一些思考:在中间语言层面去挖掘通用型。如果想即符合语法规范,又要能闭合逃逸点上下文,则需要更加复杂的构造(论文中提到高超的 hacking skills),不可避免得在模板的语法作研究,但是本文是绕过它的
限制
- 对于新的模板引擎,需要手动抽离分界符、编写驱动和测试样例适应规则,耗费人力
- 无法检测种子语料库中未覆盖到的模板标签相关的漏洞
- 未考虑到模板引擎当中的控制流/数据流限制
- 一些思考
- 种子语料库的覆盖问题。结合 DL 生成一些模板预料
- EXP 合成模块的结果无法通过模板解析过程问题。
参考链接
[1] https://www.usenix.org/conference/usenixsecurity23/presentation/zhaoyudi
[2] CVE-2021-26119 PHP Smarty
[3] https://blog.gm7.org/个人知识库/01.渗透测试/02.WEB漏洞/05.SSTI注入/