西湖论剑2025Misc—cscs

打印 上一主题 下一主题

主题 878|帖子 878|积分 2634

西湖论剑2025cscs详解

Cobalt Strike流量主要是找beacon,主要以两种形式呈现
·一小段shellcode(几百个字节),通常叫做stager shellcode,这段代码下载整个的beacon。
·一个完全的beacon:一个可以反射性加载的PE文件
先来了解下cs流量的特性
cs流量特性:
1,底子特性:心跳包
2,请求特性:下发的指令,url路径,老版本固定的ua头
3,源码特性:checksum8 (92L 93L)
回到标题给的附件,我们来判断下给的流量包是否存在魔改
判断魔改

  1. def checksum8(text):  
  2.     if len(text) < 4:  
  3.         return 0  
  4.   
  5.     text = text.replace("/", "")  
  6.   
  7.     sum_value = 0  
  8.   
  9.     for char in text:  
  10.         sum_value += ord(char)  
  11.   
  12.     return sum_value % 256  
  13.   
  14.   
  15. if __name__ == "__main__":  
  16.     print(checksum8("mB9u"))
复制代码
输出为93,64位的后门,未魔改
解密心跳包

导出mB9u文件,后缀改为.vir,这是我们要的beacon,我们需要1768.py去分析,
1768.py是加密和解密beacon的配置文件
https://blog.didierstevens.com/2021/10/11/update-1768-py-version-0-0-8/
运行可以得到公钥等信息

公钥数据
  1. 30819e300d06092a864886f70d010101050003818c00308188028180525e1781f2f02d132a7818a6d269baddbf39352c8d20290ec2294fbe4d77e6549ef4766d8b0e1620000adfbd7aff99cd72f05623eb0def202265cf631dd895acd5e981da8424c03a295895c8194a31641f2eecd5a8715ca89cdbf9433c5d437538767666c3bdb0f8629555375b574fe408a94ae82f92960085d416374f1654b30203010001
复制代码
from hex to base64
  1. MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgFJeF4Hy8C0TKngYptJput2/OTUsjSApDsIpT75Nd+ZUnvR2bYsOFiAACt+9ev+ZzXLwViPrDe8gImXPYx3YlazV6YHahCTAOilYlcgZSjFkHy7s1ahxXKic2/lDPF1DdTh2dmbDvbD4YpVVN1tXT+QIqUroL5KWAIXUFjdPFlSzAgMBAAE=
复制代码
ps:
  1. import base64
  2. def hex_to_base64(hex_string):
  3.     # 将十六进制字符串转换为字节数据
  4.     byte_data = bytes.fromhex(hex_string)
  5.     # 将字节数据编码为 Base64
  6.     base64_data = base64.b64encode(byte_data)
  7.     # 返回 Base64 字符串(解码为 UTF-8)
  8.     return base64_data.decode('utf-8')
  9. # 示例用法
  10. hex_input = ""
  11. base64_output = hex_to_base64(hex_input)
  12. print("Base64 输出:", base64_output)
复制代码
这边建议使用厨子,因为后面会有超长的hex字节,会卡爆

获取私钥

本题流量是通信流量
通信流量是通过天生的 AES Key 和 HMAC Key 举行加密的
AES Key 和 HMAC Key是根据 TeamServer 端接收到第一个心跳包时用私钥去解密心跳包中公钥加密的 cookie根据解密出的协商公钥天生的
用cs-decrypt-metadata去解cookie发现根本解不开
我们用开源的rsatools去解私钥
https://github.com/RsaCtfTool/RsaCtfTool
帮我刚刚得到的公钥转换为标准格式并生存为key.pub
  1. -----BEGIN PUBLIC KEY-----
  2. MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgFJeF4Hy8C0TKngYptJput2/OTUsjSApDsIpT75N
  3. d+ZUnvR2bYsOFiAACt+9ev+ZzXLwViPrDe8gImXPYx3YlazV6YHahCTAOilYlcgZSjFkHy7s1ahx
  4. XKic2/lDPF1DdTh2dmbDvbD4YpVVN1tXT+QIqUroL5KWAIXUFjdPFlSzAgMBAAE=
  5. -----END PUBLIC KEY-----
复制代码
终端命令
  1. python RsaCtfTool.py --publickey ./key.pub --private
复制代码

