冰蝎动态二进制加密WebShell的检测

中国菜刀等工具管理WebShell的时候会有一些固定的特征,容易被WAF或者IPS检测到,最近1年出来了个动态加密的WebShell管理工具,给检测带来了一定的困难,所以写个文章简单解剖一下。

注:本文只针对当前的最新版冰蝎(Behinder) v2.0.1,以PHP WebShell为例,其他WebShell只是有细微的差别,有兴趣可以自行研究。

 

实验环境

客户端: Windows 7 + 冰蝎(Behinder) v2.0.1服务端:Ubuntu 16.04 + Apache + PHP
Webshell文件分析以php为例

其实就两个功能

1、首先存在pass参数的情况(其实这个就是通常所说的一句话木马),就是通过截取随机数的md5的高16位作为密钥,保存在服务器的全局 $_SESSION变量中,同时打印出来,这样客户端接收到就可以用这个密钥进行通信了。2、假如不带参数,就是加密通信的过程。假如PHP不存在OpenSSL这个extension,就是用base64解码后,使用key进行循环异或解密。而存在OpenSSL就使用AES128进行解密。基于上面分析可以得到通信流程:
下面我们看看实际通信流量。
数据包分析
通过在服务器上传WebShell,客户端连接后通过wireshark抓取数据包。
可以看到请求了两次密钥才开始真正的POST通信,接下来的通信,就是AES128加密后的base64密文。
所以我们检测只能从请求密钥阶段入手了。
通过获取密钥的数据包,我们发现以下特征:
1、使用GET方法
2、参数名即木马的密码(这个可以修改,不能作为特征),但是参数值为纯数字可以作为特征,暂时来看应该1到5位数字可以匹配到了,保险一点可以1-8都可以
3、请求中有HEADER字段:Content-type: application/x-www-form-urlencoded
4、响应中会有Content-Length: 16
5、当然响应的body肯定也是16长度,而且字符是16进制的字符,即[0-9a-f]通信过程实际发送的payload通过在WebShell中加入如下代码,即可获得解密后的payload。

获得的如下:(由于base64_decode后面的比较长所以省略了)

assert|eval(base64_decode(‘QGVycm9yX3JlcG9ydGluZygwKTsNCg0KZnVuY…………………………’));

所以它就是将字符串base64解密之后通过eval执行。

解码上面的base64串得到下面真正的代码(以命令执行为例的代码):

可以看到考虑了编码问题,还有一些执行命令的函数被禁用的问题,最后输出结构也是AES128加密的。只需更换倒数第二行$cmd的”whoami”,就可以执行其他指令。

 

总结

攻防是不断对抗升级的,冰蝎虽然通信过程加密,但是请求密钥阶段有很多特征,假如将请求密钥阶段特征抹掉,那么我们防御端会更加难以检查。

<作者:陆巨枝-绿盟科技网络攻防实验室>

发表评论