Log in

View Full Version : Your free airline ticket is ready.


Woodmann
December 20th, 2011, 23:26
Have at it. 2527

Silkut
December 25th, 2011, 11:53
http://www.virustotal.com/file-scan/report.html?id=c38c64033055380679e5a51b6c2779cc898addc947a2eb8ffe5e311a0624b8e7-1324830951
http://www.threatexpert.com/report.aspx?md5=9c809fb94a19a4f30e9dfbca8098849b

You're not gonna fly far with this, or at least don't forget your chapka.

Merry X-Mass
Happy 500th post
Ваше здоровье

ZaiRoN
December 25th, 2011, 15:36
Did someone try it?

Kayaker
December 26th, 2011, 18:29
Hi Z,

Um, I get hung up on the first call to _lread. Instead of

lread(hFile, lpBuffer, uBytes)
it's called as
lread("KERNEL32.DLL", garbage, garbage)

While there's lots of garbage code, it's easy to trace and I don't see any traps up until that point. Just looks like a dumb API call that was expected to return the base address of kernel32? Code after the call (ret to 40a9cc) indicates the return value is to be parsed as a PE file. Do you get the same thing?

K.

Woodmann
December 26th, 2011, 22:36
Lovely.

Woodmann

ZaiRoN
December 27th, 2011, 05:21
Hey K,
you are working on the dumped file, right?
Try to load the untouched exe and you'll get the same code but with different parameters:

40AB8A sub ebx, 524157h
40AB90 dec edi
40AB91 mov edi, edx
40AB93 retn

At 40AB91 the stack is:
- LoadLibraryA address
- 0x40A9CC which is the point from where the code will go on later
- "KERNEL32.DLL" string

Your guess is right, it only gets kernel32 address...

Due to the nature of the malware I think it's better to work on the original file, because as you might have seen it does use a large amount of data from PE header.

The mistery is the fact that the malware does nothing... did I lost something important from the code!?!

blabberer
December 27th, 2011, 06:42
well Zai i tried it got it dumped then tried dumped file failed on some constant tried the packed file again
this time it flew somewhere to some virtual allocateed place

decrypted some crap and erased its own memory and rep stosb'ed the decrypted crap

i dumped the memory

then it went to second oep (i think) at 401538 where i dumped it again
this second seems to be a valid pe file

but after some create window blah blah it terminated after a SleepEx call i didnt look after that

but nothing seemed to be malwarelike anywhere dont know have to check again

i put together all the crap in one zip and uploaded it here see if you can find something different

ZaiRoN
December 27th, 2011, 07:11
hey blabbere!

your description is right, basically the idea of the malware is to replace the old exe bytes. In this way you'll have the *same* exe running but with different bytes... As you said 401538 is the right oep of the final exe and the dumped files you provide are ok. That's really strange...

It's time to solve this puzzle

blabberer
December 27th, 2011, 13:53
i pieced up a small snippet to print all the registers on startup
ran it alone in live system
ran it in live system in ollydbg
ran it alone in vpc 2007
ran it in ollydbg iniside vpc2007

and snap shotted all 4 msg boxes and uploaded here for reference
there seems to some differences which this exe is utilising for the first hurdle
maybe it uses this for other purposes too

ZaiRoN
December 27th, 2011, 18:02
I could be wrong but I doubt the problem is connected with the initial value of the registers.
Point 1: if you look at the original and the unpacked exe they have the same initial registers values (stack is different of course, but it doesn't matter).
Point 2: stepping through the initial code you'll see that every register is associated with a specific value (decided by the malware itself), the starting value is not relevant for a register...

Kayaker
December 28th, 2011, 02:38
Quote:
[Originally Posted by blabberer;91622]
but after some create window blah blah it terminated after a SleepEx call


A bp on the lpCompletionRoutine of ReadFileEx (called during the SleepEx) in that mapped code bears fruit.

modified EP of a mapped svchost.exe process returns immediately to another mapped section which needs looking into...

ZaiRoN
December 28th, 2011, 09:37
Just to clarify Kayaker's words, here is a snippet from MSDN SleepEx page:

bAlertable (2° parameter):
If the parameter is TRUE and the thread that called this function is the same thread that called the extended I/O function (ReadFileEx or WriteFileEx), the function returns when either the time-out period has elapsed or when an I/O completion callback function occurs...

Kayaker
December 29th, 2011, 06:08
Thanks for making my sleepy(Ex) post more coherent Z

I'll try to describe a couple of ways I was able to break into the subverted svchost process, where the real malware hides..

As Zairon mentioned, if you unpack the modified UPX file with the default 'upx -d' command, you don't get the real malware, so you need to work with the original packed file. After some routine tracing you can find where some code is mapped into virtually allocated memory and executed.

Blabberer provided a dump of that memory in his attachment. From his file _008E0000.mem we can see the ReadFileEx which is called with a CompletionRoutine callback. It is from within this callback that the next steps occur. Malwares commonly use various benign API's which have callbacks to disguise the path of execution.

Code:

:0040169E push offset CompletionRoutine ; lpCompletionRoutine
:004016A3 push offset Overlapped ; lpOverlapped
:004016A8 push edi ; nNumberOfBytesToRead
:004016A9 push offset FileName ; lpBuffer
:004016AE push edi ; hFile
:004016AF call ReadFileEx

:00401238 ; void __stdcall CompletionRoutine(DWORD, DWORD, LPOVERLAPPED)
:00401238 CompletionRoutine proc near ; DATA XREF: start+166
:00401238


The code in the callback maps another section of code into an svchost.exe process, which it creates. The CreateProcess call occurs here:

Code:

:004013A9 call ds:dword_404010 ; CreateProcessA (svchost.exe)


It then modifies the Entry Point of svchost to jump immediately to the mapped section, which is the real heart of the malware which will now be running under an svchost process. The byte modification occurs here:

Code:

:004014DA mov al, 68h // PUSH opcode
:004014DC stosb
:004014DD mov eax, [ebp+var_4] // offset of mapped section
:004014E0 stosd
:004014E1 mov al, 0C3h // RET opcode
:004014E3 stosb

The Entry Point of svchost is now changed to:

PUSH xxxxxxxx
RET



Again, this seems a common occurence, malware code ultimately running under svchost, csrss, or other standard system process in order to hide itself. This makes it a bit tricky to debug - how do you break on execution of the secondary process?

I guess you can debug it as a child process, for example in WinDbg with ".childdbg 1". I think there's a similar trick with Olly (wasn't there a plugin for that Blabberer?).


I tried it 2 different ways, one with Softice, another with WinDbg.

In Softice I set a global breakpoint on CreateProcessA and started up the original malware. It broke at the :004013A9 address (CreateProcessA) I showed above. I allowed the malware to modify the Entry Point of svchost that it was mapping out (down to address :004014E3), but then I modified the first 2 bytes myself in Softice to 0xEB 0xFE (jmp eip). Then just Ctrl-D out of Softice for a few seconds, Ctrl-D back in and you are paused at the start of the svchost process. Replace the original bytes and trace.

This is a standard way of debugging a created child process and can be done in a usermode debugger as well.



More interesting was a method that I tried for the first time with a remote WinDbg/VMWare setup.

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

The first step is to enable loading of kernel debugger symbols, which can be done dynamically with the !gflags command:

Code:

kd> !gflag +ksl
Current NtGlobalFlag contents: 0x00040000
ksl - Enable loading of kernel debugger symbols


The next step is to use the sxe ld command to enable a breakpoint when the module of interest loads:

Code:

kd> sxe ld svchost.exe

kd> g



Now I head over to the guest VM and start up the malware. Sure enough WinDbg breaks on the host and confirms that we're in the context of svchost:

Code:

kd> !process -1 0
PROCESS 81438da0 SessionId: 0 Cid: 0000 Peb: 00000000 ParentCid: 04e4
DirBase: 020a8000 ObjectTable: e1745728 HandleCount: 0.
Image: svchost.exe



So far so good, but at this point we're paused somewhere deep in nt!NtCreateProcessEx. How to break on the Entry Point of svchost, which is where I want to start tracing from?

In WinDbg the address of the entry point of the first executable of the current process is given by the pseudo-register $exentry.