得到私钥
  1. -----BEGIN RSA PRIVATE KEY-----
  2. MIICWgIBAAKBgFJeF4Hy8C0TKngYptJput2/OTUsjSApDsIpT75Nd+ZUnvR2bYsO
  3. FiAACt+9ev+ZzXLwViPrDe8gImXPYx3YlazV6YHahCTAOilYlcgZSjFkHy7s1ahx
  4. XKic2/lDPF1DdTh2dmbDvbD4YpVVN1tXT+QIqUroL5KWAIXUFjdPFlSzAgMBAAEC
  5. gYApWVrrvY2c0zZKu/VjQ/ivQUPy0b63GmVyS1Lg8frzAiAaESnE2Pl6bwsGbxTE
  6. I+3jeYuE1IdWOAeMnKPhY80fOSgws6vSri7CcxnMUEEn3AMw4YSwBIaBGkdLnfxf
  7. pbS/kUUb/z7/A1SRtNq1n4hZYinnG2NpUuiO1WqwHqOGoQJBAJE14+VVt8ONGIZ1
  8. qIf4cqAnAmtonPhyDNdYZQC0IlxNzyixo/lnlTc80b3jYUA4w8GGQQZea70op4RS
  9. fIJV420CQQCRNePlVbfDjRiGdaiH+HKgJwJraJz4cgzXWGUAtCJcTc8osaP5Z5U3
  10. PNG942FAOMPBhkEGXmu9KKeEUnyCVeSfAkB6vJQuKe+zaDVMoXKbyxIH8DEJXFkh
  11. XjUgZ+SnXZqVbmclPFEe48Cp+cxGtkRjJhfAIZwgp/pk3lIJdDctay9ZAkAhlDeu
  12. CcNj6hXYyg592tsO49ZwZhGedik4Bw3cOsuTUr7r5yBHBUgBLQRHh/QuOLIz50rU
  13. ITOC24rZU4XNUfV7AkAipEfvmXf4RaJLlIoWZe/XkNXpGcsYIeaedUv29xqaNAbA
  14. 7HhEs3twu6+G0QP1YuAPNp28FNoe52XfJhVWTw1D
  15. -----END RSA PRIVATE KEY-----
复制代码
通过cookie得到HMACK key和AES key

工具地址
https://github.com/WBGlIl/CS_Decrypt
因为密码库M2Crypto非常老,我们要修改代码
  1. '''
  2. Beacon元数据
  3. '''
  4. import hashlib
  5. import M2Crypto
  6. import base64
  7. import hexdump
  8. PRIVATE_KEY = """
  9. -----BEGIN RSA PRIVATE KEY-----
  10. {}
  11. -----END RSA PRIVATE KEY-----
  12. """
  13. encode_data = ""
  14. base64_key = ""
  15. pubkey = M2Crypto.RSA.load_key_string(PRIVATE_KEY.format(base64_key).encode())
  16. ciphertext = pubkey.private_decrypt(base64.b64decode(encode_data), M2Crypto.RSA.pkcs1_padding)
复制代码
将上面的一部门代码更换成下面的
  1. '''
  2. Beacon元数据
  3. '''
  4. import hashlib
  5. from Crypto.PublicKey import RSA
  6. from Crypto.Cipher import PKCS1_v1_5
  7. import base64
  8. import hexdump
  9. PRIVATE_KEY = """-----BEGIN RSA PRIVATE KEY-----
  10. {}
  11. -----END RSA PRIVATE KEY-----"""
  12. encode_data = ""
  13. base64_key = """
  14. private_key = RSA.import_key(PRIVATE_KEY.format(base64_key).encode())
  15. cipher = PKCS1_v1_5.new(private_key)
  16. ciphertext = cipher.decrypt(base64.b64decode(encode_data), 0)
复制代码

得到AES Key 和 HMAC Key
  1. AES key:9fe14473479a283821241e2af78017e8
  2. HMAC key:1e3d54f1b9f0e106773a59b7c379a89d
复制代码
解密数据

用CS_Task_AES_Decrypt.py提取最大的包(开头349bytes的cm文件),解密出得到secret.pcapng流量包

将生存的data.bin改为1.pcapng,发现wireshark是打不开的
恢复流量包

第一种就是手动删去多余的部门

比较贫苦,直接工具修了

乐成打开流量包

cs1.6流量
L3HCTF的原题
https://www.anquanke.com/post/id/261339
引用其中的C代码,并作修改
[code]extern "C"  {      int _LongSwap(int l)      {          unsigned int res = __builtin_bswap32(*(unsigned int *)&l);          return *(int *)&(res);      }        const unsigned char mungify_table[] =          {              0x7A, 0x64, 0x05, 0xF1,              0x1B, 0x9B, 0xA0, 0xB5,              0xCA, 0xED, 0x61, 0x0D,              0x4A, 0xDF, 0x8E, 0xC7};        const unsigned char mungify_table2[] =          {              0x05, 0x61, 0x7A, 0xED,              0x1B, 0xCA, 0x0D, 0x9B,              0x4A, 0xF1, 0x64, 0xC7,              0xB5, 0x8E, 0xDF, 0xA0};        unsigned char mungify_table3[] =          {              0x20, 0x07, 0x13, 0x61,              0x03, 0x45, 0x17, 0x72,              0x0A, 0x2D, 0x48, 0x0C,              0x4A, 0x12, 0xA9, 0xB5};        void COM_UnMunge2(unsigned char *data, int len, int seq)      {          int i;          int mungelen;          int c;          int *pc;          unsigned char *p;          int j;            mungelen = len & ~3;          mungelen /= 4;            for (i = 0; i < mungelen; i++)          {              pc = (int *)&data[i * 4];              c = *pc;              c ^= seq;                p = (unsigned char *)&c;              for (j = 0; j < 4; j++)              {                  *p++ ^= (0xa5 | (j 10:        if struct.unpack('

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

伤心客

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表