In current nomenclature, Rex Sockets are objects created by calls
to Rex::Socket::<Transport>.create and Rex::Socket.create_...
When the LocalHost or Comm parameters are set to remotely routed
addresses (currently via Meterpreter sessions), Rex will create a
Channel which will abstract communications with the remote end of
the session. These channel based abstractions are called pivots,
and present in three separate flavors:
1 - TcpClientChannel, a fully abstracted, selectable Socket.
2 - TcpServerChannel, a virtual Channel which distributes client
channels.
3 - UdpChannel, a virtual Channel which provides common methods for
UDP socket operations, but is not a full (selectable) abstraction.
Unfortunately this differentiation results in inconsistent returns
from the aforementioned socket creation calls, as the call chain
creates parameters and supplies them to the create method on the
comm object referenced in the params. The comm object may be a
channel, and produce a virtual representation of a socket with
functional methods analogous to Sockets, but without a kernel FD.
This commit begins the work of ensuring that all calls for socket
creation return selectable Rex::Socket objects with semantics
familiar to Ruby developers who have not read into the details of
Rex::Socket and Rex::Post.
-----
Summary of changes:
Convert Rex::IO::StreamAbstraction to SocketAbstraction and use
the new mixin in StreamAbstraction and DatagramAbstraction. This
approach allows for common methods to reuse the abstraction data
flow, while initializing separate types of socket obects and an
optional monitor as needed.
In the Rex::Post::Meterpreter namespace, extract common methods
from Stream to a SocketAbstraction mixin, include that mixin in
Stream, and add Datagram with the dio_write handler override
exported from the current implementation of UdpChannel, also using
the mixin. This relies on the Rex::IO work above to implement the
proper type of socket abstraction to the Channel descendants.
In Rex::Post::Meterpreter::Extensions::Stdapi::Net, convert the
UdpChannel to inherit from the Rex::Post::Meterpreter::Datagram
class, implementing only the send method at this tier. Convert
create_udp_channel to return the local socket side of the datagram
abstraction presented analogous to the TcpClientChannel approach
used before.
-----
Notes and intricacies:
In order to implement recvfrom on the UDP abstraction, a shim layer
has been put in place to forward the sockaddr information from the
remote peer to the local UDP socketpair in the abstraction. This
information takes up buffer space in the UDP socket, and in order
to maintain compatibility with consumers, the dio_write_handler
pushes the data buffer, and in a separate send call, he sockaddr
information from the remote socket. On the abstraction side, the
recvfrom_nonblock call of the real UDPSocket has been overriden
via the mixed in module to call the real method twice, once for
the data buffer, and once for the packed sockaddr data. The Rex
level consumer for recvfrom calls the underlying nonblock method
and expects this exact set of returns (as opposed to what standard
library UDPSocket.recvfrom returns, which is a data buffer and an
Array of sockaddr data).
-----
Testing:
Local and lab testing only so far.
Test RC script to be added in GH comments.
-----
Issues:
Currently, sendto on a remote socket does not appear to honor
LocalPort which causes DNS responses (#6611) to come from the
wrong port to remote clients being serviced over a pivot socket.
We add finalizers to an assortment of Meterpreter-managed objects in order to
clean things up in the event that a post module crashes and does not clean
things up. However, this also means that even a properly-written post module
can lead to an object getting double-closed on the Meterpreter session when the
garbage collector kicks in. This can lead to quite non-deterministic behavior
and crashes.
This change modifies the instance close methods to unregister the finalizer on
close, ensuring we cannot do a double-close automatically if one is requested
explicitly first. As an additional measure, we check an instance variable to
see if we called close directly twice as well. This is not sufficient in
itself, since we do not have a reference to 'self' in the finalizer proc to
check the close state.
This also removes a couple of references to 'self' in the finalizer proc
itself, which may cure some memory leaks as well due to circular references.
The method is used as follows:
if notify_response_waiter(response)
# Proceed as if a waiter was notified
end
Previously the return value would be `nil` whenever the loop broke early
due to a waiter being found. This meant that the dispatcher thread often
believed that a packet was not being handled. As a result the
backlog == incomplete sleep kicked in unnecessarily.
This commit changes the migrate function so that an optional timeout parameter can be given. This means that people in high-latency scenarios can extend the timeout when migration in order to increase the chances that things will work.
adsi_group_enum - Lists all groups on the specified domain
adsi_nested_group_user_enum - Lists all users on the specified domain who are members of a given group DN (taking into account recursive/nested groups)
This commit does a few tidies of code, as well as adds the ability to
write all the kiwi output to disk as well as to the console. We can't
yet add this stuff to the credential DB because it's tied to machine,
where the creds that come out of kiwi are often tied to domains.
This also removes duplicate creds from the output list, and gets rid of
the auth id stuff from the output too (not sure why it was useful
before).
It should not look like this:
```
meterpreter > ps -h
Usage: ps [ options ]
OPTIONS:
-S Search string to filter by
-h This help menu
```
It should not not look like this:
```
meterpreter > ps -h
Use the command with no arguments to see all running processes.
The following options can be used to filter those results:
OPTIONS:
-A <opt> Filters processes on architecture (x86 or x86_64)
-S <opt> String to search for (converts to regex)
-U <opt> Filters processes on the user using the supplied RegEx
-h Help menu.
-s Show only SYSTEM processes
```
Allow searching through netstat output tables for specific strings.
Example:
```
meterpreter > netstat -S 192
Connection list
===============
Proto Local address Remote address State User Inode PID/Program name
----- ------------- -------------- ----- ---- ----- ----------------
tcp 10.1.1.20:3389 192.168.100.186:38470 ESTABLISHED 0 0 3076/svchost.exe
tcp 10.1.1.20:63826 192.168.100.186:31158 ESTABLISHED 0 0 4568/powershell.exe
tcp 10.1.1.20:64887 192.168.100.186:31158 ESTABLISHED 0 0 -
```
from @sempervictus
Merge forked changes to cmd_ps allowing for the use of string
matching on listing output via Rex::Ui::Text::Table's SearchTerm
facility
Example:
```
meterpreter > ps -S x64.*Auth.*Sys
Process list
============
PID Name Arch Session User Path
--- ---- ---- ------- ---- ----
400 smss.exe x64 0 NT AUTHORITY\SYSTEM C:\Windows\System32\smss.exe
...
```
from @sempervictus
Merge forked changes to cmd_ls allowing for the use of string
matching on listing output via Rex::Ui::Text::Table's SearchTerm
facility.
Example:
```
meterpreter > ls chef -R -S wget
No entries exist in chef/backup/chef/handlers
No entries exist in chef/backup/chef/ohai_plugins
No entries exist in chef/backup/chef
No entries exist in chef/backup
No entries exist in chef/cache/cookbooks/avast/attributes
No entries exist in chef/cache/cookbooks/avast/recipes
No entries exist in chef/cache/cookbooks/avast
No entries exist in chef/cache/cookbooks/chef-client/attributes
No entries exist in chef/cache/cookbooks/chef-client/libraries
No entries exist in chef/cache/cookbooks/chef-client/recipes
No entries exist in chef/cache/cookbooks/chef-client
No entries exist in chef/cache/cookbooks/chef_handler/attributes
No entries exist in chef/cache/cookbooks/chef_handler/libraries
No entries exist in chef/cache/cookbooks/chef_handler/providers
No entries exist in chef/cache/cookbooks/chef_handler/recipes
No entries exist in chef/cache/cookbooks/chef_handler/resources
No entries exist in chef/cache/cookbooks/chef_handler
No entries exist in chef/cache/cookbooks/cron/providers
No entries exist in chef/cache/cookbooks/cron/recipes
No entries exist in chef/cache/cookbooks/cron/resources
No entries exist in chef/cache/cookbooks/cron
No entries exist in chef/cache/cookbooks/logrotate/attributes
No entries exist in chef/cache/cookbooks/logrotate/definitions
No entries exist in chef/cache/cookbooks/logrotate/libraries
No entries exist in chef/cache/cookbooks/logrotate/recipes
No entries exist in chef/cache/cookbooks/logrotate
No entries exist in chef/cache/cookbooks/ohai/attributes
No entries exist in chef/cache/cookbooks/ohai/files/default/plugins
No entries exist in chef/cache/cookbooks/ohai/files/default
No entries exist in chef/cache/cookbooks/ohai/files
No entries exist in chef/cache/cookbooks/ohai/recipes
No entries exist in chef/cache/cookbooks/ohai
No entries exist in chef/cache/cookbooks/svit-windows/attributes
No entries exist in chef/cache/cookbooks/svit-windows/recipes
No entries exist in chef/cache/cookbooks/svit-windows/templates/default/plugins
No entries exist in chef/cache/cookbooks/svit-windows/templates/default
No entries exist in chef/cache/cookbooks/svit-windows/templates
No entries exist in chef/cache/cookbooks/svit-windows
No entries exist in chef/cache/cookbooks/windows/attributes
No entries exist in chef/cache/cookbooks/windows/files/default/handlers
No entries exist in chef/cache/cookbooks/windows/files/default
No entries exist in chef/cache/cookbooks/windows/files
No entries exist in chef/cache/cookbooks/windows/libraries
No entries exist in chef/cache/cookbooks/windows/providers
No entries exist in chef/cache/cookbooks/windows/recipes
No entries exist in chef/cache/cookbooks/windows/resources
No entries exist in chef/cache/cookbooks/windows
No entries exist in chef/cache/cookbooks
No entries exist in chef/cache
No entries exist in chef/handlers
No entries exist in chef/log
No entries exist in chef/ohai_plugins
No entries exist in chef/run
Listing: chef
=============
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
100666/rw-rw-rw- 161 fil 2014-07-21 11:08:26 -0400 wget.ps1
100666/rw-rw-rw- 1285 fil 2014-07-21 11:08:26 -0400 wget.vbs
meterpreter >
```
This makes meterpeter shut down it's comms and sleep for a while before
it attempts to open communications again. This is effectively the same
as doing a transport change back to the same transport, but with
a timeout.
Merged with HD's stuff as he fixed up a few things that I had done too.
Conflicts:
lib/msf/base/sessions/meterpreter_options.rb
lib/rex/post/meterpreter/client_core.rb
lib/rex/post/meterpreter/packet_dispatcher.rb
Timeouts are correctly passed through to the client instances from the
handlers. The cilent also passes those values through to the RDI code so
that the binaries are correctly patched.
the NTDS Parser class will take a meterpreter
client and a fielpath and provide an enumerator for reading
out the user accounts as ruby objects
MSP-12357
The 'next' and 'prev' commands were added so that the session can jump
transports without having to add new ones at the same time.
There's also a command which gives the UUID now so that this can be
reused across sessions.
Migration now uses the new meterpreter loader. Migration configuration
is loaded and created by meterpreter on the fly, and supports the
multiple transport stuff that's just been wired in.
added a priv extension method to open
a stream channel to read ntdsaccounts from
and an NTDS account class to accept the
data and parse it into a useable structure
MSP-12357
The original URI is registered as '/foobar/' but is deregistered as
'//foobar/', causing it to never get deregistered. Changing this fixes
unregistration of the service handler for staged payloads, but stageless
doesn't work properly if the URI actually gets deregistered.
Rather than listening forever after a session shuts down, close the session if
there are no other URI's registered on the listener. This allows reconfiguring
the listener without restarting framework, but should be safe for situations
where multiple modules share the same listener.
Session expiry, comms timeout, retry total/wait are all now part of all
of the meterpreter payloads as these are going to be used for
maintaining access with resiliency and will aim for consistency across
the payload types.
There is an old-looking bug where the deletekey command opens the key it tries
to delete, then deletes the same key name again. Basically, it uses the wrong
level of indirection.
If the session doesn't have a payload UUID we now generate one as best
we can. This code will probably go away when TCP related transports have
had the UUID stuf baked in.
This uses HD's UUID stuff to generate a new URI for the transport.
Currently we don't have UUID support for TCP connections, but that's
coming.
Still do to: generation of a valid UUID for payloads that don't already
have one.
Add support to meterpreter that allows for the querying and toggling of
SSL certificate verification on the fly.
In order to verify that the socket was SSL-enabled, some rejigging had
to be done of the type? method in the ssl socket class.
We had a workaround to close connections on very old wininet implementations
that would not do it themselves. With the new WinHttp API-using meterpreters
and stagers, we no longer should use this workaround. It can actually be
actively bad and prematurely close the connection.
This needs testing around different payloads, and they should be on real
networks, ideally where TCP really has to work to get data transfered.
* Move the uri checksum code to a spot that can be shared with rex.
* Adjust modules to make use of this new location.
* Fix up the tranpsort switcher to add the URI for those payloads.
This commit adds plumbing which allows for the creation of stageless
meterpreter payloads that include extensions. The included transprots at
this point are bind_tcp, reverse_tcp and reverse_https, all x86.
More coming for x64. Will also validate http soon.
Rather than operating on a passed-in HKEY, these open and close the registry
key directly for each operation.
This pattern better reflects the actual API usage within msf, and removes extra
round-trips to open and close the registry key, reducing traffic and increasing
performance. I did not add direct versions of every registry operation.
There was no benefit for more rarely-used operations, other than requiring more
churn in the meterpreters.
The primary beneficiary of this is post exploitation modules that do registry
or service enumeration. See #3693 for test cases.
Rather than assume that the destination argument is a directory, check
first, and then do the same thing that 'cp' would do.
- If dest exists and is a directory, copy to the directory.
- If dest exists and is a file, copy over the file.
- If dest does not exist and is a directory, fail.
- If dest does not exist and is a file, create the file.
In #4475, I incorrectly interpreted the role of the 'incomplete' array
in monitor_socket, and that change should be reverted.
What appears to happen is, we play a kind of 3-card monty with the list
of received packets that are waiting for a handler to use them.
monitor_socket continually loops between putting the packets on @pqueue,
then into backlog[] to sort them, then into incomplete[] to list all of
the packets that did not have handlers, finally back into @pqueue again.
If packets don't continually get shuffled back into incomplete, they are
not copied back into @pqueue to get rescanned again.
The only reason anything should really get into incomplete[] is if we
receive a packet, but there is nothing to handle it. This scenario
sounds like a bug, but it is exactly what happens with the Tcp Client
channel - one can open a new channel, and receive a response packet back
from the channel before the subsequent read_once code runs to register a
handler to actually process it. This would be akin to your OS
speculatively accepting data on a TCP socket with no listener, then when
you open the socket for the first time, its already there.
While it would be nice if the handlers were setup before the data was
sent back, rather than relying on a handler being registered some time
between connect and PacketTimeout, this needs to get in now to stop the
bleeding. The original meterpreter crash issue from #4475 appears to be
gone as well.
When using the Meterpreter Binaries gem to locate the path to the
meterpreter DLLs, it's not necessary to use File.expand_path on
the result because the gem's code does this already.
This commit simple removes those unnecessary calls.
When a meterpreter binary cannot be found, give the user some hint about what
went wrong.
```
msf > use exploit/multi/handler
msf exploit(handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf exploit(handler) > set lhost 192.168.43.1
lhost => 192.168.43.1
msf exploit(handler) > exploit
[*] Started reverse handler on 192.168.43.1:4444
[*] Starting the payload handler...
[*] Sending stage (770048 bytes) to 192.168.43.252
[*] Meterpreter session 1 opened (192.168.43.1:4444 -> 192.168.43.252:49297) at 2014-12-29 12:32:37 -0600
meterpreter > use mack
Loading extension mack...
[-] Failed to load extension: No module of the name ext_server_mack.x86.dll found
```
This is also useful for not scaring away would-be developers who replaced only
half (the wrong half) of their DLLs from a fresh meterpreter build and
everything exploded. Not that thats ever happened to me :)
The current logic times out every packet almost immediately, making it possible
for almost any non-trivial meterpreter session to receive duplicate packets.
This causes problems especially with any interactions that involve passing
resource handles or pointers back and forth between MSF and meterpreter, since
meterpreter can be told to operate on freed pointers, double-closes, etc.
This probably fixes tons of heisenbugs, including #3798.
To reproduce this, I enabled all debug messages in meterpreter to slow it
down, then ran this RC script with a reverse TCP meterpreter, after linking in
the test modules:
(cd modules/post
ln -s ../../test/modules/post/test)
die.rc:
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set lhost 192.168.43.1
exploit -j
sleep 5
use post/test/services
set SESSION 1
run
See #4400. This should be all of them, except for, of course, the module
that targets Redmine itself.
Note that this also updates the README.md with more current information
as well.