When setting a breakpoint we can specify the process that is associated with this breakpoint with the /p switch, followed by the address of the EPROCESS structure, or more simply by the $proc pseudo-register.

So I tried the following breakpoint:

kd> bp /p @$proc @$exentry

The breakpoint never hit. It worked fine when monitoring the loading of a simple process like notepad.exe for example, but not for the svchost process created by the malware. The reason for this will become apparent in a minute (hint, svchost process started execution paged-out).


After scratching my head for a bit I decided to try a Break on Access (hardware) breakpoint instead, specifying a break on execution, using the same syntax as before:

Code:

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

kd> bl
0 e 01002509 e 1 0001 (0001) svchost!wmainCRTStartup
Match process data 81438da0



This time it worked, but I got the following display in the disassembly window. Correct breakpoint address but no code. Everything was paged out!

Code:

kd> g
Breakpoint 0 hit
svchost!wmainCRTStartup:
001b:01002509 ?? ???


No prior disassembly possible
svchost!wmainCRTStartup:
001b:01002509 ?? ???
001b:0100250a ?? ???
001b:0100250b ?? ???
001b:0100250c ?? ???
001b:0100250d ?? ???
svchost!_wmainCRTStartup:
001b:0100250e ?? ???



However, as soon as I started tracing everything became paged in and I could see the modifed EP of svchost that the malware created, as explained above.

Code:

svchost!wmainCRTStartup:
001b:01002509 6800000900 push 90000h
svchost!_wmainCRTStartup:
001b:0100250e c3 ret



Tracing this code, you return to address 0x90000 (the offset of the mapped section created in the CompletionRoutine callback earlier). Again this memory is paged out initially, but as soon as you start tracing it magically appears. (You can also use the .pagein command).



Anyway, all this work gets you to the mapped section in svchost which you can start tracing if you really need to know what this malware is up to:

Code:

001b:00090000 e800000000 call 00090005
001b:00090005 5b pop ebx
001b:00090006 83eb05 sub ebx,5
001b:00090009 31c9 xor ecx,ecx
001b:0009000b 648b7130 mov esi,dword ptr fs:[ecx+30h]
001b:0009000f 8b760c mov esi,dword ptr [esi+0Ch]
001b:00090012 8b761c mov esi,dword ptr [esi+1Ch]
001b:00090015 8b6e08 mov ebp,dword ptr [esi+8]
001b:00090018 8b7e20 mov edi,dword ptr [esi+20h]
001b:0009001b 8b36 mov esi,dword ptr [esi]
001b:0009001d 384f18 cmp byte ptr [edi+18h],cl
001b:00090020 75f3 jne 00090015
001b:00090022 89ab00050000 mov dword ptr [ebx+500h],ebp
001b:00090028 8db304050000 lea esi,[ebx+504h]
001b:0009002e e852010000 call 00090185



That was fun.

Kayaker

blabberer
December 29th, 2011, 12:44
I realized i Stepped Too Fast Seeing The infinite Parameter in SleepEx i normally Set Bp On All Callbacks , Completion Routines ,ThreadStart Routines Etc Before Stepping further
but erred this time
yes on the IoCompletionRoutine You Can Find It Resolves these import address

Code:

00404008 7C80B55F kernel32.GetModuleFileNameA
0040400C 7C809BD7 kernel32.CloseHandle
00404010 7C80236B kernel32.CreateProcessA
00404014 7C809AE1 kernel32.VirtualAlloc
00404018 7C80BE46 kernel32.lstrlenA
0040401C 7C802446 kernel32.Sleep
00404020 7C90D160 ntdll.ZwCreateSection
00404024 7C90D500 ntdll.ZwMapViewOfSection
00404028 7C90DEF0 ntdll.ZwUnmapViewOfSection
0040402C 7C90DB20 ntdll.ZwResumeThread
00404030 7C90D7E0 ntdll.ZwQueryInformationProcess
00404034 7C90D9E0 ntdll.ZwReadVirtualMemory



ZwCreateSection , ZwMapViewSection ( i am attaching the memdump) , ZwunMapViewOfSection, Createprocess()

Code:

