Full Disclosure mailing list archives
bug in Process Explorer (a gift for malware)
From: kris kaspersky <poldhiir () gmail com>
Date: Sun, 4 May 2008 21:14:23 +0400
Hello full-disclosure! years ago I found a bug in Process Explorer tool, written by Mark Russinovich. well, not a bug, just misfeature :) Process Explorer tries to determine the start address of a thread, but does this wrong and under certain conditions gives us an incorrect result. I sent a report to Mark, but had got no answer and the bug is still unfixed. to demonstrate this bug (well, not a bug, just misfeature) I wrote a simple prog http://nezumi.org.ru/souriz/va_thread.zip), creating two threads: the first one is a normal thread, created by CreateThread API call, the second one is malware-like thread: program allocates memory on the heap, copies malicious code to the allocated block, and calls Create[Remote]Thread. to simplificate things va_thread.c uses CreateThread, creating a malware-like thread inside its own address space. === va_thread.c doesn't not inject code into any other process! === thus, we have three threads: 1) main process-thread; 2) "fair" thread, created by CreateThread; 3) "malware-like" thread, created by Create[Remote]Thread on the heap; Process Explorer correctly determines the start addresses of the two first threads, but stumbles over third, claims that the address is: KERNEL32.DLL+B700h, what is definitely wrong! actual start address should look like 003F0000h (the exact address depends on the heap allocator behavior). I don't know how Process Explorer determines the start address of a thread, but I found my own simply and reliable way to do that. I discovered that the start address of any thread is stored at the bottom of the user stack in the second or third dword, followed by lpParameter. this trick works under Windows 2000 and Server 2003, I didn't check it out under XP yet, but I hope, it'll be the same (is there someone who wants to check it under XP? plz, tell me what you'll get). I wrote quick-n-dirty utility proc_list.c correctly determines the start addresses in the most cases and discovers malware, injecting shell-code into process by allocating memory via VirtualAllocEx, or loading malicious dll via creating remote thread and passing address of the LoadLibraryA/W with name of malicious dll in lpParameter. * if malicious code is on the heap, the start address of the malware-thread belongs to MEM_PRIVATE block (instead of MEM_IMAGE like normal exe/dll does); * if malicious code is injected via dll, the start address of the malware-thread matches the address of LoadLibraryA/W. I checked this method on a quite big malware collection and got a good result (see my blog http://souriz.wordpress.com) $proc_list.exe > out.txt * * * PROCESS INFO * * * ----------------------------------------------------- szExeFile : va_thread.exe cntUsage : 0h th32ProcessID : 58Ch ; <- we need to know ProcessID th32DefaultHeapID : 0h th32ModuleID : 0h cntThreads : 3h th32ParentProcessID : 668h pcPriClassBase : 8h dwFlags : 0h --thr------------------------------------------------ cntUsage : 0h th32ThreadID : 6B4h th32OwnerProcessID : 58Ch ; <- va_thread.exe tpBasePri : 8h tpDeltaPri : 0h dwFlags : 0h handle : 3D8h ESP : 0012FF84h EIP : 77F883A3h start address : 00401010h ; <- main thread point to args : 00000000h type : MEM_IMAGE ; <- normal thread [0012FFF0h: 00000000 00000000 00401010 00000000] --thr------------------------------------------------ cntUsage : 0h th32ThreadID : 668h th32OwnerProcessID : 58Ch ; <- va_thread.exe tpBasePri : 8h tpDeltaPri : 0h dwFlags : 0h handle : 3D8h ESP : 003EFF80h EIP : 77F883A3h start address : 00401000h ; <- "fair" thread point to args : 0012FFC8h type : MEM_IMAGE ; <- normal thread [003EFFF0h: 00000000 00401000 0012FFC8 00000000] --thr------------------------------------------------ cntUsage : 0h th32ThreadID : 764h th32OwnerProcessID : 58Ch ; <- va_thread.exe tpBasePri : 8h tpDeltaPri : 0h dwFlags : 0h handle : 3D8h ESP : 0050FF80h EIP : 77F883A3h start address : 003F0000h ; <- heap block point to args : 0012FFC8h type : MEM_PRIVATE ; <- malware thread [0050FFF0h: 00000000 003F0000 0012FFC8 00000000] _______________________________________________ Full-Disclosure - We believe in it. Charter: http://lists.grok.org.uk/full-disclosure-charter.html Hosted and sponsored by Secunia - http://secunia.com/
Current thread:
- bug in Process Explorer (a gift for malware) kris kaspersky (May 04)