This code is at the point where we SHOULD see a crash (given that the
payloads in use for kernel/user are both just As and Bs (deliberate at
this point).
Unforunately the exploit does not result in a crash. Things just keep
on going! I've looked at the difference in the traffic across the two
different exploits (py and rb) and what's clear is that the mixin is
doing a lot more work at the start.
Also, the mixin generates packets of smaller size in the way that it
encodes data (ie. it doesn't always use 2 bytes for a short value, it'll
use 1 instead if only 1 is required).
Pretty sure that the size issues aren't the problem, I think there's
something else in play. I'm at the point where diving into the RDP stuff
even more isn't inspiring so I'm hoping that opening this up to collab
will help us move forward.
Slowly moving away from a huge hard-coded blob of inflexible bytes
towards a more data-driven approach that allows configuration of various
elements of the packets that are generated.
When dealing with the RDP mixin it makes more sense to not expose
TCP-level things, instead it's better to talk RDP. This changeset makes
it so that consumers of the RDP mixin talk RDP only. They can access the
socket through the `rdp_socket` member if required, but the changes made
here mean they don't have to. Ultimately, this new member should be
`private` instead of `protected`, but I'm leaving it like this for now
in case it is required down the track.
I've also made the assumption that all RDP connects want TCP_NODELAY
set. This might be wrong, but I don't think it is.
From here, users can call `rdp_connect` and `rdp_disconnect` to manage
connectivity to the RDP endpoint. The `rdp_connect` function does not
register the TCP client socket as the global `sock` member on the TCP
module instance, this is to prevent the mixin from clashing with other
users of the TCP client in a given module.
Currently, if any payload fails to generate that has a dynamic size, it causes a Framework instance to throw an exception on start. This can happen for a number of reasons, and more often than not it is enviromental (files missing, Y2k38 bugs, etc.). Instead of failing entirely, catch the exception and log as an error, don't register the payload, but continue booting.
Since these stagers can shrink based on the expected size of the next
stage, do our best to anticipate a small size. This makes the cached
payload size consistent for now, though if the x64 mettle stager grows
past 128 bytes I think we'll see the stager start oscillating in size
again. If you run into that and are reading this, sorry :(
Push read_size to edx as suggested by Adam, optimize shellcode a
bit by selecting using dx instead of edx for sizes under 64K.
Testing:
Internal only, creates session on every try instead of every 5th.
See notes for x64.
This part does not appear to be working properly yet - stages
generated with this commit recv 102b on the first call to read(),
but subsequently things seem to go off the rails after the
intermediate stage is loaded.
Needs testing and fixup at present for x86 (no worse than before
in terms of success rate however).
The linux x64 reverse tcp stager is hardcoded to read 4K off the
socket. When a small intermediate stager is used, this can result
in reading part of the next stage as well, which means that the
intermediate stager will never recv the # of bytes it needs and
hang indefinitely.
Break out the mettle piece to use separate methods for assembly and
binary payload generation as well as actually putting the product
on the existing session socket.
Change the first part of the stage to check for the intermediate
stager generation method, and use the size of the produced stager
in the recvfrom call or fall back to the prior 4K read size.
Testing:
None yet
Ping @bcook-r7, @acammack-r7, @OJ, @ZeroSteiner
Also uses the class refname where appropriate since an instances refname
reflects the alias currently in use and if a module is reloaded while
using an alias the old behavior would generate spurious cache entries
that would not be cleaned up or modified. Specifically, this could
register a self-referential alias that would cause a stack overflow when
trying to `use` such an alias.
Additionally, some other `fullname`s were changed to `realname`s for
clarity.