0012FBEC 00000000 |ModuleFileName = NULL
0012FBF0 00900000 |CommandLine = "svchost.exe"
0012FBF4 00000000 |pProcessSecurity = NULL
0012FBF8 00000000 |pThreadSecurity = NULL
0012FBFC 00000000 |InheritHandles = FALSE
0012FC00 00000004 |CreationFlags = CREATE_SUSPENDED
0012FC04 00000000 |pEnvironment = NULL
0012FC08 00000000 |CurrentDir = NULL
0012FC0C 00404040 |pStartupInfo = Ticket.00404040
0012FC10 00404084 \pProcessInfo = Ticket.00404084

Handles, item 28
Handle=0000007C newly created process svchost
Type=Process
Refs= 5.
Access=001F0FFF SYNCHRONIZE|WRITE_OWNER|WRITE_DAC|READ_CONTROL|DELETE|QUERY_STATE|MODIFY_STATE|FFC




Log data, item 0
Message=hello Childdbg Enabled



yes there is a plugin for ollydbg to attach to a child process by anonymouse which can be found here

https://www.openrce.org/repositories/users/anonymouse/ModifiedCommandLinePluginWithChildDbg_Date_16082008.rar

there is an entry in crcetl but it is not latest

http://www.woodmann.com/collaborative/tools/Bin_Modified_Command_Line_Plugin_2007-10-23_21.7_modified_cmdline_plugin_date2442007.zip

ollydbg 2 has all these extra functionalites inbult

ZaiRoN
December 30th, 2011, 07:43
Thanks to you Kayaker for the nice explanation

Quote:
ollydbg 2 has all these extra functionalites inbult

Does it work with this malware too? I have to admit I prefer good old "jmp eip" trick, but sometimes I'm open to new ways too

blabberer
December 30th, 2011, 14:31
none of the childdbg works

not windbg
not ollydbg 1.10 plugin
not ollydbg 2

windbg and ollydbg 1.10 plugin simply freezes up all 3 exes (self (ie wdbg or odbg) , ticket ,svchost) a processdebugport exists so cant attach other instances too
odbg 2 seems to do nothing and the execution and creation of csrss.exe in app data folde succeeds

ZaiRoN
December 30th, 2011, 21:11
That's what I fear... I could be wrong but I bet the problem is related with the fact that they don't see the unmapped/unpaged child process

blabberer
December 31st, 2011, 08:48
in ollydbg 1.10 plugin
OpenProcess Succeeds but ReadProcessMemory Fails and freeze probably happens because SuspendThread is Called Before But before Returning Resume Thread isnt called on failure

windbg also has similar path

havent checked ollydbg2 childdbg path


Code:

