通过遍历AST来解 SCTF 2021 FUMO_on_the_Christmas_tree
字数 1735 2025-08-29 08:30:36
SCTF 2021 FUMO_on_the_Christmas_tree 解题分析与AST遍历技术教学
1. 题目背景与概述
题目提供了一个14万行的PHP文件,主要考察通过静态分析技术(特别是AST遍历)来寻找从source(__destruct函数)到sink(readfile函数)的利用路径。
2. 关键概念解析
2.1 Source与Sink
- Source: 漏洞利用的起点,本题中是
__destruct魔术方法 - Sink: 危险函数调用点,本题中是
readfile函数
2.2 AST (抽象语法树)
AST是源代码的树状表示,便于程序分析和转换。在PHP中,AST节点类型包括:
- FunctionCall(函数调用)
- ClassMethod(类方法)
- 其他表达式和语句节点
3. 静态分析技术详解
3.1 Call Graph构建
3.1.1 直接调用分析
@$this->QsIFY2PS->xly0ZQT($Q0CGxlEy);
分析步骤:
- 查找方法名为
xly0ZQT的ClassMethod节点 - 从当前ClassMethod创建call边指向目标方法
3.1.2 __call魔术方法处理
当找不到直接方法时(如@$this->oS9D89Gt->Ws2xymT($NOCGzO)),需要通过__call分析:
- 识别
__call中的extract和call_user_func调用 - 提取
extract中的硬编码字符串作为目标方法名
3.1.3 __invoke魔术方法处理
对于@call_user_func($this->WHB5xkK7, ['LUlnpp' => $RwGAFc8G])这类调用:
- 检查类是否实现了
__invoke方法 - 验证
base64_decode参数是否匹配call_user_func参数的base64编码值
3.2 污点传播分析
3.2.1 变量状态跟踪
为每个方法创建变量状态Map,跟踪变量是否可控:
- 参数传入:默认标记为可控
变量状态[参数名] = true - 赋值操作:
$b = foo($a):若foo是sanitizer函数,则变量状态[b] = false$b = $a:直接继承状态变量状态[b] = 变量状态[a]
3.2.2 Sanitizer函数识别
本题中的sanitizer函数包括:
cryptmd5sha1base64_encode(需配合base64_decode计数器使用)
4. 解题实现步骤
4.1 工具选择
使用github.com/VKCOM/php-parser解析PHP8代码,基于Go语言编写分析工具:
- 优势:处理大规模代码效率高
- 替代方案:CodeQL(但原生不支持PHP)
4.2 分析流程
- 解析PHP生成AST
- 遍历AST识别所有ClassMethod节点
- 构建Call Graph:
- 处理直接调用
- 处理
__call和__invoke魔术方法
- 执行污点传播分析
- 查找从
__destruct到readfile的可达路径
4.3 关键代码逻辑
// 伪代码示例
func buildCallGraph(astNode) {
switch node := astNode.(type) {
case *php.FunctionCall:
if isMethodCall(node) {
// 处理直接方法调用
resolveDirectCall(node)
} else if isCallUserFunc(node) {
// 处理call_user_func
resolveCallUserFunc(node)
}
// 其他节点处理...
}
}
func taintAnalysis(methodNode) {
// 初始化变量状态
state := make(map[string]bool)
// 标记参数为可控
for _, param := range methodNode.Params {
state[param.Name] = true
}
// 遍历方法体语句
for _, stmt := range methodNode.Stmts {
// 处理赋值和函数调用
}
}
5. 高级技巧与优化
5.1 动态特性处理
- 对
extract和call_user_func进行特殊处理 - 跟踪变量名生成模式(如base64编码值)
5.2 路径优化
- 优先分析短调用链
- 对sanitizer函数进行标记,提前终止不可行路径
5.3 误报消除
- 实现
base64_encode/base64_decode计数器平衡检测 - 添加更多sanitizer函数识别
6. 总结与扩展
6.1 技术总结
- AST遍历是静态分析的核心
- Call Graph构建需要考虑PHP特有的魔术方法
- 污点传播需要精确跟踪变量状态
6.2 扩展应用
- 可应用于其他PHP代码审计场景
- 技术可迁移至其他语言的静态分析工具开发
- 结合动态分析提高准确性
6.3 改进方向
- 实现更精确的字符串分析
- 添加类型推断减少误报
- 支持更多PHP动态特性分析
附录:参考工具与资源
- php-parser - PHP8解析器
- 解题工具源码
- CodeQL(虽然不支持PHP,但分析思路可借鉴)