Como encontrar malware (não) com o WinDbg
Introdução
Neste artigo, mostrarei como, por exemplo, usar o WinDbg para descobrir qual malware (ou não) substituiu o endereço da chamada de função do sistema em uma DLL carregada por algum aplicativo. Por exemplo, eu estava procurando por que o módulo de proteção não carrega na configuração 1C .
Para demonstrar, precisamos de um aplicativo que carregue algumas DLLs: uma delas é chamada vítima ( vítima ), a outra -predador injetor . O último é introduzido na vítima, substituindo a chamada para a função do sistema (para simplificar, suspender ) e chamará AV sob certas condições (que serão necessárias no próximo artigo).
Porque aplicativos escritos em Delphi não "caem" no core-dump devido a exceções não tratadas, então nosso aplicativo principal (DLLInjectionDemo) é escrito em C, vinculado por ligação antecipada à DLL vítima e, para facilitar a reprodução da situação, ele carrega o injetor DLL passou em opções na inicialização e invocou um método que prejudicaria a vítima. Especificamente para este artigo, um aplicativo escrito em qualquer linguagem de programação seria adequado para nós, mas mataremos dois coelhos com uma cajadada.
Os códigos-fonte dos aplicativos são escritos em C e Delphi 10.3 Rio Community Edition, e MinGW e Delphi são compilados, como no Win32e para o Win64 (assim como o FPC no Lazarus).
Por isso, compilamos as DLLs e o aplicativo principal
> msbuild /t:build victim.dproj /p:Platform=Win32;Config=Debug;DCC_Exeoutput=.
> msbuild /t:build injector.dproj /p:Platform=Win32;Config=Debug;DCC_Exeoutput=.
> mingw32-make
Para criar com o MinGW make, você precisa registrá-lo no PATH, é claro
:
C:\Users\demo>DLLInjectionDemo.exe
Sleeping 100 milliseconds
Done!
-L injector
(, , , - )
c:\Users\demo>DLLInjectionDemo.exe -L injector
Loading injector
Searching...
oleaut32.dll
advapi32.dll
user32.dll
kernel32.dll
kernel32.dll
user32.dll
version.dll
kernel32.dll
kernel32.dll
netapi32.dll
oleaut32.dll
Injected
Sleeping 100 milliseconds
New sleep instead of 100
Done!
, , Sleep - . ( , ). ( , GUI-, , , , -i
(interactive)).
c:\Users\demo>DLLInjectionDemo.exe -i -L injector
Loading injector
Searching...
oleaut32.dll
advapi32.dll
user32.dll
kernel32.dll
kernel32.dll
user32.dll
version.dll
kernel32.dll
kernel32.dll
netapi32.dll
oleaut32.dll
Injected
Sleeping 100 milliseconds
New sleep instead of 100
Done!
Press ENTER...
( ). : , , , , " ...", .
WinDbg, :
File
— Open Crash Dump (Ctrl+D)
:
%PROGRAM FILES%\Windows Kits\10\Debuggers\x64\windbg.exe" -z C:\Users\demo\App Data\Local\Temp\DLLInjectionDemo.DMP
Loading Dump File [C:\Users\alex\AppData\Local\Temp\DLLInjectionDemo.DMP]
User Mini Dump File with Full Memory: Only application data is available
Symbol search path is: srv*
Executable search path is:
Windows 7 Version 7601 (Service Pack 1) MP (4 procs) Free x64
Product: WinNt, suite: SingleUserTS
Machine Name:
Debug session time: Thu Jul 4 08:46:18.000 2019 (UTC + 3:00)
System Uptime: 17 days 12:25:45.404
Process Uptime: 0 days 0:00:10.000
........................
For analysis of this file, run !analyze -v
ntdll!NtRequestWaitReplyPort+0xa:
00000000`77bcddfa c3 ret
For analysis of this file, run !analyze -v
( , ).
IAT — (Import Address Table) — DLL, (? , IAT ;) ). , PE- ( DLL ) WinDbg Windows 10 SDK ( Windows 7) , " ", WinDbg 6, .
. :
lm
0:000> lm
start end module name
00000000`003b0000 00000000`003db000 injector (deferred)
00000000`00400000 00000000`00412000 DLLInjectionDemo (deferred)
00000000`00520000 00000000`00616000 victim (deferred)
00000000`6e580000 00000000`6e5b4000 libmingwex_2 (deferred)
00000000`72870000 00000000`72886000 netapi32 (deferred)
...
Nota bene: 32- , 64-...
, DLL , IAT , !dh
-a
:
!dh 009c0000 -a
!dh victim -a0:000> !dh victim -a
File Type: DLL
FILE HEADER VALUES
14C machine (i386)
A number of sections
5E5F4251 time date stamp Wed Mar 4 09:53:21 2020
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
A18E characteristics
Executable
Line numbers stripped
Symbols stripped
Bytes reversed
32 bit word machine
DLL
OPTIONAL HEADER VALUES
10B magic #
2.25 linker version
CE400 size of code
1BA00 size of initialized data
0 size of uninitialized data
CF79C address of entry point
1000 base of code
----- new -----
0000000000400000 image base
1000 section alignment
200 file alignment
2 subsystem (Windows GUI)
5.00 operating system version
0.00 image version
5.00 subsystem version
F6000 size of image
400 size of headers
0 checksum
0000000000000000 size of stack reserve
0000000000000000 size of stack commit
0000000000100000 size of heap reserve
0000000000001000 size of heap commit
0 DLL characteristics
DD000 [ A4] address [size] of Export Directory
DA000 [ 105C] address [size] of Import Directory
F3000 [ 2A00] address [size] of Resource Directory
0 [ 0] address [size] of Exception Directory
0 [ 0] address [size] of Security Directory
...
kernel32.dll ( Sleep)
Nota bene: 32- _IMAGE_IMPORT_DESCRIPTOR 64-. , , Delphi .
...
_IMAGE_IMPORT_DESCRIPTOR 00000000005fa03c
kernel32.dll
005FA398 Import Address Table
005FA11C Import Name Table
0 time date stamp
0 Index of first forwarder reference
003C7C7C 0 Sleep
76EE184A 0 VirtualFree
76EE1832 0 VirtualAlloc
76EE16DC 0 lstrlenW
76EE4422 0 VirtualQuery
76EE110C 0 GetTickCount
...
,
`kernel32.dll`0:000> !dh kernel32
File Type: DLL
FILE HEADER VALUES
14C machine (i386)
4 number of sections
5708A7E3 time date stamp Sat Apr 9 10:57:39 2016
...
----- new -----
0000000076ed0000 image base
...
Essa. 0000000076ed0000
, — ?
WinDbg lm
:
0:000> lma 003C7C7C
Browse full module list
start end module name
00000000`003b0000 00000000`003db000 injector (deferred)
, ! . ( v
lm
)
0:000> lma 003C7C7C v
Browse full module list
start end module name
00000000`003b0000 00000000`003db000 injector (deferred)
Image path: z:\habr\DLLInjectionDemo\injector.dll
Image name: injector.dll
Browse all global symbols functions data
Timestamp: Wed Mar 4 09:53:12 2020 (5E5F4248)
CheckSum: 00000000
ImageSize: 0002B000
Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4
Information from resource tables:
!
Image path: C:\Users\demo\injector.dll
, .
Portanto, em condições reais, rapidamente consegui encontrar uma DLL estranha no sistema operacional pré-instalado do fabricante que interceptou a chamada de função WriteFile
.
Eu uso o aplicativo deste artigo no próximo, no qual quero mostrar ao leitor como usar o WinDbg para descobrir por que (ou pelo menos em algum lugar) o aplicativo travou com a Violação de Acesso, que ocorreu em uma DLL escrita em Delphi quando a depuração remota não está disponível por algum motivo. qualquer razão. Apesar de o Delphi não possuir ferramentas para analisar o despejo de aplicativos, ele não sabe como gerar arquivos PDB.