Author:AI@TOD

1.前言

本文主要针对冰蝎3.0beta3版本在php环境下进行分析。分析内容包括:beta3版本建立连接开始过程以及可能特征分析。
备注:由于beta2版本很多bug,因此估计不太可能被使用,因此这里分析beta3版本。作者的更新挺快的,明显的特征被消除掉了,增大了检测难度。

2.PHP-webshell分析

PHP的webshell没有变化,如下图:

2.1.错误密码通信过程

首先输入错误密码admin,发送第一个连接的数据包。由于密码错误返回包的数据为空。

下面使用beta3版本测试,并且这里尝试使用错误密码测试多次。

通过测试发现第一个认证数据包的大小不固定。本次测试第一次第一个数据包为3052字节,第二次为6360字节,第三次(成功)为4440字节。

通过逆向分析发现作者对代码进行了优化,有多层try catch等。首先进行aes解密,如果失败则进行异或解密再失败则进入到密钥协商的流程中,数据流量看beta3和beta2相同。

解密第一个认证数据包方式相同,解密后格式也相同。

构造数据格式相同,如下图:

解密后第一个认证数据包,发现content变量变成了很长的字符串。

beta2的UUID方式变成了随机字符串,因此$content变量变成了随机字符串,并且长度为随机的不大于3000个字符。如下图:


通过上述随机长度的字符串的方式可知,第一个认证数据包的大小是变化的,因此这里将无法使用长度作为辅助检测的依据。

2.2.正确密码通信过程

第一个认证数据包解密通过则执行php代码然后返回数据。如下图:

解密返回的数据包格式与beta2版本相同,msg进行base64解编码后为随机字符串。因此返回的数据包大小也不会固定。

第二个数据包获取基本信息

解密后,beta3比beta2多出$whatever变量,里面存放随机字符串。这样规避了流量检测。


通过逆向分析可知,读取payload中的php代码时,加入了whatever变量,并赋值为随机字符串。

同时通过随机时间请求获取基本信息方式来保持存活状态。

BasicInfo获取的信息beta3和beta2完全相同。

第三个数据包为获取当前目标文件信息。

解密后,部分关键代码片段如下图:

然后测试执行cmd命令whoami


解密后,部分关键代码片段如下图:

返回数据解密后与beta2版本相同,如下图:

3.特征分析

通过分析可知目前beta3版本将UUID替换为随机长度的字符串,因此导致第一个认证数据包和返回数据以及第二个获取基本信息的数据长度不固定,不能像beta2版本一样进行检测。

3.1.HTTP头

代码中默认的HTTP头部(其他语言通用)。

1
2
3
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Language:zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Content-Type:text/html;charset=utf-8

其中Content-Type为php才用的。
User-Agent字段随机,如下图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36
Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36
Mozilla/5.0 (iPhone; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/84.0.4147.122 Mobile/15E148 Safari/604.1
Mozilla/5.0 (iPad; CPU OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/84.0.4147.122 Mobile/15E148 Safari/604.1
Mozilla/5.0 (iPod; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/84.0.4147.122 Mobile/15E148 Safari/604.1
Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Mobile Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36
Mozilla/5.0 (iPhone; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/84.0.4147.122 Mobile/15E148 Safari/604.1
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:79.0) Gecko/20100101 Firefox/79.0
Mozilla/5.0 (X11; Linux i686; rv:79.0) Gecko/20100101 Firefox/79.0
Mozilla/5.0 (Linux x86_64; rv:79.0) Gecko/20100101 Firefox/79.0
Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:79.0) Gecko/20100101 Firefox/79.0
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:79.0) Gecko/20100101 Firefox/79.0
Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:79.0) Gecko/20100101 Firefox/79.0
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2)
Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko
Mozilla/5.0 (Windows NT 6.2; Trident/7.0; rv:11.0) like Gecko
Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko

比beta2.0多出一些移动终端的user-agent头部。部分旧的user-agent被替换。

4.小结

beta3版本比beta2版本加入了随机字符串(替换了UUID),以使认证数据包和响应数据以及获取基本信息的数据包长度不固定导致无法通过长度去快速检测。但是后续执行命令等操作没有加入随机字符串(不要被作者看到),也可以通过检测一些常见命令如whoami,id等,不过由于数据包出现位置不固定,可能导致检测量较大。

目前只有使用一些默认的HTTP头部进检测,但存在一定误报。这些头部都可以通过逆向方式进行修改逃避检测,具有加大局限性。因此加上对内容进行判断是否均为base64编码字串集能降低部分误报。所以结合web日志的url请求记录通过统计分析方式可以进行进一步降低误报。

由于使用AES的CBC模式,因此生成一些常见密码的加密数据作为特征也能匹配,不过太片面和鸡肋。

题外话;对于攻击方就很容易修改了,算法、请求头、优先使用https等太多点可以规避检测了,webshell再做一次加密规避edr类设备就更好了。由于这些都是java程序可以反编译,因此重复造轮子copy的难度极低,这样可以实现定制化,甚至中间人改包都可以。