Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unhandled DBG_PRINTEXCEPTION_C exception using meterpreter #7482

Closed
megabug opened this issue Oct 24, 2016 · 5 comments
Closed

Unhandled DBG_PRINTEXCEPTION_C exception using meterpreter #7482

megabug opened this issue Oct 24, 2016 · 5 comments

Comments

@megabug
Copy link
Contributor

megabug commented Oct 24, 2016

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

  • whether it's 32-bit or 64-bit (for the ropchains), and
  • whether it's running on Windows 7 and below, or Windows 8 and above (for the different heap spraying required).

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

  • Windows >= 8 32bit: works fine, session established
  • Windows >= 8 64bit: works fine, session established
  • Windows <= 7 32bit: works fine, session established
  • Windows <= 7 64bit: unhandled DBG_PRINTEXCEPTION_C

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
Copy link
Contributor Author

megabug commented Oct 24, 2016

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
Copy link
Contributor Author

megabug commented Oct 26, 2016

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
Copy link
Contributor

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

@bcook-r7
Copy link
Contributor

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

@megabug
Copy link
Contributor Author

megabug commented Oct 28, 2016

Yeah it does, thanks!

@megabug megabug closed this as completed Oct 28, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants