前言
昨天冰蝎Behinder_v3.0 Beta 1发布,相较于冰蝎2.0做了一些修改,咱们先来看一下官方的更新说明:
2020.8.16 v3.0Beta 1 更新日志
1.去除动态密钥协商机制,采用预共享密钥,全程无明文交互,密钥格式为md5("admin")[0:16];
2.增加了插件机制,可开发安装自定义扩展插件;
3.UI框架由awt改为javafx,重写了大量逻辑;
4.增强了内网穿透功能,在原有的基于HTTP的socks5隧道基础上,增加了单端口转发功能,可一键将内网端口映射至VPS或者本机端口。
分析
在流量层,最重要的改动就是修改了原来明文认证密码并生成aes加密key的过程,将webshell连接密码md5加密后取前16位作为加密流量的密钥,脚本端变化(以php为例):
<?php
可以看到,这里将key写死了,直接使用这个key解密客户端传过来的aes流量,这个key的值是md5之后取前16位的rebeyond,也是冰蝎的默认密码:
接下来抓包看一下,在双击添加的webshell之后,客户端总共发送了4个数据包:
我们使用key将流量解密,跟冰蝎2.0一样,解aes后再解一次base64:
解密之后的post数据:
@error_reporting(0);
可以将此包理解为key的认证包,如果服务端返回了加密后的660aeec1-574f-45a6-9936-a27b0a7ce173,那么认证成功,进入后续流程
第二个包和2.0一样,会获取一些基本的信息,在php中,执行的就是**phpinfo()
**
第三个和第四个包发送的数据一致,作用是查看当前 web 目录下的文件
function main($mode, $path = ".", $content = "", $charset = "",$newpath)
在分析了开头的几个数据包后我们发现,由于流量中已经没有key值,所以就算我们捕获了冰蝎3.0的通信流量,也没有办法解密,只有找到上传webshell或者写入webshell的数据包拿到key值才行。
那么,我们如何在流量层中捕获冰蝎呢,所有的数据包全程无参数,每一次重新连接webshell时,ua也会变化。这时我们回到冰蝎连接时发送的第一个数据包,虽然进行认证的随机字符串会变化,但是长度是不会变的,这也就说明第一个认证包request和response的长度是固定的,包括第二个数据包获取基本信息的request长度也是固定的(php下长度为2220),但是由于每个服务器的环境信息不同,第二个包的response长度不是固定的。
那么在这种情况下,我们可以在全流量设备的加持下编写脚本,筛选出第一个包request长度为1112,response响应长度为128,第二个包request长度为2220的流量,即为冰蝎webshell产生的流量。
PS:上述分析基于php脚本,其他脚本略有不同,但分析思路是一样的。