Cobalt Strike流量解密

这里以一道CTF题目来讲,题目中肯定会提供.cobaltstrike.beacon_keys文件,实际上这个文件本质上为KeyPair的Java对象,Python的javaobj-py3库是可以直接读取其中存储的数据。
首先,使用parse_beacon_keys.py来分析.cobaltstrike.beacon_keys文件

import base64

import javaobj.v2 as javaobj

with open(".cobaltstrike.beacon_keys", "rb") as fd:
    pobj = javaobj.load(fd)
privateKey = pobj.array.value.privateKey.encoded.data
publicKey = pobj.array.value.publicKey.encoded.data


privateKey = (
    b"-----BEGIN PRIVATE KEY-----\n"
    + base64.encodebytes(bytes(map(lambda x: x & 0xFF, privateKey)))
    + b"-----END PRIVATE KEY-----"
)
publicKey = (
    b"-----BEGIN PUBLIC KEY-----\n"
    + base64.encodebytes(bytes(map(lambda x: x & 0xFF, publicKey)))
    + b"-----END PUBLIC KEY-----"
)
print(privateKey.decode())
print(publicKey.decode())

# print(
#     list(
#         map(
#             lambda x: list(map(lambda y: (y[0].name, y[1]), x.items())),
#             a.field_data.values(),
#         )
#     )
# )

可以得到公私钥

-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMDK2njlzNZQTuxA+EkOfL8ewGf9
QBolYb8S+oWvthlDi4powMkXT4piN2nMHh+YLJzMoq0Rr9ufalC/mHwIhGBEc62tltd6lnZEWDmj
syRtY+lLhoTVU9GYsUY0bI5z6Sco0MW4OTz760ZyHQLl+iLAPm3C2X7FFt9aSl+i6prdAgMBAAEC
gYADgF9bBvzPhBmlT/ev+JqUZ2p1tpNZRjeINyJfIKnNRZXRF5mSSvANOz8KUfqHxazgNik9H13/
Uhj+j5kvG4HgjrdNkYtfpg6pfoY7G0g3BR/kTjwAaIb9jWYPGm40xNGXR1qHRR2fxEc3Wz+OD01l
K+tpWo3lifJ0j7bvQiIX4QJBAOhfvUxWI2FOfdQVdYjWl2AyUcpTL3HBWF0e7HzbZn+L3CJs0Cwt
iZxs3r2EEbR7XfMcwmCPrcDv1ATXlKka4G0CQQDUZOEVlS/5Ly8it+WrtpMRHf5RUBT1cxJZrNRS
Wy/Kj+GoQLv9uoamUNiN5PBY4W3AV2NoEx39WIKfs1rhkH4xAkAS9XS5XLHIR6ImgpWzU2bIV3Kq
4jyVuGOgPVyoFzJ2p4+PU3dsk06N76gAqFzVb9dLdYY6YJ6ZhjezKW+cmG/FAkEAjsSkvFJFJhX+
dDLzMkKOhwIHUncnL3pDSn4vVpCvBlVDFUs2Uq7QFfngJzlOCiC2GoVjb7DyBrs5SspP+7GZ8QJB
AK+t1cHHEi/71bm0HaVeYKck8Rtgrf+vhbLCT0h/9Kechfo2HtzrW0YX+wgknLyq53TwrqKtcxOl
qhcXUY+7p1E=
-----END PRIVATE KEY-----

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAytp45czWUE7sQPhJDny/HsBn/UAaJWG/EvqF
r7YZQ4uKaMDJF0+KYjdpzB4fmCyczKKtEa/bn2pQv5h8CIRgRHOtrZbXepZ2RFg5o7MkbWPpS4aE
1VPRmLFGNGyOc+knKNDFuDk8++tGch0C5foiwD5twtl+xRbfWkpfouqa3QIDAQAB
-----END PUBLIC KEY-----

接下来使用Beacon_metadata_RSA_Decrypt.py从请求数据包中解密Cookie数据

'''
Beacon元数据
'''
import hashlib
import M2Crypto
import base64
import hexdump

