Forest #1 AD
Reconnaissance:
NMAP:
┌──(kali💀kali)-[~]
└─$ sudo nmap -sC -sV -O 10.10.10.161
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-12-22 02:13:22Z)
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: htb.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds Windows Server 2016 Standard 14393 microsoft-ds (workgroup: HTB)
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.94SVN%E=4%D=12/21%OT=53%CT=1%CU=39143%PV=Y%DS=2%DC=I%G=Y%TM=658
OS:4EF61%P=x86_64-pc-linux-gnu)SEQ(SP=FB%GCD=1%ISR=10B%TI=I%CI=I%TS=A)SEQ(S
OS:P=FC%GCD=1%ISR=10B%TI=I%CI=I%II=I%SS=S%TS=A)SEQ(SP=FC%GCD=1%ISR=10C%TI=I
OS:%CI=I%II=I%SS=S%TS=A)OPS(O1=M53CNW8ST11%O2=M53CNW8ST11%O3=M53CNW8NNT11%O
OS:4=M53CNW8ST11%O5=M53CNW8ST11%O6=M53CST11)WIN(W1=2000%W2=2000%W3=2000%W4=
OS:2000%W5=2000%W6=2000)ECN(R=Y%DF=Y%T=80%W=2000%O=M53CNW8NNS%CC=Y%Q=)T1(R=
OS:Y%DF=Y%T=80%S=O%A=S+%F=AS%RD=0%Q=)T2(R=Y%DF=Y%T=80%W=0%S=Z%A=S%F=AR%O=%R
OS:D=0%Q=)T3(R=Y%DF=Y%T=80%W=0%S=Z%A=O%F=AR%O=%RD=0%Q=)T4(R=Y%DF=Y%T=80%W=0
OS:%S=A%A=O%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=80%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6
OS:(R=Y%DF=Y%T=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=80%W=0%S=Z%A=S+%
OS:F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=80%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=
OS:G%RUD=G)IE(R=Y%DFI=N%T=80%CD=Z)
Network Distance: 2 hops
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb-os-discovery:
| OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3)
| Computer name: FOREST
| NetBIOS computer name: FOREST\x00
| Domain name: htb.local
| Forest name: htb.local
| FQDN: FOREST.htb.local
|_ System time: 2023-12-21T18:13:58-08:00
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: required
|_clock-skew: mean: 2h46m49s, deviation: 4h37m10s, median: 6m48s
| smb2-time:
| date: 2023-12-22T02:13:55
|_ start_date: 2023-12-22T02:10:33
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and requiredWe have 24 ports open.
Ports 53, 49202, 49211 & 62154: running DNS
Port 88: running Microsoft Windows Kerberos
Ports 139 & 445: running SMB
Ports 389 & 3268: running Microsoft Windows Active Directory LDAP
Port 464: running kpasswd5
Ports 593 & 49676: running ncacn_http
Ports 636 & 3269: running tcpwrapped
Port 5985: running wsman
Port 47001: running winrm
Port 9389: running .NET Message Framing
Ports 135, 49664, 49665, 49666, 49667, 49671, 49677, 49684, 49706, 49900: running Microsoft Windows RPC
Port 123: running NTP
Before we move on to enumeration, let’s make some mental notes about the scan results.
Since the Kerberos and LDAP services are running, chances are we’re dealing with a Windows Active Directory box.
The nmap scan leaks the domain and hostname: htb.local and FOREST.htb.local. Similarly, the SMB OS nmap scan leaks the operating system: Windows Server 2016 Standard 14393.
Port 389 is running LDAP. We’ll need to query it for any useful information. Same goes for SMB.
The WSMan and WinRM services are open. If we find credentials through SMB or LDAP, we can use these services to remotely connect to the box.
Enumeration:
Port 389 LDAP
We’ll start off with enumerating LDAP. Nmap has an NSE script that enumerates LDAP.
Let’s run the script on port 389.
We get a bunch of results, which I have truncated. Notice that it does leak first names, last names and addresses which are written in DTMF map format, which maps letters to their corresponding digits on the telephone keypad. This is obviously reversible. However, before I start writing a script to convert the numbers to letters, I’m going to enumerate other ports to see if I can get names from there.
We’ll run enum4linux which is a tool for enumerating information from Windows and Samba systems. It’s a wrapper around the Samba tools smbclient, rpclient, net and nmblookup. With special configuration, you can even have it query LDAP.
Take the above usernames and save them in the file usernames.txt.
Now I have a bunch of usernames but no passwords. If Kerberos pre-authentication is disabled on any of the above accounts, we can use the GETNPUsers impacket script to send a dummy request for authentication. The Key Distribution Center (KDC) will then return a TGT that is encrypted with the user’s password. From there, we can take the encrypted TGT, run it through a password cracker and brute force the user’s password.
When I first did this box, I assumed the Impacket script requires a username as a parameter and therefore ran the script on all the usernames that I found. However, it turns out that you can use the script to output both the vulnerable usernames and their corresponding encrypted TGTs.
The Kerberos pre-authentication option has been disabled for the user svc-alfresco and the KDC gave us back a TGT encrypted with the user’s password. Save the encrypted TGT in the file hash.txt.
Crack the password using John the Ripper.
We get back the following result showing us that it cracked the password.
Foothold:
EVIL-WINRM
Now that we have the username/password svc-alfresco/s3rvice, we’ll use the Evil-WinRM script to gain an initial foothold on the box. This is only possible because the WinRM and WSMan services are open (refer to nmap scan).
Privilege Escalation:
Enumerate the users on the domain.
Enumerate the user account we’re running as.
The user is part of the Service Accounts group. Let’s run bloodhound to see if there are any exploitable paths. First, download SharpHound.exe and setup a python server in the directory it resides in.
In the target machine, download the executable.
Then run the program.
This outputs two files.
We need to transfer the ZIP file to our attack machine. To do that, base64 encode the file.
Then output the base64 encoded file.
Copy it and base64 decode it on the attack machine.
BLOODHOUND:
To install Bloodhound on Kali, you can apt install bloodhound. But to get an older version, I’ll build it from source.
From /opt/, I’ll run git clone https://github.com/BloodHoundAD/BloodHound.git to check out the code from git.
cd BloodHound to get into the directory
Looking at the release page, it looks like the last 1.x version was 1.52, around April 13. I found a commit that was from that timeframe, and checked it out with git checkout a3d5d02226.
Then I ran the commands from this page on (building from source](https://github.com/BloodHoundAD/BloodHound/wiki/Building-BloodHound-from-source).
The next steps are the same for apt installation or building from source:
Run neo4j console, which opens the neo4j web interface
Log in at http://127.0.0.1:7474/ with username/password “neo4j”/”neo4j”. You’ll have to change your password on login. Close the window (but don’t exit neo4j in the console).
Run bloodhound from a new terminal window. Log in with the creds you just set
Alright, now that we how the zipped file on our attack machine, we need to upload it to BloodHound. Next, we need to start up the neo4j database.
Then run bloodhound.
I’ll load the data by clicking the Upload data button on the right side, and selecting my zip exfil. Under “Queries”, I’ll click “Find Shorter Paths to Domain Admin”, and get the following graph:
Drag and drop the zipped file into BloodHound. Then set the start node to be the svc-alfresco user.
Right click on the user and select “Mark User as Owned”.
In the Queries tab, select the pre-built query “Shortest Path from Owned Principals”.
We can see that svc-alfresco is a member of the group Service Accounts which is a member of the group Privileged IT Accounts, which is a member of Account Operators. Moreover, the Account Operators group has GenericAll permissions on the Exchange Windows Permissions group, which has WriteDacl permissions on the domain.
svc-alfresco is not just a member of Service Accounts, but is also a member of the groups Privileged IT Accounts and Account Operators.
The Account Operators group grants limited account creation privileges to a User. Therefore, the user svc-alfresco can create other users on the domain. https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/active-directory-security-groups#bkmk-accountoperators
The Account Operators group has GenericAll permission on the Exchange Windows Permissions group. This permission essentially gives members full control of the group and therefore allows members to directly modify group membership. Since svc-alfresco is a member of Account Operators, he is able to modify the permissions of the Exchange Windows Permissions group.
The Account Operators group has GenericAll permission on the Exchange Windows Permissions group. This permission essentially gives members full control of the group and therefore allows members to directly modify group membership. Since svc-alfresco is a member of Account Operators, he is able to modify the permissions of the Exchange Windows Permissions group.
Exploit
Putting all the pieces together, the following is our attack path.
Create a user on the domain. This is possible because svc-alfresco is a member of the group Account Operators.
Add the user to the Exchange Windows Permission group. This is possible because svc-alfresco has GenericAll permissions on the Exchange Windows Permissions group.
Give the user DcSync privileges. This is possible because the user is a part of the Exchange Windows Permissions group which has WriteDacl permission on the htb.local domain.
Perform a DcSync attack and dump the password hashes of all the users on the domain.
Perform a Pass the Hash attack to get access to the administrator’s account.
Create a user on the domain.
Confirm that the user was created.
Add the user to to the Exchange Windows Permission group.
Confirm that the user was added to the group.
PowerView
Give the user DCSync privileges. We’ll use PowerView for this. First download Powerview and setup a python server in the directory it resides in.
Then download the script on the target machine.
Use the Add-DomainObjectAcl function in PowerView to give the user DCSync privileges.
SecretsDump
On the attack machine, use the secretsdump Impacket script to dump the password hashes of all the users on the domain.
PSEcex
Use psecex Impacket script to perform a pass the hash attack with the Administrator’s hash.
Last updated