Chuwen 发布的文章
PHPJiaMi 免扩展加密分析及解密
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 libcurl 封装异步并发 HTTP 客户端
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();
}