PRIVATE_KEY = """
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMDK2njlzNZQTuxA+EkOfL8ewGf9
QBolYb8S+oWvthlDi4powMkXT4piN2nMHh+YLJzMoq0Rr9ufalC/mHwIhGBEc62tltd6lnZEWDmj
syRtY+lLhoTVU9GYsUY0bI5z6Sco0MW4OTz760ZyHQLl+iLAPm3C2X7FFt9aSl+i6prdAgMBAAEC
gYADgF9bBvzPhBmlT/ev+JqUZ2p1tpNZRjeINyJfIKnNRZXRF5mSSvANOz8KUfqHxazgNik9H13/
Uhj+j5kvG4HgjrdNkYtfpg6pfoY7G0g3BR/kTjwAaIb9jWYPGm40xNGXR1qHRR2fxEc3Wz+OD01l
K+tpWo3lifJ0j7bvQiIX4QJBAOhfvUxWI2FOfdQVdYjWl2AyUcpTL3HBWF0e7HzbZn+L3CJs0Cwt
iZxs3r2EEbR7XfMcwmCPrcDv1ATXlKka4G0CQQDUZOEVlS/5Ly8it+WrtpMRHf5RUBT1cxJZrNRS
Wy/Kj+GoQLv9uoamUNiN5PBY4W3AV2NoEx39WIKfs1rhkH4xAkAS9XS5XLHIR6ImgpWzU2bIV3Kq
4jyVuGOgPVyoFzJ2p4+PU3dsk06N76gAqFzVb9dLdYY6YJ6ZhjezKW+cmG/FAkEAjsSkvFJFJhX+
dDLzMkKOhwIHUncnL3pDSn4vVpCvBlVDFUs2Uq7QFfngJzlOCiC2GoVjb7DyBrs5SspP+7GZ8QJB
AK+t1cHHEi/71bm0HaVeYKck8Rtgrf+vhbLCT0h/9Kechfo2HtzrW0YX+wgknLyq53TwrqKtcxOl
qhcXUY+7p1E=
-----END PRIVATE KEY-----
"""

encode_data = "PcdKQuOPNdlyJMzB9IdLt3FyYJK5ooh2hagReIiCPX3enVE8IUWclknGedXTxAW6Seq0pUuqbA3d6h59a43lQH+2l4egkNL/aTuaMndjIcrM7HFHDQSumu/VoeG+O9vNB63W6YtJDidYt+SjFCZPOjcTblEU+CDGzN4xNO+bh1s="
base64_key = ""

pubkey = M2Crypto.RSA.load_key_string(PRIVATE_KEY.format(base64_key).encode())
ciphertext = pubkey.private_decrypt(base64.b64decode(encode_data), M2Crypto.RSA.pkcs1_padding)


def isFlag(var, flag):
	return (var & flag) == flag


def toIP(var):
	var2 = (var & -16777216) >> 24
	var4 = (var & 16711680) >> 16
	var6 = (var & 65280) >> 8
	var8 = var & 255
	return str(var2) + "." + str(var4) + "." + str(var6) + "." + str(var8)


