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

Add UDP handlers and payloads (redux) #7699

Merged
merged 7 commits into from
Feb 13, 2018

Conversation

sempervictus
Copy link
Contributor

This is a repackaging effort for the work i originally pushed in
#6035. This segment of the PR provides UDP session handlers for
bind and reverse sessions, a Windows Metasm stager (really the
TCP stager with a small change), and a pair of socat payloads for
testing simple UDP shells. Netcat or any scripting language with
a sockets library is sufficient to use these sessions as they are
stateless and simple.

Testing of this PR requires rex/core #1 and rex/socket #2

The SSL testing which was being done on 6035 is backed out, left
for a later time when we can do DTLS properly.

@sempervictus
Copy link
Contributor Author

Failure looks a bit opaque, and i was expecting a lot more of them - this sort of needs the librex changes. Could someone with a keen eye for travis eyeball the results and give me some indication if this is the librex change failing a PEBKAC issue on my end?
@bcook-r7 @OJ: yes, i am fully aware of the irony of my having to split this PR in three sections after asking for the librex split. Something about no good idea being "unpunishing" in itself... :) It'll pay off when we start making the evented changes.

@keerthy25
Copy link

hi there,i ve an idea to enhance this...give me some idea

@sempervictus
Copy link
Contributor Author

@keerthy25: ideas and submissions welcome, whats your enhancement proposal?

@jmartin-tech jmartin-tech self-assigned this Mar 24, 2017
@jmartin-tech
Copy link
Contributor

jmartin-tech commented Mar 28, 2017

@sempervictus, while I see the initial goal here was to show a udp handler working, in testing I find there needs to be an additional requirement placed on session creation that a known piece of data be delivered to the console before a session is declared available by the handler.

Just creating a handler with payload set as cmd/unix/bind_socat_udp will immediately report a session open even when the target address is completely unreachable.


[*] Started bind handler
[*] Starting the payload handler...
[*] Command shell session 3 opened (172.17.0.3:59006 -> 192.168.1.1:4444) at 2017-03-28 20:52:40 +0000

Unfortunately this may required adjustment to the example payload, or possibly some initial exercise and intercept before promoting a session exists.

@sempervictus
Copy link
Contributor Author

@jmartin-r7: Nice to "meet" you - i dont recall prior interaction here or IRC.

Nature of the beast actually, stateless transports are by design unreliable. In OSI terms, i believe you mean that our session layer should deal with stateful concerns such as "are we still live?" and "is the order of things recvd correct/is reassembly working properly?" Such changes unfortunately have no place in basic shell sessions - they are thin by design (char encoding being the difference between L4 and 7 when used sans TLS). We've discussed using DTLS to manage state before, but that leads down a black hole with @bcook-r7 and @OJ probably having to get involved, as does the easier approach of adding sequence numbers to TLVs with some reassembly logic (which we need for asymmetrically routed C2 style sessions anyway, so its an unavoidable change, whereas DTLS will require us to agree on a handshake which wont set off every IDS from here to the south pole).

As i've mentioned before - this is the groundwork, and while it actually has real world use (i've used this on engagement to punch out of unpleasant egress restrictions in order to bootstrap a smarter/safer transport), its designed to let us build better things. Plus, if the things which sit atop this are in the PR, it'll never be merged. In general, suggest looking at my PRs more for the changes to Framework internals (lib, Rex, etc), not the modules. I rarely publish modules not designed to illustrate lib functionality...

@jmartin-tech
Copy link
Contributor

@sempervictus, nice to meet you as well.

I understand this is just a start, and as such it needs to provide an example that will be effective to follow as well as build on. However, having the console report that a session exists when there is nothing on the other end is a problem. Even shell sessions should have some minimal proof of existence before being listed as available in the console, in this case the transport itself makes that "proof" something that the payload side of the connection may need to provide.

Not requesting reliability and resilience of the connection state, only a first stage "negotiation" or "acknowledgement" of connection that will keep from reporting a session exists in the console that is really just a black hole.

Consider the case of the cmd/unix/bind_socat_udp, the script generated could be expanded to inspect the socket input for a pre-shared or even standardized session start value and respond to that with data that is not passed to the console as output but used to trigger session exists, otherwise pass on any other input on to the exec. Building this concept into the handler up front will head off some of the inevitable issue of using the UDP transport. I will work up an example for this, and I am happy to collaborate on what is needed to get this over the fence and merged.

@sempervictus
Copy link
Contributor Author

From a top-down (architectural/design) perspective, it makes sense to view the operational context as a shell which sits atop a transport, therefore having the expected operational semantics of a stateful shell session. If viewed from the bottom-up (implementation/engineering), then one can infer the opposite - that the shell session is a consumer of the transport and assumes the underlying transport semantics. Either view is viable, but from the perspective of current Framework implementations (in master), we sometimes utilize shells which dont even maintain execution context on the remote end (calling /bin/sh at every iteration of an infinite loop) and are therefore effectively stateless (env included) despite having a stateful transport and/or wrapping execution context (see php rev shell). Additionally, we implement abstracted psuedo-stateless transports in HTTP, in that we can traverse proxies and contexts which close the HTTP session on every request, and meterpreter handles the persistence layer above. Shell sessions dont have this luxury - if they implement complex transport logic (i'd say anything involving assignment and conditionals), they're not "shell" sessions anymore per se, they're another class entirely such as the MetaSSH session type (not in master, but you can find it). Even having the persistence layer in meterp itself, there are periods of time between communications across HTTP when the remote session has ceased to be without notifying our end, and we have not yet tested liveness or exceeded the time to wait on our test to mark that session as dead. Think "clever blue teamer with suspender injection."

Edge cases aplenty, but the general point is that MSF and Rex are a wonderful maze of smoke and mirrors abstracting interfaces one would think to be stateful which in fact are anything but... try tracing the process by which L3 "pivots" work in TCP (a supposedly stateful context) if you have time to spare and enjoy taking the red pill. ;-)

