«introduction to malware reverse engineering» by sergey kharyuk
TRANSCRIPT
Рассмотрение техник Reverse Engineering на примере анализа вредоносного ПО
INTRODUCTION TO MALWARE REVERSE ENGINEERING
О себе
• Администратор и сооснователь форума reverse4you.org
• Организатор конференции R0-Crew
• Реверс-инжинер/вирусный аналитик
• Участник CTF команды R0-Crew
• Хаксор
О чем речь
• Что такое «Reverse engineering»
• Примеры из практики исследований
Что такое reverse engineering?
Области применения
• Создание кряков/обход лицензирования софта
• Анализ вирусов
• Анализ шеллкода
• Поиск уязвимостей
• Анализ логики ПО
Базовые знания и навыки
• Assembler x86/x64/ARM
• Программирование (C\C++\Obj-C, Python\Perl\Bash\Bat, Java)
• ОС Internals(Windows, Mac OS X, Android, iOS, Linux)
• Желание и упорство
Ресурсы для изучения
• RU
• reverse4you.org
• exelab.ru
• wasm.ru
• EN
• opensecuritytraining.info
• kernelmode.info
• tuts4you.com
Типы анализа
• Динамический
• Статический
• PE-анализаторы
• PEiD
• DiE
• CFF Explorer
• Hex-редакторы
• WinHex
• Hex Workshop
• 010 Editor
• HiEW
• Декомпиляторы
• .net Reflector
• Viper
• Dex2Jar
• ApkTool
• Дизассемблеры
• IDA Pro(BinDiff, Hex Rays)
• Hopper
• radare2
• Прочее
• Dependency Walker
• YARA
• Strings
• Resource Hacker
Инструменты для статического анализа
• Отладчики
• OllyDBG
• Immunity Debbuger
• WinDbg
• gdb
• Песочницы
• Cuckoo
• Anubis
• Системы виртуализации
• VMWare
• Virtual Box
• Bosch
• Мониторинг
• Process Monitor
• RegShot
• WireShark
• Tcpdump
• Process Hacker
• TCPView
• Другие
• Import REConstructor
• Python
Инструменты для динамического анализа
Главный инструмент
Начнем…
Результаты на VirusTotal
Базовый статический анализ
Самомодификация
.text:004014F5 push esp ; lpflOldProtect = [ESP+10]
.text:004014F6 push 40h ; flNewProtect = 0x40(PAGE_EXECUTE_READWRITE)
.text:004014F8 push 4000h ; dwSize = 4000
.text:004014FD push ebp
.text:004014FE mov dword ptr [esp], offset Main ; lpAddress = 401000
.text:00401505 mov eax, dword_405034
.text:0040150A add eax, 400000h
.text:0040150F call dword ptr [eax] ; VirtualProtect
.text:00401511 call sub_4018A6
.text:00401516 nop
.text:00401517 nop
.text:00401518 nop
.text:00401519 nop
.text:0040151A call sub_4018CC
.text:00401511 call sub_4018A6
.text:00401516 adc edx, [ebx]
.text:00401518 adc edx, [ebx]
.text:0040151A call sub_4018CC
Зашифрованный код Оригинальный код
Примеры зашифрованных участков кода
.text:00401524 sbb eax, 0C1B0061Dh
.text:00401529 fxch4 st(5)
.text:0040152B lea eax, [esi]
.text:0040152D mov eax, 8DCDDDDDh
.text:00401532 mov esi, 0F3720844h
.text:00401537 wait
.text:00401538 push es
.text:00401539 dec esp
.text:0040153A out 99h, eax
.text:0040153C adc al, 0D6h
.text:0040153E jp short loc_4015B6
.text:00401540 pop es
.text:004018AD mov ecx, 4
.text:004018B2 mov edx, 0FFFFFF83h
.text:004018B7 mov edi, [esp+10h]
.text:004018BB
.text:004018BB loc_4018BB:
.text:004018BB test ecx, ecx
.text:004018BD jz short loc_4018C5
.text:004018BF xor [edi], dl
.text:004018C1 dec ecx
.text:004018C2 inc edi
.text:004018C3 jmp short loc_4018BB
Функция расшифровки и зашифрованный участок кода
Пример функции расшифровки Пример шифрованного кода
.text:00401526 mov edi, dword_40504C ; помещаем в EDI размер расшифровываемого блока
.text:0040152C mov esi, off_405050 ; помещаем в ESI адрес начала блока расшифроки
.text:00401532 xor ecx, ecx ; обнуляем счетки
.text:00401534 test edi, edi ; если EDI == 0
.text:00401536 jle short loc_40154E ; выходим из цикла
.text:00401538
.text:00401538 loc_401538: ; CODE XREF: .text:0040154Cj
.text:00401538 mov eax, ecx ; помещаем в eax значение счетчика
.text:0040153A push 14h ; помещаем в стек значение 20
.text:0040153C cdq ; заполняем EDX значение старшего байта регистра EAX
.text:0040153D pop ebx ; извлекаем из стека значение 20 в EBX
.text:0040153E idiv ebx ; помещаем в EDX результат EBX%EAX
.text:00401540 mov al, [edx+405038h] ; извлекаем в AL ключ расшифровки
.text:00401546 xor [ecx+esi], al ; расшифровываем байт
.text:00401549 inc ecx ; увеличиваем счетчик
.text:0040154A cmp ecx, edi ; если счетчик меньше размера блока
.text:0040154C jl short loc_401538 ; продолжаем цикл
Расшифровка большого блока данных
Расшифровщик на ida-python
def xor_decrypt_key_array(effective_address, keys, size):
counter = 0
key_counter = 0
while counter < size :
key_counter = counter % 20
PatchByte( effective_address + counter,
Byte( effective_address + counter ) ^ keys [ key_counter ] )
counter += 1
Расшифрованная область памяти
.text:0040154E call loc_401573
---------------------------------------------------------------------------
.text:00401553 aGetmodulefilen db 'GetModuleFileNameA',0
.text:00401566 aKernel32_dll_1 db 'Kernel32.dll',0
---------------------------------------------------------------------------
.text:00401573 loc_401573: ; CODE XREF: sub_40142E+120
.text:00401573 pop eax
.text:00401574 push eax
.text:00401575 add eax, 13h
.text:00401578 push eax
.text:00401579 call ds:GetModuleHandleA
.text:0040157F push eax
.text:00401580 call sub_40142E ;GetFunctionPtrByName
.text:00401585 mov [ebp-4], eax
.text:00401588 add esp, 8
.text:0040158B call loc_4015AD
---------------------------------------------------------------------------
.text:00401590 aGetcommandline db 'GetCommandLineA',0
.text:004015A0 aKernel32_dll_0 db 'Kernel32.dll',0
---------------------------------------------------------------------------
.text:004015AD loc_4015AD: ; CODE XREF: .text:0040158B
.text:004015AD pop eax
.text:004015AE push eax
.text:004015AF add eax, 10h
.text:004015B2 push eax
.text:004015B3 call ds:GetModuleHandleA
.text:004015B9 push eax
.text:004015BA call sub_40142E ;GetFunctionPtrByName
.text:004015BF mov [ebp-8], eax
.text:004015C2 add esp, 8
Получение указателя на функцию
Список полученных указателей на функции
• GetModuleFileNameA
• GetCommandLineA
• NtUnmapViewOfSection
• CreateProcessA
• WriteProcessMemory
• GetThreadContext
• ReadProcessMemory
• SetThreadContext
• ResumeThread
• VirtualAllocEx
• VirtualAlloc
• VirtualFree
Создание копии процесса
.text:004011D6 push eax ; lpProcessInformation = *ptr = 0
.text:004011D7 call fill_stuct_with_zero
.text:004011DC add esp, 18h
.text:004011DF lea eax, [ebp+var_18]
.text:004011E2 push eax ; lpStartupInfo = *ptr = 0
.text:004011E3 lea eax, [ebp+var_84]
.text:004011E9 push eax ; lpCurrentDirectory = *ptr = 0
.text:004011EA push edi ; lpCurrentDirectory = 0
.text:004011EB push edi ; lpEnvironment = 0
.text:004011EC push 0Ch ; dwCreationFlags = CREATE_SUSPENDED | DETACHED_PROCESS
.text:004011EE push edi ; bInheritHandles = 0
.text:004011EF push edi ; lpThreadAttributes = 0
.text:004011F0 push edi ; lpProcessAttributes = 0
.text:004011F1 push [ebp+arg_4] ; lpCommandLine = commandline of current process
.text:004011F4 push [ebp+arg_0] ; lpApplicationName = Name of current process
.text:004011F7 call [ebp+var_38] ; CreateProcessA
.text:004012EE push [ebp+var_14]
.text:004012F1 call [ebp+var_2C] ResumeThread
.text:004012F4
.text:004012F4 loc_4012F4:
.text:004012F4 xor edi, edi
.text:004012F6 loc_4012F6:
.text:004012F6 push 8000h
.text:004012FB push edi
.text:004012FC push ebx
.text:004012FD call [ebp+var_34] VirtualFree
.text:0040378A mov [ebp+var_68], eax
.text:0040378D push eax ; Code
.text:0040378E call ds:exit
Завершение работы родительского процесса
Продолжим…
Базовая информация о втором файле
• 0x405164 InternetSetOptionA
• 0x405168 HttpQueryInfoA
• 0x40516c InternetQueryDataAvailable
• 0x405170 InternetReadFile
• 0x405174 InternetCloseHandle
• 0x405178 InternetOpenA
• 0x40517c HttpSendRequestA
• 0x405180 HttpOpenRequestA
• 0x405184 InternetConnectA
• 0x40502c GetUserDefaultUILanguage
• 0x405030 VirtualProtect
• 0x405034 LoadLibraryA
• 0x405038 GetProcAddress
• 0x40503c VirtualAlloc
• 0x405040 VirtualFree
• 0x405048 GetCurrentProcess
• 0x405068 FindFirstFileA
• 0x40507c WriteFile
• 0x405080 GetFileSize
• 0x405084 GetFileTime
Список импортируемых функций
KERNEL32.dll WININET.dll
• 0x405000 RegCloseKey
• 0x405004 RegOpenKeyExA
• 0x405008 SetSecurityDescriptorDacl
• 0x40500c InitializeSecurityDescriptor
• 0x405010 RegDeleteValueA
• 0x405014 GetSidSubAuthority
• 0x405018 GetSidSubAuthorityCount
• 0x40501c GetTokenInformation
• 0x405020 OpenProcessToken
• 0x405024 RegQueryValueExA
• 0x4050a4 GetModuleHandleA
• 0x4050a8 MultiByteToWideChar
• 0x4050ac WideCharToMultiByte
• 0x4050b0 CloseHandle
• 0x4050b4 SetFilePointer
• 0x4050b8 ReadFile
• 0x4050bc GetLastError
• 0x4050c0 lstrcpynA
Список импортируемых функций
KERNEL32.dll ADVAPI32.dll
Первый интересный участок кода
.text:00401FC9 xor edi, edi
.text:00401FCB push 8003h
.text:00401FD0 mov [ebp+var_8], edi
.text:00401FD3 call ds:SetErrorMode
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX)
Создание файла и запись в него
.text:0040133E push eax ; nNumberOfBytesToWrite = 20
.text:0040133F push edx ; lpBuffer = 44003839a2664e19a46427f1fca8f005
.text:00401340 push ecx ; lpFileName = C:\Users\ximera\AppData\LocalLow\uygqvpmhse.png
.text:00401341 call sub_403820
Создание файла и запись в него
.text:0040133E push eax ; nNumberOfBytesToWrite = 20
.text:0040133F push edx ; lpBuffer = 44003839a2664e19a46427f1fca8f005
.text:00401340 push ecx ; lpFileName = C:\Users\ximera\AppData\LocalLow\uygqvpmhse.png
.text:00401341 call sub_403820
Создание файла и запись в него
.text:0040133E push eax ; nNumberOfBytesToWrite = 20
.text:0040133F push edx ; lpBuffer = 44003839a2664e19a46427f1fca8f005
.text:00401340 push ecx ; lpFileName = C:\Users\ximera\AppData\LocalLow\uygqvpmhse.png
.text:00401341 call sub_403820
.text:00403828 push 0 ; hTemplateFile = NULL
.text:0040382A push 80h ; dwFlagsAndAttributes = NORMAL
.text:0040382F push 2 ; dwCreationDisposition = CREATE_ALWAYS
.text:00403831 push 0 ; lpSecurityAttributes = NULL
.text:00403833 push 0 ; dwShareMode = 0
.text:00403835 push 40000000h ; dwDesiredAccess = GENERIC_WRITE
.text:0040383A push eax ; lpFileName
.text:0040383B call ds:CreateFileA
.text:00403856 push edi
.text:00403857 push 0 ; lpOverlapped
.text:00403859 lea ecx, [ebp+NumberOfBytesWritten]
.text:0040385C push ecx ; lpNumberOfBytesWritten
.text:0040385D push ebx ; nNumberOfBytesToWrite
.text:0040385E push edx ; lpBuffer
.text:0040385F push esi ; hFile
.text:00403860 mov [ebp+NumberOfBytesWritten], 0
.text:00403867 call ds:WriteFile
Внутри функции записи в файл
Расшифровка IP-адреса CC
.text:00401522 loc_401522:
.text:00401522 xor byte ptr CryptedIP [ebx], 65h ; "TRSKPVKTWPKWUe"
.text:00401529 jnz short loc_401582
...
.text:00401582 loc_401582:
.text:00401582 inc ebx
.text:00401583 cmp ebx, 0Eh
.text:00401586 jb short loc_401522
Зашифрованный адрес: TRSKPVKTWPKWUe
Расшифрованный адрес: 176.53.25.20
Общение с сервером
Адрес сервера: 176.53.25.20
Запрос: get_two?v=14&a=235&u=44003839a2664e19a46427f1fca8f005&f=0&i=0
Ответ сервера
Итог:
Вступай и реверси
Вопросы
Контактная информация
Social:
• twitter.com/ximerus
• fb.com/ximerus
• linkedin.com/ximerus
Site:
• ximerus.org
• reverse4you.org
Спасибо за внимание