def getName(var0):
	if var0 == 37:
		return "IBM037"
	elif var0 == 437:
		return "IBM437"
	elif var0 == 500:
		return "IBM500"
	elif var0 == 708:
		return "ISO-8859-6"
	elif var0 == 709:
		return ""
	elif var0 == 710:
		return ""
	elif var0 == 720:
		return "IBM437"
	elif var0 == 737:
		return "x-IBM737"
	elif var0 == 775:
		return "IBM775"
	elif var0 == 850:
		return "IBM850"
	elif var0 == 852:
		return "IBM852"
	elif var0 == 855:
		return "IBM855"
	elif var0 == 857:
		return "IBM857"
	elif var0 == 858:
		return "IBM00858"
	elif var0 == 860:
		return "IBM860"
	elif var0 == 861:
		return "IBM861"
	elif var0 == 862:
		return "IBM862"
	elif var0 == 863:
		return "IBM863"
	elif var0 == 864:
		return "IBM864"
	elif var0 == 865:
		return "IBM865"
	elif var0 == 866:
		return "IBM866"
	elif var0 == 869:
		return "IBM869"
	elif var0 == 870:
		return "IBM870"
	elif var0 == 874:
		return "x-windows-874"
	elif var0 == 875:
		return "IBM875"
	elif var0 == 932:
		return "Shift_JIS"
	elif var0 == 936:
		return "x-mswin-936"
	elif var0 == 949:
		return "x-windows-949"
	elif var0 == 950:
		return "Big5"
	elif var0 == 1026:
		return "IBM1026"
	elif var0 == 1047:
		return "IBM1047"
	elif var0 == 1140:
		return "IBM01140"
	elif var0 == 1141:
		return "IBM01141"
	elif var0 == 1142:
		return "IBM01142"
	elif var0 == 1143:
		return "IBM01143"
	elif var0 == 1144:
		return "IBM01144"
	elif var0 == 1145:
		return "IBM01145"
	elif var0 == 1146:
		return "IBM01146"
	elif var0 == 1147:
		return "IBM01147"
	elif var0 == 1148:
		return "IBM01148"
	elif var0 == 1149:
		return "IBM01149"
	elif var0 == 1200:
		return "UTF-16LE"
	elif var0 == 1201:
		return "UTF-16BE"
	elif var0 == 1250:
		return "windows-1250"
	elif var0 == 1251:
		return "windows-1251"
	elif var0 == 1252:
		return "windows-1252"
	elif var0 == 1253:
		return "windows-1253"
	elif var0 == 1254:
		return "windows-1254"
	elif var0 == 1255:
		return "windows-1255"
	elif var0 == 1256:
		return "windows-1256"
	elif var0 == 1257:
		return "windows-1257"
	elif var0 == 1258:
		return "windows-1258"
	elif var0 == 1361:
		return "x-Johab"
	elif var0 == 10000:
		return "x-MacRoman"
	elif var0 == 10001:
		return ""
	elif var0 == 10002:
		return ""
	elif var0 == 10003:
		return ""
	elif var0 == 10004:
		return "x-MacArabic"
	elif var0 == 10005:
		return "x-MacHebrew"
	elif var0 == 10006:
		return "x-MacGreek"
	elif var0 == 10007:
		return "x-MacCyrillic"
	elif var0 == 10008:
		return ""
	elif var0 == 10010:
		return "x-MacRomania"
	elif var0 == 10017:
		return "x-MacUkraine"
	elif var0 == 10021:
		return "x-MacThai"
	elif var0 == 10029:
		return "x-MacCentralEurope"
	elif var0 == 10079:
		return "x-MacIceland"
	elif var0 == 10081:
		return "x-MacTurkish"
	elif var0 == 10082:
		return "x-MacCroatian"
	elif var0 == 12000:
		return "UTF-32LE"
	elif var0 == 12001:
		return "UTF-32BE"
	elif var0 == 20000:
		return "x-ISO-2022-CN-CNS"
	elif var0 == 20001:
		return ""
	elif var0 == 20002:
		return ""
	elif var0 == 20003:
		return ""
	elif var0 == 20004:
		return ""
	elif var0 == 20005:
		return ""
	elif var0 == 20105:
		return ""
	elif var0 == 20106:
		return ""
	elif var0 == 20107:
		return ""
	elif var0 == 20108:
		return ""
	elif var0 == 20127:
		return "US-ASCII"
	elif var0 == 20261:
		return ""
	elif var0 == 20269:
		return ""
	elif var0 == 20273:
		return "IBM273"
	elif var0 == 20277:
		return "IBM277"
	elif var0 == 20278:
		return "IBM278"
	elif var0 == 20280:
		return "IBM280"
	elif var0 == 20284:
		return "IBM284"
	elif var0 == 20285:
		return "IBM285"
	elif var0 == 20290:
		return "IBM290"
	elif var0 == 20297:
		return "IBM297"
	elif var0 == 20420:
		return "IBM420"
	elif var0 == 20423:
		return ""
	elif var0 == 20424:
		return "IBM424"
	elif var0 == 20833:
		return ""
	elif var0 == 20838:
		return "IBM-Thai"
	elif var0 == 20866:
		return "KOI8-R"
	elif var0 == 20871:
		return "IBM871"
	elif var0 == 20880:
		return ""
	elif var0 == 20905:
		return ""
	elif var0 == 20924:
		return ""
	elif var0 == 20932:
		return "EUC-JP"
	elif var0 == 20936:
		return "GB2312"
	elif var0 == 20949:
		return ""
	elif var0 == 21025:
		return "x-IBM1025"
	elif var0 == 21027:
		return ""
	elif var0 == 21866:
		return "KOI8-U"
	elif var0 == 28591:
		return "ISO-8859-1"
	elif var0 == 28592:
		return "ISO-8859-2"
	elif var0 == 28593:
		return "ISO-8859-3"
	elif var0 == 28594:
		return "ISO-8859-4"
	elif var0 == 28595:
		return "ISO-8859-5"
	elif var0 == 28596:
		return "ISO-8859-6"
	elif var0 == 28597:
		return "ISO-8859-7"
	elif var0 == 28598:
		return "ISO-8859-8"
	elif var0 == 28599:
		return "ISO-8859-9"
	elif var0 == 28603:
		return "ISO-8859-13"
	elif var0 == 28605:
		return "ISO-8859-15"
	elif var0 == 29001:
		return ""
	elif var0 == 38598:
		return "ISO-8859-8"
	elif var0 == 50220:
		return "ISO-2022-JP"
	elif var0 == 50221:
		return "ISO-2022-JP-2"
	elif var0 == 50222:
		return "ISO-2022-JP"
	elif var0 == 50225:
		return "ISO-2022-KR"
	elif var0 == 50227:
		return "ISO-2022-CN"
	elif var0 == 50229:
		return "ISO-2022-CN"
	elif var0 == 50930:
		return "x-IBM930"
	elif var0 == 50931:
		return ""
	elif var0 == 50933:
		return "x-IBM933"
	elif var0 == 50935:
		return "x-IBM935"
	elif var0 == 50936:
		return ""
	elif var0 == 50937:
		return "x-IBM937"
	elif var0 == 50939:
		return "x-IBM939"
	elif var0 == 51932:
		return "EUC-JP"
	elif var0 == 51936:
		return "GB2312"
	elif var0 == 51949:
		return "EUC-KR"
	elif var0 == 51950:
		return ""
	elif var0 == 52936:
		return "GB2312"
	elif var0 == 54936:
		return "GB18030"
	elif var0 == 57002:
		return "x-ISCII91"
	elif var0 == 57003:
		return "x-ISCII91"
	elif var0 == 57004:
		return "x-ISCII91"
	elif var0 == 57005:
		return "x-ISCII91"
	elif var0 == 57006:
		return "x-ISCII91"
	elif var0 == 57007:
		return "x-ISCII91"
	elif var0 == 57008:
		return "x-ISCII91"
	elif var0 == 57009:
		return "x-ISCII91"
	elif var0 == 57010:
		return "x-ISCII91"
	elif var0 == 57011:
		return "x-ISCII91"
	elif var0 == 65000:
		return ""
	elif var0 == 65001:
		return "UTF-8"


