0x00 前言

前几天去玩了 pwnhub 公开赛的题目,源码下载之后发现是 PHPJiaMi 加密。之前有分析过 phpjm 加密并写出过解密文件,所以研究下这个 PHPJiaMi。
PHP 免扩展加密的主流加密方法采用了 ascii 码 129-255 的乱码来实现变量名、函数名混淆,编辑器打开后就是一堆乱码,造成不可读。

加密流程:源码 -> 加密处理(压缩,替换,BASE64,转义)-> 安全处理(验证文件 MD5 值,限制 IP、限域名、限时间、防破解、防命令行调试)-> 加密程序成品,再简单的说:源码 + 加密外壳 == 加密程序 (该段出处)

0x01 解密准备

这里做演示,我写了 phpinfo() 然后去 http://www.phpjiami.com/ 生成加密文件,打开之后,果然都是一片乱码。
使用代码修复工具 http://zhaoyuanma.com/phpcodefix.html 将 ascii 不可见字符的变量修复成正常的变量名,再 PHP 代码美化,方便下一步分析。



- 阅读剩余部分 -

PHP 标准库内置 curl 扩展,不过实现不完整,如 multi_socket_action 接口。

无意中发现 pecl http 库同样基于 libcurl 封装,支持更多的libcurl特性,更新也比较快,底层通过 libevent(epoll) 实现 multi_socket_action 接口。

不过 pecl http 版本1和版本2 api完全不兼容,使用过程中稳定性及性能并不如PHP内置的curl,好像还有内存泄露,以下为示例代码,基于 pecl_http 2.20

<?php
function push($client, $url) {
  $req = new http\Client\Request("GET", $url, ["User-Agent"=>"My Client/0.1"]);
  $req->setOptions(array('connecttimeout'=>1, 'timeout'=>1));
  $client->enqueue($req, function($response) use ($client, $req, $url) {
     printf("%s returned '%s' (%d)\n", $response->getTransferInfo("effective_url"), $response->getInfo(), $response->getResponseCode());
     echo $client->count().PHP_EOL;
     global $urls;
     if ($urls) {
        while ($client->count() < 20) {
           $url = array_shift($urls);
           push($client, $url);
        }
        return true; // dequeue
     }
  });
}

$client = new http\Client;
$client->enablePipelining(true);
$client->enableEvents(true);

for ($i = 0; $i < 10000; ++$i) {
  $urls[] = "http://192.168.1.3/";
}
for ($i = 0; $i < 20; ++$i) {
  $url = array_shift($urls);
  push($client, $url);
}
/*
try{
  var_dump($client->send());
}
catch(http\Exception\RuntimeException  $e)
{
  echo 'Message: ' .$e->getMessage().PHP_EOL;
}
*/

while ($client->once()) {
  $client->wait();
}

- 阅读剩余部分 -