Matasano
December 2nd, 2007, 17:40
Assume a black-box pen-test ("http://www.matasano.com/log/mtso/services/deploysafe/techniques") with a Win32 target that has perfectdebugger detection (disregarding how hard “perfect” is toachieve). Arbitrarily, assume no access to the kernel; in fact, noadministrator privilege at all. We simply run in processes alongsidethe target with the same credentials.
How much control do we have over the target?
http://www.matasano.com/log/707/is-win32-a-debugging-api-if-not-how-close-is-it/
How much control do we have over the target?
How much control would a debugger have given us?
We can get a Win32 handle to the process with OpenProcess.
We can read process memory by virtual offset and length withReadProcessMemory
We can enumerate the threads in the target with Toolhelp32
We can suspend or resume individual threads with OpenThread,SuspendThread, and ResumeThread
We can write process memory by virtual offset and length withWriteProcessMemory
We can allocate memory within the target with VirtualAlloc
We can change memory protection with VirtualProtectEx
We can enumerate modules and offsets within the target withToolhelp32.
We can map out memory regions with VirtualQueryEx.
We can excute code in the context of the process withCreateRemoteThread (and RtlRemoteCall ("http://www.alex-ionescu.com/?p=28")).
Without anything more interesting than the MSDN man pages, we comereasonably close to this without invoking the debug interface. Inexchange for not showing up in NtQuerySystemInformation or muckingwith the UEF, we give up easy-to-use breakpoints, single-stepping, andregister access. But:
We’d be able to suspend and resume threads, which we can do anyways.
We’d be able to read and write memory, which we can do anyways.
We’d be able to set breakpoints.
We’d be able to single-step the program.
We’d be able to read register contents.
We’d be able to call functions, which we can do anyways.
We’d be able to search memory for strings, which we can do anyways.
How close can we get to a fully-functional debugger without Windowsknowing about it? I’ve been playing with this for a couple weeks,using Python and ctypes, turning IDLE into a debugger prompt. And itseems like the answer is “extremely close”. More later, but if this istotally obvious, pointers, links, and comments are welcome.
We can trivially get single-use, nonrecoverable breakpoints; just inject INT 3 into the text with WriteProcessMemory.
We can potentially get access to registers using NtSetThreadContext ("http://www.alex-ionescu.com/?m=200612").
We can hook functions, in all the usual ways ("http://www.matasano.com/log/620/hand-detouring-windows-function-calls-with-ht/").
http://www.matasano.com/log/707/is-win32-a-debugging-api-if-not-how-close-is-it/