前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >【容器集群安全】一文搞定K8s集群信息收集(2)——内部信息收集

【容器集群安全】一文搞定K8s集群信息收集(2)——内部信息收集

原创
作者头像
zhouzhou的奇妙编程
发布2025-02-04 19:36:49
发布2025-02-04 19:36:49
1040
举报

本文在Al1ex大佬文章的基础上进一步细化补充了各个部分内容,使其更加适合小白入门学习。

内部信息

环境信息

了解和管理环境变量是系统管理和安全维护的重要组成部分。环境变量定义了应用程序运行时的各种配置参数,包括但不限于路径、用户特定设置、网络配置等。正确配置和保护环境变量对于确保系统的稳定性和安全性至关重要。

在Linux或Unix系统中,可以通过执行env命令来查看当前shell会话中的所有环境变量及其值。这有助于排查与环境配置相关的问题,并确保敏感信息(如密码或API密钥)不会被不当暴露。

执行以下命令以列出所有环境变量:

代码语言:shell
复制
env

输出示例可能如下所示:

代码语言:shell
复制
SHELL=/bin/bash
TERM=xterm-256color
USER=admin
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/home/admin
LANG=en_US.UTF-8
HOME=/home/admin
LOGNAME=admin
_=/usr/bin/env
  • SHELL: 当前使用的shell类型。
  • TERM: 终端模拟器的类型。
  • USER: 当前登录用户名。
  • PATH: 可执行文件搜索路径。
  • PWD: 当前工作目录。
  • LANG: 语言和字符编码设置。
  • HOME: 用户主目录位置。
  • LOGNAME: 用户登录名称。

在与Kubernetes集群进行交互时,环境变量可以提供重要的配置信息,如API服务器地址、认证令牌等。通过检查这些特定于Kubernetes的环境变量,可以帮助我们确认当前环境是否正确配置以访问和管理Kubernetes资源。

执行以下命令可以过滤出所有包含“KUBERNETES”的环境变量:

代码语言:shell
复制
env | grep KUBERNETES

这将列出所有名称中包含“KUBERNETES”的环境变量及其值。例如,你可能会看到如下输出:

代码语言:shell
复制
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96/XMLSchemaObject.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
  • KUBERNETES_SERVICE_HOST: Kubernetes API服务器的主机地址。
  • KUBERNETES_SERVICE_PORT: Kubernetes API服务器的服务端口,默认为443,表示使用HTTPS协议。
  • KUBERNETES_PORT: Kubernetes服务的完整URL,通常格式为tcp://<host>:<port>。
  • KUBERNETES_PORT_443_TCP: 特定于端口443的TCP连接信息。
  • KUBERNETES_PORT_443_TCP_PROTO: 协议类型,通常是tcp。
  • KUBERNETES_PORT_443_TCP_PORT: 端口号,对于API服务器默认是443。
  • KUBERNETES_PORT_443_TCP_ADDR: API服务器的IP地址。

容器检测

在容器化环境中,了解当前目录结构和文件权限是进行故障排查、安全审计以及日常运维的重要步骤。通过列出目录内容及其权限设置,可以帮助我们确认应用是否正确部署、环境变量是否被正确设置、敏感信息是否得到了妥善保护等。

在容器内部执行ls -al命令可以显示当前工作目录下的所有文件和子目录的详细信息,包括权限、链接数、所有者、组、大小、最后修改时间以及名称。这对于检查容器内文件系统的状态特别有用。

执行以下命令以列出当前目录下的所有文件和目录的详细信息:

代码语言:shell
复制
ls -al

输出示例可能如下所示:

代码语言:shell
复制
total 48
drwxr-xr-x 1 root root  4096 Feb  4 18:04 .
drwxr-xr-x 1 root root  4096 Jan 28 10:23 ..
-rw-r--r-- 1 root root    73 Jan 28 10:23 .dockerenv
drwxr-xr-x 2 root root  4096 Jan 28 10:23 bin
drwxr-xr-x 5 root root  3600 Feb  4 18:04 dev
drwxr-xr-x 1 root root  4096 Feb  4 18:04 etc
drwxr-xr-x 2 root root  4096 Jan 28 10:23 home
drwxr-xr-x 1 root root  4096 Feb  4 18:04 lib
drwxr-xr-x 5 root root  4096 Jan 28 10:23 media
drwxr-xr-x 2 root root  4096 Jan 28 10:23 mnt
drwxr-xr-x 2 root root  4096 Jan 28 10:23 opt
drwxr-xr-x 2 root root  4096 Jan 28 10:23 proc
drwx------ 2 root root 16384 Jan 28 10:23 lost+found
drwxr-xr-x 2 root root  4096 Jan 28 10:23 root
drwxr-xr-x 1 root root  4096 Feb  4 18:04 run
drwxr-xr-x 2 root root  4096 Jan 28 10:23 sbin
drwxr-xr-x 2 root root  4096 Jan 28 10:23 srv
drwxr-xr-x 7 root root     0 Feb  4 18:04 sys
drwxrwxrwt 1 root root  4096 Feb  4 18:04 tmp
drwxr-xr-x 1 root root  4096 Jan 28 10:23 usr
drwxr-xr-x 1 root root  4096 Jan 28 10:23 var
  • 权限:如drwxr-xr-x,表示这是一个目录(d),所有者具有读、写、执行权限(rwx),组用户和其他用户具有读和执行权限(r-x)。
  • 链接数:指向该文件或目录的硬链接数量。
  • 所有者:文件或目录的所有者用户名。
  • 组:文件或目录所属的组名。
  • 大小:文件或目录的大小,单位为字节。
  • 最后修改时间:文件或目录最后一次被修改的时间。
  • 名称:文件或目录的名称。

