Overview

The config is stored in the .bss PE section with the following format.

Key length | key | data

import argparse
import struct
import pefile
import re
import binascii

Now a quick reminder ddof binary data hex encoding for Python3

RC4 Encryption

The data is encrypted using RC4. For more information on RC4 check out our RC4 tutorial video.

def rc4crypt(data, key):
    #If the input is a string convert to byte arrays
    if type(data) == str:
        data = data.encode('utf-8')
    if type(key) == str:
        key = key.encode('utf-8')
    x = 0
    box = list(range(256))
    for i in range(256):
        x = (x + box[i] + key[i % len(key)]) % 256
        box[i], box[x] = box[x], box[i]
    x = 0
    y = 0
    out = []
    for c in data:
        x = (x + 1) % 256
        y = (y + box[x]) % 256
        box[x], box[y] = box[y], box[x]
        out.append(c ^ box[(box[x] + box[y]) % 256])
    return bytes(out)

Helper functions

import binascii
data = binascii.unhexlify(b'')
key = binascii.unhexlify(b'')

def unicode_strings(buf, n=4):
    import re
    ASCII_BYTE = b' !\"#\$%&\'\(\)\*\+,-\./0123456789:;<=>\?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\[\]\^_`abcdefghijklmnopqrstuvwxyz\{\|\}\\\~\t'
    if type(buf) == str:
        buf = buf.encode('utf-8')
    reg = b'((?:[%s]\x00){%d,})' % (ASCII_BYTE, n)
    uni_re = re.compile(reg)
    out = []
    for match in uni_re.finditer(buf):
        try:
            out.append(match.group().decode("utf-16"))
        except UnicodeDecodeError:
            continue
    return out

def tohex(data):
    import binascii
    if type(data) == str:
        return binascii.hexlify(data.encode('utf-8'))
    else:
        return binascii.hexlify(data)
import pefile
import struct

warzone_file = b'/tmp/work/warzone.bin'
data = open(warzone_file, 'rb').read()
pe = pefile.PE(data=data)
section_data = None
for s in pe.sections:
    if s.Name == b'.bss\x00\x00\x00\x00':
        section_data = s.get_data()
## size (DWORD) | key | data
key_size = struct.unpack('<I', section_data[:4])[0]
key = section_data[4:4 + key_size]
ctxt = section_data[4+key_size:]
ctxt = ctxt.split(b'\x00\x00\x00\x00\x00\x00\x00\x00')[0]
ptxt = rc4crypt(ctxt, key)

host_len = struct.unpack('<I', ptxt[:4])[0]
host_wide = ptxt[4:host_len+4]
c2_host = unicode_strings(host_wide)[0]
c2_port = struct.unpack('<H', ptxt[host_len+4:host_len+4+2])[0]
print("host: %s, port: %d" % (c2_host, c2_port))
host: 165.22.5.66, port: 1111