肉眼研判小技巧

简介

  哥斯拉是一个比较常用的远控工具,目前已经停止更新。下面将从流量层面介绍这款工具,方便在护网时候对该工具产生的流量进行研判。

  哥斯拉内置了 4 种 Payload 以及 14 种加密器,6 种支持脚本后缀,20 个内置插件

  JavaDynamicPayload
   JAVA_AES_BASE64
   JAVA_AES_RAW

  CShapDynamicPayload
   CSHAP_AES_BASE64
   CSHAP_EVAL_AES_BASE64
   CSHAP_ASMX_AES_BASE64
   CSHAP_AES_RAW

  PhpDynamicPayload
   PHP_EVAL_XOR_BASE64
   PHP_XOR_BASE64
   PHP_XOR_RAW

  AspDynamicPaylod
   ASP_EVAL_BASE64
   ASP_XOR_BASE64
   ASP_XOR_BASE64
   ASP_RAW
   ASP_BASE64

  文中的这些流量加密方式所对应的接码工具已经在公司的内部工具中实现,本文主要介绍 PHP 和 JSP webshell 流量特征。

明显特征

User-Agent (中特征)

  哥斯拉客户端使用 JAVA 语言编写,在默认的情况下,如果不进行修改,可能是:User-Agent: Java/1.8.0_131 。但是哥斯拉支持自定义HTTP头部,这个默认特征是可以很容易去除的。目前在我所使用的最新版中,这个特征变成了:User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0,看到了着重注意一下。

User-Agent
User-Agent

Accept(弱特征)

  Accept 为 text/html, image/gif, image/jpeg, *; q=.2, /; q=.2
