An application that I do some development on was having trouble starting on a Windows XP machine. In this application, we hook some of the Windows API functions internally to extend functionality in print preview (long story). However, on this machine, the hook was failing.
The machine had fully up-to-date antivirus software from a major vendor; they’d run various anti-malware programs, but nothing was coming up.
No weird looking processes, DLLs or drivers were visible using Process Explorer; it looked like a pretty clean machine. So after doing the usual diagnostics, we decided to take a full dump of the process when it threw up its error message. A debug message told us that the hook function was failing to hook RegisterClassW, RegisterClassExW, RegisterClassA and RegisterClassExA.
I loaded the dump up in windbg and took a look at the functions.
0:000> u registerclassw user32!RegisterClassW: 7e41a39a 6849d31300 push 13D349h 7e41a39f c3 ret 7e41a3a0 ec in al,dx 7e41a3a1 308b45085657 xor byte ptr [ebx+57560845h],cl 7e41a3a7 6a09 push 9 7e41a3a9 59 pop ecx 7e41a3aa 8d7004 lea esi,[eax+4] 7e41a3ad 8b00 mov eax,dword ptr [eax]
Whoa. Push what? That’s definitely not what we normally see! Here’s what we’d expect to see:
USER32!RegisterClassW: 7e41a39a 8bff mov edi,edi 7e41a39c 55 push ebp 7e41a39d 8bec mov ebp,esp 7e41a39f 83ec30 sub esp,30h 7e41a3a2 8b4508 mov eax,dword ptr [ebp+8] 7e41a3a5 56 push esi 7e41a3a6 57 push edi 7e41a3a7 6a09 push 9
So that push followed by ret is going to jump to address 13D349. Let’s look to see which module owns that address space:
0:000> !address 13D349 Usage: Allocation Base: 00000000 Base Address: 00130000 End Address: 00169000 Region Size: 00039000 Type: 00000000 State: 00000000 Protect: 00000000
So, not in the image space of a normally loaded module then. So who is allocating that memory? Let’s look for some strings longer than 3 characters in that block:
0:000> s -sa 00130000 00169000
This returned a stack of garbage data , but some strings stood out:
00131fb8 "Coded by BRIAN KREBS for persona" 00131fd8 "l use only. I love my job & wife" 00131ff8 "." ... 00136f08 "http://%02x%02x%02x%02x%02x%02x%" 00136f28 "02x%02x.com/%02x%02x%02x%02x/%02" 00136f48 "x%02x%02x%02x.php" ... 00138eac "http://www.google.com/webhp" ... 00139424 "facebook.com" 00139438 "%BOTID%" 00139440 "%BOTNET%" ...
That first one was a dead giveaway. Brian Krebs is a security researcher. A Google search found that the Citadel Trojan embedded that string.
To help us diagnose similar situations more rapidly in the future, we captured a few other visible details on the file system and in the registry. Images below for your entertainment!
There was not a lot of point going any further. We understood why the problem was occurring, and how to resolve it (rebuild!). Given that no antivirus vendors appear to support removal of this trojan, we advised that the client rebuild the computer as the safest and most cost-effective way forward.
Good post, and I didn’t even fall asleep while reading it 🙂