整体步骤

  1. 通过.cobaltstrike.beacon_keys或者stage文件获得 Beacon 和 C2 之间传输数据使用的 rsa 私钥
  2. 使用 rsa 私钥去解密元数据(心跳包中的 Cookie),拿到AES keyHMAC key
  3. 使用 AES keyHMAC key解密传输数据

私钥获取

利用 .cobaltstrike.beacon_keys 文件

.cobaltstrike.beacon_keys文件本质上为KeyPair的Java对象,Python的javaobj可以直接读取其中存储的数据

利用parse_beacon_keys.py读取公钥和私钥(如果是python3环境装的是 javaobj-py3 )

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())
Python

利用 stage 文件

通过http.request.uri matches "/....$"筛选cs木马上线时所发送的stage文件

cs_dec1

接着通过1768.py解密该文件,将publickey多余0去除得到公钥

cs_dec2

30819e300d06092a864886f70d010101050003818c00308188028180525e1781f2f02d132a7818a6d269baddbf39352c8d20290ec2294fbe4d77e6549ef4766d8b0e1620000adfbd7aff99cd72f05623eb0def202265cf631dd895acd5e981da8424c03a295895c8194a31641f2eecd5a8715ca89cdbf9433c5d437538767666c3bdb0f8629555375b574fe408a94ae82f92960085d416374f1654b30203010001
Text

之后用cs_invert_pub.py将公钥转为pem格式,并提取其中的n和e

from Crypto.PublicKey import RSA
import binascii

# 将你的16进制字符串放在这里
   hex_key = "30819e300d06092a864886f70d010101050003818c00308188028180525e1781f2f02d132a7818a6d269baddbf39352c8d20290ec2294fbe4d77e6549ef4766d8b0e1620000adfbd7aff99cd72f05623eb0def202265cf631dd895acd5e981da8424c03a295895c8194a31641f2eecd5a8715ca89cdbf9433c5d437538767666c3bdb0f8629555375b574fe408a94ae82f92960085d416374f1654b30203010001" 
# 将十六进制字符串转换为字节
   key_bytes = binascii.unhexlify(hex_key)
# 导入RSA公钥
   rsa_key = RSA.import_key(key_bytes)
# 提取模数(n)和指数(e)
   n = rsa_key.n
   e = rsa_key.e
# 打印模数和指数
   print(f"Modulus (n): {n}")
   print(f"Exponent (e): {e}")

# 将RSA公钥导出为PEM格式
   pem_key = rsa_key.publickey().export_key(format='PEM')
# 打印PEM格式公钥
   print(pem_key.decode('utf-8'))
Python
Modulus (n): 57840457943390562151183056895981922848981888713417943532946260250633760347281370187050725047626507035739078370095883411759062129893337622945780596526859424702568086671495882125464325172299346781795855931036288858784790023273356190549125683636953077021666004867856782395818167722491980517593426129106599564467
Exponent (e): 65537
-----BEGIN PUBLIC KEY-----
MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgFJeF4Hy8C0TKngYptJput2/OTUs
jSApDsIpT75Nd+ZUnvR2bYsOFiAACt+9ev+ZzXLwViPrDe8gImXPYx3YlazV6YHa
hCTAOilYlcgZSjFkHy7s1ahxXKic2/lDPF1DdTh2dmbDvbD4YpVVN1tXT+QIqUro
L5KWAIXUFjdPFlSzAgMBAAE=
-----END PUBLIC KEY-----
Text

将n进行模数分解,得到p和q

cs_dec3

接着用cs_calc_pri.py通过p和q计算私钥

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

from Crypto.PublicKey import RSA

def generate_rsa_keypair(p, q, e=65537):
    """
    生成RSA密钥对。

    :param p: 大素数p
    :param q: 大素数q
    :param e: 公钥指数,默认为65537
    :return: RSA私钥
    """
    # 计算模数N
    N = p * q
    # 计算欧拉函数phi(N)
    phi = (p - 1) * (q - 1)
    # 计算私钥d
    d = pow(e, -1, phi)
    # 构造RSA私钥
    pri_key = RSA.construct((N, e, d))
    return pri_key