对这个默认特征应该很熟悉了,之前冰蝎也出现过同样的 Accept。为什么会这么巧合出现两个工具都会出现这个特征呢,其实这个也是 JDK 引入的一个特征,并不是作者自定义的 Accept(参考:https://link.zhihu.com/?target=https%3A//bugs.openjdk.java.net/browse/JDK-8177439)同样的这个默认特征也可以通过自定义头部去除,只能作为默认情况下的辅助检测特征。目前在使用的最新版中,这个值变成了Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8

Accept
Accept

Cookie (强特征)

  在请求包的 Cookie 中有一个非常致命的特征,最后的分号。标准的 HTTP 请求中最后一个 Cookie 的值是不应该出现 ; 的,这个可以作为现阶段的一个辅助识别特征。后面如果作者意识到这个问题的话应该会发布新版本修复这个问题。

Cookie
Cookie

请求体特征 (较强特征)

  哥斯拉支持对加密的数据进行 base64 编码以及原始的加密 raw 两种形式的通讯数据,对于请求体的检测也要考虑两种情况。

  Base64 编码后包含大写字母:A-Z、小写字母:a-z、数字:0-9、符号:+ 和 /、填充字符:= 。正则匹配。而且,在每一个请求前面,会有一个 XXX= 的符号,同一个 webshell 的所有请求中这个不变,是由于在生成 webshell 的时候就配置好的。

Base64
Base64

  RAW 的话,排除掉文件上传,也就是 multipart/form-data 数据包,然后匹配到大量不可见字符。
RAW
RAW

响应体特征 (强特征)

  和请求体一样,请求响应体也分两个格式,base64 编码的和原始加密 raw 数据。如果请求体采用 base64 编码,响应体返回的也是 base64 编码的数据。在使用 base64 编码时,响应体会出现一个很明显的固定特征。这个特征是客户端和服务端编写的时候引入的。

  从代码可以看到会把一个 32 位的 md5 字符串按照一半拆分,分别放在 base64 编码的数据的前后两部分。整个响应包的结构体征为:md5 前十六位 + base64 + md5 后十六位。

  从响应数据包可以明显看到这个特征,检测时匹配这个特征可以达到比较高的检出率,同时也只可以结合前面的一些弱特征进行检查,进一步提高检出率。因为 md5 的字符集范围在只落在 0123456789ABCDEF 范围内,因此很容易去匹配,正则匹配类似于 (?i:[0-9A-F]{16})[\w+/]{4,}=?=?(?i:[0-9A-F]{16})。需要注意的是 md5 需要同时匹配字母大小写两种情况,因为在 JAVA 版 webshell 响应中为大写字母,在 PHP 版中为小写字母。

会话特征(强特征)

  在哥斯拉连接的会话中,在数量特征上存在明显特征。会话的第一个请求包度极长(超过 1000Byte,同时该请求 http 响应内容为空。),后面会跟两个短请求。

第一个请求长度
第一个请求长度

第二个第三个请求长度
第二个第三个请求长度

哥斯拉静态特征

  在默认脚本编码的情况下,jsp 会出现 xc、pass 字符和 Java 反射 (ClassLoader,getClass().getClassLoader()),base64 加解码等特征。

哥斯拉动态特征

  User-Agent 字段(弱特征),如果采用默认的情况,会暴露使用的 jdk 信息。不过哥斯拉支持自定义 HTTP 头部,这个默认特征是可以很容易去除的。

  Accept 字段(弱特征),默认是 Accept:text/html, image/gif, image/jpeg, *; q=.2, /; q=.2。同上,这个也可修改,只能作为辅助检测的特征。

  Cookie 中有一个非常关键的特征,最后会有个分号。估计后续的版本会修复。

  响应体的数据有一定特征,哥斯拉会把一个 32 位的 md5 字符串按照一半拆分,分别放在 base64 编码的数据的前后两部分。整个响应包的结构体征为:md5 前十六位 + base64 + md5 后十六位。

哥斯拉长流量特征

  第三篇参考文章中写着哥斯拉使用了长 TCP 连接,中间的前三个 http 会话具备明显的统计特征。(这里的情况有待验证)

  客户端首次连接 shell 会上传一段代码 payload,以备后续操作调用。查看其请求,发现内容长度居然超过 2300 字节。同时,http 响应内容为空。
  第二个http的请求内容为:

s4kur4=VzFlBQUiW1ljVSNFaWJUU2dXaQM%2BICcLZ2lYDA%3D%3D

  解密得到原始代码 methodName=dGVzdA==,即 methodName=test。跟踪执行过程,发现最终目的是测试 shell 的连通情况,并向客户端打印输出ok。这个过程是典型的固定特征,与第一个 http 请求一样,上传的原始代码是固定的。

  第三个http的作用是获取目标的环境信息,请求内容为:

s4kur4=VzFlBQUiW1ljVSNFaWJUWXgKakIxMlN1UlUjaWdYFWxjHGVBPQsBC2dpWAw%3D

  解密得到原始代码 methodName=Z2V0QmFzaWNzSW5mbw==,即 methodName=getBasicsInfo。此操作调用 payload 中的 getBasicsInfo 方法获取目标环境信息向客户端返回。显然,这个过程又是一个固定特征。

  至此,成功挖掘到哥斯拉客户端与 shell 建连初期的三个固定行为特征,且顺序出现在同一个 TCP 连接中。

特征:发送一段固定代码(payload),http 响应为空
特征:发送一段固定代码(test),执行结果为固定内容
特征:发送一段固定代码(getBacisInfo)

  由于对内容的加密,即使哥斯拉每次都发送一段固定代码,检测引擎也无法通过规则直接匹配。另外, webshell 的密码、密钥均不固定,代码加密后的密文也不同。

  回看 webshell 代码,$P 和 $T 在生成时属于非固定值,但在 shell 连接的整个生命周期,却又是固定值。$T 是密钥的 md5 值前 16 位,属于唯一的加密因子,被用于与原始代码进行异或。哥斯拉进行异或加密时,循环使用加密因子 $T 的每一位与被加密字符串进行异或位运算。(具体生成算法参考文章 [3])这就引出了第一个真理:

长度为 l 的字符串与长度为 n 的加密因子循环按位异或,密文的长度为 l。

  对于哥斯拉中频繁使用的 Base64 编码,又会引出真理二:

长度为l的字符串进行Base64编码后长度为定值。

PHP

JSP