rapid7 / metasploit-framework

Metasploit Framework
https://www.metasploit.com/
Other
34.09k stars 13.96k forks source link

Unhandled DBG_PRINTEXCEPTION_C exception using meterpreter #7482

Closed megabug closed 8 years ago

megabug commented 8 years ago

I'm writing my own exploit module for a vuln I've found. The exploit needs to function differently depending on the target, namely:

Using the 32/64bit reverse TCP staged meterpreter payloads, I get the following results:

With regards to the last case, the exploit's ropchains succeed, passing execution to stage0 generated by windows/x64/meterpreter/reverse_tcp. stage0 connects back OK, and downloads stage1 (metsrv) from the attacking host. stage1 is reflectively loaded, and the reflective loader passes control to metsrv via the Init function. In the Init function, a call to dprintf is made, which is effectively a call to OutputDebugStringA: https://github.com/rapid7/metasploit-payloads/blob/master/c/meterpreter/source/server/metsrv.c#L19 OutputDebugStringA/W work by raising a software exception, DBG_PRINTEXCEPTION_C (0x40010006). For more info, check here.

Normally, it appears that this exception is being ignored by Windows when it bubbles through the SEH handlers, if any, and being still unhandled. But in the Win7 64bit case, this is no longer the case - the process crashes when the exception is raised, and left unhandled entirely:

0:018> .exr -1
ExceptionAddress: 000007fefd38a49d (KERNELBASE!RaiseException+0x0000000000000039)
   ExceptionCode: 40010006
  ExceptionFlags: 00000008
NumberParameters: 2
   Parameter[0]: 0000000000000045
   Parameter[1]: 0000000017e78bf0
0:018> k
 # Child-SP          RetAddr           Call Site
00 00000000`17e78820 000007fe`fd39bf7d KERNELBASE!RaiseException+0x39
01 00000000`17e788f0 00000000`19592103 KERNELBASE!OutputDebugStringA+0x6d
02 00000000`17e78bc0 00000000`19592130 metsrv+0x2103
03 00000000`17e79000 00000000`19593635 metsrv!Init+0x1c
04 00000000`17e79030 00000000`195936ce metsrv!ReflectiveLoader+0x4c5
...
0:018> da 17e78bf0
00000000`17e78bf0  "[4188] [METSRV] Getting ready to"
00000000`17e78c10  " init with config 0000000019588E"
00000000`17e78c30  "00.."

Note that despite the book I linked above, this isn't a false positive from what I can tell. This debugging output comes from a dump generated by ProcDump as the JIT debugger, so no debugger was attached at the time of the crash. With no JIT debugger, the process still crashes and the Windows event logs show that DBG_PRINTEXCEPTION_C still being the cause.

I'm not sure how to proceed here... my understanding was that Windows was meant to ignore non-fatal exceptions like this if they're unhandled but a Google search shows lots of other things crashing in the same way, so I'm not sure of this either. Why would Win8+ be ok, as well as 32-bit Win7, too?

Am I missing something that I need to do in my exploit before jumping into stage0, or has something changed in meterpreter recently to cause this behaviour? (Sorry for the noise if its the former.)

Using git version, 865eb56 ("Bump to 1.1.25"), and Ruby 2.3.1p112, on Debian stretch.

megabug commented 8 years ago

msfvenom -p windows/x64/meterpreter/reverse_tcp -f exe -a x86_64 --platform win works fine when manually executed in the Win7 64bit instance, so I guess I'm doing something wrong when transferring into meterpreter...

megabug commented 8 years ago

So a simple test program that does a stack pivot before jumping to windows/x64/meterpreter/reverse_tcp fails in the same way. I'm guessing that the broken stack stops the exception from getting to the default handler normally near the bottom of the stack.

It looks like debug messages got enabled by @OJ's commit rapid7/metasploit-payloads@0cbb86c a few months ago - perhaps by accident?

bcook-r7 commented 8 years ago

Hmm, that should be disabled @megabug - thanks for the catch.

bcook-r7 commented 8 years ago

in #7493 I rebuilt a metasploit-payloads gem without debug enabled. Does this resolve your issue @megabug ?

megabug commented 8 years ago

Yeah it does, thanks!