Emotet Config Extractor
Static config extractor for Emotet
def unhex(hex_string):
import binascii
if type(hex_string) == str:
return binascii.unhexlify(hex_string.encode('utf-8'))
else:
return binascii.unhexlify(hex_string)
def tohex(data):
import binascii
if type(data) == str:
return binascii.hexlify(data.encode('utf-8'))
else:
return binascii.hexlify(data)
import struct
import pefile
EMOTET_FILE = r'/tmp/emotet3.bin'
data = open(EMOTET_FILE, 'rb').read()
pe = pefile.PE(data = data)
txt_data = None
for s in pe.sections:
if b'.text' in s.Name:
txt_data = s.get_data()
print(txt_data[:100])
def xor_decrypt(data, key):
out = []
for i in range(len(data)):
out.append(data[i] ^ key[i%len(key)])
return bytes(out)
def is_ascii(s):
return all(c < 128 for c in s)
strings_table = []
ECS1_string = None
ECK1_string = None
for i in range(0,0x1000,4):
candidate_1 = struct.unpack('<I',txt_data[i:i+4])[0]
candidate_2 = struct.unpack('<I',txt_data[i+4:i+8])[0]
if (candidate_1 & 0xffffff00) ^ (candidate_2 & 0xffffff00) == 0:
# We have a match!
key = txt_data[i:i+4]
data_len = candidate_1 ^ candidate_2
enc_data = txt_data[i+8:i+8+data_len]
ptxt_data = xor_decrypt(enc_data, key)
if is_ascii(ptxt_data):
if ptxt_data != b'':
strings_table.append(ptxt_data.decode('latin1'))
if b'ECS1' == ptxt_data[:4]:
ECS1_string = ptxt_data
if b'ECK1' == ptxt_data[:4]:
ECK1_string = ptxt_data
# Print our strings
print(ECS1_string)
print(ECK1_string)
for s in strings_table:
print(s)
Elliptic Curve Keys
References:
- https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptimportkeypair
- https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/ns-bcrypt-bcrypt_ecckey_blob
- https://github.com/tpn/winsdk-10/blob/master/Include/10.0.14393.0/shared/bcrypt.h
- https://pycryptodome.readthedocs.io/en/latest/src/public_key/ecc.html
print(ECS1_string)
print(ECK1_string)
# Extract ECS1 key
ECS1_key_len = struct.unpack('<I',ECS1_string[4:8])[0]
ECS1_x = int.from_bytes(ECS1_string[8:8+ECS1_key_len], "big")
ECS1_y = int.from_bytes(ECS1_string[8+ECS1_key_len:], "big")
from Crypto.PublicKey import ECC
ECS1_key = ECC.construct(curve="p256", point_x=ECS1_x, point_y=ECS1_y)
print("\nECS1 Key")
print(ECS1_key.export_key(format="PEM"))
# Extract ECK1 key
ECK1_key_len = struct.unpack('<I',ECK1_string[4:8])[0]
ECK1_x = int.from_bytes(ECK1_string[8:8+ECK1_key_len], "big")
ECK1_y = int.from_bytes(ECK1_string[8+ECK1_key_len:], "big")
from Crypto.PublicKey import ECC
ECK1_key = ECC.construct(curve="p256", point_x=ECK1_x, point_y=ECK1_y)
print("\nECK1 Key")
print(ECK1_key.export_key(format="PEM"))
data_data = None
for s in pe.sections:
if b'.data' in s.Name:
data_data = s.get_data()
print(data_data[:100])
key = data_data[:4]
data_len = struct.unpack('<I',data_data[:4])[0] ^ struct.unpack('<I',data_data[4:8])[0]
enc_data = data_data[8:8+data_len]
ptxt_data = xor_decrypt(enc_data, key)
print(tohex(ptxt_data))
print("\n== C2 List== ")
for i in range(0,len(ptxt_data),8):
print("%d.%d.%d.%d:%d" % (ptxt_data[i+0],ptxt_data[i+1],ptxt_data[i+2],ptxt_data[i+3],struct.unpack('>H',ptxt_data[i+4:i+6])[0]))