if(debugevent !=0)
{
debev = *debugevent;
Eventcode = debev.dwDebugEventCode;
if((Eventcode == CREATE_PROCESS_DEBUG_EVENT))
{
if(debev.dwProcessId != (DWORD) Plugingetvalue(VAL_PROCESSID))
{
dbgactprocstop = (DEBUGACTIVEPROCESSSTOP) GetProcAddress((LoadLibrary("kernel32.dll"),"DebugActiveProcessStop";
if(!dbgactprocstop)
{
MessageBox(0,"DebugActiveProcessStop Is Not Available Needs Xp And Above","CHILDDBG",MB_OK);
return;
}
hThread = OpenThread(THREAD_ALL_ACCESS,FALSE,debev.dwThreadId);
if(!hThread)
{
MessageBox(0,"OpenThreadFailed","CHILDDBG",MB_OK);
return;
}
SuspendThread(hThread);
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,debev.dwProcessId);
if(!hProcess)
{
MessageBox(0,"OpenProcessFailed","CHILDDBG",MB_OK);
return;
}
if((ReadProcessMemory(hProcess,debev.u.CreateProcessInfo.lpStartAddress,reprocmem,4,0)) == 0)
{
MessageBox(0,"ReadProcMem Failed","CHILDDBG",0);
return;
}


ZaiRoN
January 2nd, 2012, 16:51
Ollydbg 2 refuses to debug a child process if you spawn the child process usigng CREATE_SUSPENDED flag inside CreateProcess...

ZaiRoN
January 3rd, 2012, 17:46
Quote:
I could be wrong but I bet the problem is related with the fact that they don't see the unmapped/unpaged child process
I was totally wrong! As I wrote before, the problem is related with CreateProcess's dwCreationFlags parameter. If you want to debug the child process with Ollydbg_2 you can, just change the parameter

Don't forget to manually change the first two instructions of the new file, and don't go in panic if you are not able to see the new file's code... like Kayaker said, step through the "ret" and the code will appear!

Kayaker
January 4th, 2012, 03:10
Do you know if it's always the case that a process created this way is paged out until the first instruction is executed? That seems to be what occured with the malware and apparently prevented a software breakpoint at the EP from hitting. Instead a hardware bp or EBFE was needed to ensure a forced break.

Just surmising..would the paged-out effect be the same with a gui vs console app, or if maybe the wShowWindow flag in the STARTUPINFO field is set?

ZaiRoN
January 4th, 2012, 05:39
Quote:
Do you know if it's always the case that a process created this way is paged out until the first instruction is executed?
I don't know...


Quote:
apparently prevented a software breakpoint at the EP from hitting. Instead a hardware bp or EBFE was needed to ensure a forced break.
What do you mean? I can start debugging the child process from the entry point without setting a single software/hardware breakpoint or using EBFE trick. I don't think it's a sort of breakpoint limitation.

Kayaker
January 5th, 2012, 00:23
Sorry, I was thinking about the malware specifically. I haven't been able to get WinDbg .childbg working with the malware to break on the modified svchost process (like blabberer), even if I break on CreateProcessA and clear the CREATE_SUSPENDED flag.

I was wondering if the fact that the child process seemed to be paged out (as it appeared to be in the previous post), that this also prevented .childdbg from working, or if there's some other reason for that.

Basically I'm trying to understand why the process was created paged-out. Is that normal, or was it because a section was mapped into it before it resumed? Because its Entry Point was modified? CopyOnWrite?
Because of its creation parameters? A fluke of how it was debugged (remotely, gflags +ksl set,...)? Phase of the moon?

ZaiRoN
January 5th, 2012, 08:47
Quote:
even if I break on CreateProcessA and clear the CREATE_SUSPENDED flag
It works with Ollydbg_2 only, maybe I forgot to say... sorry.
I have your problems with Windbg

blabberer
March 16th, 2012, 16:18
Quote:
[Originally Posted by Kayaker;91688]Sorry, I was thinking about the malware specifically. I haven't been able to get WinDbg .childbg working with the malware to break on the modified svchost process (like blabberer), even if I break on CreateProcessA and clear the CREATE_SUSPENDED flag.

I was wondering if the fact that the child process seemed to be paged out (as it appeared to be in the previous post), that this also prevented .childdbg from working, or if there's some other reason for that.

Basically I'm trying to understand why the process was created paged-out. Is that normal, or was it because a section was mapped into it before it resumed? Because its Entry Point was modified? CopyOnWrite?
Because of its creation parameters? A fluke of how it was debugged (remotely, gflags +ksl set,...)? Phase of the moon?



not related to childdbg but something was nagging me
recently i was searching the board and i realized i have seen this behaviour of page showing up ???? and as soon as we start trace code appears in windbg window

see the last post in this thread
http://www.woodmann.com/forum/showthread.php?7013-New-Anti-debug-protection

Code:

DBGHELP: ntdll - public symbols
c:\symbols\ntdll.dbg\38175B3079000\ntdll.dbg
c:\symbols\ntdll.pdb\380FCC4F2\ntdll.pdb
77e878c1 ?? ???
0:000> t
eax=00401000 ebx=7ffdf000 ecx=00000000 edx=00000000 esi=00000000 edi=0012fd30
eip=77f9fb64 esp=0012fd20 ebp=00000000 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ntdll!KiUserApcDispatcher+0x4:
77f9fb64 58 pop eax


did you find out what causes this what opcode is there on the line explicitly before hitting trace ??

in the above specific instance (ie when process is created and trapped in windbg with load module debug event
ths line is reached from kiDispatchApcRoutine (system bp hasnt been hit yet)

evaluator
March 28th, 2012, 14:06
i also got E-ticket.. now fake-AV not in delphi but MFC42. i'm pssed

pass:
malware