counter

View My Stats

Saturday, October 4, 2014

Dynamic Automatic Unpacking for RunPE,Process Hollowing Malware(winappdbg)

 

The code shows simple usage of winappdbg. This can be implemented in other debugger in Pydbg.

Process Hollowing ,RunPE or Process Forking are more or less the same terms used for the same technique. In this method a malware creates a process in suspended mode then injects decrypted PE into the suspended process and then executes it.

There are lot of POCs for process hollowing in internet.

One of the method is as follows:

1)Process Created in Suspended mode

2)Call to GetThreadContext

3)Call VirtualAlloc and copy unpacked PE to it

4)Call WriteProcessMemory to write the decrypted PE to suspended process

5)Call SetThreadContext

6) Call to ResumeThread

My objective is to dump the unpacked PE in Step 3 to disk.

Following is code. This is just a crude code. I have not done any sort to validation and error checking here. I have used some code available on internet.Feel free to modify the code.

NOTE: This wont work for all types of process hollowing

CODE:

#please pass absolute path of the file to be unpacked
from winappdbg import Debug, EventHandler,Process, System, CrashDump, HexInput, HexDump,win32
 
 
def process_read( pid, address, length ):
 
    process = Process( pid )
    # Read the process memory.
    data = process.read( address, length )
    return data
 
def action_WriteProcessMemoryW(event):
    # Get the return address of the call
    address = event.get_thread().read_stack_dwords(1)[0]
    fo = open("C:/unpacked.bin", "w")
 
    # Get the process and thread IDs
    pid     = event.get_pid()
    tid     = event.get_tid()
 
    process         = Process(pid)
 
    bufferAddr=event.get_thread().read_stack_dwords(6)[3] #6 is no of dwords grabbed from stack [0] is retuen addr [3] is 3rd argument
    print hex(bufferAddr)
    print "xxxxxxx"
    memoryMap       = process.get_memory_map()
    readable    = 0
    writeable   = 0
    executable  = 0
    private     = 0
    mapped      = 0
    image       = 0
    total       = 0
    for mbi in memoryMap:
        #print hex(mbi.BaseAddress)
        if mbi.BaseAddress == bufferAddr:
            print "dumping data"
            print hex(mbi.BaseAddress)
            print hex(mbi.RegionSize)
            data=process_read(pid,mbi.BaseAddress,mbi.RegionSize)
            fo.write(data)
            fo.close()
 
 
# This function will be called when our breakpoint is hit
def action_CreateProcessW( event ):
 
 
    address = event.get_thread().read_stack_dwords(1)[0]
    # Get the process and thread IDs
    pid     = event.get_pid()
    tid     = event.get_tid()
 
 
class MyEventHandler( EventHandler ):
 
    def load_dll( self, event ):
 
        # Get the new module object
        module = event.get_module()
 
        # If it's kernel32.dll...
        if module.match_name("kernel32.dll"):
 
            # Get the process ID
            pid = event.get_pid()
 
            # Get the address of CreateFile
            address = module.resolve( "CreateProcessW" )
            addressWPW = module.resolve( "WriteProcessMemory" )
 
            # Set a breakpoint at CreateFile
            event.debug.break_at( pid, address, action_CreateProcessW )
            event.debug.stalk_at( pid, addressWPW, action_WriteProcessMemoryW )
 
 
 
 
def simple_debugger( argv ):
 
    # Instance a Debug object, passing it the MyEventHandler instance
    debug = Debug( MyEventHandler() )
    try:
 
        debug.execv( argv )
 
        debug.loop()
 
    # Stop the debugger
    finally:
        debug.stop()
 
 
# When invoked from the command line,
# the first argument is an executable file theat needs tp be unpacked. Please provide absolute path
# and the remaining arguments are passed to the newly created process
if __name__ == "__main__":
    import sys
    simple_debugger( sys.argv[1:] )

 

 

Wednesday, June 25, 2014

Monitoring Thread Injection

A lot of malware inject threads into other process to bypass Security Products.
Usually malwares write the the shellcode into remote process using WriteProcessMemory() and then start threads using CreateRemoteThread() . A lot of source codes are available over internet about this.
Let’s see how we can monitor thread injection using kernel mode driver. A lot of AV products use this method. So I won’t get into much details.
Windows has a API PsSetCreateThreadNotify that can be used by Kernel mode drivers. It provides a callback function that can be invoked whenever a thread is created.
Please refer to MSDN for further details.
It can be used as follows:
PsSetCreateThreadNotifyRoutine(RemoteThreadDetect);   //registers notification routine
Now a part of RemoteThreadDetec reoutine:
VOID RemoteThreadDetect (IN HANDLE RemotePid, IN HANDLE ThreadId, IN BOOLEAN  flag) 
{
……………..
……….
currproc = PsGetCurrentProcessId();  //gets current process ID
……………….
if (currproc != RemotePid)//check if current pid and pid passed in the function are same
  {
    DbgPrint("thread injection detected"
  }
…………
}
CurrentProcessId() gets the ID of the current process in whose context thread creation is called.
The logic is really simple. If the CurrProc and RemotePid are not same means the thread has been injected.
I am not publishing the code as it’s too easy and similar codes can be found in internet

image