-
0x01 "冰蝎" 获取密钥过程
冰蝎执行流程 (图片来自红蓝对抗——加密Webshell“冰蝎”攻防)
冰蝎在连接webshell的时,会对webshell进行两次请求访问
为什么进行两次访问? 我在别的文章没有看到关于这个问题的答案,于是我去反编译冰蝎源码
通过对代码阅读,我发现冰蝎为了实现可以在webshell内添加任意内容 (比如gif89a子类的文件头或者其它标示字符) 冰蝎在初始化密钥时会对webshell进行两次访问,然后比较两次页面返回的差异,把两次请求都相同的字符记录一个位置,后续加密会用到这两个位置(beginIndex,endIndex)
)
如图,根据数据包,beginIndex:8 endIndex:4 (含换行),冰蝎开始从数据流中截取被加密的数据从下标8开始到(数据包总长度-4) Waf可以针对于返回类型为 "text/html" 的数据包中加一些空格或者换行,来扰乱冰蝎的数据包,导致冰蝎无法运行 (为什么要对返回类型为 "text/html" 的扰乱,别的格式不可以吗? 答案:jsp默认返回类型就是 "text/html" html添加一些空格或者换行,并不会影响网页的正常运行) -
0x02 "冰蝎" 解析Cookie流程
我们可以看到请求协议头中的Cookie字段,冰蝎在合并处理Cookie的时候没有考虑到,Cookie的一些属性 (比如 Path 或者 HttpOnly 之类或者其它的) 冰蝎直接把返回协议头中的Set-Cookie字段直接添加到下一个请求包的Cookie字段中
正常的请求是不会携带Cookie属性的,这可是识别冰蝎流量最直接的一种办法 -
0x03 "冰蝎" 动态加载
冰蝎动态加载的原理就是每次都发送一个class字节码(其它语言也一样) 冰蝎通过asm动态修改class字节码变量内容,实现携带参数动态执行,冰蝎在获取完密钥之后(2个请求),第三个请求就是获取BasicInfo(服务器的一些信息),冰蝎的BasicInfo功能并没有动态修改参数(一个获取服务器信息的能有啥参数),这会导致每次获取BasicInfo的数据包都是固定的大小 -
0x04 总结
Waf可以对一个ip连续访问2次的数据包进行截取,比对相同字符,比对之后,截取两次不同的数据,如果剩下的是16位的key,就可以证明这两个数据包就是冰蝎发出的,第三个数据包通过 0x02,0x03 中的一些bug,可以100%的匹配到冰蝎流量,不会误报