-
Notifications
You must be signed in to change notification settings - Fork 14k
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
Support checks in relay modules #19639
base: master
Are you sure you want to change the base?
Conversation
RangeWalker handles many more formats for specifying multiple hosts, so simply checking for a space is insufficient.
@@ -209,11 +209,22 @@ def print_prefix | |||
# Otherwise we are logging in the global context where rhost can be any | |||
# size (being an alias for rhosts), which is not very useful to insert into | |||
# a single log line. | |||
if rhost && rhost.split(' ').length == 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check for a space does not account for all of the different ways RangeWalker can handle multiple hosts. Instead, we should actually use RangeWalker to count how many hosts were targeted and only report it if there's a single target. Because this calculation is too expensive to run each time a message is printed, we cache the value.
The comment implies that this was always the intention.
target_host = nil | ||
unless m.target_host.blank? | ||
# only propagate the target_host value if it's exactly 1 host | ||
if (rw = Rex::Socket::RangeWalker.new(m.target_host)).length == 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because RHOSTS wasn't being split any more, RHOST was still a range. This caused Rex::Socket.getaddress
to raise a resolution error. Instead we use RangeWalker again to count how many hosts were being target and only propagate the address if it's exactly one. This also fixes an issues in the previous implementation where if a hostname resolved to multiple addresses, the wrong one may have been selected and copied to #target_host
. This avoids that by only copying when we're confident that the target is correct because it's a single value.
Almost everything looks right, but I'm seeing that the psexec from relay is failing, despite full authentication as Domain Admin.
|
We now have two relay modules with more on the horizon. This PR adds the ability for our users to check targets for viability in the context of the modules. In the case of SMB, this checks the target has SMB signing disabled. In the case of ESC8, it checks that the target URI responds with a 401 and offers NTLM as an authentication mechanism.
Adding the check method required changes to how the modules operate. They had originally used the
RELAY_TARGETS
datastore option to avoid the framework splitting RHOSTS into individual RHOST options as it does for other modules types (except those that are scanners or do not register the RHOSTS option). In order for thecheck
command to work, the RHOSTS needed to be registered, so the target to check is available to the module. For the actual exploitation though, the RHOSTS value needed to be kept as it is (e.g. a list of IP addresses, CIDR range, etc.). To support this, I added a newMultipleTargetHosts
mixin that is checked for in therun
command dispatcher when an Auxiliary or Exploit module is run. This check is included where the previousScanner
mixin check was included and where the datastore is checked for containingRHOSTS
. With this in place, the relay modules can now uses the RHOSTS datastore option and iterate over the targets itself, while also having acheck_host
method that can return a check code for individual hosts. This ensures the option works consistently when theRHOSTS
datastore option is set or a range is specified as an argument to thecheck
command.Because of where the RHOSTS string is split into individual target hosts, the
MultipleTargetHosts
mixin is incompatible with theAutoCheck
mixin. The issue here is that therun
method has the RHOSTS string without having been split and theAutoCheck
mixin is incapable of splitting it and checking each host individually for exploitability. This would also introduce an ambiguity for how a case where a group of N hosts are defined and N-1 are vulnerable. Presumably, the module should fail, but it's not well equipped to report the vulnerability status of each individual host as thecheck
command is. This seems like a reasonable limitation at this time and something that can be left alone for the time being.Testing
auxiliary/server/relay/esc8
modulecheck
command with no arguments, see it pulled the hosts to test from theRHOSTS
datastore optioncheck
command with a target host argument (e.g.check 192.168.159.10-11
) and see that it pulled the hosts to test from the argumentexploit/windows/smb/smb_relay
modulecheck
command with no arguments, see it pulled the hosts to test from theRHOSTS
datastore optioncheck
command with a target host argument (e.g.check 192.168.159.10-11
) and see that it pulled the hosts to test from the argumentExample
ESC8 checking:
SMB relay checking: