6
0
mirror of https://github.com/avast/ioc synced 2024-06-20 13:58:34 +00:00
ioc-collection/Meh-part-2/extras/decrypt_strings_IDAPython.py
2020-11-12 10:27:22 +01:00

64 lines
1.8 KiB
Python

__author__ = "Jan Rubin, Avast Software"
from base64 import b64decode
from functools import reduce
from typing import Optional
def decrypt(encoded_text: bytes, key_material: bytes) -> bytes:
ciphertext = b64decode(encoded_text)
key = reduce(lambda x, y: x ^ y, key_material) # XOR all bytes of the key
key ^= len(key_material)
plaintext = bytes([key ^ 255 ^ byte for byte in ciphertext])
return plaintext
def find_key(offset: int) -> Optional[bytes]:
for i in range(32): # scan next 32 bytes for the decryption function
offset += 1
if print_operand(offset, 0) != "sub_448F58":
continue
string_offset = get_operand_value(offset - 0x5, 1)
string = get_strlit_contents(string_offset)
return string
def process_string(offset: int, ciphertext: bytes, key_material: bytes) -> int:
decrypted = decrypt(ciphertext, key_material)
try:
set_cmt(offset, str(decrypted), False)
return 1
except Exception as error:
print(f"[!] Could not resolve address {offset}, error: {error}")
return 0
def find_strings(base: int, end: int):
ea = base
count = 0
while ea <= end:
ea = idc.next_addr(ea)
if not print_operand(ea, 0) == "sub_443DDC":
continue
addr_key = get_operand_value(ea - 0x5, 1)
ciphertext = get_strlit_contents(addr_key)
key_material = find_key(ea)
if key_material == None or ciphertext == None:
ea = idc.next_addr(ea)
continue
count += process_string(ea, ciphertext, key_material)
if count > 0:
print(f"[+] Successfully decrypted {count} strings")
else:
print("[-] Could not decrypt strings. See errors above.")
print("Start decrypt")
find_strings(base=0x00401000, end=0x0044f000)