PHP AST + 反混淆 + 矩阵快速幂
唯一带有Web特征的逆向题
题目是一个经过混淆的PHP抽象语法树文件,请点击题目下载
一开始想直接找抽象语法树(AST)转为PHP代码的函数,找到了pretty_printing,但是尝试许久,无法直接将AST初始化
JsonDecoder
继续查资料看到PHP-Parser可以将json字符串和AST进行互转
https://github.com/nikic/PHP-Parser/blob/master/lib/PhpParser/JsonDecoder.php
AST转json脚本如下
1 |
|
其中json字符串如下
1 | [ |
AST如下
1 | array( |
根据上面的例子,我们可以观察到要把AST转为Json需要进行以下处理:
- 将
array(...)
转换为[...]
- 将
Stmt_Function(...)
转化为{"nodeType": "Stmt_Function", ...}
- 对于全部字符串要加上引号
- 在
"nodeType"
后面添加"attributes": {}
属性
这里给出一个AST转Json的脚本
1 | import re |
最后再用上面的pretty_printing代码转出一份稍微好看点的混淆过的PHP代码
1 |
|
反混淆
因为混淆用的是闭包函数,所以用正常的xdebug调式并不能看出函数间的调用,而且会因为函数调用层数过多而报错,所以这里唯一的技巧就是手动化简变量名(x
这里给出一份自己处理后的代码
1 |
|
基本逻辑都写在注释里面了,代码的重点在如何找到for循环的规律,正所谓逆向七分解三分猜,这里其实就是对$v2,$v3的数据进行处理,而且是整整齐齐的三组数据连起来进行计算
我们先把矩阵打印出来看看
1 | 0: [3,5,9,8,0,4,9,9,8] => 第一步的$v2 |
再把经过第一次转换的flag打印出来
1 | flag{76-27-139-76-72-104-141-81-217} |
然后我们就可以猜测其实它们就是进行了这样一个运算
1 | $v4[0] = $v2[0] * $v3[0] + $v2[1] * $v3[3] + $v2[2] * $v3[6]; |
根据这个规律我们可以得到初步的exp
1 | def calc(): |
矩阵快速幂
想要上面的脚本暴力解出来不可能的,因为需要3377699221405695次运算
仔细观察,其实这刚好是一个3组3*3矩阵连乘的运算,这里考察的是一个矩阵快速幂的算法
推荐使用SageMath解题,SageMath整合了很多数学的常用算法
参考@ver大哥exp给出自己的exp
1 | #/usr/bin/sage |