很多人都说冰蝎好用,流量加密的,可是流量加密在哪里,很多人可能还是懵懵懂懂的,于是就分析记录了一下,大佬勿喷。

AntSword流量分析

蚁剑有一个非常好用的扩展功能为编码器和解码器,利用此功能可以自定义加密,这里分析的是默认的加密方式,在文章最后放了一张图方便大家理解。
蚁剑中默认的编码模块有:base64.js、chr.js、chr16.js、rot13.js。这里分析一下常用的base64模块为例,查看编码器 randomID 随机生成一个随机数,需要执行的代码在 data['_'] 当中,下面的Buffer.from(data['_']).toString('base64'); 就是将 data['_'] 中的内容进行base64编码,其中可以看到 data[pwd], 此函数的作用是作为参数传递的,所以这里在流量当中是明文传输。


从上图可以看到 _0x81bf9df1758a97 这个参数是base64加密的,但是aaa这个参数并不是加密的,但是这种加密也是非常容器被waf探测到,其他的编码器也是相同的道理,其中有url编码,生成随机字符串为变量名称,chr编码,16进制编码。

蚁剑内置了一个编码器模块,有一个RSA模块,使用了RSA非对称加密进行传输,新建编码器 -> RSA配置 -> 点击生成公私钥,然后将生成好的shell放到目标机器点击连接查看流量,可以直接使用公钥进行解密,但是这种需要目标机器安装OpenSsh扩展库才可以。

蚁剑修改了编码器也会有一个明显的特征就是在执行命令,文件操作等地方会有0x开头的参数,这是写死在蚁剑源码当中的跟编码器无关,Git好像有一个大佬改了蚁剑把这个特征删掉了,如删掉请忽略。

冰蝎2.0流量分析

代码分析:
以php版本的webshell为例分析,查看冰蝎的webshell代码,先会对 Get 传入的pass这个参数进行检查,如果存在的话会以时间的方式生成长度16的随机key,然后存入到session当中,再往后判断是否开启了openssl这个扩展,开启的情况就会开启AES进行解密,得到中间结果字符串 assert|eval("phpinfo();") 此数据是由冰蝎加载器发出的,已经定义好的,服务端利用explode函数将拆分为一个字符串数据,然后以可变函数方式调用索引为0的数组元素,参数为索引为1的数组元素,即为 assert("eval("phpinfo;")")。没有开启的情况,进行异或处理然后通过base64加密。这就是同时在早期有一定的免杀效果,但是这个函数现在已经被标注为危险函数。

流量分析:
使用Wireshark 查看连接webshell的流量进行分析,查看会发送俩次Get请求,分为俩次Get的握手请求,第一次请求服务端产生密钥写入session,session和当前会话绑定。不同的客户端的密钥也是不同的,第二次请求是为了获取key。此时的 99030fc0bb93de17就为解密代码的key。

post的数据可以利用上面的Key进行解密获得代码,可以自己写代码也可以使用在线网站进行解密,在线网站只有在这个网站解密成功,http://tools.bugscaner.com/cryptoaes/

解密后的内容会对代码再次进行了一次base64的编码。

左边是没有开启OpenSsl扩展的响应,右面是开启OpenSsl扩展的,对响应进行AES的解密 (下图2) ,base64解码后的内容:{"status":"success","msg":"1a6ed26a-009d-4127-a6fb-1fd4e90c84fa"}


现在很多厂商已经对返回的内容进行匹配。所以这种动态加密的方式会在冰蝎3取消。

冰蝎3.0流量分析

代码分析:
同样这里以php分析为例,查看shell代码,对密码进行了md5的加密,少了一个响应随机生成16位字符key的功能,改了一个ui的框架,界面由swt改为javafx。

流量分析:
分析流量发现相比2.0少了动态密钥的获取的请求,aes密钥变为 md5("pass")[0:16] 意思就是为32位md5的前16位。全程不再交互密钥生成。一共就俩次请求,第一次请求为判断是否可以建立连接,少了俩次get获取冰蝎动态密钥的行为,第二次发送phpinfo等代码执行,获取网站的信息。

解密第一次发送的数据查看,这里有一个参数为 $content 这个变量名称和里面的内容为随机生成的, 目的是为了绕过 $Content-Length ,这个已经在冰蝎2.0中已经被加入了Waf的检测规则当中,所以在冰蝎3.0当中用数据填充的方式绕过。

由此可以看出冰蝎2.0和3.0的区别主要在于取消动态密钥获取,目前很多waf等设备都做了冰蝎2.0的流量特征分析。所以3.0取消了动态密钥获取。

哥斯拉流量分析

这里首先查看一下PHP的加密器 PHP_XOR_BASE64 的代码 ,其中 $E 为异或的加密或解密, $F=O(E(O($_POST[$P]),$T)); 主要用于解密代码, 解密流程为:接受代码 -> Base64编码 -> E函数进行异或加密 -> 再Base64编码Q(E(@run($F),$T)); 为加密代码,加密流程为: E函数进行异或加密 -> Base64编码。最后密码和后面的字符串进行md5加密,其中 $T 为密钥的md5值的前16位,以16位字符分割为2份分别输出在加密内容的首部和尾部。

点击哥斯拉的测试连接功能发现一共发送了三次包,第一段为加密的php代码,非常的长,第一个包的响应为空。


$V、密码 $P、Key $T 复制出来,还有base64解密的函数 E、异或的函数 O,单独摘出来,然后使用$F=O(E(O($_POST[$P]),$T)) 进行解密。


解密后的代码一共300多行,包含各种功能,如获取服务器基本信息、文件上传、命令执行、数据库操作等功能的函数。

第二个请求响应AWEzAAN/WFI3XHNGaGBQWDEHPwY4fSQAM2AIDw==,解密后为 methodName=dGVzdA== ,后面的 dGVzdA==为test的base64编码,用来测试shell的连通性,成功会向客户端返回OK。

注:响应解密的时候需要将前16位和后16位删除。

第三个请求是为了获取环境变量。

第二种加密Raw和Base64加密的区别:

Raw : Raw是将加密后的数据直接发送或者输出

Base64 : Base64是将加密后的数据再进行Base64编码

哥斯拉的jsp的加密和PHP的加密不同,Jsp的加密主要为Base64+AES,AES的key是将生成shell时的 key 的md5 32 位前36位进行切割。

这里为响应的代码,影响为密码的md5的首尾,和PHP的加密器的响应器的内容相同,修改响应的代码,如下图2中的黄线内容,直接响应base64的内容。


流量同样是三次请求,第一次请求为空,第二次响应为methodName=dGVzdA==dGVzdA== 为OK,第三次为网站的环境变量。

加密流程:

AntSword:

requests response
base64等方式 明文

冰蝎2.0:

requests response
开启Openssl扩展-动态密钥aes加密 aes加密+base64
未开启Openssl扩展-异或 异或+base64

冰蝎3.0:

requests response
开启Openssl扩展-静态密钥aes加密 aes加密+base64
未开启Openssl扩展-异或 异或+base64

哥斯拉:

requests response
php的为base64+异或+base64 异或+base64+脏字符
jsp的为Base64+AES aes+base64+脏字符

最后贴上一张蚁剑的编码器和解码器的理解图。

参考链接:

https://www.anquanke.com/post/id/224831
https://www.cnblogs.com/pcheng/p/9629621.html
https://wh0ale.github.io/2019/09/23/%E5%86%B0%E8%9D%8E%E9%80%9A%E4%BF%A1%E7%A0%94%E7%A9%B6/

点击收藏 | 6 关注 | 2
  • 动动手指,沙发就是你的了!
登录 后跟帖