def save_private_key_to_file(private_key, filename="id_rsa"):
    """
    将私钥保存到文件中。

    :param private_key: RSA私钥对象
    :param filename: 保存的文件名,默认为"id_rsa"
    """
    with open(filename, "wb") as f:
        f.write(private_key.export_key("PEM"))

# 示例:生成RSA密钥对并保存私钥
if __name__ == "__main__":
    # 输入大素数p和q
    p = 7605291443685150594150190909345113655196508809219162555499789316232908573154196070425269090153291952292016936024761413150455793038505322748933150548026527
    q = 7605291443685150594150190909345113655196508809219162555499789316232908573154196070425269090153291952292016936024761413150455793038505322748933150548026221

    private_key = generate_rsa_keypair(p, q)
    save_private_key_to_file(private_key)
    print(f"私钥已保存到文件:id_rsa")
Python
-----BEGIN RSA PRIVATE KEY-----
MIICWgIBAAKBgFJeF4Hy8C0TKngYptJput2/OTUsjSApDsIpT75Nd+ZUnvR2bYsO
FiAACt+9ev+ZzXLwViPrDe8gImXPYx3YlazV6YHahCTAOilYlcgZSjFkHy7s1ahx
XKic2/lDPF1DdTh2dmbDvbD4YpVVN1tXT+QIqUroL5KWAIXUFjdPFlSzAgMBAAEC
gYApWVrrvY2c0zZKu/VjQ/ivQUPy0b63GmVyS1Lg8frzAiAaESnE2Pl6bwsGbxTE
I+3jeYuE1IdWOAeMnKPhY80fOSgws6vSri7CcxnMUEEn3AMw4YSwBIaBGkdLnfxf
pbS/kUUb/z7/A1SRtNq1n4hZYinnG2NpUuiO1WqwHqOGoQJBAJE14+VVt8ONGIZ1
qIf4cqAnAmtonPhyDNdYZQC0IlxNzyixo/lnlTc80b3jYUA4w8GGQQZea70op4RS
fIJV420CQQCRNePlVbfDjRiGdaiH+HKgJwJraJz4cgzXWGUAtCJcTc8osaP5Z5U3
PNG942FAOMPBhkEGXmu9KKeEUnyCVeSfAkB6vJQuKe+zaDVMoXKbyxIH8DEJXFkh
XjUgZ+SnXZqVbmclPFEe48Cp+cxGtkRjJhfAIZwgp/pk3lIJdDctay9ZAkAhlDeu
CcNj6hXYyg592tsO49ZwZhGedik4Bw3cOsuTUr7r5yBHBUgBLQRHh/QuOLIz50rU
ITOC24rZU4XNUfV7AkAipEfvmXf4RaJLlIoWZe/XkNXpGcsYIeaedUv29xqaNAbA
7HhEs3twu6+G0QP1YuAPNp28FNoe52XfJhVWTw1D
-----END RSA PRIVATE KEY-----
Text

解密Cookie

用Beacon_metadata_RSA_Decrypt.py通过私钥解密心跳包中的Cookie数据,拿到AES KeyHMAC Key

import hashlib
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
import hexdump

