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

import logging from malduck import xor from malduck.extractor import Extractor from malduck.procmem import ProcessMemory from malduck.yara import YaraRuleMatch from ..utils import Config, get_rule_metadata log = logging.getLogger(__name__) class IcedID(Extractor): family: str = "IcedID" yara_rules = ("icedid",) @Extractor.rule def icedid(self, p: ProcessMemory, match: YaraRuleMatch) -> Config | bool: _info: Config = get_rule_metadata(match) return _info @Extractor.extractor("config_decryption") def icedid_config(self, p: ProcessMemory, addr: int): log.info( "[+] IcedID loader config decryption YARA signature matched @ %X", addr ) conf: Config = {} conf[self.family] = {} try: hit = p.uint32v(addr - 3) if not hit: return conf config_location = hit + addr + 1 config_blob = p.readv(config_location, 250) key = config_blob[:32] conf["key"] = key.hex() data = config_blob[64:96] decrypted_config = xor(key, data) campaign_id = decrypted_config[:4] campaign_id = int.from_bytes(campaign_id, "little") raw = decrypted_config[4:] domains = [x.decode("UTF-8") for x in raw.split(b"\x00")] conf[self.family] = {"domains": domains, "campaign_id": campaign_id} except Exception as err: log.error(err) return conf