WIZ K8S LAN Party Writeup

前言

​ Kubernetes CTF靶场,记录一下解题过程

Link: https://www.k8slanparty.com/

​ “Welcome to the Kubernetes LAN Party! A CTF designed to challenge your Kubernetes hacking skills through a series of critical network vulnerabilities and misconfigurations. Challenge yourself, boost your skills, and stay ahead in the cloud security game.”

image-20250107103022303

START

1.RECON

Description

You have shell access to compromised a Kubernetes pod at the bottom of this page, and your next objective is to compromise other internal services further.

As a warmup, utilize DNS scanning to uncover hidden internal services and obtain the flag. We have “loaded your machine with dnscan to ease this process for further challenges.

All the flags in the challenge follow the same format: wiz_k8s_lan_party{}

提供了两个链接

以及,”loaded your machine with [dnscan]”

点进去第一个链接开头就表达了

image-20250107105141612

再结合当前Pod自带了dnscan,也就是说让扫网段探测发现其他Pod

通过env确认apiserver的地址

image-20250107110258324

而apiserver大部分都在B段

image-20250107110511034

请求下即可获得flag

image-20250107110618924

2.FINDING NEIGHBOURS

Description

Sometimes, it seems we are the only ones around, but we should always be on guard against invisible sidecars reporting sensitive secrets.

题目描述给出了Sidecar的介绍

image-20250107112612725

​ 也就是说如果是Sidecar模式,Pod中会运行一个容器外加另一个容器(或更多),它们共同运行在同一个 Pod 中,共享网络和存储资源,以完成协同工作。

​ 看一下网络连接,可以发现本地的192.168.1.51 一直向 10.100.171.123:80 通信

image-20250107134709419

tcpdump抓包

image-20250107134910627

请求包中发现flag

image-20250107134950224

3.DATA LEAKAGE

Description

The targeted big corp utilizes outdated, yet cloud-supported technology for data storage in production. But oh my, this technology was introduced in an era when access control was only network-based.

意思是网络共享存储

看一下挂载文件情况

image-20250107142434212

这里留意到有一个fs-0779524599b7d5e7e.efs.us-west-1.amazonaws.com/efs路径

cd过去没有权限打开

image-20250107142548682

GPT分析了这个域名

image-20250107142630818

查看一下挂载点和挂载详情

image-20250107142822999

这里有这么一行

image-20250107142943389

就是说路径 /efs采用了 NFS v4 协议

根据Hint#1,得知了一个NFS开源的客户端库,以及命令示例

image-20250107144020016

image-20250107144141231

nfs-catnfs-ls 是 NFS的一些常见工具,用于从 NFS 服务器上读取文件内容和列出目录内容

image-20250107144610917

提示没有权限

image-20250107144628363

根据Hint#2得知还需要提供giduid

image-20250107144844701

最终成功获取

image-20250107145038274

4.BYPASSING BOUNDARIES

Description

Apparently, new service mesh technologies hold unique appeal for ultra-elite users (root users). Don’t abuse this power; use it responsibly and with caution.

Policy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: istio-get-flag
namespace: k8s-lan-party
spec:
action: DENY
selector:
matchLabels:
app: "{flag-pod-name}"
rules:
- from:
- source:
namespaces: ["k8s-lan-party"]
to:
- operation:
methods: ["POST", "GET"]

简单看下,Policy描述了Istio 的安全策略,AuthorizationPolicy表示授权策略资源,控制了对flag-pod-name的访问权限,在k8s-lan-party 命名空间下,如果是GET或POST请求则拒绝

先走一遍dnscan

image-20250107150624693

因为Policy策略,请求被拒绝

image-20250107150659322

到处搜一下

image-20250107151441740

最终找到了很详细的一篇文章 Istio outboundTrafficPolicy Egress Control Bypass

这里有这么一句

image-20250107151551087

“An attacker who has root user access in a pod can use to switch to a UID which matches the iptables rules highlighted above and bypasses the restriction”

​ 那就看一下当前的权限

image-20250107151648347

​ 打开passwd确认其中也有一个uid为1337的账号

image-20250107151807356

使用这个1337的账号请求

image-20250107152109342

成功获取flag

5.LATERAL MOVEMET

Description

Where pods are being mutated by a foreign regime, one could abuse its bureaucracy and leak sensitive information from the administrative services.

Policy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: kyverno.io/v1
kind: Policy
metadata:
name: apply-flag-to-env
namespace: sensitive-ns
spec:
rules:
- name: inject-env-vars
match:
resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
spec:
containers:
- name: "*"
env:
- name: FLAG
value: "{flag}"

Kyverno 策略的主要功能是在 sensitive-ns 命名空间中,自动为所有的 Pod 容器注入一个名为 FLAG 的环境变量,值为 {flag}

如果想要获得flag,就需要创建一个pod,并且该 Pod 必须在 sensitive-ns 命名空间中

简单看下信息,再跑一下dnscan

image-20250107154212794

得到了如下域名

image-20250107154319779

这里让GPT推测总结一下每个域名的作用

image-20250107174445672

kyverno-svc.kyverno.svc.cluster.local则是服务入口点,结合一下源码 kyverno/pkg/config/config.go at main · kyverno/kyverno

​ 可以确定的是路径为/mutate

image-20250107174842355

在Description中,还给出了一个链接 Dynamic Admission Control | Kubernetes

image-20250107175145924

描述了AdmissionReview 请求,Kyverno 使用 AdmissionReview 请求来获取每个 API 请求的详细信息并做出相应的操作

现在的问题来到:如何构造一个AdmissionReview 请求?Hint#1中给出了提示 anderseknert/kube-review: Create Kubernetes AdmissionReview requests from Kubernetes resource manifests

依靠这个工具,把原始的 Kubernetes 资源描述文件,转化为 AdmissionReview 请求

综合上面,得出结论:当前Pod没有权限创建Pod,如果想要获得flag,那么就需要依靠kyverno,通过kube-review构造AdmissionReview请求操作 kyverno来创建Pod

写一个简单的yaml创建Pod,在这里留意命名空间要与Policy命名空间一致

image-20250107193740484

运行kube-review

image-20250107194904768

得到这些之后,根据官方文档调好请求发送即可

image-20250107195334387

​ 失败了,提示SSL问题

image-20250107195726342

​ -k 跳过证书验证即可

image-20250107195839868

​ 把这一串base64解码即可得到flag

image-20250107195937783

结束,一点感悟:在学习技术的时候,听别人讲、跟着一起做和讲给别人听,这三种学习方法对学习效果的深度逐级递增。

END