PRIVATE_KEY = """-----BEGIN RSA PRIVATE KEY-----
MIICWgIBAAKBgFJeF4Hy8C0TKngYptJput2/OTUsjSApDsIpT75Nd+ZUnvR2bYsO
FiAACt+9ev+ZzXLwViPrDe8gImXPYx3YlazV6YHahCTAOilYlcgZSjFkHy7s1ahx
XKic2/lDPF1DdTh2dmbDvbD4YpVVN1tXT+QIqUroL5KWAIXUFjdPFlSzAgMBAAEC
gYApWVrrvY2c0zZKu/VjQ/ivQUPy0b63GmVyS1Lg8frzAiAaESnE2Pl6bwsGbxTE
I+3jeYuE1IdWOAeMnKPhY80fOSgws6vSri7CcxnMUEEn3AMw4YSwBIaBGkdLnfxf
pbS/kUUb/z7/A1SRtNq1n4hZYinnG2NpUuiO1WqwHqOGoQJBAJE14+VVt8ONGIZ1
qIf4cqAnAmtonPhyDNdYZQC0IlxNzyixo/lnlTc80b3jYUA4w8GGQQZea70op4RS
fIJV420CQQCRNePlVbfDjRiGdaiH+HKgJwJraJz4cgzXWGUAtCJcTc8osaP5Z5U3
PNG942FAOMPBhkEGXmu9KKeEUnyCVeSfAkB6vJQuKe+zaDVMoXKbyxIH8DEJXFkh
XjUgZ+SnXZqVbmclPFEe48Cp+cxGtkRjJhfAIZwgp/pk3lIJdDctay9ZAkAhlDeu
CcNj6hXYyg592tsO49ZwZhGedik4Bw3cOsuTUr7r5yBHBUgBLQRHh/QuOLIz50rU
ITOC24rZU4XNUfV7AkAipEfvmXf4RaJLlIoWZe/XkNXpGcsYIeaedUv29xqaNAbA
7HhEs3twu6+G0QP1YuAPNp28FNoe52XfJhVWTw1D
-----END RSA PRIVATE KEY-----"""

encode_data = "SLHAIOj8/1icVtP6fImtJz6B6wR0t/XwLg1G0Y3AxoxnseBfPONxoyjAWCCOH84IJULnCZZrO7cIRxJPS2PtmDD4MvD8/PIpoW8Gj8536vhwd+tyXjNKyLNyNYcj+JgO4N5FTnKtkONgv7KnsMjJC3E0eI0ctqmZll8SrXLUS9k="

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]
   # print(raw_aes_keys)
   raw_aes_hash256 = hashlib.sha256(raw_aes_keys).digest()
   aes_key = raw_aes_hash256[0:16]
   hmac_key = raw_aes_hash256[16:]

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

   hexdump.hexdump(ciphertext)
