
CovenantDecryptor is designed to decrypt the communication data of Covenant traffic.
The extraction of the private key from memory is applicable to other C2, such as Empire, given its use of the
RSACryptoServiceProviderto create the key.
The Covenant communication initialization consists of 3 stages :
SetupAESKey, which is embedded in a malicious executable. Before sending, it formats the text as described in GruntHTTPStager with the type set to 0.SessionKey, encrypted with the RSA public key, for subsequent communication.SetupAESKey to decrypt the message, and then leverages the RSA private key to decrypt the SessionKey. Afterwards, it encrypts 4 randomly generated bytes with the SessionKey and transmits them. Before sending, it formats the text as described in GruntHTTPStager with the type set to 1.SessionKey, appends 4 additional randomly generated bytes and transfers the resulting 8 bytes data to the infected agent.SessionKey. Subsequently, it checks if the first 4 bytes match the data it had previously transmitted, and proceeds transfer the last 4 bytes back to the C2. Before sending, it formats the text as described in GruntHTTPStager with the type set to 2.Once verification is complete, data can be exchanged.
CovenantDecryptor is composed of two utilities. The extract_privatekey script retrieves the p and q primes from a minidump file to construct an RSA private key by employing the public modulus. The decrypt_covenant_traffic script consists of 3 commands modulus, key and decrypt. The first command extracts the modulus from Covenant communication, while the second recovers the AES key used for encrypting data traffic. Lastly, the third command decrypts the traffic.
Extract the modulus from the stage 0 request of an infected host :
$ python3 decrypt_covenant_traffic.py modulus -i traffic.txt -k "EQCZiHdmVUQzIhEAmYh3ZlVEMyIRAJmId2ZVRDMiEQA=" -t base64
[+] Modulus:
19574201286059123715221634877085223155972629451020572575626246458715199192950082143183900970133840359007922584516900405154928253156404028820410452946729670930374022025730036806358075325420793866358986719444785030579682635785758091517397518826225327945861556948820837789390500920096562699893770094581497500786817915616026940285194220703907757879335069896978124429681515117633335502362832425521219599726902327020044791308869970455616185847823063474157292399830070541968662959133724209945293515201291844650765335146840662879479678554559446535460674863857818111377905454946004143554616401168150446865964806314366426743287
[+] Exponent: 65537
Retrieve the RSA private key from a minidump file of an infected Covenant process :
$ python3 extract_privatekey.py -i memory.dmp -m 19574201286059123715221634877085223155972629451020572575626246458715199192950082143183900970133840359007922584516900405154928253156404028820410452946729670930374022025730036806358075325420793866358986719444785030579682635785758091517397518826225327945861556948820837789390500920096562699893770094581497500786817915616026940285194220703907757879335069896978124429681515117633335502362832425521219599726902327020044791308869970455616185847823063474157292399830070541968662959133724209945293515201291844650765335146840662879479678554559446535460674863857818111377905454946004143554616401168150446865964806314366426743287 -o ./keys/
[+] Saved private key /home/user/privkey1.pem
The script will try to get p and q as little and big endian.
Recover the SessionKey from the stage 0 response of Covenant C2, which is employed to encrypt network traffic :
$ python3 decrypt_covenant_traffic.py key -i traffic.txt --key "EQCZiHdmVUQzIhEAmYh3ZlVEMyIRAJmId2ZVRDMiEQA=" -t base64 -r mykey.pem -s 1
[+] New AES key : 0011223344556677889900112233445566778899001122334455667788990011
Decrypt the Covenant communication :
$ 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 - Parse raw file.extract_privatekey - Search private keys based on the header (without the modulus).As mentioned on StackOverflow, decryption of data is also achievable by utilizing the raw Microsoft RSA private key.