<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>llurry&#39;s blog</title>
  
  <subtitle>blog</subtitle>
  <link href="https://llurry.github.io/atom.xml" rel="self"/>
  
  <link href="https://llurry.github.io/"/>
  <updated>2026-04-01T13:39:11.115Z</updated>
  <id>https://llurry.github.io/</id>
  
  <author>
    <name>llurry</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>2026 CCSSSC Reverse WP</title>
    <link href="https://llurry.github.io/2026/03/16/2026%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8%E8%B5%9Bwp/"/>
    <id>https://llurry.github.io/2026/03/16/2026%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8%E8%B5%9Bwp/</id>
    <published>2026-03-16T02:21:12.000Z</published>
    <updated>2026-04-01T13:39:11.115Z</updated>
    
    <content type="html"><![CDATA[<p>周末参加了这次软件系统安全赛初赛，又是坐牢的一天啊，不过应该是进复赛了，在这篇文章中分享一下解题过程</p><h2 id="re1"><a href="#re1" class="headerlink" title="re1"></a>re1</h2><p>题目附件给了一个mp4和一个elf文件，先ida分析Loader，通过交叉应用找到main函数</p><p><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/jieti/main.png" alt="main.png" data-caption="main.png" loading="lazy"></p><p>C++程序首先检查当前目录下是否存在 video.mp4文件，如果视频存在，程序会读取内置的全局变量 stager_pyc_base64[0]，然后将这段 Base64 字符串解码，并将解码后的二进制数据写入到名为 stager.pyc 的文件中，最后给stager.pyc 赋予执行权限 (chmod 0755)，然后调用 Python 解释器运行这个脚本 (run_python_script(v16))  </p><p>解码base64后就拿到了隐藏的pyc</p><p><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/jieti/cyber.png" alt="cyber.png" data-caption="cyber.png" loading="lazy"></p><p>发现了一个硬编码的二进制常量字符串 10101010,出题逻辑： 将真实的 Payload 转换为二进制串 -&gt; 与 0xAA (10101010) 进行异或加密 -&gt; 将加密后的 0 和 1 渲染为黑白像素方块，生成 video.mp4<br>进行解密：<br>由于加密是对称的（XOR），需要利用 OpenCV 读取视频，提取像素块还原二进制，再与 0xAA 异或<br><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><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> re<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">fix_and_find_flag</span>():<br>    <span class="hljs-comment"># 1. 读取提取出的乱码文件</span><br>    <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&#x27;extracted_payload.bin&#x27;</span>, <span class="hljs-string">&#x27;rb&#x27;</span>) <span class="hljs-keyword">as</span> f:<br>        data = f.read()<br>    <br>    <span class="hljs-comment"># 2. 修复黑白颠倒：对每个字节进行按位取反 (XOR 0xFF)</span><br>    fixed_data = <span class="hljs-built_in">bytearray</span>([b ^ <span class="hljs-number">0xFF</span> <span class="hljs-keyword">for</span> b <span class="hljs-keyword">in</span> data])<br>    <br>    <span class="hljs-comment"># 3. 将修复好的真实的 ELF 文件保存下来</span><br>    <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&#x27;fixed_payload.elf&#x27;</span>, <span class="hljs-string">&#x27;wb&#x27;</span>) <span class="hljs-keyword">as</span> f:<br>        f.write(fixed_data)<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;[+] 成功修复文件，已保存为 fixed_payload.elf (Linux 可执行文件)&quot;</span>)<br><br>    <span class="hljs-comment"># 4. 尝试直接从修复后的二进制中暴力搜索 dart&#123;&#125; 格式的字符串</span><br>    <span class="hljs-keyword">try</span>:<br>        <span class="hljs-comment"># 将二进制强制转换为 ASCII 文本（忽略无法识别的字符）</span><br>        text = fixed_data.decode(<span class="hljs-string">&#x27;ascii&#x27;</span>, errors=<span class="hljs-string">&#x27;ignore&#x27;</span>)<br>        <br>        <span class="hljs-comment"># 搜索 dart&#123;...&#125; </span><br>        <span class="hljs-keyword">match</span> = re.search(<span class="hljs-string">r&#x27;dart\&#123;.*?\&#125;&#x27;</span>, text)<br>        <span class="hljs-keyword">if</span> <span class="hljs-keyword">match</span>:<br>            <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;\n&quot;</span> + <span class="hljs-string">&quot;=&quot;</span>*<span class="hljs-number">50</span>)<br>            <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;🎉 直接在 ELF 文件中找到了 Flag:&quot;</span>)<br>            <span class="hljs-built_in">print</span>(<span class="hljs-keyword">match</span>.group(<span class="hljs-number">0</span>))<br>            <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;=&quot;</span>*<span class="hljs-number">50</span> + <span class="hljs-string">&quot;\n&quot;</span>)<br>        <span class="hljs-keyword">else</span>:<br>            <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;\n[-] 没有直接搜到明文 Flag。&quot;</span>)<br>            <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;[*] 出题人可能把 Flag 动态加密了。请在 Linux 虚拟机中运行 ./fixed_payload.elf，或者把它扔进 IDA Pro 里逆向！&quot;</span>)<br>    <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:<br>        <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;[-] 搜索出错: <span class="hljs-subst">&#123;e&#125;</span>&quot;</span>)<br><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&#x27;__main__&#x27;</span>:<br></code></pre></td></tr></table></figure><br>提取出的 payload 并不是压缩包，而是一个完整的 Linux ELF 可执行文件</p><p>继续ida分析这个fixed_payload.elf，main函数非常短，在栈上分配了 336 字节的数组 v4。使用qmemcpy将 .data 段 off_4020 处的 336 字节拷贝到 v4。程序并未对 v4 进行任何处理，只是打印了提示：每个 MD5 哈希对应一个 ASCII 字符…” 的伪装信息后就退出了。跟进数据段 off_4020，发现这里连续存放了 42 个指针（刚好 336 字节），每个指针指向一个 32 位的 MD5 字符串。</p><p><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/jieti/ida.png" alt="ida.png" data-caption="ida.png" loading="lazy"></p><p>程序没有动态加密，而是将 Flag 拆成了单个字符，并将每个字符的 MD5 值按顺序硬编码在了数据段中。 通过简单的单字符 MD5 查表（或跑脚本爆破），将这 42 个 MD5 逐一映射回明文<br>拼接所有破解出的单字符，得到： dart{2ab1fb8a-b830-45e7-8830-66c7e3b3e05a}</p><h2 id="re2"><a href="#re2" class="headerlink" title="re2"></a>re2</h2><p>查壳后发现是upx加壳的，并且有魔改,当时懒得脱了，插个眼后面复盘一下</p><h2 id="re3"><a href="#re3" class="headerlink" title="re3"></a>re3</h2><p>附件一个pyinstaller打包的elf，一个.pcap，不出意料的话就是elf程序有加密逻辑，而流量中有加密结果，先流量分析发现客户像服务器端发送了三个文件加密结果，最终目标是解密flag.txt的加密结果（hex编码）</p><p><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/jieti/pcap.png" alt="pcap.png" data-caption="pcap.png" loading="lazy"></p><p>解包后再将pyc扔进pylingual,拿到py源码<br><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><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># Decompiled with PyLingual (https://pylingual.io)</span><br><span class="hljs-comment"># Internal filename: &#x27;client.py&#x27;</span><br><span class="hljs-comment"># Bytecode version: 3.10.b1 (3439)</span><br><span class="hljs-comment"># Source timestamp: 1970-01-01 00:00:00 UTC (0)</span><br><br><span class="hljs-keyword">import</span> base64<br><span class="hljs-keyword">import</span> sys<br><span class="hljs-keyword">import</span> os<br><span class="hljs-keyword">import</span> json<br><span class="hljs-keyword">import</span> socket<br><span class="hljs-keyword">import</span> hashlib<br><span class="hljs-keyword">import</span> crypt_core<br><span class="hljs-keyword">import</span> builtins<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">_oe</span>(<span class="hljs-params">_d, _k1, _k2, _rn</span>):<br>    <span class="hljs-comment"># ***&lt;module&gt;._oe: Failure: Compilation Error</span><br>    <span class="hljs-keyword">try</span>:<br>        _b = base64.b85decode(_d.encode())<br>        _r = []<br>        <span class="hljs-keyword">for</span> _i, _x <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(_b):<br>            <span class="hljs-keyword">return</span> ((_k1, _k2, _rn), _i, <span class="hljs-number">3</span>) <span class="hljs-keyword">or</span> ((_k1, _k2, _rn), _i, <span class="hljs-number">3</span>) <span class="hljs-keyword">or</span> ((_k1, _k2, _rn), _i, <span class="hljs-number">3</span>) <span class="hljs-keyword">or</span> ((_k1, _k2, _rn), _i, <span class="hljs-number">3</span>) <span class="hljs-keyword">or</span> ((_k1, _k2, _rn), _i, <span class="hljs-number">3</span>) <span class="hljs-keyword">or</span> ((_k1, _k2, _rn), _i, <span class="hljs-number">3</span>) <span class="hljs-keyword">or</span> ((_k1, _k2, _rn), _i, <span class="hljs-number">3</span>) <span class="hljs-keyword">or</span> ((_k1, _k2, _rn), _i, <span class="hljs-number">3</span>) <span class="hljs-keyword">or</span> ((_k1, _k2, _rn), _i, <span class="hljs-number">3</span>) <span class="hljs-keyword">or</span> ((_k1, _k2, _rn), _i, <span class="hljs-number">3</span>) <span class="hljs-keyword">or</span> ((_k1, _k2, _rn), _i, <span class="hljs-number">3</span>) <span class="hljs-keyword">or</span> ((_k1, _k2, _rn), _i, <span class="hljs-number">3</span>) <span class="hljs-keyword">or</span> ((_k1, _k2, _rn),<br>            _r.append(_x, _k <span class="hljs-keyword">if</span> _k <span class="hljs-keyword">else</span> <span class="hljs-literal">None</span>)<br>        _s = <span class="hljs-built_in">bytes</span>(_r).decode()<br>        _res = []<br>        <span class="hljs-keyword">for</span> _c <span class="hljs-keyword">in</span> _s:<br>            <span class="hljs-keyword">if</span> _c.isalpha():<br>                _base = <span class="hljs-built_in">ord</span>(<span class="hljs-string">&#x27;A&#x27;</span>) <span class="hljs-keyword">if</span> _c.isupper() <span class="hljs-keyword">else</span> <span class="hljs-built_in">ord</span>(<span class="hljs-string">&#x27;a&#x27;</span>)<br>                _res.append((<span class="hljs-built_in">chr</span>, <span class="hljs-built_in">ord</span>(_c), _base, _rn, <span class="hljs-number">26</span>, _base))<br>            <span class="hljs-keyword">else</span>:<br>                <span class="hljs-keyword">if</span> _c.isdigit():<br>                    _res.append(<span class="hljs-built_in">str</span>(<span class="hljs-built_in">int</span>(_c), _rn <span class="hljs-keyword">or</span> <span class="hljs-number">10</span>))<br>                <span class="hljs-keyword">else</span>:<br>                    _res.append(_c)<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;&#x27;</span>.join(_res)<br>    <span class="hljs-keyword">except</span>:<br>        <span class="hljs-keyword">return</span> _d<br>_globs = <span class="hljs-built_in">dict</span>(__name__=<span class="hljs-string">&#x27;__main__&#x27;</span>, __file__=__file__, __package__=<span class="hljs-literal">None</span>, _oe=_oe)<br><span class="hljs-keyword">for</span> _k <span class="hljs-keyword">in</span> <span class="hljs-built_in">dir</span>(builtins):<br>    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> _k.startswith(<span class="hljs-string">&#x27;_&#x27;</span>):<br>        _globs[_k] = <span class="hljs-built_in">getattr</span>(builtins, _k)<br>_globs[<span class="hljs-string">&#x27;base64&#x27;</span>] = base64<br>_globs[<span class="hljs-string">&#x27;sys&#x27;</span>] = sys<br>_globs[<span class="hljs-string">&#x27;os&#x27;</span>] = os<br>_globs[<span class="hljs-string">&#x27;json&#x27;</span>] = json<br>_globs[<span class="hljs-string">&#x27;socket&#x27;</span>] = socket<br>_globs[<span class="hljs-string">&#x27;hashlib&#x27;</span>] = hashlib<br>_globs[<span class="hljs-string">&#x27;crypt_core&#x27;</span>] = crypt_core<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">_obf_check</span>():<br>    <span class="hljs-keyword">if</span> <span class="hljs-built_in">hasattr</span>(sys, <span class="hljs-string">&#x27;gettrace&#x27;</span>):<br>        _tr = sys.gettrace()<br>        <span class="hljs-keyword">if</span> _tr <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-literal">None</span>:<br>            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span><br>    <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">_obf_exec</span>(<span class="hljs-params">_code</span>):<br>    <span class="hljs-comment"># ***&lt;module&gt;._obf_exec: Failure: Different bytecode</span><br>    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> _obf_check():<br>        <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span><br>    <span class="hljs-keyword">else</span>:<br>        <span class="hljs-built_in">exec</span>(<span class="hljs-built_in">compile</span>, _code, <span class="hljs-built_in">chr</span>(<span class="hljs-number">60</span>) | <span class="hljs-built_in">chr</span>(<span class="hljs-number">111</span>) | <span class="hljs-built_in">chr</span>(<span class="hljs-number">98</span>) | <span class="hljs-built_in">chr</span>(<span class="hljs-number">102</span>) | <span class="hljs-built_in">chr</span>(<span class="hljs-number">101</span>) | <span class="hljs-built_in">chr</span>(<span class="hljs-number">120</span>) | <span class="hljs-built_in">chr</span>(<span class="hljs-number">99</span>))<br>_1667 = <span class="hljs-string">&#x27;###&#x27;</span><br>_obf_exec(base64.b85decode(_1667).decode())<br></code></pre></td></tr></table></figure><br>真正的逻辑被 Base85 编码隐藏在 _1667 这个超长字符串里了,代码最后一行意味着它在运行时解码并直接 exec() 内存中的代码。先把真正的python逻辑dump出来<br><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">import</span> base64<br><br>_1667 = <span class="hljs-string">&#x27;UurNQJs@mhZDM3$Iv^-BFd$waF)&#125;tOAS... (把完整的字符串复制过来) ...Uu0!rWM5-pY-1=X3I&#x27;</span><br>real_code = base64.b85decode(_1667).decode()<br><br><span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&quot;real_client.py&quot;</span>, <span class="hljs-string">&quot;w&quot;</span>) <span class="hljs-keyword">as</span> f:<br>    f.write(real_code)<br>    <br><span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;解码完成，请查看 real_client.py&quot;</span>)<br></code></pre></td></tr></table></figure><br>运行脚本得到<br><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><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br></pre></td><td class="code"><pre><code class="hljs python">_j0 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">30</span> ^ <span class="hljs-number">126</span>) + (<span class="hljs-number">520</span> % <span class="hljs-number">26</span>)<br>_j1 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">158</span> ^ <span class="hljs-number">184</span>) + (<span class="hljs-number">820</span> % <span class="hljs-number">54</span>)<br>_j2 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">37</span> ^ <span class="hljs-number">2</span>) + (<span class="hljs-number">687</span> % <span class="hljs-number">25</span>)<br>_j3 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">72</span> ^ <span class="hljs-number">112</span>) + (<span class="hljs-number">474</span> % <span class="hljs-number">30</span>)<br>_j4 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">173</span> ^ <span class="hljs-number">82</span>) + (<span class="hljs-number">257</span> % <span class="hljs-number">73</span>)<br>_j5 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">117</span> ^ <span class="hljs-number">203</span>) + (<span class="hljs-number">331</span> % <span class="hljs-number">54</span>)<br>_j6 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">242</span> ^ <span class="hljs-number">46</span>) + (<span class="hljs-number">846</span> % <span class="hljs-number">33</span>)<br>_j7 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">21</span> ^ <span class="hljs-number">148</span>) + (<span class="hljs-number">425</span> % <span class="hljs-number">77</span>)<br>_j8 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">139</span> ^ <span class="hljs-number">134</span>) + (<span class="hljs-number">427</span> % <span class="hljs-number">21</span>)<br>_j9 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">245</span> ^ <span class="hljs-number">62</span>) + (<span class="hljs-number">413</span> % <span class="hljs-number">85</span>)<br>_j10 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">242</span> ^ <span class="hljs-number">65</span>) + (<span class="hljs-number">892</span> % <span class="hljs-number">30</span>)<br>_j11 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">22</span> ^ <span class="hljs-number">58</span>) + (<span class="hljs-number">740</span> % <span class="hljs-number">59</span>)<br>_j12 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">139</span> ^ <span class="hljs-number">248</span>) + (<span class="hljs-number">771</span> % <span class="hljs-number">74</span>)<br>_j13 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">219</span> ^ <span class="hljs-number">230</span>) + (<span class="hljs-number">262</span> % <span class="hljs-number">63</span>)<br>_j14 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">17</span> ^ <span class="hljs-number">89</span>) + (<span class="hljs-number">622</span> % <span class="hljs-number">38</span>)<br>_j15 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">229</span> ^ <span class="hljs-number">205</span>) + (<span class="hljs-number">369</span> % <span class="hljs-number">25</span>)<br>_j16 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">111</span> ^ <span class="hljs-number">33</span>) + (<span class="hljs-number">433</span> % <span class="hljs-number">50</span>)<br>_j17 = <span class="hljs-keyword">lambda</span>: (<span class="hljs-number">41</span> ^ <span class="hljs-number">142</span>) + (<span class="hljs-number">512</span> % <span class="hljs-number">21</span>)<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">_Obf3776</span>:<br>    <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self</span>):<br>        <span class="hljs-variable language_">self</span>._v = <span class="hljs-number">751</span><br>    <span class="hljs-keyword">def</span> <span class="hljs-title function_">_m</span>(<span class="hljs-params">self</span>):<br>        <span class="hljs-keyword">return</span> <span class="hljs-variable language_">self</span>._v * <span class="hljs-number">5</span><br><br><span class="hljs-comment">#!/usr/bin/env python3</span><br><br><span class="hljs-keyword">import</span> socket<br><span class="hljs-keyword">import</span> json<br><span class="hljs-keyword">import</span> os<br><span class="hljs-keyword">import</span> sys<br><span class="hljs-keyword">import</span> hashlib<br><span class="hljs-keyword">import</span> time<br><br>sys.path.insert(<span class="hljs-number">0</span>, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))<br><span class="hljs-keyword">import</span> crypt_core<br><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">CustomBase64</span>:<br>    CUSTOM_ALPHABET = _oe(<span class="hljs-string">&quot;8&lt;&lt;BLok1UrR&#125;_R&gt;27yTmms1djUI&amp;&#123;(7Ls&#123;Apm;c@eJQYZA-rTHu4po&#125;aw559KBaUw?kHpDBVghrW#KRr&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>)<br>    STANDARD_ALPHABET = (<br>        _oe(<span class="hljs-string">&quot;0fj&#123;dfJO_COA?e)7n4^Mo&gt;&amp;&gt;3T^^WT1BYWEqGTnZX)3I6F|~Czuy#AYdpNp$J-J~b;VEk7AYtVtX5cz&#125;&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>)<br>    )<br>    ENCODE_TABLE = <span class="hljs-built_in">str</span>.maketrans(STANDARD_ALPHABET, CUSTOM_ALPHABET)<br>    DECODE_TABLE = <span class="hljs-built_in">str</span>.maketrans(CUSTOM_ALPHABET, STANDARD_ALPHABET)<br><br><span class="hljs-meta">    @classmethod</span><br>    <span class="hljs-keyword">def</span> <span class="hljs-title function_">decode</span>(<span class="hljs-params">cls, data: <span class="hljs-built_in">str</span></span>) -&gt; <span class="hljs-built_in">bytes</span>:<br>        <span class="hljs-keyword">import</span> base64<br><br>        std_b64 = data.translate(cls.DECODE_TABLE)<br>        <span class="hljs-keyword">return</span> base64.b64decode(std_b64)<br><br><br>SERVER_HOST = <span class="hljs-string">&quot;&quot;</span><br>SERVER_PORT = <span class="hljs-number">9999</span><br>KEY_B64 = _oe(<span class="hljs-string">&quot;C7MAupdc5tRBM!52kv4Wmp~Hle`A4N5`t?5nObY+L~6Pz5wdF*y=E$zQv!xZ&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>)<br>KEY = CustomBase64.decode(KEY_B64)<br>FILES_TO_SEND = [_oe(<span class="hljs-string">&quot;I-p&#125;FvS)q0emD&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>), _oe(<span class="hljs-string">&quot;B(-BJ_&lt;B6O&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>), _oe(<span class="hljs-string">&quot;C$MxRtZ99&#123;emD&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>)]<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">_opaque_true</span>():<br>    _x = <span class="hljs-number">0</span><br>    <span class="hljs-keyword">for</span> _i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">100</span>):<br>        _x += _i * (_i - _i + <span class="hljs-number">1</span>)<br>    <span class="hljs-keyword">return</span> _x &gt;= <span class="hljs-number">0</span><br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">_opaque_false</span>():<br>    _a, _b = <span class="hljs-number">5</span>, <span class="hljs-number">7</span><br>    <span class="hljs-keyword">return</span> (_a * _b) == (_b * _a + <span class="hljs-number">1</span>)<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">_dead_calc</span>():<br>    _dead = <span class="hljs-number">0</span><br>    <span class="hljs-keyword">for</span> _i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">50</span>):<br>        _dead = (_dead + _i) % <span class="hljs-number">17</span><br>        <span class="hljs-keyword">if</span> _dead &gt; <span class="hljs-number">100</span>:<br>            _dead = _dead * <span class="hljs-number">2</span> + <span class="hljs-number">1</span><br>    <span class="hljs-keyword">return</span> _dead<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">encrypt_file</span>(<span class="hljs-params">key: <span class="hljs-built_in">bytes</span>, plaintext: <span class="hljs-built_in">bytes</span></span>) -&gt; <span class="hljs-built_in">bytes</span>:<br>    _state = <span class="hljs-number">0</span><br>    _result = <span class="hljs-literal">None</span><br>    <span class="hljs-keyword">while</span> _state &lt; <span class="hljs-number">3</span>:<br>        <span class="hljs-keyword">if</span> _state == <span class="hljs-number">0</span>:<br>            <span class="hljs-keyword">if</span> _opaque_true():<br>                _result = crypt_core.encode_data(plaintext, key[:<span class="hljs-number">16</span>])<br>                _state = <span class="hljs-number">2</span><br>            <span class="hljs-keyword">else</span>:<br>                _dead_calc()<br>                _state = <span class="hljs-number">1</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">1</span>:<br>            _dead_calc()<br>            _state = <span class="hljs-number">2</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">2</span>:<br>            <span class="hljs-keyword">if</span> _opaque_false():<br>                _result = <span class="hljs-literal">None</span><br>            _state = <span class="hljs-number">3</span><br>    <span class="hljs-keyword">return</span> _result<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">send_single_file</span>(<span class="hljs-params">sock, filename, plaintext</span>):<br>    _s = <span class="hljs-number">0</span><br>    _ct = <span class="hljs-literal">None</span><br>    _pl = <span class="hljs-literal">None</span><br>    <span class="hljs-keyword">while</span> _s &lt; <span class="hljs-number">5</span>:<br>        <span class="hljs-keyword">if</span> _s == <span class="hljs-number">0</span>:<br>            _ct = encrypt_file(KEY, plaintext)<br>            _s = <span class="hljs-number">1</span><br>        <span class="hljs-keyword">elif</span> _s == <span class="hljs-number">1</span>:<br>            _pl = &#123;_oe(<span class="hljs-string">&quot;B&amp;&gt;2Jvtu`)&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>): filename, _oe(<span class="hljs-string">&quot;C#-fVpm;c-emD&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>): _ct.<span class="hljs-built_in">hex</span>()&#125;<br>            _s = <span class="hljs-number">2</span><br>        <span class="hljs-keyword">elif</span> _s == <span class="hljs-number">2</span>:<br>            <span class="hljs-keyword">if</span> _opaque_true():<br>                sock.sendall(json.dumps(_pl).encode(_oe(<span class="hljs-string">&quot;KfPvt;&#123;&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>)) + <span class="hljs-string">b&quot;\n&quot;</span>)<br>                _s = <span class="hljs-number">4</span><br>            <span class="hljs-keyword">else</span>:<br>                _dead_calc()<br>                _s = <span class="hljs-number">3</span><br>        <span class="hljs-keyword">elif</span> _s == <span class="hljs-number">3</span>:<br>            _dead_calc()<br>            _s = <span class="hljs-number">4</span><br>        <span class="hljs-keyword">elif</span> _s == <span class="hljs-number">4</span>:<br>            <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> _opaque_false():<br>                time.sleep(<span class="hljs-number">0.1</span>)<br>            _s = <span class="hljs-number">5</span><br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">_verify_cmd</span>(<span class="hljs-params">cmd</span>):<br>    _state = <span class="hljs-number">10</span><br>    _hash_val = <span class="hljs-literal">None</span><br>    _valid = <span class="hljs-literal">False</span><br><br>    <span class="hljs-keyword">while</span> _state &lt; <span class="hljs-number">50</span>:<br>        <span class="hljs-keyword">if</span> _state == <span class="hljs-number">10</span>:<br>            <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(cmd) &gt; <span class="hljs-number">0</span>:<br>                _state = <span class="hljs-number">20</span><br>            <span class="hljs-keyword">else</span>:<br>                _state = <span class="hljs-number">49</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">20</span>:<br>            _hash_val = hashlib.md5(cmd.encode()).hexdigest()<br>            _state = <span class="hljs-number">30</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">30</span>:<br>            <span class="hljs-keyword">if</span> _opaque_true():<br>                _valid = _hash_val == _oe(<span class="hljs-string">&quot;VWK4=qGuqYBxK?sVWlBw&lt;RW0^B4q9&amp;VB;re&lt;0L2U&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>)<br>                _state = <span class="hljs-number">40</span><br>            <span class="hljs-keyword">else</span>:<br>                _dead_calc()<br>                _state = <span class="hljs-number">49</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">40</span>:<br>            <span class="hljs-keyword">if</span> _valid:<br>                _state = <span class="hljs-number">50</span><br>            <span class="hljs-keyword">else</span>:<br>                _state = <span class="hljs-number">49</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">49</span>:<br>            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span><br><br>    <span class="hljs-keyword">return</span> _valid<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">_get_server_host</span>(<span class="hljs-params">args</span>):<br>    _s = <span class="hljs-number">100</span><br>    _host = <span class="hljs-literal">None</span><br><br>    <span class="hljs-keyword">while</span> _s &lt; <span class="hljs-number">200</span>:<br>        <span class="hljs-keyword">if</span> _s == <span class="hljs-number">100</span>:<br>            <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(args) &gt; <span class="hljs-number">2</span>:<br>                _s = <span class="hljs-number">110</span><br>            <span class="hljs-keyword">else</span>:<br>                _s = <span class="hljs-number">120</span><br>        <span class="hljs-keyword">elif</span> _s == <span class="hljs-number">110</span>:<br>            _host = args[<span class="hljs-number">2</span>]<br>            _s = <span class="hljs-number">200</span><br>        <span class="hljs-keyword">elif</span> _s == <span class="hljs-number">120</span>:<br>            <span class="hljs-keyword">if</span> _opaque_true():<br>                _host = <span class="hljs-string">&quot;&quot;</span><br>            _s = <span class="hljs-number">200</span><br>        <span class="hljs-keyword">elif</span> _s == <span class="hljs-number">200</span>:<br>            <span class="hljs-keyword">if</span> _opaque_false():<br>                _host = _oe(<span class="hljs-string">&quot;Ywsm&#125;;Xh&gt;fDF&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>)<br>            _s = <span class="hljs-number">201</span><br><br>    <span class="hljs-keyword">return</span> _host<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">main</span>():<br>    _state = <span class="hljs-number">0</span><br>    _sock = <span class="hljs-literal">None</span><br>    _idx = <span class="hljs-number">0</span><br>    _printed_header = <span class="hljs-literal">False</span><br><br>    <span class="hljs-keyword">while</span> _state &lt; <span class="hljs-number">100</span>:<br>        <span class="hljs-keyword">if</span> _state == <span class="hljs-number">0</span>:<br>            <span class="hljs-keyword">if</span> _opaque_false():<br>                <span class="hljs-built_in">print</span>(_oe(<span class="hljs-string">&quot;2B2dm_GLArX8&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>))<br>            _state = <span class="hljs-number">1</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">1</span>:<br>            <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(sys.argv) &lt; <span class="hljs-number">2</span>:<br>                _state = <span class="hljs-number">5</span><br>            <span class="hljs-keyword">else</span>:<br>                _state = <span class="hljs-number">2</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">2</span>:<br>            <span class="hljs-keyword">if</span> _verify_cmd(sys.argv[<span class="hljs-number">1</span>]):<br>                _state = <span class="hljs-number">3</span><br>            <span class="hljs-keyword">else</span>:<br>                _state = <span class="hljs-number">4</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">3</span>:<br>            <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> _printed_header:<br>                <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;=&quot;</span> * <span class="hljs-number">50</span>)<br>                <span class="hljs-built_in">print</span>(_oe(<span class="hljs-string">&quot;8K7l9zh`rSYcQZO7&#123;6mSyk;f8F$cA4C9`^SyD5F)&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>))<br>                <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;=&quot;</span> * <span class="hljs-number">50</span>)<br>                _printed_header = <span class="hljs-literal">True</span><br>            _state = <span class="hljs-number">10</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">4</span>:<br>            <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;������Ч������&quot;</span>)<br>            _state = <span class="hljs-number">99</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">5</span>:<br>            <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;�÷���python client.py &lt;command&gt; [SERVER_HOST]&quot;</span>)<br>            _state = <span class="hljs-number">99</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">10</span>:<br>            <span class="hljs-keyword">try</span>:<br>                _sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<br>                _state = <span class="hljs-number">11</span><br>            <span class="hljs-keyword">except</span> Exception:<br>                _state = <span class="hljs-number">99</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">11</span>:<br>            _host = _get_server_host(sys.argv)<br>            _state = <span class="hljs-number">12</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">12</span>:<br>            <span class="hljs-keyword">try</span>:<br>                _sock.connect((_host, SERVER_PORT))<br>                _state = <span class="hljs-number">20</span><br>            <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:<br>                <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;[!] ����ʧ�ܣ�<span class="hljs-subst">&#123;e&#125;</span>&quot;</span>)<br>                _state = <span class="hljs-number">99</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">20</span>:<br>            <span class="hljs-keyword">if</span> _idx &lt; <span class="hljs-built_in">len</span>(FILES_TO_SEND):<br>                _state = <span class="hljs-number">21</span><br>            <span class="hljs-keyword">else</span>:<br>                _state = <span class="hljs-number">30</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">21</span>:<br>            _fname = FILES_TO_SEND[_idx]<br>            _state = <span class="hljs-number">22</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">22</span>:<br>            <span class="hljs-keyword">if</span> os.path.exists(_fname):<br>                _state = <span class="hljs-number">23</span><br>            <span class="hljs-keyword">else</span>:<br>                _state = <span class="hljs-number">28</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">23</span>:<br>            <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(_fname, <span class="hljs-string">&quot;rb&quot;</span>) <span class="hljs-keyword">as</span> _f:<br>                _data = _f.read()<br>            _state = <span class="hljs-number">24</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">24</span>:<br>            <span class="hljs-keyword">if</span> _opaque_true():<br>                <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;[*] �����ļ�&quot;</span>)<br>            _state = <span class="hljs-number">25</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">25</span>:<br>            <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> _opaque_false():<br>                send_single_file(_sock, _fname, _data)<br>            _state = <span class="hljs-number">26</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">26</span>:<br>            _idx += <span class="hljs-number">1</span><br>            _state = <span class="hljs-number">20</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">28</span>:<br>            <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;[-] �ļ�������&quot;</span>)<br>            _state = <span class="hljs-number">29</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">29</span>:<br>            _idx += <span class="hljs-number">1</span><br>            _state = <span class="hljs-number">20</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">30</span>:<br>            <span class="hljs-keyword">if</span> _opaque_true():<br>                time.sleep(<span class="hljs-number">0.2</span>)<br>            _state = <span class="hljs-number">31</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">31</span>:<br>            <span class="hljs-keyword">if</span> _sock:<br>                _sock.close()<br>            _state = <span class="hljs-number">99</span><br>        <span class="hljs-keyword">elif</span> _state == <span class="hljs-number">99</span>:<br>            <span class="hljs-keyword">break</span><br><br><br><span class="hljs-keyword">if</span> __name__ == _oe(<span class="hljs-string">&quot;42g9itaJ&gt;C&quot;</span>, <span class="hljs-number">83</span>, <span class="hljs-number">214</span>, <span class="hljs-number">17</span>):<br>    _dead_calc()<br>    <span class="hljs-keyword">if</span> _opaque_true():<br>        main()<br>    <span class="hljs-keyword">else</span>:<br>        _dead_calc()<br></code></pre></td></tr></table></figure><br>其中有魔改的base64解码，然后调用了crypt_core.encode_data，密文的长度全部是 16 的整数倍，所以只有前16字节参与加密<br>去混淆后获取到密钥：passvkcDKWLAA45ocFAXBPM63X4G8XzzTE1B<br><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">import</span> base64<br>CUSTOM = <span class="hljs-string">&#x27;QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890!@&#x27;</span><br>STD    = <span class="hljs-string">&#x27;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&#x27;</span><br>table = <span class="hljs-built_in">str</span>.maketrans(CUSTOM, STD)<br>key_b64 = <span class="hljs-string">&#x27;eUYme4MkN1KSC1bWJZJ2w3FUJCiEXT13D2u1KmiNtfhXKZYE&#x27;</span><br>std_b64 = key_b64.translate(table)<br>key = base64.b64decode(std_b64)<br><span class="hljs-built_in">print</span>(key)<br><span class="hljs-built_in">print</span>(key[:<span class="hljs-number">16</span>])<br></code></pre></td></tr></table></figure><br>ida分析crypt_core.so,交叉引用找到关键函数sub_60B0,发现就是魔改SM4</p><p><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/jieti/ida2.png" alt="ida2.png" data-caption="ida2.png" loading="lazy"></p><p>最终解密脚本<br><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><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> __future__ <span class="hljs-keyword">import</span> annotations<br><br><span class="hljs-keyword">import</span> argparse<br><span class="hljs-keyword">import</span> json<br><span class="hljs-keyword">import</span> subprocess<br><span class="hljs-keyword">import</span> sys<br><span class="hljs-keyword">from</span> pathlib <span class="hljs-keyword">import</span> Path<br><br><br><span class="hljs-comment"># ===== 常量 =====</span><br><br>BLOCK_SIZE = <span class="hljs-number">16</span><br>KEY = <span class="hljs-string">b&quot;passvkcDKWLAA45o&quot;</span><br><br>SBOX = <span class="hljs-built_in">bytes</span>.fromhex(<br>    <span class="hljs-string">&quot;ecca0ef308f02aa23b182b5c37bd12a8&quot;</span><br>    <span class="hljs-string">&quot;05d3a1574f96fcf5a7141966589bbfb4&quot;</span><br>    <span class="hljs-string">&quot;39d51e1a30bc6c80b7ed4106d91767cd&quot;</span><br>    <span class="hljs-string">&quot;1d2cae240313c65383110af7c04dc49e&quot;</span><br>    <span class="hljs-string">&quot;8d001fc33f359fcb729d166facce3c5e&quot;</span><br>    <span class="hljs-string">&quot;a6e17b343632b895918952c1e7a33348&quot;</span><br>    <span class="hljs-string">&quot;04cf10eb25bb8e0f816eb343458f49f8&quot;</span><br>    <span class="hljs-string">&quot;4b59074adefdc8d0848bfbdadb28d43e&quot;</span><br>    <span class="hljs-string">&quot;a42f56beef86c762ea76e9d674a56bf9&quot;</span><br>    <span class="hljs-string">&quot;987d3a265aaf870d1b2eb2e36accf1ff&quot;</span><br>    <span class="hljs-string">&quot;d7f61cc9e870204e233dc2aadc0bf25f&quot;</span><br>    <span class="hljs-string">&quot;7afa889747d10c02317ff4751593388a&quot;</span><br>    <span class="hljs-string">&quot;429071dd73557eb55b294c9ae08cb0e5&quot;</span><br>    <span class="hljs-string">&quot;642701dfad2179949251697c22635085&quot;</span><br>    <span class="hljs-string">&quot;2de2404644a982b661d8d2b968abb15d&quot;</span><br>    <span class="hljs-string">&quot;655477a0c5ba609ce4feee99e6786d09&quot;</span><br>)<br><br>FK = (<span class="hljs-number">0x3B1F86A4</span>, <span class="hljs-number">0x83F7332D</span>, <span class="hljs-number">0x58ADBA8E</span>, <span class="hljs-number">0x71DC3F73</span>)<br><br>CK = (<br>    <span class="hljs-number">0x9A148706</span>, <span class="hljs-number">0x657904A4</span>, <span class="hljs-number">0xB0535D2D</span>, <span class="hljs-number">0x865C7AA7</span>,<br>    <span class="hljs-number">0xF7FEF2D4</span>, <span class="hljs-number">0xF09D3A8B</span>, <span class="hljs-number">0x67CB0390</span>, <span class="hljs-number">0xF3B1D1AA</span>,<br>    <span class="hljs-number">0x1941EDE3</span>, <span class="hljs-number">0xCDD55650</span>, <span class="hljs-number">0x272AA612</span>, <span class="hljs-number">0x397B1DC6</span>,<br>    <span class="hljs-number">0x767AAB6B</span>, <span class="hljs-number">0x71A39044</span>, <span class="hljs-number">0x8A77F592</span>, <span class="hljs-number">0x7B5A7907</span>,<br>    <span class="hljs-number">0x97D18251</span>, <span class="hljs-number">0xCA1960CB</span>, <span class="hljs-number">0x44B54134</span>, <span class="hljs-number">0x3F30C70A</span>,<br>    <span class="hljs-number">0x5EB36C72</span>, <span class="hljs-number">0x5569E716</span>, <span class="hljs-number">0x51BF832C</span>, <span class="hljs-number">0xF13A95BC</span>,<br>    <span class="hljs-number">0x92D9F824</span>, <span class="hljs-number">0xE75CED15</span>, <span class="hljs-number">0x4558D865</span>, <span class="hljs-number">0xBE5250CD</span>,<br>    <span class="hljs-number">0x8F658E94</span>, <span class="hljs-number">0xB4EA5DC0</span>, <span class="hljs-number">0xB0377FCE</span>, <span class="hljs-number">0x4DF44762</span>,<br>)<br><br><br><span class="hljs-comment"># ===== 基础函数 =====</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">rol32</span>(<span class="hljs-params">x: <span class="hljs-built_in">int</span>, n: <span class="hljs-built_in">int</span></span>) -&gt; <span class="hljs-built_in">int</span>:<br>    x &amp;= <span class="hljs-number">0xFFFFFFFF</span><br>    <span class="hljs-keyword">return</span> ((x &lt;&lt; n) | (x &gt;&gt; (<span class="hljs-number">32</span> - n))) &amp; <span class="hljs-number">0xFFFFFFFF</span><br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">tau</span>(<span class="hljs-params">x: <span class="hljs-built_in">int</span></span>) -&gt; <span class="hljs-built_in">int</span>:<br>    <span class="hljs-keyword">return</span> (<br>        (SBOX[(x &gt;&gt; <span class="hljs-number">24</span>) &amp; <span class="hljs-number">0xFF</span>] &lt;&lt; <span class="hljs-number">24</span>)<br>        | (SBOX[(x &gt;&gt; <span class="hljs-number">16</span>) &amp; <span class="hljs-number">0xFF</span>] &lt;&lt; <span class="hljs-number">16</span>)<br>        | (SBOX[(x &gt;&gt; <span class="hljs-number">8</span>) &amp; <span class="hljs-number">0xFF</span>] &lt;&lt; <span class="hljs-number">8</span>)<br>        | SBOX[x &amp; <span class="hljs-number">0xFF</span>]<br>    )<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">l_transform</span>(<span class="hljs-params">x: <span class="hljs-built_in">int</span></span>) -&gt; <span class="hljs-built_in">int</span>:<br>    <span class="hljs-keyword">return</span> x ^ rol32(x, <span class="hljs-number">2</span>) ^ rol32(x, <span class="hljs-number">10</span>) ^ rol32(x, <span class="hljs-number">18</span>) ^ rol32(x, <span class="hljs-number">24</span>)<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">l_prime</span>(<span class="hljs-params">x: <span class="hljs-built_in">int</span></span>) -&gt; <span class="hljs-built_in">int</span>:<br>    <span class="hljs-keyword">return</span> x ^ rol32(x, <span class="hljs-number">13</span>) ^ rol32(x, <span class="hljs-number">23</span>)<br><br><br><span class="hljs-comment"># ===== 密钥扩展 =====</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">expand_round_keys</span>(<span class="hljs-params">key: <span class="hljs-built_in">bytes</span></span>) -&gt; <span class="hljs-built_in">list</span>[<span class="hljs-built_in">int</span>]:<br>    <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(key) != BLOCK_SIZE:<br>        <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">&quot;invalid key length&quot;</span>)<br><br>    words = [<span class="hljs-built_in">int</span>.from_bytes(key[i:i + <span class="hljs-number">4</span>], <span class="hljs-string">&quot;big&quot;</span>) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>, <span class="hljs-number">16</span>, <span class="hljs-number">4</span>)]<br>    state = [words[i] ^ FK[i] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">4</span>)]<br><br>    rk = []<br>    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">24</span>):<br>        mix = state[i + <span class="hljs-number">1</span>] ^ state[i + <span class="hljs-number">2</span>] ^ state[i + <span class="hljs-number">3</span>] ^ CK[i]<br>        new = state[i] ^ l_prime(tau(mix))<br>        state.append(new)<br>        rk.append(new)<br><br>    <span class="hljs-keyword">return</span> rk<br><br><br><span class="hljs-comment"># ===== 分组加解密 =====</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">crypt_block</span>(<span class="hljs-params">block: <span class="hljs-built_in">bytes</span>, rk: <span class="hljs-built_in">list</span>[<span class="hljs-built_in">int</span>]</span>) -&gt; <span class="hljs-built_in">bytes</span>:<br>    <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(block) != BLOCK_SIZE:<br>        <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">&quot;invalid block size&quot;</span>)<br><br>    state = [<span class="hljs-built_in">int</span>.from_bytes(block[i:i + <span class="hljs-number">4</span>], <span class="hljs-string">&quot;big&quot;</span>) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>, <span class="hljs-number">16</span>, <span class="hljs-number">4</span>)]<br><br>    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">24</span>):<br>        mix = state[i + <span class="hljs-number">1</span>] ^ state[i + <span class="hljs-number">2</span>] ^ state[i + <span class="hljs-number">3</span>] ^ rk[i]<br>        state.append(state[i] ^ l_transform(tau(mix)))<br><br>    <span class="hljs-keyword">return</span> <span class="hljs-string">b&quot;&quot;</span>.join(w.to_bytes(<span class="hljs-number">4</span>, <span class="hljs-string">&quot;big&quot;</span>) <span class="hljs-keyword">for</span> w <span class="hljs-keyword">in</span> state[-<span class="hljs-number">1</span>:-<span class="hljs-number">5</span>:-<span class="hljs-number">1</span>])<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">pkcs7_unpad</span>(<span class="hljs-params">data: <span class="hljs-built_in">bytes</span></span>) -&gt; <span class="hljs-built_in">bytes</span>:<br>    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> data <span class="hljs-keyword">or</span> <span class="hljs-built_in">len</span>(data) % BLOCK_SIZE:<br>        <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">&quot;invalid padding&quot;</span>)<br><br>    pad = data[-<span class="hljs-number">1</span>]<br>    <span class="hljs-keyword">if</span> pad &lt; <span class="hljs-number">1</span> <span class="hljs-keyword">or</span> pad &gt; BLOCK_SIZE <span class="hljs-keyword">or</span> data[-pad:] != <span class="hljs-built_in">bytes</span>([pad]) * pad:<br>        <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">&quot;invalid padding&quot;</span>)<br><br>    <span class="hljs-keyword">return</span> data[:-pad]<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">decrypt</span>(<span class="hljs-params">ct: <span class="hljs-built_in">bytes</span>, key: <span class="hljs-built_in">bytes</span> = KEY</span>) -&gt; <span class="hljs-built_in">bytes</span>:<br>    <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(ct) % BLOCK_SIZE:<br>        <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">&quot;invalid ciphertext length&quot;</span>)<br><br>    rk = <span class="hljs-built_in">list</span>(<span class="hljs-built_in">reversed</span>(expand_round_keys(key)))<br>    pt = <span class="hljs-string">b&quot;&quot;</span>.join(<br>        crypt_block(ct[i:i + <span class="hljs-number">16</span>], rk)<br>        <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>, <span class="hljs-built_in">len</span>(ct), <span class="hljs-number">16</span>)<br>    )<br>    <span class="hljs-keyword">return</span> pkcs7_unpad(pt)<br><br><br><span class="hljs-comment"># ===== PCAP 解析 =====</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">extract_json_messages</span>(<span class="hljs-params">pcap: Path</span>) -&gt; <span class="hljs-built_in">list</span>[<span class="hljs-built_in">dict</span>[<span class="hljs-built_in">str</span>, <span class="hljs-built_in">str</span>]]:<br>    out = subprocess.check_output(<br>        [<span class="hljs-string">&quot;tshark&quot;</span>, <span class="hljs-string">&quot;-r&quot;</span>, <span class="hljs-built_in">str</span>(pcap), <span class="hljs-string">&quot;-q&quot;</span>, <span class="hljs-string">&quot;-z&quot;</span>, <span class="hljs-string">&quot;follow,tcp,raw,0&quot;</span>],<br>        text=<span class="hljs-literal">True</span>,<br>    )<br><br>    msgs = []<br>    <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> out.splitlines():<br>        line = line.strip()<br>        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> line <span class="hljs-keyword">or</span> <span class="hljs-built_in">any</span>(c <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> <span class="hljs-string">&quot;0123456789abcdef&quot;</span> <span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> line):<br>            <span class="hljs-keyword">continue</span><br><br>        raw = <span class="hljs-built_in">bytes</span>.fromhex(line)<br>        <span class="hljs-keyword">if</span> raw.startswith(<span class="hljs-string">b&quot;&#123;&quot;</span>):<br>            msgs.append(json.loads(raw.decode()))<br><br>    <span class="hljs-keyword">return</span> msgs<br><br><br><span class="hljs-comment"># ===== 输出 =====</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">print_result</span>(<span class="hljs-params">name: <span class="hljs-built_in">str</span>, pt: <span class="hljs-built_in">bytes</span></span>) -&gt; <span class="hljs-literal">None</span>:<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;=== <span class="hljs-subst">&#123;name&#125;</span> ===&quot;</span>)<br>    <span class="hljs-keyword">try</span>:<br>        <span class="hljs-built_in">print</span>(pt.decode())<br>    <span class="hljs-keyword">except</span> UnicodeDecodeError:<br>        <span class="hljs-built_in">print</span>(pt.<span class="hljs-built_in">hex</span>())<br>    <span class="hljs-built_in">print</span>()<br><br><br><span class="hljs-comment"># ===== 主程序 =====</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">main</span>() -&gt; <span class="hljs-built_in">int</span>:<br>    parser = argparse.ArgumentParser()<br>    parser.add_argument(<span class="hljs-string">&quot;--pcap&quot;</span>, <span class="hljs-built_in">type</span>=Path, default=Path(<span class="hljs-string">&quot;capture.pcap&quot;</span>))<br>    parser.add_argument(<span class="hljs-string">&quot;--ciphertext&quot;</span>)<br>    parser.add_argument(<span class="hljs-string">&quot;--raw&quot;</span>, action=<span class="hljs-string">&quot;store_true&quot;</span>)<br>    args = parser.parse_args()<br><br>    <span class="hljs-comment"># 单条解密模式</span><br>    <span class="hljs-keyword">if</span> args.ciphertext:<br>        pt = decrypt(<span class="hljs-built_in">bytes</span>.fromhex(args.ciphertext))<br>        output = pt.<span class="hljs-built_in">hex</span>() <span class="hljs-keyword">if</span> args.raw <span class="hljs-keyword">else</span> pt.decode(errors=<span class="hljs-string">&quot;ignore&quot;</span>)<br>        <span class="hljs-built_in">print</span>(output)<br>        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span><br><br>    <span class="hljs-comment"># PCAP 模式</span><br>    msgs = extract_json_messages(args.pcap)<br>    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> msgs:<br>        <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;no messages found&quot;</span>, file=sys.stderr)<br>        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span><br><br>    <span class="hljs-keyword">for</span> m <span class="hljs-keyword">in</span> msgs:<br>        pt = decrypt(<span class="hljs-built_in">bytes</span>.fromhex(m[<span class="hljs-string">&quot;ciphertext&quot;</span>]))<br>        print_result(m[<span class="hljs-string">&quot;filename&quot;</span>], pt)<br><br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span><br><br><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:<br>    <span class="hljs-keyword">raise</span> SystemExit(main())<br></code></pre></td></tr></table></figure></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;周末参加了这次软件系统安全赛初赛，又是坐牢的一天啊，不过应该是进复赛了，在这篇文章中分享一下解题过程&lt;/p&gt;
&lt;h2 id=&quot;re1&quot;&gt;&lt;a href=&quot;#re1&quot; class=&quot;headerlink&quot; title=&quot;re1&quot;&gt;&lt;/a&gt;re1&lt;/h2&gt;&lt;p&gt;题目附件给了一个</summary>
      
    
    
    
    <category term="wp" scheme="https://llurry.github.io/categories/wp/"/>
    
    
    <category term="re" scheme="https://llurry.github.io/tags/re/"/>
    
  </entry>
  
  <entry>
    <title>2025ciscn初赛</title>
    <link href="https://llurry.github.io/2025/12/30/2025ciscn%E5%88%9D%E8%B5%9B/"/>
    <id>https://llurry.github.io/2025/12/30/2025ciscn%E5%88%9D%E8%B5%9B/</id>
    <published>2025-12-30T02:21:12.000Z</published>
    <updated>2026-04-01T13:35:57.710Z</updated>
    
    <content type="html"><![CDATA[<p>依旧坐牢，但还是有收获的</p><h2 id="Eternum"><a href="#Eternum" class="headerlink" title="Eternum"></a>Eternum</h2><p>go程序结合流量分析来考察<br>先追踪TCP流，发现所有数据包均以 45 54 33 52 4E 55 4D 58 开头，对应ASCIL是  “ET3RNUMX”，猜测是自定义的C2通信协议， 结构为 Header(8) + Length(4) + EncryptedData<br>交叉引用发现go程序还是加壳了的，脱壳后在ida打开</p><p><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/ciscn/1.png" alt="1.png" data-caption="1.png" loading="lazy"></p><p>函数名去除了符号，用GoReSym工具分析二进制文件，<a href="https://github.com/mandiant/GoReSym/releases，恢复部分运行时元数据，并生成">https://github.com/mandiant/GoReSym/releases，恢复部分运行时元数据，并生成</a> IDAPython 脚本导入 IDA。虽然混淆后的函数名无法完全还原语义，但标准库函数得到了恢复<br>以下是题目程序恢复符号后的main.main函数伪代码：<br><figure class="highlight r"><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><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br></pre></td><td class="code"><pre><code class="hljs R"><br>void __fastcall main_main<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span><br><span class="hljs-punctuation">&#123;</span><br>  __int64 v0; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> r14<br>  __int64 v1; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> rcx<br>  __int64 v2; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> rax<br>  _QWORD <span class="hljs-operator">*</span>v3; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> rax<br>  __int64 v4; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> rcx<br>  __int64 v5; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> rsi<br>  _QWORD <span class="hljs-operator">*</span>v6; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> r11<br>  _QWORD <span class="hljs-operator">*</span>v7; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> rax<br>  _QWORD <span class="hljs-operator">*</span>v8; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> rcx<br>  _QWORD <span class="hljs-operator">*</span>v9; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> r11<br>  __int64 v10; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> <span class="hljs-punctuation">[</span>rsp<span class="hljs-operator">-</span><span class="hljs-number">20</span>h<span class="hljs-punctuation">]</span> <span class="hljs-punctuation">[</span>rbp<span class="hljs-operator">-</span><span class="hljs-number">80</span>h<span class="hljs-punctuation">]</span><br>  __int64 v11; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> <span class="hljs-punctuation">[</span>rsp<span class="hljs-operator">+</span><span class="hljs-number">0</span>h<span class="hljs-punctuation">]</span> <span class="hljs-punctuation">[</span>rbp<span class="hljs-operator">-</span><span class="hljs-number">60</span>h<span class="hljs-punctuation">]</span><br>  __int64 v12; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> <span class="hljs-punctuation">[</span>rsp<span class="hljs-operator">+</span><span class="hljs-number">8</span>h<span class="hljs-punctuation">]</span> <span class="hljs-punctuation">[</span>rbp<span class="hljs-operator">-</span><span class="hljs-number">58</span>h<span class="hljs-punctuation">]</span><br>  _QWORD <span class="hljs-operator">*</span>v13; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> <span class="hljs-punctuation">[</span>rsp<span class="hljs-operator">+</span><span class="hljs-number">10</span>h<span class="hljs-punctuation">]</span> <span class="hljs-punctuation">[</span>rbp<span class="hljs-operator">-</span><span class="hljs-number">50</span>h<span class="hljs-punctuation">]</span><br>  __int64 v14; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> <span class="hljs-punctuation">[</span>rsp<span class="hljs-operator">+</span><span class="hljs-number">18</span>h<span class="hljs-punctuation">]</span> <span class="hljs-punctuation">[</span>rbp<span class="hljs-operator">-</span><span class="hljs-number">48</span>h<span class="hljs-punctuation">]</span><br>  __int64 v15; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> <span class="hljs-punctuation">[</span>rsp<span class="hljs-operator">+</span><span class="hljs-number">28</span>h<span class="hljs-punctuation">]</span> <span class="hljs-punctuation">[</span>rbp<span class="hljs-operator">-</span><span class="hljs-number">38</span>h<span class="hljs-punctuation">]</span><br>  void <span class="hljs-operator">*</span>retaddr; <span class="hljs-operator">/</span><span class="hljs-operator">/</span> <span class="hljs-punctuation">[</span>rsp<span class="hljs-operator">+</span><span class="hljs-number">60</span>h<span class="hljs-punctuation">]</span> <span class="hljs-punctuation">[</span>rbp<span class="hljs-operator">+</span><span class="hljs-number">0</span>h<span class="hljs-punctuation">]</span> BYREF<br><br>  <span class="hljs-keyword">if</span> <span class="hljs-punctuation">(</span> <span class="hljs-punctuation">(</span>unsigned __int64<span class="hljs-punctuation">)</span><span class="hljs-operator">&amp;</span>retaddr <span class="hljs-operator">&lt;=</span> <span class="hljs-operator">*</span><span class="hljs-punctuation">(</span>_QWORD <span class="hljs-operator">*</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">(</span>v0 <span class="hljs-operator">+</span> <span class="hljs-number">16</span><span class="hljs-punctuation">)</span> <span class="hljs-punctuation">)</span><br>    goto LABEL_11;<br>  <span class="hljs-keyword">if</span> <span class="hljs-punctuation">(</span> <span class="hljs-punctuation">(</span>unsigned __int64<span class="hljs-punctuation">)</span>qword_9A8A58 <span class="hljs-operator">&lt;=</span> <span class="hljs-number">1</span> <span class="hljs-punctuation">)</span><br>  <span class="hljs-punctuation">&#123;</span><br>    runtime_panicIndex<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span>;<br>LABEL_11<span class="hljs-operator">:</span><br>    runtime_morestack_noctxt<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span>;<br>    j_main_main<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span>;<br>    <span class="hljs-built_in">return</span>;<br>  <span class="hljs-punctuation">&#125;</span><br>  v11 <span class="hljs-operator">=</span> <span class="hljs-operator">*</span><span class="hljs-punctuation">(</span>_QWORD <span class="hljs-operator">*</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">(</span>qword_9A8A50 <span class="hljs-operator">+</span> <span class="hljs-number">24</span><span class="hljs-punctuation">)</span>;<br>  v14 <span class="hljs-operator">=</span> <span class="hljs-operator">*</span><span class="hljs-punctuation">(</span>_QWORD <span class="hljs-operator">*</span><span class="hljs-punctuation">)</span><span class="hljs-punctuation">(</span>qword_9A8A50 <span class="hljs-operator">+</span> <span class="hljs-number">16</span><span class="hljs-punctuation">)</span>;<br>  v10 <span class="hljs-operator">=</span> iGw9vplejnCj_FPKxH3Y<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span>;<br>  v15 <span class="hljs-operator">=</span> v1;<br>  v12 <span class="hljs-operator">=</span> v2;<br>  v3 <span class="hljs-operator">=</span> <span class="hljs-punctuation">(</span>_QWORD <span class="hljs-operator">*</span><span class="hljs-punctuation">)</span>runtime_newobject<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span>;<br>  v3<span class="hljs-punctuation">[</span><span class="hljs-number">3</span><span class="hljs-punctuation">]</span> <span class="hljs-operator">=</span> v11;<br>  <span class="hljs-keyword">if</span> <span class="hljs-punctuation">(</span> dword_9CB880 <span class="hljs-punctuation">)</span><br>  <span class="hljs-punctuation">&#123;</span><br>    v3 <span class="hljs-operator">=</span> <span class="hljs-punctuation">(</span>_QWORD <span class="hljs-operator">*</span><span class="hljs-punctuation">)</span>runtime_gcWriteBarrier3<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span>;<br>    v4 <span class="hljs-operator">=</span> v14;<br>    <span class="hljs-operator">*</span>v6 <span class="hljs-operator">=</span> v14;<br>    v6<span class="hljs-punctuation">[</span><span class="hljs-number">1</span><span class="hljs-punctuation">]</span> <span class="hljs-operator">=</span> <span class="hljs-operator">&amp;</span>qword_9CB440;<br>    v5 <span class="hljs-operator">=</span> v15;<br>    v6<span class="hljs-punctuation">[</span><span class="hljs-number">2</span><span class="hljs-punctuation">]</span> <span class="hljs-operator">=</span> v15;<br>  <span class="hljs-punctuation">&#125;</span><br>  <span class="hljs-keyword">else</span><br>  <span class="hljs-punctuation">&#123;</span><br>    v4 <span class="hljs-operator">=</span> v14;<br>    v5 <span class="hljs-operator">=</span> v15;<br>  <span class="hljs-punctuation">&#125;</span><br>  v13 <span class="hljs-operator">=</span> v3;<br>  v3<span class="hljs-punctuation">[</span><span class="hljs-number">2</span><span class="hljs-punctuation">]</span> <span class="hljs-operator">=</span> v4;<br>  v3<span class="hljs-punctuation">[</span><span class="hljs-number">4</span><span class="hljs-punctuation">]</span> <span class="hljs-operator">=</span> v12;<br>  v3<span class="hljs-punctuation">[</span><span class="hljs-number">5</span><span class="hljs-punctuation">]</span> <span class="hljs-operator">=</span> <span class="hljs-operator">&amp;</span>qword_9CB440;<br>  v3<span class="hljs-punctuation">[</span><span class="hljs-number">6</span><span class="hljs-punctuation">]</span> <span class="hljs-operator">=</span> v5;<br>  runtime_makechan<span class="hljs-punctuation">(</span>v10<span class="hljs-punctuation">)</span>;<br>  ktyrAE7wjsb_AmuaG1Qm280<span class="hljs-punctuation">(</span><span class="hljs-number">2L</span>L<span class="hljs-punctuation">)</span>;<br>  v7 <span class="hljs-operator">=</span> <span class="hljs-punctuation">(</span>_QWORD <span class="hljs-operator">*</span><span class="hljs-punctuation">)</span>runtime_newobject<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span>;<br>  <span class="hljs-operator">*</span>v7 <span class="hljs-operator">=</span> main_main_func1;<br>  <span class="hljs-keyword">if</span> <span class="hljs-punctuation">(</span> dword_9CB880 <span class="hljs-punctuation">)</span><br>  <span class="hljs-punctuation">&#123;</span><br>    v7 <span class="hljs-operator">=</span> <span class="hljs-punctuation">(</span>_QWORD <span class="hljs-operator">*</span><span class="hljs-punctuation">)</span>runtime_gcWriteBarrier1<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span>;<br>    v8 <span class="hljs-operator">=</span> v13;<br>    <span class="hljs-operator">*</span>v9 <span class="hljs-operator">=</span> v13;<br>  <span class="hljs-punctuation">&#125;</span><br>  <span class="hljs-keyword">else</span><br>  <span class="hljs-punctuation">&#123;</span><br>    v8 <span class="hljs-operator">=</span> v13;<br>  <span class="hljs-punctuation">&#125;</span><br>  v7<span class="hljs-punctuation">[</span><span class="hljs-number">1</span><span class="hljs-punctuation">]</span> <span class="hljs-operator">=</span> v8;<br>  runtime_newproc<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span>;<br>  runtime_chanrecv1<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span>;<br>  iupHvc2q4__ptr_H1eV17y_Stop<span class="hljs-punctuation">(</span><span class="hljs-punctuation">)</span>;<br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><br>发现程序是一个 C2 Agent  ，为了快速找到加密算法，直接去分析KeepAlive，路径追踪：Agent.Run -&gt; gowrap2 -&gt; KeepAlive -&gt; SendHeartbeat，在 SendHeartbeat 的底层调用链中，定位到封包函数 iupHvc2q4_S1msIZMcWt03。 在iupHvc2q4_S1msIZMcWt03中发现了关键特征：</p><ol><li>硬编码密钥: 加载了一个 32 字节的字符串 “xfqGcVjrOWp5tUGCPFQq448nPDjILTe7”。</li><li>AES 特征: 密钥长度符合 AES-256。</li><li>封包逻辑:<br>○ 序列化 Payload。<br>○ 加密 Payload (AES-GCM，带 Nonce 和 Tag)。<br>○ 拼接包头：[Magic (8)] + [Total Length (4)] + [Nonce (12)] + [Ciphertext] + [Tag (16)]。<br>确定完整协议结构<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></pre></td><td class="code"><pre><code class="hljs C++"><span class="hljs-keyword">struct</span> <span class="hljs-title class_">Packet</span> &#123;<br>    <span class="hljs-type">char</span> Magic[<span class="hljs-number">8</span>];     <span class="hljs-comment">// &quot;ET3RNUMX&quot;</span><br>    uint32 Length;     <span class="hljs-comment">// Big-Endian, 包含后续所有数据的长度</span><br>    byte Nonce[<span class="hljs-number">12</span>];    <span class="hljs-comment">// AES-GCM IV</span><br>    byte CipherText[]; <span class="hljs-comment">// 具体的密文</span><br>    byte Tag[<span class="hljs-number">16</span>];      <span class="hljs-comment">// AES-GCM 校验位 (Go标准库通常附加在密文末尾)</span><br>&#125;;<br></code></pre></td></tr></table></figure>先批量解密<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><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> re<br><span class="hljs-keyword">import</span> struct<br><span class="hljs-keyword">from</span> Crypto.Cipher <span class="hljs-keyword">import</span> AES<br><br><span class="hljs-comment"># 1. 配置</span><br>KEY = <span class="hljs-string">b&quot;xfqGcVjrOWp5tUGCPFQq448nPDjILTe7&quot;</span><br>INPUT_FILE = <span class="hljs-string">&quot;trace.txt&quot;</span>  <span class="hljs-comment"># 把你的 Hex 文本保存到这个文件</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">decrypt_payload</span>(<span class="hljs-params">ciphertext_with_nonce_tag</span>):<br>    <span class="hljs-keyword">try</span>:<br>        <span class="hljs-comment"># Go AES-GCM: [Nonce (12)] [Ciphertext] [Tag (16)]</span><br>        <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(ciphertext_with_nonce_tag) &lt; <span class="hljs-number">28</span>:<br>            <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>, <span class="hljs-string">&quot;Data too short&quot;</span><br><br>        nonce = ciphertext_with_nonce_tag[:<span class="hljs-number">12</span>]<br>        tag = ciphertext_with_nonce_tag[-<span class="hljs-number">16</span>:]<br>        ciphertext = ciphertext_with_nonce_tag[<span class="hljs-number">12</span>:-<span class="hljs-number">16</span>]<br><br>        cipher = AES.new(KEY, AES.MODE_GCM, nonce=nonce)<br>        decrypted = cipher.decrypt_and_verify(ciphertext, tag)<br>        <span class="hljs-keyword">return</span> decrypted, <span class="hljs-string">&quot;Success&quot;</span><br>    <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:<br>        <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>, <span class="hljs-built_in">str</span>(e)<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">parse_trace</span>(<span class="hljs-params">filename</span>):<br>    <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(filename, <span class="hljs-string">&#x27;r&#x27;</span>, encoding=<span class="hljs-string">&#x27;utf-8&#x27;</span>) <span class="hljs-keyword">as</span> f:<br>        content = f.read()<br><br>    <span class="hljs-comment"># 简单的清洗逻辑，移除行号和偏移量，只保留 Hex</span><br>    <span class="hljs-comment"># 这里假设输入格式比较杂乱，我们用正则提取所有 Hex 字节流</span><br>    <span class="hljs-comment"># 更好的方法是根据 Magic &quot;45 54 33 52 4E 55 4D 58&quot; 定位</span><br><br>    <span class="hljs-comment"># 将所有文本转换为类似于二进制流的大字符串（忽略非Hex字符）</span><br>    clean_hex = re.sub(<span class="hljs-string">r&#x27;[^0-9A-Fa-f]&#x27;</span>, <span class="hljs-string">&#x27;&#x27;</span>, content)<br>    <span class="hljs-comment"># 转换成 bytes</span><br>    <span class="hljs-keyword">try</span>:<br>        data = <span class="hljs-built_in">bytes</span>.fromhex(clean_hex)<br>    <span class="hljs-keyword">except</span>:<br>        <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;[-] Error parsing hex from file. Check format.&quot;</span>)<br>        <span class="hljs-keyword">return</span><br><br>    <span class="hljs-comment"># 遍历寻找 Magic Header</span><br>    magic = <span class="hljs-string">b&quot;\x45\x54\x33\x52\x4E\x55\x4D\x58&quot;</span><br>    offset = <span class="hljs-number">0</span><br><br>    <span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:<br>        offset = data.find(magic, offset)<br>        <span class="hljs-keyword">if</span> offset == -<span class="hljs-number">1</span>:<br>            <span class="hljs-keyword">break</span><br><br>        <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;\n[+] Found Packet at offset <span class="hljs-subst">&#123;offset&#125;</span>&quot;</span>)<br><br>        <span class="hljs-comment"># 读取长度 (Offset + 8, 4 bytes, Big Endian)</span><br>        <span class="hljs-keyword">if</span> offset + <span class="hljs-number">12</span> &gt; <span class="hljs-built_in">len</span>(data):<br>            <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;[-] Truncated header&quot;</span>)<br>            <span class="hljs-keyword">break</span><br><br>        payload_len = struct.unpack(<span class="hljs-string">&quot;&gt;I&quot;</span>, data[offset+<span class="hljs-number">8</span> : offset+<span class="hljs-number">12</span>])[<span class="hljs-number">0</span>]<br>        <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;    Payload Length: <span class="hljs-subst">&#123;payload_len&#125;</span>&quot;</span>)<br><br>        <span class="hljs-comment"># 提取完整密文段</span><br>        <span class="hljs-comment"># Packet End = Offset + 12 (Header+Len) + payload_len</span><br>        <span class="hljs-keyword">if</span> offset + <span class="hljs-number">12</span> + payload_len &gt; <span class="hljs-built_in">len</span>(data):<br>            <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;[-] Truncated payload&quot;</span>)<br>            <span class="hljs-comment"># 可能是因为 hex 数据不完整，尝试解密现有的部分</span><br>            encrypted_data = data[offset+<span class="hljs-number">12</span>:]<br>        <span class="hljs-keyword">else</span>:<br>            encrypted_data = data[offset+<span class="hljs-number">12</span> : offset+<span class="hljs-number">12</span>+payload_len]<br><br>        <span class="hljs-comment"># 解密</span><br>        decrypted, status = decrypt_payload(encrypted_data)<br><br>        <span class="hljs-keyword">if</span> decrypted:<br>            <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;    [Decrypted HEX]: &quot;</span> + decrypted.<span class="hljs-built_in">hex</span>()[:<span class="hljs-number">60</span>] + <span class="hljs-string">&quot;...&quot;</span>)<br>            <span class="hljs-keyword">try</span>:<br>                <span class="hljs-comment"># 尝试打印 ASCII，过滤不可见字符</span><br>                ascii_text = <span class="hljs-string">&#x27;&#x27;</span>.join([<span class="hljs-built_in">chr</span>(b) <span class="hljs-keyword">if</span> <span class="hljs-number">32</span> &lt;= b &lt;= <span class="hljs-number">126</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;.&#x27;</span> <span class="hljs-keyword">for</span> b <span class="hljs-keyword">in</span> decrypted])<br>                <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;    [Decrypted ASCII]: <span class="hljs-subst">&#123;ascii_text&#125;</span>&quot;</span>)<br><br>                <span class="hljs-comment"># *** 自动寻找 Flag ***</span><br>                <span class="hljs-keyword">if</span> <span class="hljs-string">&quot;flag&quot;</span> <span class="hljs-keyword">in</span> ascii_text.lower() <span class="hljs-keyword">or</span> <span class="hljs-string">&quot;gwht&quot;</span> <span class="hljs-keyword">in</span> ascii_text.lower():<br>                    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;\n    🔥 CRITICAL: POTENTIAL FLAG FOUND! 🔥&quot;</span>)<br>                    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;    &quot;</span> + ascii_text)<br>                    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;\n&quot;</span>)<br>            <span class="hljs-keyword">except</span>:<br>                <span class="hljs-keyword">pass</span><br>        <span class="hljs-keyword">else</span>:<br>            <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;    [-] Decryption Failed: <span class="hljs-subst">&#123;status&#125;</span>&quot;</span>)<br><br>        offset += <span class="hljs-number">1</span> <span class="hljs-comment"># 继续搜下一个</span><br><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:<br>    <span class="hljs-comment"># 如果你没有文件，可以直接把那一大段 hex 粘贴到这里作为 string 测试</span><br>    <span class="hljs-comment"># parse_trace(&quot;trace.txt&quot;)</span><br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;Please save your hex data to trace.txt and run.&quot;</span>)<br></code></pre></td></tr></table></figure>发现是 Protobuf 序列化数据<br>● Field 1: OpCode (4 = Heartbeat)<br>● Field 2: Payload Data (嵌套结构)<br>● Field 5: TraceID<br>最后进行流量行为审计，攻击者执行了命令 base32 /var/opt/s*，在响应包中发现明显base32字符串’IMZWGCZ33MI3WGNJYG4YDALJSMIYDCLJUMRSDILJYGUZDMLLBGRQTIN3BGY2WCMLBHF6QU===’<br>解密发现不对，根据 Protobuf 结构分析，字符串开头的 ‘I’ (0x49) 实际上是 Protobuf 嵌套字段的一部分或数据流残留。去掉I后解密</li></ol><p><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/ciscn/2.png" alt="2.png" data-caption="2.png" loading="lazy"></p><h2 id="babygame"><a href="#babygame" class="headerlink" title="babygame"></a>babygame</h2><p>玩了下游戏发现过不了，用<a href="https://github.com/GDRETools/gdsdecomp">https://github.com/GDRETools/gdsdecomp</a> 来解包<br>解包以后定位到flag.gdc</p><p><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/ciscn/3.png" alt="3.png" data-caption="3.png" loading="lazy"></p><p>不难发现是aes加密，可以找到key和加密后的密文，同时analyze_flag.py 将A替换成B，直接用cyberchef解密就好了</p><p><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/ciscn/4.png" alt="4.png" data-caption="4.png" loading="lazy"></p><h2 id="wasm-login"><a href="#wasm-login" class="headerlink" title="wasm-login"></a>wasm-login</h2><p>wasm逆向，用wabt工具来反编译拿到.wat<br>html源码<br><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/ciscn/5.png" alt="5.png" data-caption="5.png" loading="lazy"><br>题目已经提示了时间<br> 某人本想在2025年12月第三个周末爆肝一个web安全登录demo，结果不仅搞到周一凌晨，他自己还忘了成功登录时的时间戳了，你能帮他找回来吗？<br>Source Map 利⽤：目录下暴露了 release.wasm.map ，可以直接基于时间戳来爆破<br>解题思路主要是直接利用 release.js 导出的函数，并通过 Hook Date.now 来欺骗 WASM<br><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><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> &#123; authenticate &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./build/release.js&#x27;</span>;<br><span class="hljs-keyword">import</span> crypto <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;crypto&#x27;</span>;<br><br>// 目标前缀<br>const TARGET_PREFIX = <span class="hljs-string">&quot;ccaf33e3512e31f3&quot;</span>;<br><br>// 搜索范围：<span class="hljs-number">2025</span>-<span class="hljs-number">12</span>-<span class="hljs-number">22</span> <span class="hljs-number">00</span>:<span class="hljs-number">00</span>:<span class="hljs-number">00</span> (UTC+<span class="hljs-number">8</span>) 附近<br>// 起始：<span class="hljs-number">1766332800000</span><br>// 结束：<span class="hljs-number">1766343600000</span><br>const START_MS = <span class="hljs-number">1766332800000</span>;<br>const END_MS   = <span class="hljs-number">1766343600000</span>;<br><br>console.log(`[+] 开始极速爆破...`);<br>console.log(`[+] 范围: $&#123;START_MS&#125; -&gt; $&#123;END_MS&#125; (共 $&#123;(END_MS - START_MS)&#125; 毫秒)`);<br><br>const startTime = performance.now();<br><br><span class="hljs-keyword">for</span> (let ms = START_MS; ms &lt;= END_MS; ms++) &#123;<br>    <br>    // --- 核心 Hook 逻辑 ---<br>    // 强制修改 Date.now，使得 release.js 内部调用 Date.now() 时获取到我们伪造的时间<br>    Date.now = () =&gt; ms; <br><br>    <span class="hljs-keyword">try</span> &#123;<br>        // 直接调用 WASM 导出的函数<br>        const authResult = authenticate(<span class="hljs-string">&quot;admin&quot;</span>, <span class="hljs-string">&quot;admin&quot;</span>);<br><br>        // 严格按照题目逻辑：JSON.parse -&gt; JSON.stringify -&gt; MD5<br>        // (模拟前端的数据处理流程)<br>        const authData = JSON.parse(authResult);<br>        const jsonStr = JSON.stringify(authData);<br>        <br>        const check = crypto.createHash(<span class="hljs-string">&#x27;md5&#x27;</span>)<br>            .update(jsonStr)<br>            .digest(<span class="hljs-string">&#x27;hex&#x27;</span>);<br><br>        <span class="hljs-keyword">if</span> (check.startsWith(TARGET_PREFIX)) &#123;<br>            console.log(`\n========== BINGO! ==========`);<br>            console.log(`Timestamp : $&#123;ms&#125;`);<br>            console.log(`Time (ISO): $&#123;new Date(ms).toISOString()&#125;`);<br>            console.log(`Check Val : $&#123;check&#125;`);<br>            console.log(`\nFlag: flag&#123;$&#123;check&#125;&#125;`);<br>            console.log(`============================`);<br>            <span class="hljs-keyword">break</span>; // 找到后退出<br>        &#125;<br><br>    &#125; catch (e) &#123;<br>        // 忽略 JSON 解析错误或其他 WASM 内部错误<br>        <span class="hljs-keyword">continue</span>;<br>    &#125;<br><br>    // 每 <span class="hljs-number">5000</span> 次打印一下进度（因为速度很快，可以适当减少打印频率）<br>    <span class="hljs-keyword">if</span> ((ms - START_MS) % <span class="hljs-number">5000</span> === <span class="hljs-number">0</span>) &#123;<br>        process.stdout.write(`\rProgress: $&#123;ms&#125; ...`);<br>    &#125;<br>&#125;<br><br>const endTime = performance.now();<br>console.log(`\n[+] 耗时: $&#123;((endTime - startTime) / <span class="hljs-number">1000</span>).toFixed(<span class="hljs-number">2</span>)&#125; 秒`);<br></code></pre></td></tr></table></figure><br>直接node solve.mjs</p><h2 id="ECDSA"><a href="#ECDSA" class="headerlink" title="ECDSA"></a>ECDSA</h2><p>通过分析发现，题目中的ECDSA签名使用了可预测的nonce（k值），这使得私钥可以被恢复。关键问题在于ecdsa库默认使用SHA1作为hash函数，而不是SHA512。通过使用正确的hash函数（SHA1）和已知的nonce生成方式，成功恢复了私钥，并计算出其MD5值。<br><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><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> ecdsa <span class="hljs-keyword">import</span> VerifyingKey, NIST521p<br><span class="hljs-keyword">from</span> hashlib <span class="hljs-keyword">import</span> sha512, sha1<br><span class="hljs-keyword">from</span> Crypto.Util.number <span class="hljs-keyword">import</span> long_to_bytes, bytes_to_long<br><span class="hljs-keyword">import</span> binascii<br><span class="hljs-keyword">import</span> hashlib<br><br><span class="hljs-comment"># 从public.pem读取公钥</span><br><span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&quot;public.pem&quot;</span>, <span class="hljs-string">&quot;rb&quot;</span>) <span class="hljs-keyword">as</span> f:<br>    vk_pem = f.read()<br><br>vk = VerifyingKey.from_pem(vk_pem)<br>curve_order = NIST521p.order<br><br><span class="hljs-comment"># 读取签名文件</span><br>signatures = []<br><span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&quot;signatures.txt&quot;</span>, <span class="hljs-string">&quot;r&quot;</span>) <span class="hljs-keyword">as</span> f:<br>    <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> f:<br>        <span class="hljs-keyword">if</span> line.strip():<br>            msg_hex, sig_hex = line.strip().split(<span class="hljs-string">&quot;:&quot;</span>)<br>            msg = binascii.unhexlify(msg_hex)<br>            sig = binascii.unhexlify(sig_hex)<br>            signatures.append((msg, sig))<br><br><span class="hljs-comment"># nonce函数（与task.py中相同）</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">nonce</span>(<span class="hljs-params">i</span>):<br>    seed = sha512(<span class="hljs-string">b&quot;bias&quot;</span> + <span class="hljs-built_in">bytes</span>([i])).digest()<br>    k = <span class="hljs-built_in">int</span>.from_bytes(seed, <span class="hljs-string">&quot;big&quot;</span>)<br>    <span class="hljs-keyword">return</span> k<br><br><span class="hljs-comment"># 选择第一个签名进行攻击</span><br>msg, sig = signatures[<span class="hljs-number">0</span>]<br>msg_index = <span class="hljs-number">0</span>  <span class="hljs-comment"># 因为msg是&quot;message-\x00&quot;</span><br><br><span class="hljs-comment"># 计算nonce k</span><br>k = nonce(msg_index)<br><br><span class="hljs-comment"># 解析ECDSA签名 (r, s)</span><br><span class="hljs-comment"># NIST521p的签名长度是132字节 (66字节r + 66字节s)</span><br>sig_len = <span class="hljs-built_in">len</span>(sig)<br>half_len = sig_len // <span class="hljs-number">2</span><br>r = bytes_to_long(sig[:half_len])<br>s = bytes_to_long(sig[half_len:])<br><br><span class="hljs-comment"># 计算消息的hash (ecdsa库默认使用SHA1)</span><br>msg_hash = bytes_to_long(sha1(msg).digest()) % curve_order<br><br><span class="hljs-comment"># 验证r和s是否有效</span><br><span class="hljs-keyword">assert</span> <span class="hljs-number">1</span> &lt;= r &lt; curve_order<br><span class="hljs-keyword">assert</span> <span class="hljs-number">1</span> &lt;= s &lt; curve_order<br><br><span class="hljs-comment"># 计算私钥 d = (s * k - hash(m)) * r^(-1) mod n</span><br>r_inv = <span class="hljs-built_in">pow</span>(r, -<span class="hljs-number">1</span>, curve_order)<br>d = ((s * k - msg_hash) * r_inv) % curve_order<br><br><span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Recovered private key: <span class="hljs-subst">&#123;d&#125;</span>&quot;</span>)<br><span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Private key hex: <span class="hljs-subst">&#123;<span class="hljs-built_in">hex</span>(d)&#125;</span>&quot;</span>)<br><br><span class="hljs-comment"># 验证私钥是否正确</span><br><span class="hljs-keyword">from</span> ecdsa <span class="hljs-keyword">import</span> SigningKey<br><span class="hljs-comment"># 使用与task.py相同的方式创建私钥</span><br>d_bytes_for_sk = long_to_bytes(d, <span class="hljs-number">66</span>)<br>sk_recovered = SigningKey.from_string(d_bytes_for_sk, curve=NIST521p)<br>vk_recovered = sk_recovered.verifying_key<br><br><span class="hljs-comment"># 验证公钥是否匹配</span><br><span class="hljs-keyword">if</span> vk.to_string() == vk_recovered.to_string():<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;Private key is correct!&quot;</span>)<br>    <br>    <span class="hljs-comment"># 计算MD5 - 注意：MD5应该基于原始的私钥整数，而不是填充后的字节</span><br>    <span class="hljs-comment"># 但根据task.py，私钥是priv_int，所以我们应该对priv_int取MD5</span><br>    original_d_bytes = long_to_bytes(d)  <span class="hljs-comment"># 不带长度参数，只包含必要的字节</span><br>    md5_hash = hashlib.md5(original_d_bytes).hexdigest()<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Flag: flag&#123;&#123;<span class="hljs-subst">&#123;md5_hash&#125;</span>&#125;&#125;&quot;</span>)<br><span class="hljs-keyword">else</span>:<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;Private key recovery failed!&quot;</span>)<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Expected vk: <span class="hljs-subst">&#123;binascii.hexlify(vk.to_string()).decode()&#125;</span>&quot;</span>)<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Recovered vk: <span class="hljs-subst">&#123;binascii.hexlify(vk_recovered.to_string()).decode()&#125;</span>&quot;</span>)<br></code></pre></td></tr></table></figure><br>还原得到的key是11786190273906782566706300546504742629011900435269701041731697414027484824601255112180676531145294320443777235338538357924760601782873554458995940394745073<br>得到flag<br><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/ciscn/6.png" alt="6.png" data-caption="6.png" loading="lazy"></p><h2 id="EzFlag"><a href="#EzFlag" class="headerlink" title="EzFlag"></a>EzFlag</h2><p>逆向题目和密码的结合<br>main函数，比较输入内容与硬编码字符串 “V3ryStr0ngp@ssw0rd”，用’’-‘’隔断flag<br><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/ciscn/8.png" alt="8.png" data-caption="8.png" loading="lazy"><br>f函数逻辑<br><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/ciscn/7.png" alt="7.png" data-caption="7.png" loading="lazy"><br>斐波那契数列模 n 具有周期性（皮萨诺周期，Pisano Period）。 对于 n=16 (24)，其周期是 24。 即：Fib(x)(mod16)==Fib(x(mod24))(mod16)，并且k的值也知道<br><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><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">solve</span>():<br>    <span class="hljs-comment"># 1. 题目给出的映射表 K</span><br>    k = <span class="hljs-string">&quot;012ab9c3478d56ef&quot;</span><br><br>    <span class="hljs-comment"># 2. 预计算模 16 的斐波那契序列（周期为 24）</span><br>    <span class="hljs-comment"># F[0]=0, F[1]=1, F[n] = (F[n-1] + F[n-2]) % 16</span><br>    fib_mod = [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>]<br>    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">2</span>, <span class="hljs-number">24</span>):<br>        fib_mod.append((fib_mod[-<span class="hljs-number">1</span>] + fib_mod[-<span class="hljs-number">2</span>]) &amp; <span class="hljs-number">0xF</span>)<br><br>    <span class="hljs-keyword">def</span> <span class="hljs-title function_">get_char</span>(<span class="hljs-params">v11_val</span>):<br>        <span class="hljs-comment"># 利用周期性：F[v11] % 16 == F[v11 % 24] % 16</span><br>        idx = fib_mod[v11_val % <span class="hljs-number">24</span>]<br>        <span class="hljs-keyword">return</span> k[idx]<br><br>    v11 = <span class="hljs-number">1</span><br>    flag_content = <span class="hljs-string">&quot;&quot;</span><br><br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;正在计算 Flag...&quot;</span>)<br>    <br>    <span class="hljs-comment"># 3. 循环 32 次</span><br>    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">32</span>):<br>        <span class="hljs-comment"># 先取字符</span><br>        char = get_char(v11)<br>        flag_content += char<br>        <br>        <span class="hljs-comment"># 格式化：在特定的索引 i 之后添加横杠</span><br>        <span class="hljs-comment"># i=7 (第8个字符), i=12 (第13个字符)...</span><br>        <span class="hljs-keyword">if</span> i <span class="hljs-keyword">in</span> [<span class="hljs-number">7</span>, <span class="hljs-number">12</span>, <span class="hljs-number">17</span>, <span class="hljs-number">22</span>]:<br>            flag_content += <span class="hljs-string">&quot;-&quot;</span><br>        <br>        <span class="hljs-comment"># 更新 v11</span><br>        <span class="hljs-comment"># 关键点：模拟 C++ unsigned long long (64位) 溢出行为</span><br>        v11 = (v11 * <span class="hljs-number">8</span> + i + <span class="hljs-number">64</span>) &amp; <span class="hljs-number">0xFFFFFFFFFFFFFFFF</span><br><br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;最终 Flag: flag&#123;&#123;<span class="hljs-subst">&#123;flag_content&#125;</span>&#125;&#125;&quot;</span>)<br><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:<br>    solve()<br></code></pre></td></tr></table></figure></p><h2 id="SnakeBackdoor-2"><a href="#SnakeBackdoor-2" class="headerlink" title="SnakeBackdoor-2"></a>SnakeBackdoor-2</h2><p>题目内容：<br>攻击者通过漏洞利用获取Flask应用的 <code>SECRET_KEY</code> 是什么，结果提交形式：flag{xxxxxxxxxx}<br>攻击者在利用那个复杂的 RCE（远程代码执行）Payload 之前，通常会先通过简单的 SSTI Payload 来探测环境和读取敏感配置，而 Flask 应用的 SECRET_KEY 就存储在全局对象 config 中。<br>在过滤器中搜索:http.request.method == “POST” &amp;&amp; http.request.uri contains “/admin/preview”<br>有三个包，一个个地看， 这个数据包完美记录了攻击者通过  Payload 窃取 Flask 配置信息的过程<br><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/ciscn/9.png" alt="9.png" data-caption="9.png" loading="lazy"></p><p>定位关键信息 在响应包的 div 标签中，可以看到如下内容（HTML 实体编码格式）：<br> &#39;SECRET_KEY&#39;: &#39;c6242af0-6891-4510-8432-e1cdf051f160&#39;</p><p>解码 将 HTML 实体 &#39; 还原为单引号 ‘，内容即为： ‘SECRET_KEY’: ‘c6242af0-6891-4510-8432-e1cdf051f160’<br>得到flag:flag{c6242af0-6891-4510-8432-e1cdf051f160}<br>​</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;依旧坐牢，但还是有收获的&lt;/p&gt;
&lt;h2 id=&quot;Eternum&quot;&gt;&lt;a href=&quot;#Eternum&quot; class=&quot;headerlink&quot; title=&quot;Eternum&quot;&gt;&lt;/a&gt;Eternum&lt;/h2&gt;&lt;p&gt;go程序结合流量分析来考察&lt;br&gt;先追踪TCP流，发现所有数</summary>
      
    
    
    
    <category term="wp" scheme="https://llurry.github.io/categories/wp/"/>
    
    
    <category term="CTF" scheme="https://llurry.github.io/tags/CTF/"/>
    
  </entry>
  
  <entry>
    <title>GeekCTF 2025</title>
    <link href="https://llurry.github.io/2025/11/26/GeekCTF%202025/"/>
    <id>https://llurry.github.io/2025/11/26/GeekCTF%202025/</id>
    <published>2025-11-26T03:43:12.000Z</published>
    <updated>2026-03-20T01:40:58.763Z</updated>
    
    <content type="html"><![CDATA[<p>今年继续参加了极客大挑战，依然记得去年参加的时候只能做出来两三道逆向题目，今年基本上都能解出来了，AI现在确实在逆向方面能起到非常大的帮助，但是还是得把基础打牢</p><p>完整版 Writeup 阅读提示</p><p>由于本文包含大量截图与详细的分析过程，导出为 PDF 后体积高达 40多MB，为了保证您的阅读体验，完整复盘已托管至语雀知识库</p><p><a href="https://www.yuque.com/llllxx-01bqd/vaw2ch/hwm02b10b34wke80?singleDoc#" target="_blank" rel="noopener">点击这里阅读完整版的 《WhaleCalf-校外-9》 CTF WriteUp</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;今年继续参加了极客大挑战，依然记得去年参加的时候只能做出来两三道逆向题目，今年基本上都能解出来了，AI现在确实在逆向方面能起到非常大的帮助，但是还是得把基础打牢&lt;/p&gt;
&lt;p&gt;完整版 Writeup 阅读提示&lt;/p&gt;
&lt;p&gt;由于本文包含大量截图与详细的分析过程，导出为 PD</summary>
      
    
    
    
    <category term="wp" scheme="https://llurry.github.io/categories/wp/"/>
    
    
    <category term="re" scheme="https://llurry.github.io/tags/re/"/>
    
  </entry>
  
  <entry>
    <title>基于 ADB 与 Frida 的大麦 App 自动化抢票研究</title>
    <link href="https://llurry.github.io/2025/10/09/%E5%A4%A7%E9%BA%A6%E8%87%AA%E5%8A%A8%E6%8A%A2%E7%A5%A8/"/>
    <id>https://llurry.github.io/2025/10/09/%E5%A4%A7%E9%BA%A6%E8%87%AA%E5%8A%A8%E6%8A%A2%E7%A5%A8/</id>
    <published>2025-10-09T02:21:12.000Z</published>
    <updated>2026-04-01T13:37:56.798Z</updated>
    
    <content type="html"><![CDATA[<h2 id="项目概述"><a href="#项目概述" class="headerlink" title="项目概述"></a>项目概述</h2><p>EZDM (Easy DaMai) 是一个旨在自动化Android平台上大麦App抢票功能的项目。</p><h2 id="技术栈"><a href="#技术栈" class="headerlink" title="技术栈"></a>技术栈</h2><p>Python: 主编程语言<br>ADB: 用于与 Android 设备通信，执行命令如点击、滑动、截图等。<br>Frida: 动态插桩工具，用于 hook App 的方法</p><h2 id="系统架构"><a href="#系统架构" class="headerlink" title="系统架构"></a>系统架构</h2><p>ADB模块：通过封装adb命令，实现模拟UI交互、获取系统信息等功能<br>Frida模块：使用frida提供的能力获取系统和app信息，hook关键函数和方法<br>通知模块：用于向管理员通知开票时间、抢票结果等信息</p><h2 id="开发计划"><a href="#开发计划" class="headerlink" title="开发计划"></a>开发计划</h2><p>模拟点击方案<br>该方案通过adb操控手机或者模拟器方式，模拟用户抢票的行为实现抢票功能。</p><p>抓包重放方案<br>该方案通过抓取大麦抢票流程的所有数据包进行分析，在抢票时通过脚本发送数据包实现抢票功能。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;项目概述&quot;&gt;&lt;a href=&quot;#项目概述&quot; class=&quot;headerlink&quot; title=&quot;项目概述&quot;&gt;&lt;/a&gt;项目概述&lt;/h2&gt;&lt;p&gt;EZDM (Easy DaMai) 是一个旨在自动化Android平台上大麦App抢票功能的项目。&lt;/p&gt;
&lt;h2 id=&quot;</summary>
      
    
    
    
    <category term="技术" scheme="https://llurry.github.io/categories/%E6%8A%80%E6%9C%AF/"/>
    
    
    <category term="Frida" scheme="https://llurry.github.io/tags/Frida/"/>
    
  </entry>
  
  <entry>
    <title>安卓逆向题目的详细解析</title>
    <link href="https://llurry.github.io/2025/07/28/%E5%AE%89%E5%8D%93%E9%80%86%E5%90%91%E9%A2%98%E7%9B%AE%E7%9A%84wp/"/>
    <id>https://llurry.github.io/2025/07/28/%E5%AE%89%E5%8D%93%E9%80%86%E5%90%91%E9%A2%98%E7%9B%AE%E7%9A%84wp/</id>
    <published>2025-07-28T06:12:11.000Z</published>
    <updated>2026-04-01T13:38:40.085Z</updated>
    
    <content type="html"><![CDATA[<p>在这篇博客中，我将分享我在安卓逆向学习过程中遇到的一道题目，并记录下我的分析思路与解题过程。</p><h2 id="题目一：3-火焰风暴"><a href="#题目一：3-火焰风暴" class="headerlink" title="题目一：3-火焰风暴"></a>题目一：3-火焰风暴</h2><h3 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h3><p>这道题目需要用Frida来强制移动应用程序的一个函数工作来获得密码，然后在strings.xml文件中找到一个Firebase配置，再用密码和电子邮件对firebase数据库进行身份验证</p><p>这里的Password() 方法从 strings.xml 中获取多个字符串资源并对这些字符串进行子串截取并拼接成一个新的字符串。 将拼接后的字符串传递给 native 方法 generateRandomString() 进行处理。最终返回处理后的结果。看了wp后才知道该函数来自本机库“firestorm”。<br><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/jieti/android.png" alt="android.png" data-caption="android.png" loading="lazy"></p><p>在AI的帮助下先写好JS代码，使它强制执行 Password 函数，然后打印该函数的结果。</p><p>脚本<br><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><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 javascript"><span class="hljs-title class_">Java</span>.<span class="hljs-title function_">perform</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">function</span> <span class="hljs-title function_">getPassword</span>(<span class="hljs-params"></span>) &#123;<br>        <span class="hljs-title class_">Java</span>.<span class="hljs-title function_">choose</span>(<span class="hljs-string">&#x27;com.pwnsec.firestorm.MainActivity&#x27;</span>, &#123;<br>            <span class="hljs-attr">onMatch</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">instance</span>) &#123;<br>                <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;MainActivity instance found: &quot;</span> + instance);<br>                <span class="hljs-keyword">try</span> &#123;<br>                    <span class="hljs-keyword">var</span> pass = instance.<span class="hljs-title class_">Password</span>();<br>                    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;FireBase Password: &quot;</span> + pass);<br>                &#125; <span class="hljs-keyword">catch</span> (e) &#123;<br>                    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;Error occurred: &quot;</span> + e);<br>                &#125;<br>            &#125;,<br>            <span class="hljs-attr">onComplete</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) &#123;<br>                <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&quot;Search completed. Exiting script.&quot;</span>);<br><br>            &#125;<br>        &#125;);<br>    &#125;<br><br>    <span class="hljs-comment">// Delay execution to ensure the app is fully started</span><br>    <span class="hljs-built_in">setTimeout</span>(getPassword, <span class="hljs-number">4000</span>); <span class="hljs-comment">// Adjust the delay as needed (4000 ms = 4 seconds)</span><br></code></pre></td></tr></table></figure></p><p>终于搞到密码了，这里我的模拟器有点问题，搞了很久才搞好。<br><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/jieti/password.png" alt="password.png" data-caption="password.png" loading="lazy"></p><p>得到了密码后密码将用于向 Firebase 数据库进行身份验证，firebase 配置可以在“strings.xml”文件中找到。</p><p>找到了firebase 配置和 firebase 电子邮件后现在需要使用电子邮件和密码向 Firebase 数据库进行身份验证。</p><p>得到flag: PWNSEC{C0ngr4ts<em>Th4t_w45_4N_345y_P4$$w 0rd_t0_G3t!!_0R</em>！5_！t???}</p><p>脚本<br><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> pyrebase<br><span class="hljs-keyword">import</span> requests<br><br><br>config = &#123;<br>  <span class="hljs-string">&quot;apiKey&quot;</span>: <span class="hljs-string">&quot;AIzaSyAXsK0qsx4RuLSA9C8IPSWd0eQ67HVHuJY&quot;</span>,<br>  <span class="hljs-string">&quot;authDomain&quot;</span>: <span class="hljs-string">&quot;firestorm-9d3db.firebaseapp.com&quot;</span>,<br>  <span class="hljs-string">&quot;databaseURL&quot;</span>: <span class="hljs-string">&quot;https://firestorm-9d3db-default-rtdb.firebaseio.com&quot;</span>,<br>  <span class="hljs-string">&quot;storageBucket&quot;</span>: <span class="hljs-string">&quot;firestorm-9d3db.appspot.com&quot;</span>,<br>  <span class="hljs-string">&quot;projectId&quot;</span>: <span class="hljs-string">&quot;firestorm-9d3db&quot;</span><br>&#125;<br><br><br>firebase = pyrebase.initialize_app(config)<br><br><br>auth = firebase.auth()<br>email = <span class="hljs-string">&quot;TK757567@pwnsec.xyz&quot;</span><br>password = <span class="hljs-string">&quot;C7_dotpsC7t7f_._In_i.IdttpaofoaIIdIdnndIfC&quot;</span><br>user = auth.sign_in_with_email_and_password(email, password)<br><br>db = firebase.database()<br><br><span class="hljs-built_in">print</span>(db.get(user[<span class="hljs-string">&#x27;idToken&#x27;</span>]).val()) <br></code></pre></td></tr></table></figure></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;在这篇博客中，我将分享我在安卓逆向学习过程中遇到的一道题目，并记录下我的分析思路与解题过程。&lt;/p&gt;
&lt;h2 id=&quot;题目一：3-火焰风暴&quot;&gt;&lt;a href=&quot;#题目一：3-火焰风暴&quot; class=&quot;headerlink&quot; title=&quot;题目一：3-火焰风暴&quot;&gt;&lt;/a&gt;题目</summary>
      
    
    
    
    <category term="Android" scheme="https://llurry.github.io/categories/Android/"/>
    
    
    <category term="CTF" scheme="https://llurry.github.io/tags/CTF/"/>
    
    <category term="逆向工程" scheme="https://llurry.github.io/tags/%E9%80%86%E5%90%91%E5%B7%A5%E7%A8%8B/"/>
    
    <category term="安卓逆向" scheme="https://llurry.github.io/tags/%E5%AE%89%E5%8D%93%E9%80%86%E5%90%91/"/>
    
  </entry>
  
  <entry>
    <title>JQCTF wp</title>
    <link href="https://llurry.github.io/2025/06/04/JQCTF-wp/"/>
    <id>https://llurry.github.io/2025/06/04/JQCTF-wp/</id>
    <published>2025-06-04T03:43:12.000Z</published>
    <updated>2026-03-20T01:40:33.125Z</updated>
    
    <content type="html"><![CDATA[<ul><li><a href="#customize-vm">第一题 Writeup</a></li></ul><h1 id="JQCTF-re复现"><a href="#JQCTF-re复现" class="headerlink" title="JQCTF re复现"></a>JQCTF re复现</h1><h2 id="第一题-writeup-customize-vm"><a href="#第一题-writeup-customize-vm" class="headerlink" title="第一题-writeup-customize-vm"></a>第一题-writeup-customize-vm</h2><p>这个比赛对我来说还是比较难的，re里这道题稍微简单一点，所以先复现了它。</p><p>输入长度50，构造关键逻辑在这里，此处是取输入的字符与一组密文进行异或，func_len中所存的即是每一组密文的长度，而\func_data即是所存储的函数（加密之后的），那么就是一个smc了，input只要能满足正常解密出所有的函数逻辑即可<br><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/jieti/example.png" alt="example.png" data-caption="example.png" loading="lazy"></p><p>使用解密出的函数做后面的约束<br><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/jieti/re.png" alt="re.png" data-caption="re.png" loading="lazy"><br>然后这里有点卡了，看了别人的wp后才懂了，只要能fuzz出那个满足正常异或出函数逻辑的输入即可，单字节的一个爆破，翻看一下待解密的模块，找到一点小技巧，0异或一个字节是那个字节本身，那么正确的字节是0的话异或目标字节就会是那个字节，就像下面这块，有连续的z出现，那么目标字节大概率就是z。</p><p>输入z之后修一下，成功修复，找一下规律，每个函数最后的retn就是最好的标志<br><img onerror="imgOnError(this);" data-fancybox="gallery" src="/images/jieti/ree.jpg" alt="ree.jpg" data-caption="ree.jpg" loading="lazy"></p><p>写个脚本fuzz一下，retn对应的字节码是c3,手动替换一下bytes_array。</p><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><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># 定义字节数组</span><br>bytes_array = [<br>    <span class="hljs-number">0x90</span>, <span class="hljs-number">0xFB</span>, <span class="hljs-number">0xF1</span>, <span class="hljs-number">0x17</span>, <span class="hljs-number">0x89</span>, <span class="hljs-number">0x89</span>, <span class="hljs-number">0x89</span>, <span class="hljs-number">0xF5</span>, <span class="hljs-number">0x86</span>, <span class="hljs-number">0x7D</span>,<br>    <span class="hljs-number">0xF5</span>, <span class="hljs-number">0xB6</span>, <span class="hljs-number">0x73</span>, <span class="hljs-number">0xB5</span><br>]<br><br><span class="hljs-comment"># 获取最后一个字节并与目标值进行异或运算</span><br>last_byte = bytes_array[-<span class="hljs-number">1</span>]<br>target = <span class="hljs-number">0xC3</span><br>xor_char = last_byte ^ target<br><br><span class="hljs-comment"># 检查计算结果是否在 [0-9], [a-z], _ 范围内</span><br>is_number = (<span class="hljs-number">48</span> &lt;= xor_char &lt;= <span class="hljs-number">57</span>)<br>is_lowercase = (<span class="hljs-number">97</span> &lt;= xor_char &lt;= <span class="hljs-number">122</span>)<br>is_underscore = (xor_char == <span class="hljs-number">95</span>)<br><br><span class="hljs-keyword">if</span> is_number <span class="hljs-keyword">or</span> is_lowercase <span class="hljs-keyword">or</span> is_underscore:<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;找到的异或字符: &#x27;<span class="hljs-subst">&#123;<span class="hljs-built_in">chr</span>(xor_char)&#125;</span>&#x27;&quot;</span>)<br><span class="hljs-keyword">else</span>:<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;没有找到符合条件的异或字符。&quot;</span>)<br></code></pre></td></tr></table></figure><p>跳转测试<br><a href="#第一题-writeup-customize-vm">第一题</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#customize-vm&quot;&gt;第一题 Writeup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;JQCTF-re复现&quot;&gt;&lt;a href=&quot;#JQCTF-re复现&quot; class=&quot;headerlink&quot; title=&quot;JQCTF re复现&quot;&gt;</summary>
      
    
    
    
    <category term="wp" scheme="https://llurry.github.io/categories/wp/"/>
    
    
    <category term="re" scheme="https://llurry.github.io/tags/re/"/>
    
  </entry>
  
</feed>