Python
RAW key: 28ab951fc96bcb93ec13cf9dd5f21373
AES key: 9fe14473479a283821241e2af78017e8
HMAC key: 1e3d54f1b9f0e106773a59b7c379a89d
00000000: 00 00 BE EF 00 00 00 5D  28 AB 95 1F C9 6B CB 93  .......](....k..
00000010: EC 13 CF 9D D5 F2 13 73  A8 03 A8 03 43 50 DF EC  .......s....CP..
00000020: 00 00 0B 50 00 00 0E 06  01 1D B0 00 00 00 00 77  ...P...........w
00000030: 02 04 D0 77 02 34 70 8C  B8 A8 C0 57 49 4E 2D 52  ...w.4p....WIN-R
00000040: 52 49 39 54 39 53 4E 38  35 44 09 41 64 6D 69 6E  RI9T9SN85D.Admin
00000050: 69 73 74 72 61 74 6F 72  09 61 72 74 69 66 61 63  istrator.artifac
00000060: 74 2E 65 78 65                                    t.exe
Text

用Beacon_metadata_moreInfo_RSA_Decrypt.py可以获得hostPC nameusername等更多信息

import hashlib
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
import hexdump

PRIVATE_KEY = """-----BEGIN RSA PRIVATE KEY-----
MIICWgIBAAKBgFJeF4Hy8C0TKngYptJput2/OTUsjSApDsIpT75Nd+ZUnvR2bYsO
FiAACt+9ev+ZzXLwViPrDe8gImXPYx3YlazV6YHahCTAOilYlcgZSjFkHy7s1ahx
XKic2/lDPF1DdTh2dmbDvbD4YpVVN1tXT+QIqUroL5KWAIXUFjdPFlSzAgMBAAEC
gYApWVrrvY2c0zZKu/VjQ/ivQUPy0b63GmVyS1Lg8frzAiAaESnE2Pl6bwsGbxTE
I+3jeYuE1IdWOAeMnKPhY80fOSgws6vSri7CcxnMUEEn3AMw4YSwBIaBGkdLnfxf
pbS/kUUb/z7/A1SRtNq1n4hZYinnG2NpUuiO1WqwHqOGoQJBAJE14+VVt8ONGIZ1
qIf4cqAnAmtonPhyDNdYZQC0IlxNzyixo/lnlTc80b3jYUA4w8GGQQZea70op4RS
fIJV420CQQCRNePlVbfDjRiGdaiH+HKgJwJraJz4cgzXWGUAtCJcTc8osaP5Z5U3
PNG942FAOMPBhkEGXmu9KKeEUnyCVeSfAkB6vJQuKe+zaDVMoXKbyxIH8DEJXFkh
XjUgZ+SnXZqVbmclPFEe48Cp+cxGtkRjJhfAIZwgp/pk3lIJdDctay9ZAkAhlDeu
CcNj6hXYyg592tsO49ZwZhGedik4Bw3cOsuTUr7r5yBHBUgBLQRHh/QuOLIz50rU
ITOC24rZU4XNUfV7AkAipEfvmXf4RaJLlIoWZe/XkNXpGcsYIeaedUv29xqaNAbA
7HhEs3twu6+G0QP1YuAPNp28FNoe52XfJhVWTw1D
-----END RSA PRIVATE KEY-----"""

encode_data = "SLHAIOj8/1icVtP6fImtJz6B6wR0t/XwLg1G0Y3AxoxnseBfPONxoyjAWCCOH84IJULnCZZrO7cIRxJPS2PtmDD4MvD8/PIpoW8Gj8536vhwd+tyXjNKyLNyNYcj+JgO4N5FTnKtkONgv7KnsMjJC3E0eI0ctqmZll8SrXLUS9k="

private_key = RSA.import_key(PRIVATE_KEY.encode())
cipher = PKCS1_v1_5.new(private_key)
ciphertext = cipher.decrypt(base64.b64decode(encode_data), 0)

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))
Python
Beacon id:1129373676
pid:2896
port:0
barch:x64
is64:1
bypass:True
windows var:6.1
windows build:7600
host:192.168.184.140
PC name:WIN-RRI9T9SN85D
username:Administrator
process name:artifact.exe
AES key:9fe14473479a283821241e2af78017e8
HMAC key:1e3d54f1b9f0e106773a59b7c379a89d
00000000: 00 00 BE EF 00 00 00 5D  28 AB 95 1F C9 6B CB 93  .......](....k..
00000010: EC 13 CF 9D D5 F2 13 73  A8 03 A8 03 43 50 DF EC  .......s....CP..
00000020: 00 00 0B 50 00 00 0E 06  01 1D B0 00 00 00 00 77  ...P...........w
00000030: 02 04 D0 77 02 34 70 8C  B8 A8 C0 57 49 4E 2D 52  ...w.4p....WIN-R
00000040: 52 49 39 54 39 53 4E 38  35 44 09 41 64 6D 69 6E  RI9T9SN85D.Admin
00000050: 69 73 74 72 61 74 6F 72  09 61 72 74 69 66 61 63  istrator.artifac
00000060: 74 2E 65 78 65                                    t.exe
Text

CS流量解密

通过data筛选 Beacon 和 C2 之间传输的数据

通过CS_Task_And_Return_AES_Decrypt.py解密数据

import hmac
import binascii
import base64
import hexdump
from Crypto.Cipher import AES

AES_KEY = binascii.unhexlify("9fe14473479a283821241e2af78017e8")
HMAC_KEY = binascii.unhexlify("1e3d54f1b9f0e106773a59b7c379a89d")
encrypt_data = "00000040efeda3e57f7d7fd589d11640ea0f9a4fe6bc91332723ffc5f43f78b37c21cc7485c44d6c8eb6af74fc7044046059c76519e493e351c9f631d6785d5c07eae9e3"

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

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

encrypt_data = bytes.fromhex(encrypt_data)

try:
       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, AES_KEY, HMAC_KEY)
except:
       dec = decrypt(encrypt_data, iv_bytes, signature, AES_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(dec[12:])
print(hexdump.hexdump(dec))
Python

cs_dec4

参考文章

https://1cepeak.cn/posts/cobaltstrike-traffic-analysis/

https://5ime.cn/cobaltstrike-decrypt.html

https://www.freebuf.com/articles/system/327060.html

https://blog.csdn.net/AomCC/article/details/133298604

发表回复