Упаковщик: отсутствует
Дата компиляции: 2020-08-13
- SHA1-хеш: a8bff99e1ea76d3de660ffdbd78ad04f81a8c659
Описание
Модуль бэкдора PlugX, написан на языке С и предназначен для расшифровки из реестра шелл-кода, загружающего основной бэкдор в память.
Принцип действия
В начале работы бэкдор получает по хешу адрес функции VirtualProtect(), которую использует для изменения прав доступа на PAGE_EXECUTE_READWRITE, начиная с функции по адресу 0x10001000 и заканчивая всей секцией .text:
Функция получения адреса функции по хешу, переданному в качестве параметра:
Скрипт для получения функции по хешу:
import pefile
ror = lambda val, r_bits, max_bits: \
((val & (2**max_bits-1)) >> r_bits%max_bits) | \
(val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1))
max_bits = 32
library_path_list = [...] # absolute path dlls
def get_func_addr(hash):
for library_path in library_path_list:
library = library_path.split('\\')
name_dll = library[len(library) - 1].upper() + b'\x00'
hash_name_dll = 0
for i in name_dll:
hash_name_dll = ord(i) + ror(hash_name_dll, 0x0D, max_bits)
hash_name_dll = 0 + ror(hash_name_dll, 0x0D, max_bits)
pe = pefile.PE(library_path)
for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
func_name = exp.name + b'\x00'
hash_name_func = 0
for i in func_name:
hash_name_func = ord(i) + ror(hash_name_func, 0x0D, max_bits)
if (hash_name_dll + hash_name_func == hash):
print '{}-> 0x{:08x} -> {}'.format(name_dll, hash, exp.name)
return
Изменение прав доступа на PAGE_EXECUTE_READWRITE нужно было для того, чтобы дешифровать код с помощью операции XOR:
Также существует версия бэкдора с динамическим XOR-шифрованием. С дешифрованием в начале функции:
И с шифрованием в конце функции:
Облегчающий работу скрипт для IDAPython:
import idaapi
def xor_dec(address, count, key):
for i in xrange(count):
idaapi.patch_dword(address, idaapi.get_dword(address) ^ key)
key += idaapi.get_dword(address)
address += 4
Перед тем как начать выполнять вредоносные действия, бэкдор, как в случае с VirtualProtect(), получает адреса других нужных для работы функций:
Полученные функции:
Имя функции | Хеш |
---|---|
CloseHandle | 0x528796C6 |
CreateFileA | 0x4FDAF6DA |
DeleteFileA | 0x13DD2ED7 |
ExitProcess | 0x56A2B5F0 |
GetAdaptersInfo | 0x62C9E1BD |
GetModuleFileNameA | 0xFE61445D |
GetSystemDirectoryA | 0x60BCDE05 |
LoadLibraryA | 0x726774C |
ReadFile | 0xBB5F9EAD |
RegCloseKey | 0x81C2AC44 |
RegDeleteValueA | 0x3846A3A8 |
RegEnumValueA | 0x2EC95AA4 |
RegOpenKeyExA | 0x3E9E3F88 |
RegQueryValueExA | 0x8FF0E305 |
VirtualAlloc | 0xE553A458 |
VirtualFree | 0x300F2F0B |
VirtualProtect | 0xC38AE110 |
WinExec | 0x876F8B31 |
WriteFile | 0x5BAE572D |
Помимо этого, бэкдор проверяет, исполняется ли он в песочнице:
После получения адресов функций и проверки на исполнение в песочнице BackDoor.PlugX.93 удаляет задачу updatecfgSetup из планировщика задач:
Ключом для шифрования шелл-кода является MD5 от следующих значений ключей реестра:
HKLM\Software\Microsoft\Windows NT\CurrentVersion\InstallDate
HKLM\System\ControlSet001\Control\ComputerName\ComputerName
Шелл-код сохраняется в следующих ключах реестра:
HKLM\Software\BINARY
HKCU\Software\BINARY
Перед запуском шелл-кода он будет расшифрован в 2 этапа — сначала с помощью алгоритма RC4:
А затем с помощью XOR: