zloader/zloader.py (39 lines of code) (raw):

import logging from malduck import rc4 from malduck.extractor import Extractor from malduck.procmem import ProcessMemory from malduck.yara import YaraRuleMatch from ..utils import Config, get_rule_metadata # A Code Cleanup / Port of kevoreilly's ZLoader Configuration to Malduck # https://github.com/kevoreilly/CAPEv2/blob/master/modules/processing/parsers/mwcp/Zloader.py log = logging.getLogger(__name__) __author__ = "c3rb3ru5" __version__ = "1.0.0" class ZLoader(Extractor): """ A ZLoader Configuration Extractor """ family: str = "zloader" yara_rules = ("zloader",) @Extractor.rule def zloader(self, p: ProcessMemory, match: YaraRuleMatch) -> Config | bool: _info: Config = get_rule_metadata(match) return _info @Extractor.extractor("decrypt_conf") def decrypt_conf(self, p: ProcessMemory, addr: int) -> Config | bool: conf: Config = {"family": self.family, self.family: {}} try: key_addr = p.uint32v(addr + 21) if not key_addr: return conf key = p.asciiz(key_addr) data_offset = p.uint32v(addr + 26) if not data_offset: return conf config_encrypted = p.readv(addr=data_offset).split(b"\0\0")[0] config_raw = rc4(key, config_encrypted) config_items = list(filter(None, config_raw.split(b"\x00\x00"))) for i in range(0, len(config_items)): config_items[i] = config_items[i].strip(b"\x00") conf[self.family]["name"] = config_items[1].decode("utf-8") conf[self.family]["campaign_id"] = config_items[2].decode("utf-8") conf[self.family]["urls"] = [config_items[3].decode("utf-8")] except Exception as error: log.warning(error) return False return conf