Pod K8s API权限检查脚本

https://www.cnblogs.com/iAmSoScArEd/p/19487570

#!/bin/bash

# Kubernetes API 权限检测脚本

# 颜色定义
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

# 获取 ServiceAccount Token 和 API Server 地址
KUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
KUBE_CA=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
API_SERVER=https://kubernetes.default.svc
NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)

echo -e "${BLUE}╔════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║          Kubernetes API 权限检测脚本                          ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}"
echo -e "当前命名空间: ${YELLOW}$NAMESPACE${NC}\n"

# 定义只读 API 端点
READONLY_APIS=(
    # Core API v1
    "api/v1/namespaces|list,get|命名空间列表/详情|管理多租户隔离"
    "api/v1/pods|list,get|Pod列表/详情|查看容器运行状态"
    "api/v1/services|list,get|Service列表/详情|查看服务暴露配置"
    "api/v1/configmaps|list,get|ConfigMap列表/详情|查看配置数据"
    "api/v1/secrets|list,get|Secret列表/详情|查看敏感数据(密码/证书)"
    "api/v1/serviceaccounts|list,get|ServiceAccount列表/详情|查看服务账号配置"
    "api/v1/persistentvolumeclaims|list,get|PVC列表/详情|查看存储声明"
    "api/v1/persistentvolumes|list,get|PV列表/详情|查看持久化存储"
    "api/v1/nodes|list,get|Node列表/详情|查看集群节点信息"
    "api/v1/endpoints|list,get|Endpoints列表/详情|查看服务端点"
    "api/v1/events|list,get|Event列表/详情|查看集群事件日志"
    "api/v1/limitranges|list,get|LimitRange列表/详情|查看资源限制配置"
    "api/v1/resourcequotas|list,get|ResourceQuota列表/详情|查看资源配额"
    "api/v1/componentstatuses|list,get|组件状态|查看控制平面组件健康状态"
    "api/v1/replicationcontrollers|list,get|RC列表/详情|查看副本控制器"
    
    # Apps API
    "apis/apps/v1/deployments|list,get|Deployment列表/详情|查看无状态应用部署"
    "apis/apps/v1/daemonsets|list,get|DaemonSet列表/详情|查看守护进程集"
    "apis/apps/v1/statefulsets|list,get|StatefulSet列表/详情|查看有状态应用"
    "apis/apps/v1/replicasets|list,get|ReplicaSet列表/详情|查看副本集"
    "apis/apps/v1/controllerrevisions|list,get|ControllerRevision列表|查看控制器版本历史"
    
    # Batch API
    "apis/batch/v1/jobs|list,get|Job列表/详情|查看批处理任务"
    "apis/batch/v1/cronjobs|list,get|CronJob列表/详情|查看定时任务"
    
    # RBAC API
    "apis/rbac.authorization.k8s.io/v1/roles|list,get|Role列表/详情|查看命名空间角色权限"
    "apis/rbac.authorization.k8s.io/v1/rolebindings|list,get|RoleBinding列表/详情|查看角色绑定关系"
    "apis/rbac.authorization.k8s.io/v1/clusterroles|list,get|ClusterRole列表/详情|查看集群角色权限"
    "apis/rbac.authorization.k8s.io/v1/clusterrolebindings|list,get|ClusterRoleBinding列表/详情|查看集群角色绑定"
    
    # Networking API
    "apis/networking.k8s.io/v1/networkpolicies|list,get|NetworkPolicy列表/详情|查看网络策略规则"
    "apis/networking.k8s.io/v1/ingresses|list,get|Ingress列表/详情|查看入口流量规则"
    "apis/networking.k8s.io/v1/ingressclasses|list,get|IngressClass列表/详情|查看Ingress控制器类型"
    
    # Storage API
    "apis/storage.k8s.io/v1/storageclasses|list,get|StorageClass列表/详情|查看存储类配置"
    "apis/storage.k8s.io/v1/volumeattachments|list,get|VolumeAttachment列表|查看卷挂载状态"
    "apis/storage.k8s.io/v1/csidrivers|list,get|CSIDriver列表|查看CSI驱动"
    "apis/storage.k8s.io/v1/csinodes|list,get|CSINode列表|查看CSI节点信息"
    "apis/storage.k8s.io/v1/csistoragecapacities|list,get|CSI存储容量|查看存储容量信息"
    
    # Autoscaling API
    "apis/autoscaling/v1/horizontalpodautoscalers|list,get|HPA列表/详情(v1)|查看Pod水平自动伸缩"
    "apis/autoscaling/v2/horizontalpodautoscalers|list,get|HPA列表/详情(v2)|查看高级自动伸缩配置"
    
    # Policy API
    "apis/policy/v1/poddisruptionbudgets|list,get|PDB列表/详情|查看Pod中断预算"
    
    # Certificates API
    "apis/certificates.k8s.io/v1/certificatesigningrequests|list,get|CSR列表/详情|查看证书签名请求"
    
    # Coordination API
    "apis/coordination.k8s.io/v1/leases|list,get|Lease列表/详情|查看领导者选举租约"
    
    # Discovery API
    "apis/discovery.k8s.io/v1/endpointslices|list,get|EndpointSlice列表/详情|查看端点切片(新版)"
    
    # Node API
    "apis/node.k8s.io/v1/runtimeclasses|list,get|RuntimeClass列表/详情|查看容器运行时类型"
    
    # Scheduling API
    "apis/scheduling.k8s.io/v1/priorityclasses|list,get|PriorityClass列表/详情|查看Pod优先级配置"
    
    # Admissionregistration API
    "apis/admissionregistration.k8s.io/v1/mutatingwebhookconfigurations|list,get|MutatingWebhook配置|查看变更准入控制器"
    "apis/admissionregistration.k8s.io/v1/validatingwebhookconfigurations|list,get|ValidatingWebhook配置|查看验证准入控制器"
    
    # Apiextensions API
    "apis/apiextensions.k8s.io/v1/customresourcedefinitions|list,get|CRD列表/详情|查看自定义资源定义"
    
    # Flowcontrol API
    "apis/flowcontrol.apiserver.k8s.io/v1beta2/flowschemas|list,get|FlowSchema列表|查看API流量控制规则"
    "apis/flowcontrol.apiserver.k8s.io/v1beta2/prioritylevelconfigurations|list,get|优先级配置|查看API请求优先级"
    
    # Metrics API
    "apis/metrics.k8s.io/v1beta1/nodes|list,get|Node指标|查看节点CPU/内存使用率"
    "apis/metrics.k8s.io/v1beta1/pods|list,get|Pod指标|查看Pod资源使用率"
)