Far as solution vectors go, if you want to introduce logic in the Msf side which keeps a timer counting against the last transmission over the transport and ensuring that no long-running post modules are executing, and then initiating a liveness check across the only comms channel shell sessions have, i'm sure that would be useful to a number of namespaces and modules outside the scope of this PR. Also, feel free to make pull requests against this branch or any other stuff you find in my public repo of interest, or just throw inline suggestions to the review.

That said, i'm not trying to be difficult in the least, but the operating constraints of stateless transports under thin execution contexts can only be overcome with logic that, if implemented, would change the class of session from "shell" to something between that and meterpreter. I'd like to implement/upstream these intermediate types, such as interactive SOL/IPMI and telnet/MAC (still a gram for all intents, just framed differently), but that doesn't mean excluding functionality such as that provided by the modules in this branch. While dead session garbage collection is a useful function, which should always be a target for improvement (especially with the slowly growing momentum toward asynchronous and asymmetrical session transports) this code has been used on engagement successfully, and despite being written as an example for the implementation, is already a bit salty. So lets improve what we have to in order to gain merge acceptance from the powers that be, or nix the example shells altogether (more fun for me, while its not fully upstream, they're not looking for it as much), and keep the lib components we need for further work.

RageLtMan added 3 commits January 23, 2018 02:00
This is a repackaging effort for the work i originally pushed in
6035. This segment of the PR provides UDP session handlers for
bind and reverse sessions, a Windows Metasm stager (really the
TCP stager with a small change), and a pair of socat payloads for
testing simple UDP shells. Netcat or any scripting language with
a sockets library is sufficient to use these sessions as they are
stateless and simple.

Testing of this PR requires rex/core #1 and rex/socket #2

The SSL testing which was being done on 6035 is backed out, left
for a later time when we can do DTLS properly.
Python-based UDP egress shell, another PoC of the protocol used
as a raw transport.
@sempervictus
Copy link
Contributor Author

Thank you!

While this method here is somewhat noisy on the network it eliminates
a poor user experience when the handler is started but the payload is
not yet running on the target.

When a target is sent a udp packet and it is not rejected push down
an initial "echo syn" command that will respond with output.  This
allows framework to be aware that the payload is what is running on
the server port instead of assuming a non-existent target is a valid
session.
@jmartin-tech
Copy link
Contributor

jmartin-tech commented Feb 13, 2018

I have added a minor gate on bind session promotion to better the user interaction. Due to the nature of UDP connections there is still a bit of incomplete state when exit is called on bind payloads. Example below, landing as is and if need be we can better resolve this in master at a later date since a simple return will get bring us back to a usable state.

msf5 > use multi/handler
msf5 exploit(multi/handler) > set payload python/shell_reverse_udp
payload => python/shell_reverse_udp
msf5 exploit(multi/handler) > set payload cmd/unix/bind_socat_udp
payload => cmd/unix/bind_socat_udp
msf5 exploit(multi/handler) > set RHOST 192.168.15.29
RHOST => 192.168.15.29
msf5 exploit(multi/handler) > run

[*] Started bind handler
[*] Command shell session 1 opened (192.168.70.2:57603 -> 192.168.15.29:4444) at 2018-02-13 14:53:04 -0600



vagrant@vagrant:~$ ls
ls
cmd_udp  linux.iso
vagrant@vagrant:~$ pwd
pwd
/home/vagrant
vagrant@vagrant:~$ exit
exit
logout


[*] 192.168.15.29 - Command shell session 1 closed.  Reason: Died from Errno::ECONNREFUSED
msf5 exploit(multi/handler) >```

@jmartin-tech jmartin-tech merged commit f5768e7 into rapid7:master Feb 13, 2018
@jmartin-tech
Copy link
Contributor

jmartin-tech commented Feb 13, 2018

Release Notes

UDP session handlers are now available for bind and reverse sessions, along with a Windows Metasm stager and a pair of socat payloads for testing simple UDP shells.

@jmartin-tech
Copy link
Contributor

Thank you very much, for the added functionality and your patience on this @sempervictus

jmartin-tech added a commit to jmartin-tech/metasploit-framework that referenced this pull request Feb 13, 2018
@sempervictus
Copy link
Contributor Author

sempervictus commented Feb 14, 2018 via email

@busterb
Copy link
Member

busterb commented Feb 14, 2018

\o/ awesome

@allrosenthal-r7 allrosenthal-r7 added the rn-enhancement release notes enhancement label Feb 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants