rapid7 / metasploit-framework

Metasploit Framework
https://www.metasploit.com/
Other
34.25k stars 14k forks source link

Support checks in relay modules #19639

Open zeroSteiner opened 1 week ago

zeroSteiner commented 1 week ago

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 the check 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 new MultipleTargetHosts mixin that is checked for in the run command dispatcher when an Auxiliary or Exploit module is run. This check is included where the previous Scanner mixin check was included and where the datastore is checked for containing RHOSTS. With this in place, the relay modules can now uses the RHOSTS datastore option and iterate over the targets itself, while also having a check_host method that can return a check code for individual hosts. This ensures the option works consistently when the RHOSTS datastore option is set or a range is specified as an argument to the check command.

Because of where the RHOSTS string is split into individual target hosts, the MultipleTargetHosts mixin is incompatible with the AutoCheck mixin. The issue here is that the run method has the RHOSTS string without having been split and the AutoCheck 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 the check command is. This seems like a reasonable limitation at this time and something that can be left alone for the time being.

Testing

Example

ESC8 checking:

metasploit-framework.pr (S:0 J:0) auxiliary(server/relay/esc8) > check 192.168.159.10-11
[*] 192.168.159.10:80 - The target appears to be vulnerable. Server replied that authentication is required and NTLM is supported.

[-] The host (192.168.159.11:80) was unreachable.
[*] 192.168.159.11:80 - Cannot reliably check exploitability.
metasploit-framework.pr (S:0 J:0) auxiliary(server/relay/esc8) >

SMB relay checking:

metasploit-framework.pr (S:0 J:0) exploit(windows/smb/smb_relay) > check 192.168.159.10-11
[+] 192.168.159.10 - The target is vulnerable. Signing is not required by the target server.
[*] 192.168.159.11 - Cannot reliably check exploitability. Failed to connect and negotiate an SMB connection.
metasploit-framework.pr (S:0 J:0) exploit(windows/smb/smb_relay) >
bwatters-r7 commented 3 days ago

Almost everything looks right, but I'm seeing that the psexec from relay is failing, despite full authentication as Domain Admin. This behavior is shared with master, so it is not a regression and not blocking.

[+] Identity: EXAMPLE\Administrator - Successfully authenticated against relay target smb://10.5.132.182:445
[SMB] NTLMv2-SSP Client     : 10.5.132.182
[SMB] NTLMv2-SSP Username   : EXAMPLE\Administrator
[SMB] NTLMv2-SSP Hash       : Administrator::EXAMPLE:079f5ab963313aca:92293435dd6a03d6bad87cffb3cceaad:01010000000000003590a56dfb3cdb0110adea21f20d79a00000000002000e004500580041004d0050004c00450001001e00570049004e002d00440052004300390048004300440049004d0041005400040016006500780061006d0070006c0065002e0063006f006d0003003600570049004e002d00440052004300390048004300440049004d00410054002e006500780061006d0070006c0065002e0063006f006d00050016006500780061006d0070006c0065002e0063006f006d00070008003590a56dfb3cdb0106000400020000000800300030000000000000000100000000200000ed167b4f6270d072cfe535a4835f2ad50c97dc0c4e4f2e7e326e2acbb4766f670a001000000000000000000000000000000000000900220063006900660073002f00310030002e0035002e003100330035002e003200300031000000000000000000

[*] 10.5.132.182:445 - Running psexec
D, [2024-11-22T10:27:31.149237 #3457] DEBUG -- : Dispatching request to do_tree_connect_smb2 (session: #<Session id: 965129682, user_id: "EXAMPLE\\Administrator", state: :valid>)
[*] Received request for EXAMPLE\Administrator
[-] Failed running psexec against target  - RubySMB::Error::UnexpectedStatusCode The server responded with an unexpected status code: STATUS_ACCESS_DENIED

https://github.com/rapid7/metasploit-framework/issues/19673