check_api_access() {
    local endpoint=$1
    local verb=$2
    local description=$3
    local capability=$4
    local url="${API_SERVER}/${endpoint}"
    
    # 检查集群级别
    response=$(curl -s -o /dev/null -w "%{http_code}" \
        --cacert $KUBE_CA \
        -H "Authorization: Bearer $KUBE_TOKEN" \
        "$url" 2>/dev/null)
    
    if [ "$response" = "200" ]; then
        echo -e "${GREEN}[✓] ${verb} ${description}${NC}"
        echo -e "    ${YELLOW}权限范围:${NC} 集群级别 (cluster-wide)"
        echo -e "    ${YELLOW}可执行操作:${NC} ${capability}"
        echo ""
        return 0
    fi
    
    # 检查命名空间级别
    if [[ "$endpoint" == api/v1/* ]]; then
        resource=$(echo $endpoint | sed 's|api/v1/||')
        ns_url="${API_SERVER}/api/v1/namespaces/${NAMESPACE}/${resource}"
    elif [[ "$endpoint" == apis/* ]]; then
        api_group=$(echo $endpoint | cut -d'/' -f1-3)
        resource=$(echo $endpoint | cut -d'/' -f4)
        ns_url="${API_SERVER}/${api_group}/namespaces/${NAMESPACE}/${resource}"
    fi
    
    if [ ! -z "$ns_url" ]; then
        ns_response=$(curl -s -o /dev/null -w "%{http_code}" \
            --cacert $KUBE_CA \
            -H "Authorization: Bearer $KUBE_TOKEN" \
            "$ns_url" 2>/dev/null)
        
        if [ "$ns_response" = "200" ]; then
            echo -e "${GREEN}[✓] ${verb} ${description}${NC}"
            echo -e "    ${YELLOW}权限范围:${NC} 命名空间级别 (namespace: $NAMESPACE)"
            echo -e "    ${YELLOW}可执行操作:${NC} ${capability}"
            echo ""
            return 0
        fi
    fi
    
    return 1
}

echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE}  资源读取权限检测 (GET/LIST)${NC}"
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}\n"

for api_entry in "${READONLY_APIS[@]}"; do
    IFS='|' read -r endpoint verb description capability <<< "$api_entry"
    check_api_access "$endpoint" "$verb" "$description" "$capability"
done

echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE}  权限审查能力检测${NC}"
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}\n"

# SelfSubjectAccessReview
sar_response=$(curl -s -o /dev/null -w "%{http_code}" \
    --cacert $KUBE_CA \
    -H "Authorization: Bearer $KUBE_TOKEN" \
    -H "Content-Type: application/json" \
    -X POST \
    -d '{"kind":"SelfSubjectAccessReview","apiVersion":"authorization.k8s.io/v1","spec":{"resourceAttributes":{"namespace":"default","verb":"get","resource":"pods"}}}' \
    "${API_SERVER}/apis/authorization.k8s.io/v1/selfsubjectaccessreviews" 2>/dev/null)

if [ "$sar_response" = "201" ]; then
    echo -e "${GREEN}[✓] create SelfSubjectAccessReview${NC}"
    echo -e "    ${YELLOW}权限范围:${NC} 集群级别"
    echo -e "    ${YELLOW}可执行操作:${NC} 检查自身是否有特定资源的特定操作权限"
    echo -e "    ${YELLOW}安全影响:${NC} 可枚举自身所有权限,辅助权限提升攻击\n"
fi

# SelfSubjectRulesReview
srr_response=$(curl -s -o /dev/null -w "%{http_code}" \
    --cacert $KUBE_CA \
    -H "Authorization: Bearer $KUBE_TOKEN" \
    -H "Content-Type: application/json" \
    -X POST \
    -d "{\"kind\":\"SelfSubjectRulesReview\",\"apiVersion\":\"authorization.k8s.io/v1\",\"spec\":{\"namespace\":\"$NAMESPACE\"}}" \
    "${API_SERVER}/apis/authorization.k8s.io/v1/selfsubjectrulesreviews" 2>/dev/null)

if [ "$srr_response" = "201" ]; then
    echo -e "${GREEN}[✓] create SelfSubjectRulesReview${NC}"
    echo -e "    ${YELLOW}权限范围:${NC} 命名空间级别"
    echo -e "    ${YELLOW}可执行操作:${NC} 列出自身在指定命名空间的所有权限规则"
    echo -e "    ${YELLOW}安全影响:${NC} 完整枚举权限列表,快速发现可利用的高危权限\n"
fi

# TokenReview
tr_response=$(curl -s -o /dev/null -w "%{http_code}" \
    --cacert $KUBE_CA \
    -H "Authorization: Bearer $KUBE_TOKEN" \
    -H "Content-Type: application/json" \
    -X POST \
    -d "{\"kind\":\"TokenReview\",\"apiVersion\":\"authentication.k8s.io/v1\",\"spec\":{\"token\":\"$KUBE_TOKEN\"}}" \
    "${API_SERVER}/apis/authentication.k8s.io/v1/tokenreviews" 2>/dev/null)

if [ "$tr_response" = "201" ]; then
    echo -e "${GREEN}[✓] create TokenReview${NC}"
    echo -e "    ${YELLOW}权限范围:${NC} 集群级别"
    echo -e "    ${YELLOW}可执行操作:${NC} 验证任意ServiceAccount Token的有效性和身份信息"
    echo -e "    ${YELLOW}安全影响:${NC} 可验证窃取的Token是否有效\n"
fi

echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE}  Pod 特殊操作权限检测${NC}"
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}\n"

# 获取第一个 Pod 用于测试
pods_response=$(curl -s --cacert $KUBE_CA \
    -H "Authorization: Bearer $KUBE_TOKEN" \
    "${API_SERVER}/api/v1/namespaces/${NAMESPACE}/pods" 2>/dev/null)

if echo "$pods_response" | grep -q "\"kind\":\"PodList\""; then
    pod_name=$(echo "$pods_response" | grep -o '"name":"[^"]*"' | head -1 | cut -d'"' -f4)
    
    if [ ! -z "$pod_name" ]; then
        # 检查 logs
        logs_response=$(curl -s -o /dev/null -w "%{http_code}" \
            --cacert $KUBE_CA \
            -H "Authorization: Bearer $KUBE_TOKEN" \
            "${API_SERVER}/api/v1/namespaces/${NAMESPACE}/pods/${pod_name}/log" 2>/dev/null)
        
        if [ "$logs_response" = "200" ]; then
            echo -e "${GREEN}[✓] get pods/log${NC}"
            echo -e "    ${YELLOW}权限范围:${NC} 命名空间级别 (namespace: $NAMESPACE)"
            echo -e "    ${YELLOW}可执行操作:${NC} 读取Pod容器的标准输出日志"
            echo -e "    ${YELLOW}安全影响:${NC} 可能泄露应用日志中的敏感信息(密码、Token等)\n"
        fi
        
        # 检查 status
        status_response=$(curl -s -o /dev/null -w "%{http_code}" \
            --cacert $KUBE_CA \
            -H "Authorization: Bearer $KUBE_TOKEN" \
            "${API_SERVER}/api/v1/namespaces/${NAMESPACE}/pods/${pod_name}/status" 2>/dev/null)
        
        if [ "$status_response" = "200" ]; then
            echo -e "${GREEN}[✓] get pods/status${NC}"
            echo -e "    ${YELLOW}权限范围:${NC} 命名空间级别 (namespace: $NAMESPACE)"
            echo -e "    ${YELLOW}可执行操作:${NC} 查看Pod运行状态、IP地址、容器状态等"
            echo -e "    ${YELLOW}安全影响:${NC} 获取网络拓扑和运行时信息\n"
        fi
        
        # 检查 exec (需要升级到WebSocket,这里只检查初始请求)
        exec_response=$(curl -s -o /dev/null -w "%{http_code}" \
            --cacert $KUBE_CA \
            -H "Authorization: Bearer $KUBE_TOKEN" \
            "${API_SERVER}/api/v1/namespaces/${NAMESPACE}/pods/${pod_name}/exec?command=ls&stdout=true" 2>/dev/null)
        
        if [ "$exec_response" = "400" ] || [ "$exec_response" = "101" ]; then
            echo -e "${GREEN}[✓] create pods/exec${NC}"
            echo -e "    ${YELLOW}权限范围:${NC} 命名空间级别 (namespace: $NAMESPACE)"
            echo -e "    ${YELLOW}可执行操作:${NC} 在Pod容器内执行任意命令"
            echo -e "    ${YELLOW}安全影响:${NC} ⚠️ 高危! 可直接获取容器Shell,读取secrets,逃逸等\n"
        fi
        
        # 检查 portforward
        pf_response=$(curl -s -o /dev/null -w "%{http_code}" \
            --cacert $KUBE_CA \
            -H "Authorization: Bearer $KUBE_TOKEN" \
            "${API_SERVER}/api/v1/namespaces/${NAMESPACE}/pods/${pod_name}/portforward" 2>/dev/null)
        
        if [ "$pf_response" = "400" ] || [ "$pf_response" = "101" ]; then
            echo -e "${GREEN}[✓] create pods/portforward${NC}"
            echo -e "    ${YELLOW}权限范围:${NC} 命名空间级别 (namespace: $NAMESPACE)"
            echo -e "    ${YELLOW}可执行操作:${NC} 转发Pod端口到本地进行访问"
            echo -e "    ${YELLOW}安全影响:${NC} 绕过NetworkPolicy访问内部服务\n"
        fi
        
        # 检查 attach
        attach_response=$(curl -s -o /dev/null -w "%{http_code}" \
            --cacert $KUBE_CA \
            -H "Authorization: Bearer $KUBE_TOKEN" \
            "${API_SERVER}/api/v1/namespaces/${NAMESPACE}/pods/${pod_name}/attach?stdout=true" 2>/dev/null)
        
        if [ "$attach_response" = "400" ] || [ "$attach_response" = "101" ]; then
            echo -e "${GREEN}[✓] create pods/attach${NC}"
            echo -e "    ${YELLOW}权限范围:${NC} 命名空间级别 (namespace: $NAMESPACE)"
            echo -e "    ${YELLOW}可执行操作:${NC} 附加到Pod容器的stdin/stdout/stderr"
            echo -e "    ${YELLOW}安全影响:${NC} 可与运行中的进程交互\n"
        fi
    fi
fi

echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE}  API Discovery 能力检测${NC}"
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}\n"

# API versions
api_versions=$(curl -s -o /dev/null -w "%{http_code}" \
    --cacert $KUBE_CA \
    -H "Authorization: Bearer $KUBE_TOKEN" \
    "${API_SERVER}/api" 2>/dev/null)

if [ "$api_versions" = "200" ]; then
    echo -e "${GREEN}[✓] get /api${NC}"
    echo -e "    ${YELLOW}权限范围:${NC} 集群级别"
    echo -e "    ${YELLOW}可执行操作:${NC} 发现Core API组支持的版本"
    echo -e "    ${YELLOW}安全影响:${NC} 枚举API版本,寻找已知漏洞\n"
fi

# APIs
apis_response=$(curl -s -o /dev/null -w "%{http_code}" \
    --cacert $KUBE_CA \
    -H "Authorization: Bearer $KUBE_TOKEN" \
    "${API_SERVER}/apis" 2>/dev/null)

if [ "$apis_response" = "200" ]; then
    echo -e "${GREEN}[✓] get /apis${NC}"
    echo -e "    ${YELLOW}权限范围:${NC} 集群级别"
    echo -e "    ${YELLOW}可执行操作:${NC} 列出所有API组和版本"
    echo -e "    ${YELLOW}安全影响:${NC} 发现扩展API和CRD,扩大攻击面\n"
fi

# Version
version_response=$(curl -s -o /dev/null -w "%{http_code}" \
    --cacert $KUBE_CA \
    -H "Authorization: Bearer $KUBE_TOKEN" \
    "${API_SERVER}/version" 2>/dev/null)

if [ "$version_response" = "200" ]; then
    echo -e "${GREEN}[✓] get /version${NC}"
    echo -e "    ${YELLOW}权限范围:${NC} 集群级别"
    echo -e "    ${YELLOW}可执行操作:${NC} 获取Kubernetes版本信息"
    echo -e "    ${YELLOW}安全影响:${NC} 识别集群版本,查找对应CVE漏洞\n"
fi

# OpenAPI
openapi_response=$(curl -s -o /dev/null -w "%{http_code}" \
    --cacert $KUBE_CA \
    -H "Authorization: Bearer $KUBE_TOKEN" \
    "${API_SERVER}/openapi/v2" 2>/dev/null)

if [ "$openapi_response" = "200" ]; then
    echo -e "${GREEN}[✓] get /openapi/v2${NC}"
    echo -e "    ${YELLOW}权限范围:${NC} 集群级别"
    echo -e "    ${YELLOW}可执行操作:${NC} 获取完整的API Schema定义"
    echo -e "    ${YELLOW}安全影响:${NC} 了解所有API接口和参数,辅助漏洞挖掘\n"
fi

# Healthz
healthz_response=$(curl -s -o /dev/null -w "%{http_code}" \
    --cacert $KUBE_CA \
    -H "Authorization: Bearer $KUBE_TOKEN" \
    "${API_SERVER}/healthz" 2>/dev/null)

if [ "$healthz_response" = "200" ]; then
    echo -e "${GREEN}[✓] get /healthz${NC}"
    echo -e "    ${YELLOW}权限范围:${NC} 集群级别"
    echo -e "    ${YELLOW}可执行操作:${NC} 检查API Server健康状态"
    echo -e "    ${YELLOW}安全影响:${NC} 信息收集\n"
fi

# Livez
livez_response=$(curl -s -o /dev/null -w "%{http_code}" \
    --cacert $KUBE_CA \
    -H "Authorization: Bearer $KUBE_TOKEN" \
    "${API_SERVER}/livez" 2>/dev/null)

if [ "$livez_response" = "200" ]; then
    echo -e "${GREEN}[✓] get /livez${NC}"
    echo -e "    ${YELLOW}权限范围:${NC} 集群级别"
    echo -e "    ${YELLOW}可执行操作:${NC} 检查API Server存活状态"
    echo -e "    ${YELLOW}安全影响:${NC} 信息收集\n"
fi

# Readyz
readyz_response=$(curl -s -o /dev/null -w "%{http_code}" \
    --cacert $KUBE_CA \
    -H "Authorization: Bearer $KUBE_TOKEN" \
    "${API_SERVER}/readyz" 2>/dev/null)

if [ "$readyz_response" = "200" ]; then
    echo -e "${GREEN}[✓] get /readyz${NC}"
    echo -e "    ${YELLOW}权限范围:${NC} 集群级别"
    echo -e "    ${YELLOW}可执行操作:${NC} 检查API Server就绪状态"
    echo -e "    ${YELLOW}安全影响:${NC} 信息收集\n"
fi

echo -e "${BLUE}╔════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║                    检测完成                                   ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}"
posted @ 2026-01-15 15:24  我超怕的  阅读(1)  评论(0)    收藏  举报