CovenantDecryptor 旨在解密 Covenant 流量的通信数据。
由于使用
RSACryptoServiceProvider创建密钥,从内存中提取私钥的方法也适用于其他 C2,例如 Empire。
Covenant 通信初始化包含 3 个阶段:
SetupAESKey 加密的公钥来发起 RSA 会话,SetupAESKey 嵌入在恶意可执行文件中。发送前,它会按照 GruntHTTPStager 中的描述格式化文本,并将类型设置为 0。SessionKey,用于后续通信。SetupAESKey 解密消息,然后利用 RSA 私钥解密 SessionKey。之后,它使用 SessionKey 加密 4 个随机生成的字节并传输。发送前,它会按照 GruntHTTPStager 中的描述格式化文本,并将类型设置为 1。SessionKey 解密这 4 个字节,追加 4 个额外的随机生成字节,并将生成的 8 字节数据传输给受感染代理。SessionKey 解密这 8 个字节。随后,它检查前 4 个字节是否与之前传输的数据匹配,并将最后 4 个字节传回 C2。发送前,它会按照 GruntHTTPStager 中的描述格式化文本,并将类型设置为 2。验证完成后,就可以交换数据了。
CovenantDecryptor 由两个工具组成。extract_privatekey 脚本从 minidump 文件中提取 p 和 q 两个质数,并利用公钥模数构造 RSA 私钥。decrypt_covenant_traffic 脚本包含 3 个命令:modulus、key 和 decrypt。第一个命令从 Covenant 通信中提取模数,第二个命令恢复用于加密数据流量的 AES 密钥,最后一个命令解密流量。
从受感染主机的阶段 0 请求中提取模数:
$ python3 decrypt_covenant_traffic.py modulus -i traffic.txt -k "EQCZiHdmVUQzIhEAmYh3ZlVEMyIRAJmId2ZVRDMiEQA=" -t base64
[+] Modulus:
19574201286059123715221634877085223155972629451020572575626246458715199192950082143183900970133840359007922584516900405154928253156404028820410452946729670930374022025730036806358075325420793866358986719444785030579682635785758091517397518826225327945861556948820837789390500920096562699893770094581497500786817915616026940285194220703907757879335069896978124429681515117633335502362832425521219599726902327020044791308869970455616185847823063474157292399830070541968662959133724209945293515201291844650765335146840662879479678554559446535460674863857818111377905454946004143554616401168150446865964806314366426743287
[+] Exponent: 65537
从受感染的 Covenant 进程的 minidump 文件中获取 RSA 私钥:
$ python3 extract_privatekey.py -i memory.dmp -m 19574201286059123715221634877085223155972629451020572575626246458715199192950082143183900970133840359007922584516900405154928253156404028820410452946729670930374022025730036806358075325420793866358986719444785030579682635785758091517397518826225327945861556948820837789390500920096562699893770094581497500786817915616026940285194220703907757879335069896978124429681515117633335502362832425521219599726902327020044791308869970455616185847823063474157292399830070541968662959133724209945293515201291844650765335146840662879479678554559446535460674863857818111377905454946004143554616401168150446865964806314366426743287 -o ./keys/
[+] Saved private key /home/user/privkey1.pem
该脚本将尝试以小端和大端格式获取 p 和 q。
从 Covenant C2 的阶段 0 响应中恢复用于加密网络流量的 SessionKey:
$ python3 decrypt_covenant_traffic.py key -i traffic.txt --key "EQCZiHdmVUQzIhEAmYh3ZlVEMyIRAJmId2ZVRDMiEQA=" -t base64 -r mykey.pem -s 1
[+] New AES key : 0011223344556677889900112233445566778899001122334455667788990011
解密 Covenant 通信:
$ python3 decrypt_covenant_traffic.py decrypt -i traffic.txt -k "0011223344556677889900112233445566778899001122334455667788990011" -t hex -s 2
[...]
[*] Response message 10 : {"status":"2","output":"Hello.\r\n"}
[...]
extract_privatekey - 解析原始文件。extract_privatekey - 根据头部(不含模数)搜索私钥。正如 StackOverflow 上所述,也可以通过使用原始 Microsoft RSA 私钥来实现数据解密。