PHPJiaMi 免扩展加密分析及解密 作者: Chuwen 时间: 2018-07-05 分类: PHP,其他分类 # 0x00 前言 前几天去玩了 pwnhub 公开赛的题目,源码下载之后发现是 PHPJiaMi 加密。之前有分析过 phpjm 加密并写出过解密文件,所以研究下这个 PHPJiaMi。 PHP 免扩展加密的主流加密方法采用了 ascii 码 129-255 的乱码来实现变量名、函数名混淆,编辑器打开后就是一堆乱码,造成不可读。 > 加密流程:源码 -> 加密处理(压缩,替换,BASE64,转义)-> 安全处理(验证文件 MD5 值,限制 IP、限域名、限时间、防破解、防命令行调试)-> 加密程序成品,再简单的说:源码 + 加密外壳 == 加密程序 ([该段出处][1]) # 0x01 解密准备 这里做演示,我写了 phpinfo() 然后去 http://www.phpjiami.com/ 生成加密文件,打开之后,果然都是一片乱码。 使用代码修复工具 http://zhaoyuanma.com/phpcodefix.html 将 ascii 不可见字符的变量修复成正常的变量名,再 PHP 代码美化,方便下一步分析。 # 0x02 函数分析 代码内有三个函数,由于每次加密这三个函数的顺序都不一样,这个以传参方式区分这三个函数 fun1 = ($var1, $var2 = '') = 核心函数,将乱码转成正常字符串 fun2 = (&$var1, $var2) = 校验 IP、域名,防止被破解。最后一句是解密整个 php 文件 fun3 = ($var1) = 将需要用到的函数赋值给 N 个全局变量 先从 fun1 开始逆起,在编辑器中双击变量名,该变量高亮之后,可以看到它怎么变化,在哪里被使用。 一句句语句逆下去,发现有语法错误,其实是代码修复后的 bug,用 winhex 打开定位到这句代码,发现是三元运算符 ```php $var2 = !$var2 ? ord('乱码') : $var2; ``` 接下来是一句很奇怪很无用的代码,再下一句是 for 循环,我猜测是给 $i 赋值 ```php for($i=0; $i $var2 && ord($var1{$i}) < ord(pack("H*",'F5'))) ? chr(ord($var1{$i}) / 2) : $var1{$i}) : ''; } $de1 = base64_decode($str); $len = $len2 = strlen($md5); $str2 = ''; for($i=0; $i ,chr,addslashes,rand,gzuncompress,assert_options,assert,file_exists,file_get_contents,substr,unpack,constant,strpos,create_function,str_rot13,md5,set_include_path,dirname,preg_replace,base64_encode,base64_decode, 接着暂且先不看 fun3,回到主代码中。 ![2265835617.png][2] 这里创建了一堆全局变量,通过 fun2 赋值,每个变量都代表一个函数名 ![1848056089.png][3] 接着还原 fun3 函数,步骤一样。 ```php function fun3() { php_sapi_name() == 'cli' ? die():''; $file = file_get_contents(__FILE__); if(!isset($_SERVER['HTTP_HOST']) && !isset($_SERVER['SERVER_ADDR']) && !isset($_SERVER['REMOTE_ADDR'])) { die(); } $time = microtime(true) * 1000; if(microtime(true) * 1000 - $time > 100) { die(); } if(strpos(__FILE__, gtmclaei) !== 0){$exitfunc();} !strpos(de1(substr($file, de1('A8414145'), de1('A841AA3D'))), md5(substr($file, de1('AAA23D3D'), de1('A8414190')))) ? unkonw1() : unkonw2(); $loc1 = fun1('A841AA45ACEE3D3D'); $loc1 = fun1('A8414190'); $de = str_rot13(gzuncompress(fun1(substr($file, $loc1, $loc2))));//核心解密 return $de; } ``` 后面的代码已经不用再看了,fun2 解出来的就是解密后的原代码。 ![3757017134.png][4] 最后附上解密脚本 http://sec2hack.com/phpjiami.zip [1]: http://www.liqingbo.cn/blog-1325.html [2]: https://cdn.nowtime.cc/2018/07/05/1620135597.png [3]: https://cdn.nowtime.cc/2018/07/05/1195882919.png [4]: https://cdn.nowtime.cc/2018/07/05/4218976599.png 标签: PHP