内核版本

在Pod中下载kubectl并使用它来获取节点的内核版本信息,你需要确保Pod有足够的权限执行此操作。通常情况下,这需要在具有适当RBAC(基于角色的访问控制)权限的命名空间中运行Pod。以下是具体步骤:

步骤1:确保适当的RBAC权限

首先,确认你的服务账户有权限执行kubectl get nodes命令。如果需要,可以创建一个ClusterRole和RoleBinding来赋予相应的权限。

代码语言:shell
复制
# 创建一个ClusterRole,允许获取节点信息
kubectl create clusterrole node-reader --verb=get,list,watch --resource=nodes

# 绑定该ClusterRole到默认的服务账户或特定的服务账户
kubectl create clusterrolebinding default-node-reader --clusterrole=node-reader --serviceaccount=default:default

步骤2:进入目标Pod或启动一个新的带有适当权限的Pod

如果你已经有了一个正在运行的Pod,并且它有网络访问能力,可以直接进入该Pod。如果没有合适的Pod,可以通过以下命令启动一个新的:

代码语言:shell
复制
kubectl run -i --tty --rm debug --image=debian --restart=Never -- sh

这个命令会启动一个一次性的Debian容器,你可以在此基础上安装kubectl。

步骤3:安装kubectl

在Pod内部,你可能需要先安装一些依赖项,然后下载并安装kubectl。这里以Debian为基础的镜像为例:

代码语言:shell
复制
# 更新包列表并安装curl
apt-get update && apt-get install -y curl

# 下载kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

# 应用可执行权限
chmod +x ./kubectl

# 将kubectl移动到PATH路径下
mv ./kubectl /usr/local/bin/kubectl

步骤4:执行命令获取节点内核版本

现在,在同一个Pod内,你可以执行之前提到的命令来获取所有节点的内核版本信息:

代码语言:shell
复制
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.nodeInfo.kernelVersion}{"\n"}{end}'

这条命令将输出类似如下的信息:

代码语言:shell
复制
node1    5.4.0-77-generic
node2    5.4.0-77-generic
...

每行显示了一个节点的名字和它的内核版本。

Token类

K8s集群创建的Pod中容器内部默认携带K8s Service Account认证凭据(/run/secrets/kubernetes.io/serviceaccount/token),利用该凭据可以认证K8s API-Server服务器并访问高权限接口,如果执行成功意味着该账号拥有高权限,可以直接利用Service Account管理K8s集群

要查看当前Pod使用的Service Account的token,可以执行以下命令:

代码语言:shell
复制
cat /var/run/secrets/kubernetes.io/serviceaccount/token

此命令会输出一长串字符,这是Bearer Token,可用于对Kubernetes API Server的身份验证请求。

有了这个token后,你可以使用它来向API Server发起请求。下面是一个示例,展示了如何使用curl命令结合获取到的token查询集群节点的信息,并检查是否具有高权限访问能力:

首先,获取API Server地址:

代码语言:shell
复制
APISERVER=https://$(cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt | openssl x509 -noout -text | grep "Issuer" | awk '{print $3}')

实际上,更简单的方式是直接读取service account的API server地址:

代码语言:shell
复制
APISERVER=https://kubernetes.default.svc

然后,使用curl命令访问API Server并列出所有节点及其内核版本信息:

代码语言:shell
复制
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl -X GET $APISERVER/api/v1/nodes -H "Authorization: Bearer $TOKEN" --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -o - | jq '.items[] | {name: .metadata.name, kernelVersion: .status.nodeInfo.kernelVersion}'

如果你能成功执行上述命令并获得预期的结果,这意味着当前Pod所使用的Service Account拥有足够的权限来执行这些操作。

Secret类

