Open sempervictus opened 4 years ago
Remove the false premise of
Platform
and the intended execution context being the same thing, or even in the same place, by properly describing how and where things are executing. Example: lambda service running python with access to an otherwise air-gapped Windows system running a vulnerable service capable of executing .NET stagers for binary meterpreter shellcode.
Slightly off topic, and perhaps out of scope for this piece of work, but perhaps Arch
should also be considered. ie, do you have a proposed solution for this Arch
madness :
'Arch' =>
[
ARCH_CMD,
ARCH_X86,
ARCH_X64,
ARCH_ARMLE,
ARCH_AARCH64,
ARCH_PPC,
ARCH_MIPSLE,
ARCH_MIPSBE
],
Commencing Random Thoughts I just don't know about the demand for multi-ring payloads. We have a couple of high-profile kernel mode exploits now for Windows that could theoretically run entirely in ring-0, but I don't think they should for stability and maintenance sake. I'd prefer to see a simplified solution to this problem in the form of a standardized stager to go from a ring-0 context to running a typical user-mode payload in a reusable and tested way.
I need to wrap up the UDP work. I have everything done, it just needs further testing. One concern I had though and it's mostly around the semantics of calling it a UDP stager is that it would be incompatible with the existing UDP stagers due to it using application-level (both framework and payload side) logic to track session information.
Back in 2013, I opened #2475 which was trying to move in the direction of delivering more payload types over ARCH_CMD
by leveraging it with python -c
, ruby -e
etc. There might be parts in there that could be reused. I would definitely be interested in resuming work in the direction of expanding on what can be delivered with exploits that support running OS commands.
I don't know if stackable payloads and wrapped transports would resonate with the typical penetration-tester audience.
An async transport as you described would be super nice and useful. I could see that getting a lot of mileage.
Overview
The purpose of this RFC is to get feedback on the proposed design/architecture and work out implementation details in order to achieve the following objectives:
Platform
and the intended execution context being the same thing, or even in the same place, by properly describing how and where things are executing. Example: lambda service running python with access to an otherwise air-gapped Windows system running a vulnerable service capable of executing .NET stagers for binary meterpreter shellcode.meterpreter/bind_awsssm/post_bind_ssh/find_fd
for a payload delievered viareverse_dns
or just something likemeterpreter/bind_awsssm/post_ssh_connect/bind_memfd_python
The Problem
The current system handling setup and generation for payloads/stagers & handlers/transports is somewhat inflexible in its design; making rigid assumptions about the clarity of definition for what a
Platform
is, and mixing transport and session semantics into the programmatic equivalent of a hard alloy. Upstream, this produces effects like resolving an IP address for a reverse_http payload on the framework host such that most users can't push rev_http over the myriad of public Tor ingress points... the current in-house "fix" for this is a hack (OptString
), it needs to be intrinsically understood by the Framework that resolution of the LHOST module parameter is proxy-side as perceived by the victim machine going through the proxy (so passed as a string all the way out the http proxy used to enter Tor).The first problem becomes apparent when trying to run python payloads on windows systems with which have it installed, only to discover that calls to system functions which dont exist in the OS keel. This is also apparent when trying to do things across different versions of interpreters/VMs - our exploits know which version of Ruby to target, but our payloads have no differentiation between 1.8 and 2.7.
We've seen the second issue with the whole UDP transport debacle - assumed packet order would be consistent, session state would be handled for us, etc etc. TCP isn't the only socket protocol, and at least UDP is synchronous-ish. Going up a couple of OSI layers, we "speak L7" using plain HTTP on a socket we own at the other end, but can't communicate with something even as simple a get var or a post param being our endpoint (which we need for tunneling proxies dropped into IIS for instance) - we need to talk to the DOM, to URIs which proxy forward to the stage/payload, etc. MQ, S3, G docs, post on that which shall not be named... there are lots of asynchronous channels for us to tap for both delivery and comms, which our transport handling and protocol state do not allow us to explore. These things depend on the HTTP component being smarter. Then there's HTTP/2 (will PR something soon as it doesnt look like Walenki's walls in Dark City), which should be a godsend for us until the proxy people figure out how to MITM it or the policy people figure out how to enforce corporate controls for policy on disabling it (that'll come two weeks after they figure out patching, i'm sure).
FInally, all of this has created a decade of headache for those of us working complex targets and writing pieces of framework itself (module authors can hack the gibson to get it to do that one thing that the module must do, lib authors shouldn't) in that we have no place for intermediate delivery mechanisms. Consider Powershell - Rex::Powershell:: should not* be writing the actual execution wrappers as it does now, it should be performing all of the work on the powershell, structuring code, doing obfu, etc, but the execution harnesses should be at least selected by Framework if not passed down to Rex by it. Then we have command stagers - solid gold code for when you gotta get that elephant in the trunk, but functionally hard to get at in framework for those times you wanna use em to generate something cool, and also missing that critical context awareness.
Proposed Solution Approach
Platform
structure in the OS rings paradigm(-1..3).map {|e| Platform.ring(e)}
(magic opcodes/MSRs anyone?), etcMsf
namespaceAvengers Assemble
Community and R7 developers, please weigh in and help flesh this out. Does this make sense as a whole or in the subject-domain-specific sections with which you're familiar? Do we need to ammend the top-line problem and solution sections before we go into the weeds on implementation ideas? What do we need to do, with as much granularity as possible, to get dependencies and described components from where they are today, to being able to do whats described above? Whats the work effort, whats the interdependency and common goal based comms effort? Who wants to take a bite at which piece of this? Who already has bits and bytes to throw into the pot? Ping @bcook-r7 @acammack-r7 @OJ @zeroSteiner @mubix, all active community members, and anyone from days gone by who might be reading this with a flicker of recognition.