诈尸水一篇博文。8月份写的一个解密加密PHP源码的工具( http://d.poetn.cc:7727/),打算小范围使用。刚好最近看到 PwnHub 上有个解密的题目,p神微博上吐槽居然有人花钱解密了,2333 那分享一波另类解密思路吧。
从 WebShell 混淆说起
经常跟 WebShell 打交道的朋友会比较清楚,最觉见的 WebShell 是这样的:
1 | <?php eval($_POST['cmd']); ?> |
然后这种 Shell 很容易就会被静态查杀的正则匹配出来,于是就出现了变形,比如这样:
1 | <?php |
隐藏一下 eval 关键字,比如用一下 base64 就是这样的:
1 | <?php |
这里给个我之前录的 AntSword 过狗的一个视频感受一下: AntSword过狗演示(1)
反正就是各种变形,比如下面这样的:
1 | <?php |
诸如此类的 WebShell 特别多,每次手工去解挺麻烦的,有没有什么好思路呢?答案是:有
一句话 WebShell 共性
一句话 WebShell 再怎么变形,它们的行为是一致的:「执行客户端发送过来的代码」,为了方便嘛。
关于这个「代码执行」,方法就比较多了,举几个简单常见的能引起代码执行的函数(方法):
1 | eval |
说这些函数有什么用呢?是想收集然后做正则吗?
累不死你
基于 Hook 机制检测
调用 eval 等代码执行的函数,最终会调用 php 内核的zend_compile_string
函数。
所以呢,我们只用Hook住这个函数,就差不多了,具体关于 Hook 机制的讲解,后面找到好的文章了再贴上来。
提一嘴子,D盾、云锁等安全防护产品说的 「免疫一句话 WebShell」 就是基于这个原理来的。据我所知,D哥应该是国内最早搞这个的。任你一句话再怎么变形,最终还是逃不过这道门。
哦对了,说到 D 盾的一句话免疫机制,D哥之前说过,只杀「参数 eval」,所以还是给了一点点可以使用 eval 的机会滴,具体就不在这说了,不然会被打死(逃..)
再来说解密,很多加密方式也是这样,先把源代码字符串各种捣腾,然后在执行的时候,会还原回来,还原回来之后的代码是字符串,那要怎么执行呢? Bingo, 用 eval
执行喽。
所以说,我们完全可以 Hook 住 zend_compile_string
,然后在每次调用的时候呢,把这个函数的参数 dump 出来,就能达到解密的效果了。
具体呢,参考一下老外的这篇文章:Decoding a User Space Encoded PHP Script
也可以参考一下 TSRC 的这篇文章:浅谈变形PHP WEBSHELL检测
老外的代码下载点这里:evalhook-0.1.tar.gz
在线解密工具 PHPDecode
这个工具做了什么?
把 PHP 代码上传之后,执行,然后 dump 出 eval 的参数,以完成解密效果
酱酱〜首页
酱酱〜登录后
显示解密记录,下载解密的每一步中间代码,任务出错后可手动重试任务
快夸一下我的页面真好看,哈哈哈哈好不要脸
单文件解密
单文件解密的前提是需要这个单文件能单独执行,如果该文件执行解密逻辑的时候需要配合其它文件触发,就得一起喽,没啥说的
以这个 WebShell 为例:
1 | <?php |
将上述代码保存成 1.php
,然后上传,就能看到解密后的源代码了:
1 | function __lambda_func(){eval($_POST[1]);} |
__lambda_func 说明是匿名函数,可知上面的代码是
create_function
来实现代码执行的,这个 WebShell 的密码是 1
除了解 WebShell, 像 phpjm 这样的是可以用这种办法轻松解的(如果有变量名混淆,是还原不回变量名的)。
多文件解密
如果直接访问该文件不能触发解密,就用到多文件解密了。
本来想以 PwnHub 傻 fufu 的工作日 这道题为例来说,看了一下时间,还在比赛中,还是不说了,后面等结束了再说吧,哈哈哈。
我们还是以上面那个代码为例子来说怎么用
1 | <?php |
将上述代码保存成
123.php
由于我们把
$_=$_fF("",$_cC);@$_();
这段代码干掉了,导致不能触发 eval, 所以单独上传这个文件是不行滴。编写
index.php
1
2
3
4<?php
include "123.php";
$_=$_fF("",$_cC);@$_();
?>在 index.php 里面把1的文件导入进来,然后触发(实际解密的文件解密代码肯定比我给的例子要直观的多)
将两个文件打包成 zip 文件,然后上传
酱酱〜,就解完了
实战解密之「PwnHub 傻 fufu 的工作日
具体非解密部分的细节在此不表述,我们只关注解密这部分。
拿到
UploadFile.class.php
,部分代码如下:从头部加密信息来看,是用的 PHPJiaMi,看到代码里面有
eval
,那这种方式解密成功率就很大了。直接解该文件没成功,说明存在调用才会解密的情况,从
index.php
里发现了调用的代码。1
2
3
4
5
6
7if($_FILES) {
include 'UploadFile.class.php';
$dist = 'upload';
$upload = new UploadFile($dist, 'upfile');
$data = $upload->upload();
}
?>把原来的
index.php
拿过来,我们需要在上面2中的代码前构造表单里的变量,让它能成功执行,所以我们最终的index.php
是这个样子1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<?php
$_FILES["upfile"] = array(
"name" => "1303.jpg",
"type" => "image/jpeg",
"tmp_name" => "/tmp/php/phpSDsuf7",
"error" => 0,
"size" => 1024
);
// 上面的代码是加的
if($_FILES) {
include 'UploadFile.class.php';
$dist = 'upload';
$upload = new UploadFile($dist, 'upfile');
$data = $upload->upload();
}
?><!DOCTYPE html>
<html>
....后面省略然后把
index.php
和UploadFile.class.php
打个 zip 包, 注意 index 所在的目录不要打包进去1
$ zip -r mytest.zip index.php UploadFile.class.php
把
mytest.zip
上传后,如果出现解密失败,点后面的重试
,就能看到结果了。
最后
说下服务端,基于 Flask 和 MongoDB 做的,总共花了2天时间(写页面就花了1天半,强迫症害死人),暂时就先这样吧,不完善的地方还比较多,不打算现在放出来给大家玩了,就只邀请了几个朋友参与内测。
在线解的话肯定不怎么灵活,建议呢,自己去装老外写的那个 evalhook 来解「防同行马」喽〜
邀请码
如果有兴趣,欢迎来体验「会删档」的内测,有什么好的建议欢迎邮件交流
PS: 还有一个页面没写完 2333
[20180727邀请码]
- 9728c6ce-27c9-5d85-9204-abe897c90378
- eabdb169-2933-5ac3-a7ca-25ec5e8c1a16
- fb011a3a-dd7e-5ae4-b3f5-90157274e333
- 84a786f3-06e1-59c0-9c5c-d8a1c9458355
- 2b8c0b16-f410-5d51-92ee-c8734106d326
- 586f70e6-dc35-5e99-851f-cd960064001e
- f89e78a1-6d1e-5ed8-9df9-ab7aa4d54732
- 13eab2a0-74ba-5e62-80be-cf901d5dc482
- ef1b533a-69b0-5af0-b483-361ca59282bf
- 047ad00f-56f7-545b-9995-98d7c0c19c10
- 5b3f6054-a004-585e-97f5-cafa1d74ecbe
- eea8749c-dda2-5aac-ab9c-72ca275228db
[20170921邀请码]
873225de-fd6f-5de3-b55a-9eb43629215d0d2de847-f873-5801-8dfe-4252694da74d7c8875c4-6214-5875-b6fd-1d619b76e67162dcca8f-388a-5999-b65b-9c1fc94af7e4b1779fed-4a3f-5e42-acac-0da991a65c53