As was announced earlier we start cataloguing elemental malware detection and analysis patterns. We skip Part 1 because we assign Deviant Module to it. Part 2 deals with Fake Module pattern where one of loaded modules masquerades as a legitimate system DLL or a widely known value adding DLL from some popular 3rd party product. To illustrate this pattern we modeled it as Victimware: a process crashed after loading a malware module:
0:000> k
*** Stack trace for last set context - .thread/.cxr resets it
Child-SP RetAddr Call Site
00000000`0026f978 00000001`3f89103a 0x0
00000000`0026f980 00000001`3f8911c4 FakeModule!wmain+0x3a
00000000`0026f9c0 00000000`76e3652d FakeModule!__tmainCRTStartup+0x144
00000000`0026fa00 00000000`7752c521 kernel32!BaseThreadInitThunk+0xd
00000000`0026fa30 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
When we inspect loaded modules we don’t find anything suspicious:
0:000> lmp
start end module name
00000000`76e20000 00000000`76f3f000 kernel32 <none>
00000000`77500000 00000000`776a9000 ntdll <none>
00000001`3f890000 00000001`3f8a6000 FakeModule <none>
000007fe`f8cb0000 000007fe`f8cc7000 winspool <none>
000007fe`fdb30000 000007fe`fdb9c000 KERNELBASE <none>
However, when checking modules images for any modifications we find that winspool was not compared with existing binary from Microsoft symbol server:
0:000> !for_each_module "!chkimg -v -d @#ModuleName"
Searching for module with expression: kernel32
Will apply relocation fixups to file used for comparison
Will ignore NOP/LOCK errors
Will ignore patched instructions
Image specific ignores will be applied
Comparison image path: C:\WSDK8\Debuggers\x64\sym\kernel32.dll\503285C111f000\kernel32.dll
No range specified
Scanning section: .text
Size: 633485
Range to scan: 76e21000-76ebba8d
Total bytes compared: 633485(100%)
Number of errors: 0
0 errors : kernel32
Searching for module with expression: ntdll
Will apply relocation fixups to file used for comparison
Will ignore NOP/LOCK errors
Will ignore patched instructions
Image specific ignores will be applied
Comparison image path: C:\WSDK8\Debuggers\x64\sym\ntdll.dll\4EC4AA8E1a9000\ntdll.dll
No range specified
Scanning section: .text
Size: 1049210
Range to scan: 77501000-7760127a
Total bytes compared: 1049210(100%)
Number of errors: 0
Scanning section: RT
Size: 474
Range to scan: 77602000-776021da
Total bytes compared: 474(100%)
Number of errors: 0
0 errors : ntdll
Searching for module with expression: FakeModule
Error for FakeModule: Could not find image file for the module. Make sure binaries are included in the symbol path.
Searching for module with expression: winspool
Error for winspool: Could not find image file for the module. Make sure binaries are included in the symbol path.
Searching for module with expression: KERNELBASE
Will apply relocation fixups to file used for comparison
Will ignore NOP/LOCK errors
Will ignore patched instructions
Image specific ignores will be applied
Comparison image path: C:\WSDK8\Debuggers\x64\sym\KERNELBASE.dll\503285C26c000\KERNELBASE.dll
No range specified
Scanning section: .text
Size: 302047
Range to scan: 7fefdb31000-7fefdb7abdf
Total bytes compared: 302047(100%)
Number of errors: 0
0 errors : KERNELBASE
Checking module data reveals that it was loaded not from System32 folder and doesn’t have any version information:
0:000> lmv m winspool
start end module name
000007fe`f8cb0000 000007fe`f8cc7000 winspool (deferred)
Image path: C:\Work\AWMA\FakeModule\x64\Release\winspool.drv
Image name: winspool.drv
Timestamp: Fri Dec 28 22:22:42 2012 (50DE1BB2)
CheckSum: 00000000
ImageSize: 00017000
File version: 0.0.0.0
Product version: 0.0.0.0
File flags: 0 (Mask 0)
File OS: 0 Unknown Base
File type: 0.0 Unknown
File date: 00000000.00000000
Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4
We could see that path from running this command as well :
0:000> !for_each_module
00: 0000000076e20000 0000000076f3f000 kernel32 C:\Windows\System32\kernel32.dll kernel32.dll
01: 0000000077500000 00000000776a9000 ntdll C:\Windows\System32\ntdll.dll ntdll.dll
02: 000000013f890000 000000013f8a6000 FakeModule C:\Work\AWMA\FakeModule\x64\Release\FakeModule.exe FakeModule.exe
03: 000007fef8cb0000 000007fef8cc7000 winspool C:\Work\AWMA\FakeModule\x64\Release\winspool.drv
04: 000007fefdb30000 000007fefdb9c000 KERNELBASE C:\Windows\System32\KERNELBASE.dll KERNELBASE.dll
or from PEB:
0:000> !peb
PEB at 000007fffffdf000
[...]
7fef8cb0000 50de1bb2 Dec 28 22:22:42 2012 C:\Work\AWMA\FakeModule\x64\Release\winspool.drv
[…]
Another sign is module size in memory which is much smaller than real winspool.drv:
0:000> ? 000007fe`f8cc7000 - 000007fe`f8cb0000
Evaluate expression: 94208 = 00000000`0001700
Module size can help if legitimate module from well-known folder was replaced. Module debug directory and the size of export and import directories are also different with the former revealing the development folder:
0:000> !dh 000007fe`f8cb0000
[...]
0 [ 0] address [size] of Export Directory
[…]
9000 [ 208] address [size] of Import Address Table Directory
[…]
Debug Directories(2)
Type Size Address Pointer
cv 49 e2c0 cac0 Format: RSDS, guid, 1, C:\Work\AWMA\FakeModule\x64\Release\winspool.pdb
This can also be seen from the output of !lmi command:
0:000> !lmi 7fef8cb0000
Loaded Module Info: [7fef8cb0000]
Module: winspool
Base Address: 000007fef8cb0000
Image Name: winspool.drv
Machine Type: 34404 (X64)
Time Stamp: 50de1bb2 Fri Dec 28 22:22:42 2012
Size: 17000
CheckSum: 0
Characteristics: 2022
Debug Data Dirs: Type Size VA Pointer
CODEVIEW 49, e2c0, cac0 RSDS - GUID: {29D85193-1C9D-4997-95BA-DD190FA3C1BF}
Age: 1, Pdb: C:\Work\AWMA\FakeModule\x64\Release\winspool.pdb
?? 10, e30c, cb0c [Data not mapped]
Symbol Type: DEFERRED - No error - symbol load deferred
Load Report: no symbols loaded
- Dmitry Vostokov @ DumpAnalysis.org + TraceAnalysis.org -