icedid/photoloader/icedid_photoloader.py (40 lines of code) (raw):
import logging
from malduck import asciiz
from malduck.extractor import Extractor
from malduck.pe import PE
from malduck.procmem import ProcessMemory
from malduck.yara import YaraRuleMatch
from ...utils import Config, get_rule_metadata
log = logging.getLogger(__name__)
__author__ = "4rchib4ld"
__version__ = "1.0.0"
class IcedIDPhotoLoader(Extractor):
"""
IcedID PhotoLoader C2 Domain Configuration Extractor
"""
family: str = "icedid_photoloader"
yara_rules: tuple = ("icedid_photoloader",)
@staticmethod
def extractPayload(pe: PE) -> bytes:
"""
Extracting the payload from the .data section
"""
for section in pe.sections:
if ".data" in str(section.Name):
data = section.get_data()
payload = asciiz(data[4:])
return payload
return b""
@Extractor.rule
def icedid_photoloader(self, p: ProcessMemory, match: YaraRuleMatch) -> Config | bool:
conf: Config = {}
info: Config = get_rule_metadata(match)
obfuscationCode = match.elements["obfuscationCode"][0][2]
xorCountValue = obfuscationCode[3] # Getting this values dynamically because... you never know
countValue = obfuscationCode[-1]
pe_rep = PE(data=p)
payload = self.extractPayload(pe_rep)
decrypted = bytearray()
for i in range(countValue):
try:
decrypted.append(payload[i + xorCountValue] ^ payload[i])
except IndexError:
pass
c2 = asciiz(decrypted)
if len(c2) > 0:
conf[self.family] = [c2.decode("utf-8")]
return conf | info