We started cataloguing elemental malware detection and analysis patterns. The first such a pattern is called Deviant Module (page 133). In Fake Module pattern one of the 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 inspected loaded modules we didn'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 module images for any modifications we find that winspool module was not compared with the corresponding 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:WSDK8Debuggersx64symkernel32.dll503285C111f000kernel32.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:WSDK8Debuggersx64sym tdll.dll4EC4AA8E1a9000 tdll.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:WSDK8Debuggersx64symKERNELBASE.dll503285C26c000KERNELBASE.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 also doesn't have any version information:
0:000> lmv m winspool start end module name 000007fe`f8cb0000 000007fe`f8cc7000 winspool (deferred) Image path: C:WorkAWMAFakeModulex64Releasewinspool.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 the following command as well:
0:000> !for_each_module 00: 0000000076e20000 0000000076f3f000 kernel32 C:WindowsSystem32kernel32.dll kernel32.dll 01: 0000000077500000 00000000776a9000 ntdll C:WindowsSystem32 tdll.dll ntdll.dll 02: 000000013f890000 000000013f8a6000 FakeModule C:WorkAWMAFakeModulex64ReleaseFakeModule.exe FakeModule.exe 03: 000007fef8cb0000 000007fef8cc7000 winspool C:WorkAWMAFakeModulex64Releasewinspool.drv 04: 000007fefdb30000 000007fefdb9c000 KERNELBASE C:WindowsSystem32KERNELBASE.dll KERNELBASE.dll
Or from PEB:
0:000> !peb PEB at 000007fffffdf000 [...] 7fef8cb0000 50de1bb2 Dec 28 22:22:42 2012 C:WorkAWMAFakeModulex64Releasewinspool.drv [...]
Another sign is the module size in memory which is much smaller than the real winspool.drv:
0:000> ? 000007fe`f8cc7000 - 000007fe`f8cb0000 Evaluate expression: 94208 = 00000000`0001700
Module size can help if legitimate module from the well-known folder was replaced. Module debug directory and the size of export and import directories are also different with the original one 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:WorkAWMAFakeModulex64Releasewinspool.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:WorkAWMAFakeModulex64Releasewinspool.pdb ?? 10, e30c, cb0c [Data not mapped] Symbol Type: DEFERRED - No error - symbol load deferred Load Report: no symbols loaded