Skip to content

Commit

Permalink
style: Automatic code formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
actions-user committed Oct 25, 2024
1 parent 81e2b53 commit c0cb5ed
Show file tree
Hide file tree
Showing 6 changed files with 404 additions and 17 deletions.
28 changes: 19 additions & 9 deletions modules/processing/parsers/CAPE/KoiLoader.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import pefile
import yara
import struct
import re
from itertools import cycle
import struct
from contextlib import suppress
from itertools import cycle

import pefile
import yara

# Hash = b462e3235c7578450b2b56a8aff875a3d99d22f6970a01db3ba98f7ecb6b01a0

Expand All @@ -21,6 +22,7 @@
}
"""


def yara_scan(raw_data):
yara_rules = yara.compile(source=RULE_SOURCE)
matches = yara_rules.match(data=raw_data)
Expand All @@ -41,14 +43,16 @@ def yara_scan(raw_data):

return (payload_resource_id, xor_key_resource_id)


def remove_nulls(buffer, buffer_size):
"""
Modify a buffer removing null bytes
"""
num_nulls = count_nulls(buffer)
result = skip_nth(buffer, num_nulls+1)
result = skip_nth(buffer, num_nulls + 1)
return bytearray(result)


def count_nulls(buffer):
"""
Count null separation in a buffer
Expand All @@ -66,24 +70,28 @@ def count_nulls(buffer):

return num_nulls


def skip_nth(buffer, n):
iterable = list(buffer)
yield from (value for index, value in enumerate(iterable) if (index + 1) % n and (index - 1) % n)


def find_c2(decoded_buffer):
decoded_buffer = bytearray(skip_nth(decoded_buffer, 2))
url_regex = re.compile(rb"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+")
urls = [url.lower().decode() for url in url_regex.findall(decoded_buffer)]
return urls


def xor_data(data, key):
return bytes(c ^ k for c, k in zip(data, cycle(key)))


def extract_config(data):
config_dict = {"C2": []}

xor_key = b''
encoded_payload = b''
xor_key = b""
encoded_payload = b""

payload_resource_id, xor_key_resource_id = yara_scan(data)

Expand All @@ -101,11 +109,11 @@ def extract_config(data):
if directory.struct.Id == xor_key_resource_id:
offset = resource.data.struct.OffsetToData
xor_phrase_size = resource.data.struct.Size
xor_key = pe.get_memory_mapped_image()[offset:offset+xor_phrase_size]
xor_key = pe.get_memory_mapped_image()[offset : offset + xor_phrase_size]
elif directory.struct.Id == payload_resource_id:
offset = resource.data.struct.OffsetToData
encoded_payload_size = resource.data.struct.Size
encoded_payload = pe.get_memory_mapped_image()[offset:offset+encoded_payload_size]
encoded_payload = pe.get_memory_mapped_image()[offset : offset + encoded_payload_size]

encoded_payload = remove_nulls(encoded_payload, encoded_payload_size)
decoded_payload = xor_data(encoded_payload, xor_key)
Expand All @@ -114,7 +122,9 @@ def extract_config(data):

return config_dict


if __name__ == "__main__":
import sys

with open(sys.argv[1], "rb") as f:
print(extract_config(f.read()))
2 changes: 2 additions & 0 deletions modules/processing/parsers/CAPE/Lumma.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ def extract_config(data):

return config_dict


if __name__ == "__main__":
import sys

with open(sys.argv[1], "rb") as f:
print(extract_config(f.read()))
14 changes: 10 additions & 4 deletions modules/processing/parsers/CAPE/Stealc.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import yara
import pefile
import struct
from contextlib import suppress

import pefile
import yara

MAX_STRING_SIZE = 100

Expand All @@ -27,6 +27,7 @@
$decode_1
}"""


def yara_scan(raw_data):
yara_rules = yara.compile(source=RULE_SOURCE)
matches = yara_rules.match(data=raw_data)
Expand All @@ -36,15 +37,18 @@ def yara_scan(raw_data):
for instance in block.instances:
yield instance.offset


def xor_data(data, key):
decoded = bytearray()
for i in range(len(data)):
decoded.append(data[i] ^ key[i])
return decoded


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


def extract_config(data):
config_dict = {"C2": []}

Expand Down Expand Up @@ -79,14 +83,14 @@ def extract_config(data):
key_rva = data[str_decode_offset + 3 : str_decode_offset + 7]
encoded_str_rva = data[str_decode_offset + 8 : str_decode_offset + 12]
dword_rva = data[str_decode_offset + 21 : str_decode_offset + 25]

key_offset = pe.get_offset_from_rva(struct.unpack("i", key_rva)[0] - image_base)
encoded_str_offset = pe.get_offset_from_rva(struct.unpack("i", encoded_str_rva)[0] - image_base)
dword_offset = hex(struct.unpack("i", dword_rva)[0])[2:]

key = string_from_offset(data, key_offset)
encoded_str = string_from_offset(data, encoded_str_offset)

decoded_str = xor_data(encoded_str, key).decode()
if "http://" in decoded_str or "https://" in decoded_str:
config_dict["C2"].append(decoded_str)
Expand All @@ -95,7 +99,9 @@ def extract_config(data):

return config_dict


if __name__ == "__main__":
import sys

with open(sys.argv[1], "rb") as f:
print(extract_config(f.read()))
2 changes: 1 addition & 1 deletion tests_parsers/test_koiloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
def test_koiloader():
with open("tests/data/malware/b462e3235c7578450b2b56a8aff875a3d99d22f6970a01db3ba98f7ecb6b01a0", "rb") as data:
conf = extract_config(data.read())
assert conf == {'C2': ['http://91.202.233.209/hypermetropia.php', 'https://admiralpub.ca/wp-content/uploads/2017']}
assert conf == {"C2": ["http://91.202.233.209/hypermetropia.php", "https://admiralpub.ca/wp-content/uploads/2017"]}
15 changes: 13 additions & 2 deletions tests_parsers/test_lumma.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,16 @@
def test_lumma():
with open("tests/data/malware/5d58bc449693815f6fb0755a364c4cd3a8e2a81188e431d4801f2fb0b1c2de8f", "rb") as data:
conf = extract_config(data.read())
assert conf == {'C2': ['delaylacedmn.site', 'writekdmsnu.site', 'agentyanlark.site', 'bellykmrebk.site', 'underlinemdsj.site', 'commandejorsk.site', 'possiwreeste.site', 'famikyjdiag.site', 'agentyanlark.site']}

assert conf == {
"C2": [
"delaylacedmn.site",
"writekdmsnu.site",
"agentyanlark.site",
"bellykmrebk.site",
"underlinemdsj.site",
"commandejorsk.site",
"possiwreeste.site",
"famikyjdiag.site",
"agentyanlark.site",
]
}
Loading

0 comments on commit c0cb5ed

Please sign in to comment.