在Kubernetes中,Secrets是一种用于存储和管理敏感信息的对象,比如密码、OAuth令牌和SSH密钥等。正确地使用Secrets可以有效保护这些敏感数据不被未授权访问。然而,如果Secrets管理不当或被恶意利用,它们也可能成为攻击者的目标,用于进一步的渗透攻击,如通过获取的Access Key (AK) 和其他通信凭证从外部API或云产品中窃取信息。

代码语言:shell
复制
#命令格式
./cdk run k8s-secret-dump (auto|<service-account-token-path>)   
 
 #使用实例
 ./cdk run k8s-secret-dump auto

这个命令是用来自动检测并导出Kubernetes集群内的所有Secrets数据。auto选项可能意味着该工具将尝试自动发现可用的Service Account token,并利用它来访问API Server以检索Secrets信息。而另一种形式则允许用户直接指定Service Account token文件的路径。

安全策略

在Kubernetes中,Pod Security Policies (PSP) 是一种集群级别的资源,用于控制Pod可以使用的安全相关选项。它们帮助管理员定义一组条件,这些条件必须满足才能创建Pod。当攻击者已经获得了kubeconfig文件或服务账户(Service Account, SA)的权限,并试图创建具有特定配置的容器时,如果受到PSP策略的限制,了解当前应用的PSP规则就变得至关重要。

对于已经获取了kubeconfig或sa账号权限,进而想要创建特殊配置的容器,但是受到了K8s Pod Security Policies的限制时可以使用这个Exploit获取Pod Security Policies的规则信息

代码语言:shell
复制
#命令格式
./cdk run k8s-psp-dump (auto|<service-account-token-path>
#使用实例
./cdk run k8s-psp-dump auto

这里的(auto|<service-account-token-path>)表示你可以选择让工具自动查找可用的Service Account token (auto) 或者手动指定token文件的路径。

  • auto:工具将尝试自动发现并使用现有的Service Account token。
  • <service-account-token-path>:允许用户直接指定Service Account token文件的具体路径。

执行上述命令后,将会查询API Server以获取所有Pod Security Policies的详细信息,这包括但不限于允许的卷类型、特权模式是否启用、运行As非root用户的限制等。

端口服务

内部网络

在Kubernetes集群中,容器网络接口(CNI)插件用于实现Pod之间的通信。不同的CNI插件可能采用不同的默认网络配置。以下是两个广泛使用的CNI插件及其默认网络范围:

  • Flannel Flannel是一个非常流行的轻量级网络覆盖解决方案,旨在简化Kubernetes集群内的网络配置。它通过为每个节点分配一个子网来工作,从而确保所有Pod都能获得唯一的IP地址。默认网络:10.244.0.0/16。这意味着整个集群的Pod IP地址空间从10.244.0.0到10.244.255.255。每个节点会从这个范围内分配一个更小的子网(通常是/24),用于该节点上运行的所有Pod。
  • Calico Calico提供了一种灵活且高性能的方式为容器和虚拟机提供网络连接和网络安全策略。它不仅支持基于BGP的路由,还允许管理员定义复杂的网络策略来增强安全性。默认网络:192.168.0.0/16 。Calico默认使用192.168.0.0/16作为其IP地址池,这覆盖了从192.168.0.0到192.168.255.255的地址范围。同样地,每个节点也会被分配一个子网以供其上的Pod使用。

总结

本文深入探讨了从红队(攻击者视角)角度对Kubernetes集群进行内部信息收集的策略与方法,覆盖了环境信息、容器检测、内核版本、Token类、Secret类、安全策略、端口服务、内部网络配置等多个关键领域。此外,还特别讨论了第三方集成方面,包括服务网格如Istio和Linkerd的安全配置审查,以及外部服务的安全性评估。

通过具体的命令示例和代码片段,本文指导读者如何有效地识别潜在的安全威胁,例如未加密的服务通信、弱认证机制以及不当配置的服务网格组件等。强调了在实际操作中,必须注重保护敏感信息的重要性,并且所有活动都应遵循最佳安全实践及法律法规的要求。

重要的是,无论是对于防御方还是攻击方而言,理解这些信息收集技术和方法都是至关重要的。它不仅有助于发现和修复集群中的安全隐患,同时也是构建更加健壮的安全防护体系的基础。通过定期执行这样的安全评估,可以显著提升Kubernetes集群的整体安全性,确保其能够在面对各种威胁时保持稳健和可靠。同时,这也提醒我们,在享受技术带来的便利的同时,不可忽视随之而来的安全挑战,始终将安全作为首要考虑因素。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 内部信息
    • 环境信息
    • 容器检测
    • 内核版本
    • Token类
    • Secret类
    • 安全策略
    • 端口服务
    • 内部网络
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档