if ciphertext[0:4] == b'\x00\x00\xBE\xEF':

	# 16
	raw_aes_keys = ciphertext[8:24]

	# 2
	var9 = ciphertext[24:26]
	var9 = int.from_bytes(var9, byteorder='little', signed=False)
	var9 = getName(var9)
	# 2
	var10 = ciphertext[26:28]
	var10 = int.from_bytes(var10, byteorder='little', signed=False)
	var10 = getName(var10)

	# 4
	id = ciphertext[28:32]
	id = int.from_bytes(id, byteorder='big', signed=False)
	print("Beacon id:{}".format(id))

	# 4
	pid = ciphertext[32:36]
	pid = int.from_bytes(pid, byteorder='big', signed=False)
	print("pid:{}".format(pid))

	# 2
	port = ciphertext[36:38]
	port = int.from_bytes(port, byteorder='big', signed=False)
	print("port:{}".format(port))

	# 1
	flag = ciphertext[38:39]
	flag = int.from_bytes(flag, byteorder='big', signed=False)
	# print(flag)

	if isFlag(flag, 1):
		barch = ""
		pid = ""
		is64 = ""
	elif isFlag(flag, 2):
		barch = "x64"
	else:
		barch = "x86"

	if isFlag(flag, 4):
		is64 = "1"
	else:
		is64 = "0"

	if isFlag(flag, 8):
		bypassuac = "True"
	else:
		bypassuac = "False"

	print("barch:" + barch)
	print("is64:" + is64)
	print("bypass:" + bypassuac)

	# 2
	var_1 = ciphertext[39:40]
	var_2 = ciphertext[40:41]
	var_1 = int.from_bytes(var_1, byteorder='big', signed=False)
	var_2 = int.from_bytes(var_2, byteorder='big', signed=False)
	windows_var = str(var_1) + "." + str(var_2)
	print("windows var:" + windows_var)

	# 2
	windows_build = ciphertext[41:43]
	windows_build = int.from_bytes(windows_build, byteorder='big', signed=False)
	print("windows build:{}".format(windows_build))

	# 4
	x64_P = ciphertext[43:47]

	# 4
	ptr_gmh = ciphertext[47:51]
	# 4
	ptr_gpa = ciphertext[51:55]

	# if ("x64".equals(this.barch)) {
	# this.ptr_gmh = CommonUtils.join(var10, this.ptr_gmh)
	# this.ptr_gpa = CommonUtils.join(var10, this.ptr_gpa)
	# }
	#
	# this.ptr_gmh = CommonUtils.bswap(this.ptr_gmh)
	# this.ptr_gpa = CommonUtils.bswap(this.ptr_gpa)

	# 4
	intz = ciphertext[55:59]
	intz = int.from_bytes(intz, byteorder='little', signed=False)
	intz = toIP(intz)

	if intz == "0.0.0.0":
		intz = "unknown"
	print("host:" + intz)

	if var9 == None:
		ddata = ciphertext[59:len(ciphertext)].decode("ISO8859-1")
	else:
		# ??x-mswin-936
		# ddata = ciphertext[59:len(ciphertext)].decode(var9)
		ddata = ciphertext[59:len(ciphertext)].decode("ISO8859-1")

	ddata = ddata.split("\t")
	if len(ddata) > 0:
		computer = ddata[0]
	if len(ddata) > 1:
		username = ddata[1]
	if len(ddata) > 2:
		process = ddata[2]

	print("PC name:" + computer)
	print("username:" + username)
	print("process name:" + process)

	raw_aes_hash256 = hashlib.sha256(raw_aes_keys)
	digest = raw_aes_hash256.digest()
	aes_key = digest[0:16]
	hmac_key = digest[16:]

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



	print(hexdump.hexdump(ciphertext))

成功解密元数据,可以拿到AES KeyHMAC Key

Beacon id:1188523432
pid:4012
port:0
barch:x86
is64:1
bypass:False
windows var:54.46
windows build:12809
host:67.78.73.76
PC name:HUAN7155
username:Linchuan
process name:4321.exe
AES key:d62ad6c7a26831a42542089ea0347321
HMAC key:89635825b91c90e63d459b3de05ebfd2
00000000: 00 00 BE EF 00 00 00 4D  FD 16 72 C5 C7 28 ED 2A  .......M..r..(.*
00000010: 75 DE 6F 2D DE 7A 06 F0  A8 03 A8 03 46 D7 6D A8  u.o-.z......F.m.
00000020: 00 00 0F AC 00 00 04 36  2E 32 09 31 30 2E 32 31  .......6.2.10.21
00000030: 31 2E 35 35 2E 37 09 4C  49 4E 43 48 55 41 4E 37  1.55.7.LINCHUAN7
00000040: 31 35 35 09 4C 69 6E 63  68 75 61 6E 09 34 33 32  155.Linchuan.432
00000050: 31 2E 65 78 65                                    1.exe

然后再解密CS流量,既然存在通信,那么必然有数据传输,所以直接查看存在data字段的数据包。

因为cs的beacon模式返回包是定时任务去延期查询的,所以继续往下翻应该就能找到执行命令的结果。

再解密下hex数据。

解密出来的hex数据使用base64编码,再调用CS_Task_AES_Decrypt.py来解密执行的命令,记得替换解密脚本中的shell_whoami变量。

'''
cobaltstrike任务解密
'''
import hmac
import binascii
import base64
import struct

import hexdump
from Crypto.Cipher import AES

def compare_mac(mac, mac_verif):
	if mac == mac_verif:
		return True
	if len(mac) != len(mac_verif):
		print
		"invalid MAC size"
		return False

	result = 0

	for x, y in zip(mac, mac_verif):
		result |= x ^ y

	return result == 0


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

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


def readInt(buf):
	return struct.unpack('>L', buf[0:4])[0]

# 接收到的任务数据
shell_whoami= "egbD/VKZd3OFBz/hQ0ue8bQgDJRZnCOxo2alKY+W1HHDFHfMUrpfjdNKAMvG7WCt"

if __name__ == "__main__":
	# key源自Beacon_metadata_RSA_Decrypt.py
	SHARED_KEY = binascii.unhexlify("d62ad6c7a26831a42542089ea0347321")
	HMAC_KEY = binascii.unhexlify("89635825b91c90e63d459b3de05ebfd2")

	enc_data = base64.b64decode(shell_whoami)
	print("数据总长度:{}".format(len(enc_data)))
	signature = enc_data[-16:]
	encrypted_data = enc_data[:-16]

	iv_bytes = bytes("abcdefghijklmnop",'utf-8')

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

	counter = readInt(dec)
	print("时间戳:{}".format(counter))

	decrypted_length = readInt(dec[4:])
	print("任务数据包长度:{}".format(decrypted_length))

	data = dec[8:len(dec)]
	print("任务Data")
	print(hexdump.hexdump(data))

	# 任务标志
	Task_Sign=data[0:4]
	print("Task_Sign:{}".format(Task_Sign))

	# 实际的任务数据长度
	Task_file_len = int.from_bytes(data[4:8], byteorder='big', signed=False)
	print("Task_file:{}".format(Task_file_len))

	with open('data.bin', 'wb') as f:
		f.write(data[8:Task_file_len])

	print(hexdump.hexdump(data[Task_file_len:]))

解密之后可以看到执行的命令:

盲猜下一步要echo flag或者type flag.txt

果不其然,执行了type C:\Users\Linchuan\5.txt命令,那么下一步找这个的beacon返回包就行。

解密hex数据,进行base64编码。

然后再使用Beacon_Task_return_AES_Decrypt.py来解密

# -*- coding: utf-8 -*-

'''
Beacon任务执行结果解密
'''
import hmac
import binascii
import base64
import struct
import hexdump
from Crypto.Cipher import AES

def compare_mac(mac, mac_verif):
	if mac == mac_verif:
		return True
	if len(mac) != len(mac_verif):
		print
		"invalid MAC size"
		return False

	result = 0

	for x, y in zip(mac, mac_verif):
		result |= x ^ y

	return result == 0

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

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

# key源自Beacon_metadata_RSA_Decrypt.py
SHARED_KEY = binascii.unhexlify("d62ad6c7a26831a42542089ea0347321")
HMAC_KEY = binascii.unhexlify("89635825b91c90e63d459b3de05ebfd2")

encrypt_data="AAAAwMw1gSQUNnEshHNdZb9fqnrD2hrBt1g76nnVTADFF4Zjl3hmI4GMsRr4FGC/lj59oL571Mivwn1Nfvt4POfTqInRTa2iqFHwspGa9CQu/cDkOtgAU7XX/8kzQW7Ahh0kKA9tgL9rrzkmTFNClrgWNfiyzpgk8Dg58apKKUEYa+1AggKW5WN7ForWusCAHGx54sY/AxnpsSQ0hUwHIcw0oyPwRLYwsnlkePaAJZB3TRqD92n7Hiv7HFd7/gLZWPW0HA=="

encrypt_data=base64.b64decode(encrypt_data)

encrypt_data_length=encrypt_data[0:4]

encrypt_data_length=int.from_bytes(encrypt_data_length, byteorder='big', signed=False)

encrypt_data_l = encrypt_data[4:len(encrypt_data)]

data1=encrypt_data_l[0:encrypt_data_length-16]
signature=encrypt_data_l[encrypt_data_length-16:encrypt_data_length]
iv_bytes = bytes("abcdefghijklmnop",'utf-8')

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


counter = dec[0:4]
counter=int.from_bytes(counter, byteorder='big', signed=False)
print("counter:{}".format(counter))

dec_length = dec[4:8]
dec_length=int.from_bytes(dec_length, byteorder='big', signed=False)
print("任务返回长度:{}".format(dec_length))

de_data= dec[8:len(dec)]
Task_type=de_data[0:4]
Task_type=int.from_bytes(Task_type, byteorder='big', signed=False)
print("任务输出类型:{}".format(Task_type))

# print(de_data[4:dec_length].decode('utf-8'))
print(de_data[4:dec_length])

print(hexdump.hexdump(dec))

最终可以看到命令执行返回的结果