Skip to content

Instantly share code, notes, and snippets.

@Rich5
Created May 10, 2018 20:55
Show Gist options
  • Save Rich5/e39aec6cd01ad8e6e6fd664979da1393 to your computer and use it in GitHub Desktop.
Save Rich5/e39aec6cd01ad8e6e6fd664979da1393 to your computer and use it in GitHub Desktop.
Email exchange between OJ Reeves and Rich Kelley regarding Meterpreter staging
Hey Rich,
Apologies for the delayed response mate. My email debt is insane and I'm
only just getting on top of it.
Cheers for your words about my Meterpreter work. I hope it's useful! The
recent transport changes seem to have caused quite a stir for the better,
so that's very exciting to see.
The process of stage invocation actually changed when I redid the transport
and configuration for Meterpreter payloads. Prior to the changes, this is
what would happen:
1. An exploit would fire, and the stager would run.
2. The stager establishes communication with MSF.
3. MSF loads metsrv.<arch>.dll from disk into memory.
4. MSF patches the DOS header of the dll so that it includes a small
stub of shellcode. This shellcode maintains a valid DOS header while
supporting the bootstrapping of metsrv itself, and means that the stager
can pass control directly to the start of the payload and things will "just
work".
5. MSF sends the patched DLL to the stager.
6. The stager copies the patched DLL into RWX memory.
7. The stager copies an open socket handle to EDI (or RDI).
8. The stager passes control to the start of the DLL.
9. The DOS header, which was patched by MSF, begins to execute.
10. The shellcode determines the location of the ReflectiveLoader()
function using simple offset calculations.
11. The shellcode calls the ReflectiveLoader() function, and the return
value of this function is a pointer to DllMain().
12. The shellcode takes the value in EDI (or RDI) and assumes this is a
socket handle that has been passed from the stager and hence can be reused
by Meterpreter.
13. The shellcode calls DllMain() passing in DLL_METASPLOIT_ATTACH and
the socket handle, *THIS* is where Meterpreter actually kicks in.
14. Meterpreter runs and does all of its goodness.
15. The user exits Meterpreter and it returns to the shellcode in the
patched DOS header.
16. The shellcode calls DllMain() again, this time with
DLL_METASPLOIT_DETACH passing in the requested ExitFunc that was set up
during the staging process.
17. The whole thing shuts down.
Once the changes were made for transport and configuration, the above was
modified so that:
1. The shellcode calculates the location of the ReflectiveLoader()
function AND the location of the configuration block.
2. The shellcode then calls ReflectiveLoader().
3. The shellcode takes the socket handle from EDI (or RDI) and instead
of passing it to DllMain(), writes it to the start of the configuration
block.
4. The shellcode calls DllMain() with DLL_METASPLOIT_ATTACH and passes
in a pointer to the configuration block, which contains the socket handle
and a bunch of other stuff.
5. Meterpreter takes over.
6. When a user exits, Meterpreter handles the shutting down of
everything instead of returning control to the shellcode.
I hope that helps clear things up! Feel free to drop me a line if things
are still hazy. Again, apologies for the slow response, I'll do my best to
get back to faster in future.
All the best mate.
OJ
On 30 July 2015 at 10:44, RK <> wrote:
>
> Hi, I hope you don't mind me emailing you out of the blue. First, I think
> the work you did with meterpreter is awesome. I do have a question about
> how the meterpreter stage 0 actually invokes the stage1 though. Mainly
> after the reflective dll is injected into the process space it looks like
> dllmain is invoked. A what point in the code is the actual metsrv executed?
> I have a custom reflective payload compiled and I can inject it into
> memory, but my payload doesn't execute because it's part of an exported
> function. So at some point I suppose the stager would have to invoke the
> function. I've been looking over the meterpreter code, and attaching to the
> process what actual starts the server? If I'm off on this please let me
> know. I'm trying to understand how this is actual working rather than just
> conceptually.
>
> Thanks for your time!
>
> -Rich
>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment