Jump to content
bio.sh

ZLoader

Recommended Posts

```from mwcp.parser import Parser
import struct
import string
import pefile
import yara
import re
from Crypto.Cipher import ARC4
import logging
log = logging.getLogger(__name__)

rule_source = '''
rule Zloader
{
    meta:
        description = "Zloader Payload"
        cape_type = "Zloader Payload"
    strings:
        $rc4_init = {31 [1-3] 66 C7 8? 00 01 00 00 00 00 90 90 [0-5] 8? [5-90] 00 01 00 00 [0-15] (74|75)}
        $decrypt_conf = {e8 ?? ?? ?? ?? e8 ?? ?? ?? ?? e8 ?? ?? ?? ?? e8 ?? ?? ?? ?? 68 ?? ?? ?? ?? 68 ?? ?? ?? ?? e8 ?? ?? ?? ?? 83 c4 08 e8 ?? ?? ?? ??}
    condition:
        uint16(0) == 0x5A4D and any of them
}

'''
MAX_STRING_SIZE = 32

yara_rules = yara.compile(source=rule_source)

def decrypt_rc4(key, data):
    cipher = ARC4.new(key)
    return cipher.decrypt(data)

def string_from_offset(data, offset):
    string = data[offset : offset + MAX_STRING_SIZE].split(b"\0")[0]
    return string

class Zloader(Parser):

    DESCRIPTION = 'Zloader configuration parser'

    def run(self):
        filebuf = self.file_object.file_data
        pe = pefile.PE(data=filebuf, fast_load=False)
        image_base = pe.OPTIONAL_HEADER.ImageBase
        matches = yara_rules.match(data=filebuf)
        if not matches:
            return
        for match in matches:
            if match.rule != "Zloader":
                continue
            for item in match.strings:
                if '$decrypt_conf' in item[1]:
                    decrypt_conf = int(item[0])+21
        va = struct.unpack("I",filebuf[decrypt_conf:decrypt_conf+4])[0]
        key = string_from_offset(filebuf, pe.get_offset_from_rva(va-image_base))
        data_offset = pe.get_offset_from_rva(struct.unpack("I",filebuf[decrypt_conf+5:decrypt_conf+9])[0]-image_base)
        enc_data = filebuf[data_offset:].split(b"\0\0")[0]
        raw = decrypt_rc4(key, enc_data)
        items = list(filter(None, raw.split(b'\x00\x00')))
        self.reporter.add_metadata("other", {"Botnet name": items[1].lstrip(b'\x00')})
        self.reporter.add_metadata("other", {"Campaign ID": items[2]})
        for item in items:
            item = item.lstrip(b'\x00')
            if item.startswith(b'http'):
                self.reporter.add_metadata("address", item)
            elif len(item) == 16:
                self.reporter.add_metadata("other", {"RC4 key": item})

       return```

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...