SOFTWARE\Microsoft\CryptographyMachineGuid__ProviderArchitectureROOT\CIMV2IDSELECT * FROM Win32_ShadowCopyWQLWin32_ShadowCopy.ID='%s'Global\%.8x%.8x%.8x%.8xTimes New Roman.bmpControl Panel\DesktopWallPaperWallpaperStyleZ:\dllhost.exeElevation:Administrator!new:{3E5FC7F9-9A51-4367-9063-A120244FBEC7}%s.README.txtControl Panel\InternationalLocaleNamesLanguageSOFTWARE\Microsoft\Windows NT\CurrentVersionProductName%.8x%.8x%.8x%.8x%POSTABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789%s=%s%s=%s%.8x%.8x%.8x%.8x%ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789%u.%u%u.%u\\%s\LDAP://rootDSEdefaultNamingContextLDAP://CN=Computers,dNSHostName\\%s\ExchangeInstallPathProgram FilesMailboxSOFTWARE\%shScreen
# Author: Alexey Kleymenov (a member of Nozomi Networks Labs)
import os
import struct
import pefile
import ida_kernwin
PATH_TO_DLLS = 'c:\\windows\\system32\\'
HARDCODED_XOR_KEY = 0x17019FF8
def extract_api_hashes(start):
'''
Returns a dictionary where keys are import functions to write data and values are list of hashes
The first hash is the DLL name's hash, the rest are WinAPI names' hashes
'''
decryptor_address = start
print('Bulk API decryptor address: %x' % decryptor_address)
api_hashes = {}
for head in Heads():
flags = GetFlags(head)
if isCode(flags):
prev = prev_head(head)
prev_2 = prev_head(prev)
if print_insn_mnem(head) == 'call' and get_operand_value(head, 0) == decryptor_address:
print('Found the decryptor called: %x' % head)
if print_insn_mnem(prev) == 'push' and print_insn_mnem(prev_2) == 'push':
func_hashes = get_operand_value(prev_2, 0)
import_table = get_operand_value(prev, 0)
api_hashes[import_table] = []
for i in range(0, 0xffff, 4):
api_hash = struct.unpack("> 0x0D) | (value << (0x20 - 0x0D))) & 0xFFFFFFFF
value += ord(symbol) & 0xFFFFFFFF
return value
def build_mappings(dll_filepath, dll_hashes):
'''
This function calculates API checksums for the DLLs of interest
'''
dll_name = os.path.basename(dll_filepath)
dll_checksum = calculate_checksum(dll_name.lower() + '\x00', 0)
result = {}
if dll_checksum in dll_hashes:
dll = pefile.PE(dll_filepath, fast_load=True)
dll.parse_data_directories(directories=[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_EXPORT']])
if hasattr(dll, 'DIRECTORY_ENTRY_EXPORT'):
dll_name = dll_name.replace('.', '_')
result[dll_checksum] = {'dll_name': dll_name}
export_directory = dll.DIRECTORY_ENTRY_EXPORT
for symbol in export_directory.symbols:
if symbol.name is not None:
api_name = symbol.name.decode('latin-1')
api_checksum = calculate_checksum(api_name + '\x00', dll_checksum)
result[api_checksum] = {'dll_name': dll_name, 'api_name': api_name}
return result
def parse_dlls(path_to_dlls, dll_hashes):
'''
This function goes through all the files in the specified path and calculates export hashes for DLLs matching by name hashes
'''
list_dlls = os.listdir(path_to_dlls)
mappings = {}
for dll_filename in list_dlls:
full_path = os.path.join(path_to_dlls, dll_filename)
mappings.update(build_mappings(full_path, dll_hashes))
return mappings
def decrypt_all():
'''
The function expects the cursor to be located at the bulk decryption function
'''
start = get_screen_ea()
api_hashes = extract_api_hashes(start)
dll_hashes = []
for _, hashes in api_hashes.items():
dll_hashes.append(hashes[0])
dll_mappings = parse_dlls(PATH_TO_DLLS, dll_hashes)
for import_table, hashes in api_hashes.items():
dll_hash = hashes[0]
api_hashes = hashes[1:]
if dll_hash in dll_mappings:
print('Found DLL hash %x = %s' % (dll_hash, dll_mappings[dll_hash]['dll_name']))
for i, api_hash in enumerate(api_hashes):
if api_hash in dll_mappings:
addr = import_table + (i+1)*4
print('Found API hash for %x = %s (%s)' % (addr, dll_mappings[api_hash]['api_name'], dll_mappings[api_hash]['dll_name']))
set_name(addr, dll_mappings[api_hash]['api_name'])
else:
print('API hash %x not found' % api_hash)
else:
print('DLL hash %x not found' % dll_hash)
ida_kernwin.add_hotkey("z", decrypt_all)
さらに、暗号化された文字列のほとんどを自動的に検索し、復号化するスクリプトを紹介しよう:
#著者Alexey Kleymenov (Nozomi Networks Labsのメンバー)
インポート構造体
インポート ida_kernwin
HARDCODED_XOR_KEY = 0x17019FF8
def is_utf16_heur(string):
カウンタ = 0
for val in string:
if val == 0:
カウンタ += 1
if counter/float(len(string))> 0.4:
真を返す
偽を返す
def decrypt_string(start_addr):
addr = start_addr
result = b""
for i in range(0xFFFF):
instr = print_insn_mnem(addr)
if instr != 'mov' or 'dword ptr' in GetDisasm(addr):
break
値 = get_operand_value(addr, 1)
decoded_value = value ^ HARDCODED_XOR_KEY
result += struct.pack(")