-
Notifications
You must be signed in to change notification settings - Fork 669
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
WOW64 Support for hashdump #631
Conversation
Automation compile errors:
|
@jmartin-r7 I'm confused. It looks like it's complaining that the Here's the config for the |
Automation uses |
b2cc20f
to
3779bec
Compare
Testing output - windows 7 failing and windows 10 passingWindows 7 - 32 bit 🔴Looks like this breaks opening up a normal session against a Windows 7 host with default psexec 32 bit payload - Before:
After building Meterpreter and copying the custom dll across:
From the TLV logging it dies after the stdapi dll load:
Windows 7 64 bit 🟢The
Windows 10 32 🔴
Windows 10 64 🟢
Edit: Verified the above as PEBKAC, ignore |
@adfoster-r7 did you build with MinGW or MSVC? |
MSVC - I'm just looking into this a bit more now as potentially it's pebkac. I did rebase this branch locally against the latest master before testing which might have caused the problem for me as well |
3779bec
to
46397bf
Compare
I've verified generating a stageless 32 bit payload works now:
But psexec still fails; so I believe it's an issue with staged payloads, and isn't pebkac 🤞 |
I can't reproduce the problem. It looks like you're looking at a 32-bit Meterpreter (built with MSVC) running on a 64-bit Windows 10 host right? Did you also build and load new versions of metsrv, stdapi and priv? It's possible that if one of those was not built using the new code, it'd cause a failure on load maybe. The only metsrv and stdapi changes made though were the injection API updates. Testing Output
I rebased to pull in the change for fixing stdapi built with MinGW and the build is failing again. |
@msjenkins-r7 test this please. |
This is going to build a stand-alone RDLL that can be injected into LSASS for hashdump. The samsrv.dll functions still need to be resolved because they're not exported but the rest can be used normally thanks to the RDLL loader. Defined 32-bit and 64-bit structures that are compatible with MSVC and MinGW. DLLs are dynamically linked for size and the Visual-C Runtime is not used. The reflectively loaded DLL is freed once the operation has completed.
Need to be able to pass things that are not strings
Switch to using the dump_sam RDLL for x86, WOW64 and x64 hashdump support.
46397bf
to
357f592
Compare
@msjenkins-r7 test this please. |
5b703e0
to
d5a3258
Compare
The previous Windows 7 / 10 configuration passed; and mingw output below. Separate issue raised to fix docker mingw builds from a mac host created - #641 Mingw Windows 7 32 🟢
Mingw Windows 7 64 🟢
Mingw Windows 10 32 🟢
Mingw Windows 10 64 🟢
|
Tested against a larger DC with 1k+ users; I think that's everything tested now - will land |
Overview
This closes rapid7/metasploit-framework#17776 by adding hashdump support to 32-bit Meterpreters running on 64-bit hosts.
Old Approach
The old approach was to use native code compiled into Meterpreter that it would carve out and then copy into an executable segment in the target LSASS process. This was the main source of the limitation because the architecture of LSASS has to match Meterpreter. This meant
dump_sam
was one giant function that couldn't use any external functions so they all had to be passed in through the FUNCTIONARGS struct and be resolved by the injector (meterpreter).New Approach
The new approach breaks
dump_sam
into it's own Visual Studio solution file. This allows DLLs for both 32-bit and 64-bit variants to be built. Next the 32-bit Meterpreter embeds both 32-bit and 64-bit variants within it'spriv
extension so it can inject the correct one at run time. The 64-bit Meterpreter will only ever run on systems with a 64-bit version of LSASS so it only embeds the 64-bit version of the DLL. The DLLs are embedded as resources so they don't need to be sent as an argument which retains backwards compatibility because there are no changes necessary in the Metasploit Framework. I tried to make these DLLs as small as possible. In the main MSVC release builds (the ones we ship to users) the export is by ordinal using the new pattern, they are dynamically linked to reduce the size, and the MSVCRT isn't included.ReflectiveFreeAndExitThread
Reflective DLLs can not take advantage of
FreeLibraryAndExitThread
like traditionally loaded DLLs can. This new method allows an RDLL to free it's memory and exit cleanly. It's self contained in it's own files for future reuse, and perhaps it should be moved into the ReflectiveDLLInjection repo. The problem it solves is that the memory in which the RDLL is running was VirtuallAlloc'ed by the loader and can't be simply VirtualFree'ed without running into a race condition of the executable code effectively freeing itself. This approach can be broken down into the following steps:ExitThread
as it's starting point to ensure it exits cleanly once it has executed all of the APCs that have been queued to it.NtQueueApcThread
is used to add a call toWaitForSingleObjectEx
.NtQueueApcThread
is used instead ofQueueUserAPC
because it allows the target function to be called with three arguments instead of one. The WaitForSingleObjectEx call is used to ensure the cleanup thread waits on the current thread before executing the next APC. The current thread can take its time before exiting.QueueUserAPC
is used to have the cleanup thread close the handle to the current thread, ensuring there is no handle leak.NtQueueApcThread
is used again to queue a call to VirtualFree to free the memory previously allocated by the ReflectiveLoader. This step is the whole point of the process.WaitForSingleObjectEx
call in step 3 to return and the remaining queued function to run in order.You can validate that everything works correctly by seeing that the process does not crash and that the memory is freed and handles are closed. Process Hacker is a good tool for this and you can log the freed values in the debug output. This has been validated on Windows XP and Server 2019.
Additional changes
inject_dll
signature. It had a few unnecessary limitations including:get_lsass_handle
from usingGetModuleBaseName
to useGetProcessImageFileName
so it would work in WOW64 environmentsTesting
make docker
fromc/meterpreter
)If you test the MinGW builds, note that the session will crash on initialization unless
AutoLoadStdapi
is disabled or the changes #630 are present.Demo
Shows everything working as expected in the following scenarios: