Log in

View Full Version : dumping hidden persistant malware


_genuine
July 23rd, 2012, 23:21
Hi ladies,

Im analyzing a piece of malware, I've been able to document its behavior and also been able to clean it from the system quite easily, my next course of action is to analyze the code to document 'how' it does its magic. The first approach id like to take it to see if i can get a clean dump of the process, it uses the persistence method of an autorun entry replacing itself with taskman on logon in the registry, it also hides its executable from the disk. (Which can be retrieved using GMER). The executable it packed or obfiscated, which is why i'd like to see if i can get a running dump of the file. The problem is, on boot up, the process only briefl appears and then its gone. doing its thing in silence. My question is, is there a tool out there that can be used to dump a file on bootup? or can you guys give some advice as to how you would get a dump of this file that only briefly starts on boot up on the system ( by boot i mean on logon) Thanks for any insights.

Kayaker
July 24th, 2012, 00:22
Hi

As an offhand idea, set the /BREAK switch in boot.ini, with the appropriate /DEBUG switches. This will cause a break on HAL initialization. With a suitable VM/Windbg setup you can use the .reboot command to start the process. This will break very early in bootup so you'll need to step ahead until your malware loads. You might be able to set a breakpoint on the malware process load itself with a proper Windbg command.

Another thing you could check is to see if BootlogXP records the malware loading, and if the order is consistent you could even break on the process loaded just before the malware

http://greatis.com/utilities/bootlogxp/index.html

Let us know if you can trap the little bugger.

_genuine
July 24th, 2012, 00:37
Thanks for the insight Kayaker, your responds has me thinking that maybe if i reinstall SICE on this VM I can probably catch this thing, but its been quite some time since ive used SICE, and as far as i remember, it does not have dumping capabilities. I will grab that bootlogxp program, but im fairly sure its boot is consistant. I've tried to go with the more cat and mouse technique where i tried to beat its termination by having process hacker run on startup and dump it as quickly as i could, but im not as fast as i thought i was. I wanted to avoid having to do a setup with windbg as my host machine right now is a MACbook pro, and i would have to have two VMs running in order to have a decent remote setup like the one you described. If there are any tools that do bootlogging and have some kind of framework available i am willing to code up an extension to dump processes on bootup for such a tool as well.

blabberer
July 30th, 2012, 17:25
if you employ /break in windbg on the initial break you can also
set up a break on nt!PspCreateProcess; do a gu ( go up )
and grab the last created process from
nt!psActiveProcessHead.blink

a small conditional breakpoint script shown below will print out all the process that are created on reboot of my sample virtual machine (look for calc.exe whose parent is explorer.exe that's my autorun malware )

Code:

bu nt!PspCreateProcess ".printf \"parent process %ma\\t\", @@c++( ( (nt!_EPROCESS *)@$proc)->ImageFileName);gu;.printf \"created %ma\\n\",@@C++( ( (nt!_EPROCESS *)@@masm( ( poi( nt!PsActiveProcessHead+4 )-88) ) )->ImageFileName);g";


instead of hardcoding 88 etc you can use #containing record macro to get the offset of ActiveProcessLink (which in xpsp3 is at 0x88 from start of Eprocess)

pasted below is a dump of all process that were created in my vpc

instead of /break i used a running windbg to utilize exception handling viz sx


Code:


kd> sxe ibp;.reboot
Shutdown occurred at (Tue Jul 31 03:47:24.000 2012 )...unloading all symbol tables.
Waiting to reconnect...
Connected to Windows XP 2600 x86 compatible target at (Tue Jul 31 03:47:36.968 2012 ), ptr64 FALSE
Kernel Debugger connection established. (Initial Breakpoint requested)
Symbol search path is: SRV*F:\symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
Windows XP Kernel Version 2600 UP Free x86 compatible
Built by: 2600.xpsp.080413-2111
Machine Name:
Kernel base = 0x804d7000 PsLoadedModuleList = 0x8055b1c0
System Uptime: not available
Break instruction exception - code 80000003 (first chance)
*******************************************************************************
* *
* You are seeing this message because you pressed either *
* CTRL+C (if you run kd.exe) or, *
* CTRL+BREAK (if you run WinDBG), *
* on your debugger machine's keyboard. *
* *
* THIS IS NOT A BUG OR A SYSTEM CRASH *
* *
* If you did not intend to break into the debugger, press the "g" key, then *
* press the "Enter" key now. This message might immediately reappear. If it *
* does, press "g" and "Enter" again. *
* *
*******************************************************************************
eax=00000001 ebx=80087000 ecx=80550d74 edx=80550d44 esi=80087000 edi=00000000
eip=804e3592 esp=80550d60 ebp=80550ee8 iopl=0 nv up ei pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000202
nt!RtlpBreakWithStatusInstruction:
804e3592 cc int 3

kd> bu nt!PspCreateProcess ".printf \"parent process %ma\\t\", @@c++( ( (nt!_EPROCESS *)@$proc)->ImageFileName);gu;.printf \"created %ma\\n\",@@C++( ( (nt!_EPROCESS *)@@masm( ( poi( nt!PsActiveProcessHead+4 )-88) ) )->ImageFileName);g";
kd> g


parent process created
parent process System created smss.exe
parent process smss.exe created autochk.exe
parent process smss.exe created csrss.exe
parent process smss.exe created winlogon.exe
parent process winlogon.exe created services.exe
parent process winlogon.exe created lsass.exe
parent process services.exe created svchost.exe
parent process services.exe created svchost.exe
parent process services.exe created svchost.exe
parent process services.exe created svchost.exe
parent process services.exe created svchost.exe
parent process winlogon.exe created logonui.exe
parent process winlogon.exe created userinit.exe
parent process userinit.exe created explorer.exe
parent process services.exe created spoolsv.exe
ERROR: DavReadRegistryValues/RegQueryValueExW(4). WStatus = 5
ERROR: DavReadRegistryValues/RegQueryValueExW(5). WStatus = 5
ERROR: DavReadRegistryValues/RegQueryValueExW(6). WStatus = 5
parent process services.exe created vmsrvc.exe
parent process services.exe created mscorsvw.exe
parent process services.exe created smlogsvc.exe
parent process services.exe created vpcmap.exe
parent process explorer.exe created vmusrvc.exe
parent process explorer.exe created calc.exe <-------- my autorun malware
parent process services.exe created alg.exe
parent process explorer.exe created taskmgr.exe
parent process svchost.exe created wuauclt.exe
parent process taskmgr.exe created cmd.exe
parent process cmd.exe created netstat.exe
parent process cmd.exe created hostname.exe
parent process cmd.exe created tasklist.exe
parent process svchost.exe created wmiprvse.exe
parent process cmd.exe created wmic.exe
parent process explorer.exe created rundll32.exe
parent process explorer.exe created verclsid.exe
parent process explorer.exe created verclsid.exe
parent process explorer.exe created IEXPLORE.EXE
parent process explorer.exe created procexp.exe
parent process explorer.exe created Winobj.exe
watchdog!WdUpdateRecoveryState: Recovery enabled.

_genuine
July 30th, 2012, 18:27
Thanks for the detailed response blabberer! you seem to be quite the beast on windbg scripting, unfortunately im not as skilled, I have a question about your script, while I can pretty much get the gist of what its doing, how do i employ in my virtual environment? I can connect via COM to the VM and run that script when the OS is loading? Or run it in WINDBG locally within the infected machine?
Also does WINDBG have the capability to dump the process? That is really my main goal, I've verified already that it runs on startup, but i would like to do something along the lines of, break when the process has fully started (All modules have loaded and it has been 'unpacked' in memory), suspend it and dump a full image. I can do these things with a process that is running, but this particular malware quickly kills itself. It doesnt seem to run much code at all, but i would still like to analyze what it does on initialization.
Once again thanks and i will play around with your script just to see how it works.

regards,
gen

Kayaker
July 30th, 2012, 22:31
That is very cool blabberer. I just added to my ongoing file called blabberer_windbg_trix.txt.

I like that sxe ibp Initial break point event flag. That way you don't need to modify the remote boot.ini with the /BREAK switch. Nice.


If I can make a slight diversion, since it's so useful, the other script I like is the one for listing drivers on boot you showed us in this post:

http://www.woodmann.com/forum/showthread.php?9201-Ring-0-anti-debugger-code-in-Daemon-Tools&p=61827&viewfull=1#post61827

To clarify one small point on its use, the script as blabberer wrote it, and how it looked written with the bl command was like this:

Code:

kd> bp 8049a037 ".printf \"%y\\n\", poi(eax+2c);g"
kd> bl
2 e 8049a037 0001 (0001) nt!IopLoadDriver+0x66f ".printf \"%y\n\", poi(eax+2c);g"


The magic address 8049a037 and offset nt!IopLoadDriver+0x66f you need to derive for your own system. What that offset is really pointing to is where the Entry Point of regular drivers are called from in IopLoadDriver, that is the specific breakpoint being set.

While the registers used might be different in different OS versions, the syntax is generally consistent since Win2K, not sure offhand what it looks like in Win7. You can use the Windbg "u nt!IopLoadDriver" command (or IDA) to scan for the pattern.

So for my own system I determined that the IopLoadDriver pattern occurred here

Code:

805a69c9 push dword ptr [ebp-90h]
805a69cf push edi
805a69d0 call dword ptr [edi+2Ch] // driver Entry Point called


and the Windbg breakpoint I set using blabberers scriptlet was then:

Code:

kd> bp 805a69d0 ".printf \"%y\\n\", poi(edi+2c);g"
kd> bl
0 e 805a69d0 0001 (0001) nt!IopLoadDriver+0x669 ".printf \"%y\\n\", poi(edi+2c);g"





As for breaking on a process that runs during startup, you could try this. I discovered this trick from

Break on user mode module load
http://analyze-v.com/?p=682

and used it successfully in this thread

http://www.woodmann.com/forum/showthread.php?14576-Your-free-airline-ticket-is-ready&p=91631&viewfull=1#post91631


As a further test, I created an autostart entry in the VM of a VM/WinDbg/VirtualKD setup for notepad under
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

On the initial Windbg break as the VM was starting up I set up the exception command to break on the process loading

Code:

kd> !gflag +ksl
kd> sxe ld notepad.exe


Windbg broke again (the VM screen showed the "Loading your personal settings" message) and I checked we were in the proper context

Code:

kd> !process -1 0
PROCESS 81430da0 SessionId: 0 Cid: 0000 Peb: 00000000 ParentCid: 0490
DirBase: 0a2df000 ObjectTable: e1d7ba68 HandleCount: 0.
Image: NOTEPAD.EXE


At this stage we're still not at the Entry Point of the process, so what I had done before was to use the @$exentry pseudoregister in a further breakpoint, as either of the following:

Code:

kd> bp /p @$proc @$exentry
kd> ba e1 /p @$proc @$exentry

kd> ? @$exentry


In all cases I got the following error:

Bad register error at '@$exentry'

Odd. Any guesses blabs?



Oh well, there's more than one way to find the Entry Point.

Code:

kd> lm m notepad
start end module name
01000000 01014000 NOTEPAD (deferred)

kd> !dh -f 1000000

File Type: EXECUTABLE IMAGE
OPTIONAL HEADER VALUES
739D address of entry point


And the next breakpoint becomes instead

Code:

kd> bp /p @$proc 100739d
kd> bl
0 e 0100739d 0001 (0001) NOTEPAD!WinMainCRTStartup
Match process data 81430da0


This will get us to the Entry Point of the process that loads during bootup.


I think someone had asked that question in another thread, about an easy way of dumping a full image in Windbg. It's a good question. We're used to quick tricks like OllyDump or using OllyBone or the "ESP trick" to find the OEP of packed executables. I don't know of any shortcuts with WinDbg. Other than .writemem and manual tracing to OEP and rebuilding as required.

Kayaker

blabberer
July 31st, 2012, 05:19
@_genuine

i hope you have setup a kernel debugging connection (i reread your post and you mention mac i haven't kded with mac so i cant say how to do it in mac the following description is for windows os)

assuming you have a pc running windows os xpsp3

and you can install your favourite vm inside it (i play with virtual pc )

in the vm install xpsp3 again

the physical computer running the vm is called host computer which will also run the windbg / kd

the vm is called target and you need to setup kd connection in this vm (com / 1394 / virtual kd /fancy usb/ etc)

assuming you have a valid connection between windbg running on host and os running on target

you can issue

sxe ibp;.reboot
in windbg

this will modify the event handling status of initial break point to enabled and will reboot the target computer

once rebooted windbg will break again on the initial breakpoint (this is the earliest break possible when kernel is loading

and it is at the end of hal phase initialisation when a few essential modules have been loaded and not even System process has been created)

at the break you set a breakpoint (copy paste the script as a single line in windbg command browser ) on nt!pspCreateprocess as posted earlier) and run the windbg with g

on each and every process creation windbg will print out the parent process and child process

if you want to break on every process created you would need to remove the last g in the script and enter g manually every time

the process context on every break would be of parent process not child process

the child process has no active threads yet

as far as dumping is considered you would need to setup further breakpoints
based on process matching and some times trial and error on system apis that are bound to be called for any process initialization


@kayaker

sxe ld will work only once during the first time a modules symbol is loaded
ld does not work for repeated creation of the same process

cpr and epr both work in user mode only these events arent generated in kernel mode

so sxe ld might work if you do a .reboot and say notepad.exe is loaded for first time
but if you do say start -> run -> notepad a few times you will see that sxe ld does not break
it is because the symbols is already loaded (try lm m note* and you would see notepad symbol in deferred list)

? $exentry

and ? @$exentry both work an initialised process with active threads i think (it really never worked for me actually speaking)

while i played with it it returned entry point of ntoskrnl.exe several times in the past
so i normally do not use it

see a trace below i have broken on an internal breakpoint (made by windbg on sxe ld mods) and you can see the current process is explorer.exe

but $exentry returning entry point of ntoskrnl.exe

Code:


kd> .lastevent; !process -1 0; ? $ip; ? $exentry; ? $exentry -nt; kb3; !grep -i -e "entry " -c "!dh nt"


Last event: Hit breakpoint 10000 <------------------- bp id is 10000 internal bpid
debugger time: Tue Jul 31 15:23:01.796 2012 (UTC + 5:30)


PROCESS ffaf6da0 SessionId: 0 Cid: 0570 Peb: 7ffdd000 ParentCid: 0554
DirBase: 0044d000 ObjectTable: e1d75c40 HandleCount: 394.
Image: explorer.exe <----------------- current proc is explorer.exe

Evaluate expression: -2141717310 = 8057fcc2 <------------iam in kernel address space

Evaluate expression: -2140476628 = 806aeb2c <-------------wtf ????

Evaluate expression: 1932076 = 001d7b2c <------------@sck#% it is ntos entry point see the last expression evaluated

(might be because of kestackattach and arbitrary process context execution not sure )

ChildEBP RetAddr Args to Child
f9536d38 804de7ec 01edd3f4 001f0fff 00000000 nt!NtCreateProcessEx+0x7e iam not mad i ran some process from start -> run
f9536d38 7c90e4f4 01edd3f4 001f0fff 00000000 nt!KiFastCallEntry+0xf8
01edd00c 7c90d14c 7c8192ce 01edd3f4 001f0fff ntdll!KiFastSystemCallRet


1D7B2C address of entry point <---------- see ep matches with !dh nt output


i believe that it is better to have a sure shot address by spleunking

rather than these whimsical and mostly unsupported / undocumented / UNKNOWN / RARELY understood pseudo registers