<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://cryingn.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://cryingn.github.io/" rel="alternate" type="text/html" /><updated>2026-03-16T10:22:24+08:00</updated><id>https://cryingn.github.io/feed.xml</id><title type="html">个人主页</title><subtitle>早安, 晚安, 谢谢, 再见.</subtitle><author><name>CryingN</name><email>CryingNights7v@gmail.com</email></author><entry><title type="html">[阶段性总结] Crypto个人出题经历整理</title><link href="https://cryingn.github.io/posts/2026/03/crypto_experience/" rel="alternate" type="text/html" title="[阶段性总结] Crypto个人出题经历整理" /><published>2026-03-16T00:00:00+08:00</published><updated>2026-03-16T00:00:00+08:00</updated><id>https://cryingn.github.io/posts/2026/03/crypto_experience</id><content type="html" xml:base="https://cryingn.github.io/posts/2026/03/crypto_experience/"><![CDATA[<h1 id="目录">目录</h1>

<ul>
  <li><a href="#前言">前言</a></li>
  <li><a href="#basectf2024">basectf2024</a>
    <ul>
      <li><a href="#mid_math-basectf2024">mid_math</a></li>
    </ul>
  </li>
  <li><a href="#litctf2025">litctf2025</a>
    <ul>
      <li><a href="#ez_math">ez_math</a></li>
    </ul>
  </li>
  <li><a href="#lilctf2025">lilctf2025</a>
    <ul>
      <li><a href="#ez_math-lilctf2025">ez_math</a></li>
    </ul>
  </li>
  <li><a href="#mcctf">mcctf</a>
    <ul>
      <li><a href="#ez_lattice">ez_lattice</a></li>
    </ul>
  </li>
  <li><a href="#tpcup2026">tpcup2026</a>
    <ul>
      <li><a href="#clairautdh-revenge">clairautdh-revenge</a></li>
    </ul>
  </li>
</ul>

<h1 id="前言">前言</h1>

<p>AI时代确实很不适应，加上本身就菜，做不到像其他师傅那样可以抗着AI强度出大家都解决不了的0解题，简单总结一下自己一直以来在密码题上面的贡献，感觉也该找找新的地方做事了。</p>

<p>我很喜欢ctf这种特别的学习模式，不同于教科书一个原理接一个原理的死板学习法，通过实际调试代码能够快速掌握到相关知识点。因为没有人带着学习，自己打了很长一段时间的ctftime那种全国性质的赛事，大部分都是用ctfd起一个简单平台，题目也是线性提升，即使什么都不懂也能快速融入ctf成为不爆0的选手。</p>

<p>其中我很喜欢一类题目：整体处理得干净明了，没有太多前置知识，考点也不复杂化（俗称套娃），选手一眼能看出考点，然后学习并解出，看到选手们根据题目一点一点对上思路，然后解出对于我来说会感觉很欣慰（？），不过后期的AI时代大家不需要理解原理就能解出，甚至是wp也用AI自动生成，也许从这个时候开始对于我来说ctf的意义已经被AI吞噬干净了吧。</p>

<h1 id="basectf2024">basectf2024</h1>

<p>BaseCTF应该是我自认为开始比较有代表性的出题经历，前面像tpcup、vyctf等比赛只是单纯引用一些以前学到的题目，当时出了ez_math、mid_math、hard_math，这些算是开始按照自己的理解在出题, 其中hard_math基于LLL原理进行了简单的延伸，主要只是展示一下mid_math的出题思路，出题思路源于代数中的<strong>行列式</strong>:</p>

<h2 id="mid_math-basectf2024">mid_math-basectf2024</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="o">*</span>

<span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="p">[</span><span class="n">getPrime</span><span class="p">(</span><span class="mi">128</span><span class="p">)</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">4</span><span class="p">)]</span>
<span class="n">point1</span> <span class="o">=</span> <span class="n">a</span> <span class="o">*</span> <span class="n">d</span>
<span class="n">point2</span> <span class="o">=</span> <span class="n">b</span> <span class="o">*</span> <span class="n">c</span>
<span class="n">matrix2</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">0</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">d</span><span class="p">]]</span>

<span class="n">flag</span> <span class="o">=</span> <span class="sa">b</span><span class="s">"flag{test_flag}"</span>
<span class="n">flag</span> <span class="o">=</span> <span class="n">bytes_to_long</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">randomArray</span><span class="p">():</span>
    <span class="n">upper</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">]]</span>
    <span class="n">low</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">]]</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">):</span>
            <span class="n">upper</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">128</span><span class="p">)</span>
            <span class="n">low</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">128</span><span class="p">)</span>

    <span class="n">result</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">(</span><span class="n">upper</span><span class="p">)</span> <span class="o">@</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">(</span><span class="n">low</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">result</span>

<span class="n">A</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">array</span><span class="p">([[</span><span class="n">flag</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]]</span> <span class="o">+</span> <span class="n">matrix2</span><span class="p">)</span>
<span class="n">B</span> <span class="o">=</span> <span class="n">randomArray</span><span class="p">()</span>
<span class="n">C</span> <span class="o">=</span> <span class="n">randomArray</span><span class="p">()</span>
<span class="n">MAT</span> <span class="o">=</span>  <span class="n">C</span> <span class="o">@</span> <span class="n">A</span> <span class="o">@</span> <span class="n">B</span>


<span class="k">print</span><span class="p">(</span><span class="n">point1</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">point2</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">MAT</span><span class="p">)</span>

<span class="s">'''
65540596822333029826884315503808996273733737079814345540607878287618419734231
45151244176940366132774311848077675849486332018843894072137609985463616792271
[[9259505595451159514948336330303511539525155092949382077995385373332083424570340733825203563332256599256361679775371565817159463557158551820090084800254999338417057682355404780422980119717238594927467956675771042145306399815569005775907169857728757334979422594358
  3700462282298785820527479428312072678870010244861115107206951164684911761755437333209293039456840068340334559453608012512177623936248784897843503284633804083281388001236742261832974291349480314135560368365574114042082002559069958228523318326290833422846224288247
  20791012146351643571145217310876690226642338279942557085580439219377325884045305279931904540467264182713135410067252835618936836675270813727053937054168296298149405902638242278868020381541490973458957704137657413376043351193]
 [3802535350808074374431476757195874789213113083310705049856269457737583463559458126494122484246497049005001474007088865512110432486291568737501434666990689483191924384489484665070592656641925905986397402822195880143437724155134584374613878027218950975919679551229
  1519642544380087919293814751485424198320747098741960781639133554268321708273309194651985562222274023623071346914239982055028526526058064787882720065775210796950963778381575914964024929110539407721461321785325399699126116201001806816030960662346173275101476487421
  8538097185709421082644083672229287227818939415260987123718318427750267353075860559170390896769087600458156859498331152566368881938040799840806164389020986990994328370205184734637870147251004626759120887684269603636183629300]
 [17987668490992083132878642797176089621188858356259455169173987325310681186627844776077058221612169421636403546746899152917309634315569997105261046388995579843528014810244648968375990949478033964619008761814039733347955609163
  7188579142941521685422767412932555782658469950638690886255638896617687421517941457682493542615460990114218059246938237257830976937359020731335958068934235967457123039874441635435388736524907036941379695243043923900290273902
  40388963560266769813551191613694768219344365780650048155838802242681775019274045964917142477325170274191702615504062392461666558731638338001971723737440974198823443420018559746335727687]]
'''</span>
</code></pre></div></div>

<p>已知存在一个矩阵A:</p>

\[A=\begin{bmatrix} flag &amp; 0 &amp; 0 \\ 0 &amp; a &amp; b \\ 0 &amp; c &amp; d \end{bmatrix}\]

<p>其中 a, b, c, d 为随机数, 我们明显可以将其看作一个分块矩阵:</p>

\[A=\begin{bmatrix} flag &amp; 0 \\ 0 &amp; A_{abcd} \end{bmatrix}, \\ A_{abcd}=\begin{bmatrix} a &amp; b \\ c &amp; d \end{bmatrix}\]

<p>即对A求行列式有:</p>

\[|A|=|flag|*|A_{abcd}|\]

<p>对于二阶矩阵我们可以计算:</p>

\[|A_{abcd}|=a*d-b*c\]

<p>其中已给出point1, point2, 我们可以计算出矩阵B、C的行列式, 即只需要知道矩阵的行列式即可求出flag, 对于矩阵B有:</p>

\[B = B_{upper} * B_{low} , C = C_{upper} * C_{low}\]

<p>其中upper为主对角线为1的上三角矩阵, low为主对角线为1的下三角矩阵, 易得知:</p>

\[|B|=1 , |C|=1\]

<p>又有:</p>

\[MAT = C * A * B\]

<p>故有:</p>

\[|MAT| = |A|\]

<p>我们可以通过以下方式计算flag:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">point1</span> <span class="o">=</span> <span class="mi">65540596822333029826884315503808996273733737079814345540607878287618419734231</span>
<span class="n">point2</span> <span class="o">=</span> <span class="mi">45151244176940366132774311848077675849486332018843894072137609985463616792271</span>

<span class="n">MAT</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">9259505595451159514948336330303511539525155092949382077995385373332083424570340733825203563332256599256361679775371565817159463557158551820090084800254999338417057682355404780422980119717238594927467956675771042145306399815569005775907169857728757334979422594358</span><span class="p">,</span>
  <span class="mi">3700462282298785820527479428312072678870010244861115107206951164684911761755437333209293039456840068340334559453608012512177623936248784897843503284633804083281388001236742261832974291349480314135560368365574114042082002559069958228523318326290833422846224288247</span><span class="p">,</span>
  <span class="mi">20791012146351643571145217310876690226642338279942557085580439219377325884045305279931904540467264182713135410067252835618936836675270813727053937054168296298149405902638242278868020381541490973458957704137657413376043351193</span><span class="p">],</span>
 <span class="p">[</span><span class="mi">3802535350808074374431476757195874789213113083310705049856269457737583463559458126494122484246497049005001474007088865512110432486291568737501434666990689483191924384489484665070592656641925905986397402822195880143437724155134584374613878027218950975919679551229</span><span class="p">,</span>
  <span class="mi">1519642544380087919293814751485424198320747098741960781639133554268321708273309194651985562222274023623071346914239982055028526526058064787882720065775210796950963778381575914964024929110539407721461321785325399699126116201001806816030960662346173275101476487421</span><span class="p">,</span>
  <span class="mi">8538097185709421082644083672229287227818939415260987123718318427750267353075860559170390896769087600458156859498331152566368881938040799840806164389020986990994328370205184734637870147251004626759120887684269603636183629300</span><span class="p">],</span>
 <span class="p">[</span><span class="mi">17987668490992083132878642797176089621188858356259455169173987325310681186627844776077058221612169421636403546746899152917309634315569997105261046388995579843528014810244648968375990949478033964619008761814039733347955609163</span><span class="p">,</span>
  <span class="mi">7188579142941521685422767412932555782658469950638690886255638896617687421517941457682493542615460990114218059246938237257830976937359020731335958068934235967457123039874441635435388736524907036941379695243043923900290273902</span><span class="p">,</span>
  <span class="mi">40388963560266769813551191613694768219344365780650048155838802242681775019274045964917142477325170274191702615504062392461666558731638338001971723737440974198823443420018559746335727687</span><span class="p">]]</span>
<span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="o">*</span>
<span class="k">print</span><span class="p">(</span><span class="n">long_to_bytes</span><span class="p">(</span><span class="n">det</span><span class="p">(</span><span class="n">matrix</span><span class="p">(</span><span class="n">MAT</span><span class="p">))</span> <span class="o">//</span> <span class="p">(</span><span class="n">point1</span> <span class="o">-</span> <span class="n">point2</span><span class="p">)))</span>

<span class="c1"># b'BaseCTF{E439646E-1768-18B3-DC4B-483C40C5340C}'
</span></code></pre></div></div>

<h1 id="litctf2025">litctf2025</h1>

<p>这场比赛时当时生活正面临着极大的困境，出题思路阻塞严重，庆幸的是自己对密码算法不再是只能简单使用了，当时出了ez_math, new_bag两题，ez_math基于rsa原理将数扩展到了矩阵，new_bag则是一个简单的背包问题，我想考察<strong>BKZ的基本应用</strong>，不过读的论文太早了，自己在限制的时候也限制得比较小，大家采用了各种不同解法完成题目，让我也学习到了好多新的知识，主要只简单举一下ez_math：</p>

<h2 id="ez_math">ez_math</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">uuid</span> <span class="kn">import</span> <span class="n">uuid4</span>

<span class="n">flag</span> <span class="o">=</span> <span class="sa">b</span><span class="s">'LitCTF{'</span><span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid4</span><span class="p">()).</span><span class="n">encode</span><span class="p">()</span> <span class="o">+</span> <span class="sa">b</span><span class="s">'}'</span>
<span class="n">flag</span> <span class="o">=</span> <span class="n">bytes_to_long</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span>
<span class="n">len_flag</span> <span class="o">=</span> <span class="n">flag</span><span class="p">.</span><span class="n">bit_length</span><span class="p">()</span>
<span class="n">e</span> <span class="o">=</span> <span class="mi">65537</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">512</span><span class="p">)</span>
<span class="n">P</span> <span class="o">=</span> <span class="n">GF</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
<span class="n">A</span> <span class="o">=</span> <span class="p">[[</span><span class="n">flag</span><span class="p">,</span>                 <span class="n">getPrime</span><span class="p">(</span><span class="n">len_flag</span><span class="p">)],</span>
     <span class="p">[</span><span class="n">getPrime</span><span class="p">(</span><span class="n">len_flag</span><span class="p">),</span>   <span class="n">getPrime</span><span class="p">(</span><span class="n">len_flag</span><span class="p">)]]</span>
<span class="n">A</span> <span class="o">=</span> <span class="n">matrix</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">A</span><span class="p">)</span>
<span class="n">B</span> <span class="o">=</span> <span class="n">A</span> <span class="o">**</span> <span class="n">e</span>

<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"e = </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"p = </span><span class="si">{</span><span class="n">p</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"B = </span><span class="si">{</span><span class="nb">list</span><span class="p">(</span><span class="n">B</span><span class="p">)</span><span class="si">}</span><span class="s">"</span><span class="p">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'('</span><span class="p">,</span> <span class="s">'['</span><span class="p">).</span><span class="n">replace</span><span class="p">(</span><span class="s">')'</span><span class="p">,</span> <span class="s">']'</span><span class="p">))</span>

<span class="c1"># e = 65537
# p = 8147594556101158967571180945694180896742294483544853070485096002084187305007965554901340220135102394516080775084644243545680089670612459698730714507241869
# B = [[2155477851953408309667286450183162647077775173298899672730310990871751073331268840697064969968224381692698267285466913831393859280698670494293432275120170, 4113196339199671283644050914377933292797783829068402678379946926727565560805246629977929420627263995348168282358929186302526949449679561299204123214741547], [3652128051559825585352835887172797117251184204957364197630337114276860638429451378581133662832585442502338145987792778148110514594776496633267082169998598, 2475627430652911131017666156879485088601207383028954405788583206976605890994185119936790889665919339591067412273564551745588770370229650653217822472440992]]
</span></code></pre></div></div>

<p>rsa使用p,q计算n作为公钥，这里将p直接当作n使用，2×2 矩阵下的群会进化为一般线性群,有</p>

\[|GL(2,p)|=(p^2−1)(p^2−p)\]

<p>可以直接计算：</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="o">*</span>

<span class="n">e</span> <span class="o">=</span> <span class="mi">65537</span>
<span class="n">p</span> <span class="o">=</span> <span class="mi">8147594556101158967571180945694180896742294483544853070485096002084187305007965554901340220135102394516080775084644243545680089670612459698730714507241869</span>
<span class="n">B</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">2155477851953408309667286450183162647077775173298899672730310990871751073331268840697064969968224381692698267285466913831393859280698670494293432275120170</span><span class="p">,</span> <span class="mi">4113196339199671283644050914377933292797783829068402678379946926727565560805246629977929420627263995348168282358929186302526949449679561299204123214741547</span><span class="p">],</span> <span class="p">[</span><span class="mi">3652128051559825585352835887172797117251184204957364197630337114276860638429451378581133662832585442502338145987792778148110514594776496633267082169998598</span><span class="p">,</span> <span class="mi">2475627430652911131017666156879485088601207383028954405788583206976605890994185119936790889665919339591067412273564551745588770370229650653217822472440992</span><span class="p">]]</span>
<span class="n">phi</span><span class="o">=</span> <span class="p">(</span><span class="n">p</span><span class="o">**</span><span class="mi">2</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">p</span><span class="o">**</span><span class="mi">2</span><span class="o">-</span><span class="n">p</span><span class="p">)</span>
<span class="n">d</span><span class="o">=</span><span class="n">inverse</span><span class="p">(</span><span class="n">e</span><span class="p">,</span><span class="n">phi</span><span class="p">)</span>
<span class="n">P</span> <span class="o">=</span> <span class="n">GF</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>

<span class="n">B</span> <span class="o">=</span> <span class="n">matrix</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">B</span><span class="p">)</span>
<span class="n">B</span> <span class="o">=</span><span class="n">B</span> <span class="o">**</span><span class="n">d</span>
<span class="k">print</span><span class="p">(</span><span class="n">long_to_bytes</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">B</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">])))</span>

<span class="c1">#b'LitCTF{13dd217e-9a67-4093-8a1b-d2592c45ba82}'
</span></code></pre></div></div>

<p>考虑到叫ez_math，当时留了个口，即使只知道rsa也是可以通过p-1做出来的，因为(p^2-1)=(p+1)(p-1), 选择参数时直接选在了(p-1)上。</p>

<h1 id="lilctf2025">lilctf2025</h1>

<p>这次出题差不多完成了自己一直以来的想法，共计ez_math，mid_math两题，同样的思路在ez_math中强调代数中的<strong>特征向量</strong>，然后将mid_math作为主要考题。</p>

<h2 id="mid_math-lilctf2025">mid_math-lilctf2025</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">tqdm</span> <span class="kn">import</span> <span class="n">tqdm</span>
<span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="n">randint</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.Padding</span> <span class="kn">import</span> <span class="n">pad</span>

<span class="n">flag</span> <span class="o">=</span> <span class="sa">b</span><span class="s">'LILCTF{test_flag}'</span>

<span class="n">p</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">)</span>
<span class="n">P</span> <span class="o">=</span> <span class="n">GF</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>

<span class="n">key</span> <span class="o">=</span> <span class="n">randint</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">62</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">mul</span><span class="p">(</span><span class="n">vector</span><span class="p">,</span> <span class="n">c</span><span class="p">):</span>
    <span class="k">return</span> <span class="p">[</span><span class="n">vector</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">*</span><span class="n">c</span><span class="p">,</span> <span class="n">vector</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">*</span><span class="n">c</span><span class="p">,</span> <span class="n">vector</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">*</span><span class="n">c</span><span class="p">,</span> <span class="n">vector</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span><span class="o">*</span><span class="n">c</span><span class="p">,</span> <span class="n">vector</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span><span class="o">*</span><span class="n">c</span><span class="p">]</span>

<span class="n">v1</span> <span class="o">=</span> <span class="p">[</span><span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">)]</span>
<span class="n">v2</span> <span class="o">=</span> <span class="p">[</span><span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">)]</span>
<span class="n">v3</span> <span class="o">=</span> <span class="p">[</span><span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">)]</span>
<span class="n">v4</span> <span class="o">=</span> <span class="p">[</span><span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">)]</span>
<span class="n">v5</span> <span class="o">=</span> <span class="p">[</span><span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">)]</span>
<span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">64</span><span class="p">),</span>  <span class="mi">0</span>

<span class="n">A</span> <span class="o">=</span> <span class="n">matrix</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="p">[</span><span class="n">v1</span><span class="p">,</span> <span class="n">v2</span><span class="p">,</span> <span class="n">v3</span><span class="p">,</span> <span class="n">v4</span><span class="p">,</span> <span class="n">v5</span><span class="p">])</span>
<span class="n">B</span> <span class="o">=</span> <span class="n">matrix</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="p">[</span><span class="n">mul</span><span class="p">(</span><span class="n">v1</span><span class="p">,</span><span class="n">a</span><span class="p">),</span> <span class="n">mul</span><span class="p">(</span><span class="n">v2</span><span class="p">,</span><span class="n">b</span><span class="p">),</span> <span class="n">mul</span><span class="p">(</span><span class="n">v3</span><span class="p">,</span> <span class="n">c</span><span class="p">),</span> <span class="n">mul</span><span class="p">(</span><span class="n">v4</span><span class="p">,</span> <span class="n">d</span><span class="p">),</span> <span class="n">mul</span><span class="p">(</span><span class="n">v5</span><span class="p">,</span> <span class="n">e</span><span class="p">)])</span>
<span class="n">C</span> <span class="o">=</span> <span class="n">A</span><span class="p">.</span><span class="n">inverse</span><span class="p">()</span> <span class="o">*</span> <span class="n">B</span>
<span class="n">D</span> <span class="o">=</span> <span class="n">C</span><span class="o">**</span><span class="n">key</span>

<span class="n">key</span> <span class="o">=</span> <span class="n">pad</span><span class="p">(</span><span class="n">long_to_bytes</span><span class="p">(</span><span class="n">key</span><span class="p">),</span> <span class="mi">16</span><span class="p">)</span>
<span class="n">aes</span> <span class="o">=</span> <span class="n">AES</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="n">key</span><span class="p">,</span><span class="n">AES</span><span class="p">.</span><span class="n">MODE_ECB</span><span class="p">)</span>
<span class="n">msg</span> <span class="o">=</span> <span class="n">aes</span><span class="p">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">pad</span><span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="mi">64</span><span class="p">))</span>

<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"p = </span><span class="si">{</span><span class="n">p</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'C = </span><span class="si">{</span><span class="p">[</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">C</span><span class="p">]</span><span class="si">}</span><span class="s">'</span><span class="p">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'('</span><span class="p">,</span> <span class="s">'['</span><span class="p">).</span><span class="n">replace</span><span class="p">(</span><span class="s">')'</span><span class="p">,</span> <span class="s">']'</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'D = </span><span class="si">{</span><span class="p">[</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">D</span><span class="p">]</span><span class="si">}</span><span class="s">'</span><span class="p">.</span><span class="n">replace</span><span class="p">(</span><span class="s">'('</span><span class="p">,</span> <span class="s">'['</span><span class="p">).</span><span class="n">replace</span><span class="p">(</span><span class="s">')'</span><span class="p">,</span> <span class="s">']'</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"msg = </span><span class="si">{</span><span class="n">msg</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

<span class="c1">#p = 14668080038311483271
#C = [[11315841881544731102, 2283439871732792326, 6800685968958241983, 6426158106328779372, 9681186993951502212], [4729583429936371197, 9934441408437898498, 12454838789798706101, 1137624354220162514, 8961427323294527914], [12212265161975165517, 8264257544674837561, 10531819068765930248, 4088354401871232602, 14653951889442072670], [6045978019175462652, 11202714988272207073, 13562937263226951112, 6648446245634067896, 13902820281072641413], [1046075193917103481, 3617988773170202613, 3590111338369894405, 2646640112163975771, 5966864698750134707]]
#D = [[1785348659555163021, 3612773974290420260, 8587341808081935796, 4393730037042586815, 10490463205723658044], [10457678631610076741, 1645527195687648140, 13013316081830726847, 12925223531522879912, 5478687620744215372], [9878636900393157276, 13274969755872629366, 3231582918568068174, 7045188483430589163, 5126509884591016427], [4914941908205759200, 7480989013464904670, 5860406622199128154, 8016615177615097542, 13266674393818320551], [3005316032591310201, 6624508725257625760, 7972954954270186094, 5331046349070112118, 6127026494304272395]]
#msg = b"\xcc]B:\xe8\xbc\x91\xe2\x93\xaa\x88\x17\xc4\xe5\x97\x87@\x0fd\xb5p\x81\x1e\x98,Z\xe1n`\xaf\xe0%:\xb7\x8aD\x03\xd2Wu5\xcd\xc4#m'\xa7\xa4\x80\x0b\xf7\xda8\x1b\x82k#\xc1gP\xbd/\xb5j"
</span></code></pre></div></div>

<p>特征向量对于我来说一直很具有诱惑性，不同于特征值，通过特征向量降低矩阵幂运算是代数中一个有效的应用方式，题目本质上提供了一个模p下的5x5随机矩阵A,1x5随机向量e，B=A*e, 现在构造A到B的变换C,有D=C^key, 需要求key用于解出flag。</p>

\[A*C=A*e=B\]

<p>可以看出本题是一个简单的离散对数问题，只是扩展到矩阵上，一般情况下直接求key的话算力开销很高，因为A到B的变换C进行了降维，无法求取行列式直接求离散对数拿到结果，但是我们可以反过来思考，变换C的本质是B=A<em>e，可以对角化，理论上试图求C</em>C, 我们可以通过变换转换为</p>

\[PAP^(-1)=C\]

<p>再计算</p>

\[D=PA*e*eP^(-1)\]

<p>参考以上思路，我们可以通过特征向量重新构建一组矩阵，对角化基下，原矩阵幂运算</p>

\[D=C^{key}\]

<p>被简化为各特征值的标量幂运算：</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.Padding</span> <span class="kn">import</span> <span class="n">pad</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="kn">from</span> <span class="nn">tqdm</span> <span class="kn">import</span> <span class="n">tqdm</span>

<span class="n">p</span> <span class="o">=</span> <span class="mi">14668080038311483271</span>
<span class="n">C</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">11315841881544731102</span><span class="p">,</span> <span class="mi">2283439871732792326</span><span class="p">,</span> <span class="mi">6800685968958241983</span><span class="p">,</span> <span class="mi">6426158106328779372</span><span class="p">,</span> <span class="mi">9681186993951502212</span><span class="p">],</span> <span class="p">[</span><span class="mi">4729583429936371197</span><span class="p">,</span> <span class="mi">9934441408437898498</span><span class="p">,</span> <span class="mi">12454838789798706101</span><span class="p">,</span> <span class="mi">1137624354220162514</span><span class="p">,</span> <span class="mi">8961427323294527914</span><span class="p">],</span> <span class="p">[</span><span class="mi">12212265161975165517</span><span class="p">,</span> <span class="mi">8264257544674837561</span><span class="p">,</span> <span class="mi">10531819068765930248</span><span class="p">,</span> <span class="mi">4088354401871232602</span><span class="p">,</span> <span class="mi">14653951889442072670</span><span class="p">],</span> <span class="p">[</span><span class="mi">6045978019175462652</span><span class="p">,</span> <span class="mi">11202714988272207073</span><span class="p">,</span> <span class="mi">13562937263226951112</span><span class="p">,</span> <span class="mi">6648446245634067896</span><span class="p">,</span> <span class="mi">13902820281072641413</span><span class="p">],</span> <span class="p">[</span><span class="mi">1046075193917103481</span><span class="p">,</span> <span class="mi">3617988773170202613</span><span class="p">,</span> <span class="mi">3590111338369894405</span><span class="p">,</span> <span class="mi">2646640112163975771</span><span class="p">,</span> <span class="mi">5966864698750134707</span><span class="p">]]</span>
<span class="n">D</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">1785348659555163021</span><span class="p">,</span> <span class="mi">3612773974290420260</span><span class="p">,</span> <span class="mi">8587341808081935796</span><span class="p">,</span> <span class="mi">4393730037042586815</span><span class="p">,</span> <span class="mi">10490463205723658044</span><span class="p">],</span> <span class="p">[</span><span class="mi">10457678631610076741</span><span class="p">,</span> <span class="mi">1645527195687648140</span><span class="p">,</span> <span class="mi">13013316081830726847</span><span class="p">,</span> <span class="mi">12925223531522879912</span><span class="p">,</span> <span class="mi">5478687620744215372</span><span class="p">],</span> <span class="p">[</span><span class="mi">9878636900393157276</span><span class="p">,</span> <span class="mi">13274969755872629366</span><span class="p">,</span> <span class="mi">3231582918568068174</span><span class="p">,</span> <span class="mi">7045188483430589163</span><span class="p">,</span> <span class="mi">5126509884591016427</span><span class="p">],</span> <span class="p">[</span><span class="mi">4914941908205759200</span><span class="p">,</span> <span class="mi">7480989013464904670</span><span class="p">,</span> <span class="mi">5860406622199128154</span><span class="p">,</span> <span class="mi">8016615177615097542</span><span class="p">,</span> <span class="mi">13266674393818320551</span><span class="p">],</span> <span class="p">[</span><span class="mi">3005316032591310201</span><span class="p">,</span> <span class="mi">6624508725257625760</span><span class="p">,</span> <span class="mi">7972954954270186094</span><span class="p">,</span> <span class="mi">5331046349070112118</span><span class="p">,</span> <span class="mi">6127026494304272395</span><span class="p">]]</span>
<span class="n">msg</span> <span class="o">=</span> <span class="sa">b</span><span class="s">"</span><span class="se">\xcc</span><span class="s">]B:</span><span class="se">\xe8\xbc\x91\xe2\x93\xaa\x88\x17\xc4\xe5\x97\x87</span><span class="s">@</span><span class="se">\x0f</span><span class="s">d</span><span class="se">\xb5</span><span class="s">p</span><span class="se">\x81\x1e\x98</span><span class="s">,Z</span><span class="se">\xe1</span><span class="s">n`</span><span class="se">\xaf\xe0</span><span class="s">%:</span><span class="se">\xb7\x8a</span><span class="s">D</span><span class="se">\x03\xd2</span><span class="s">Wu5</span><span class="se">\xcd\xc4</span><span class="s">#m'</span><span class="se">\xa7\xa4\x80\x0b\xf7\xda</span><span class="s">8</span><span class="se">\x1b\x82</span><span class="s">k#</span><span class="se">\xc1</span><span class="s">gP</span><span class="se">\xbd</span><span class="s">/</span><span class="se">\xb5</span><span class="s">j"</span>

<span class="n">P</span> <span class="o">=</span> <span class="n">GF</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
<span class="n">C</span> <span class="o">=</span> <span class="n">matrix</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">C</span><span class="p">)</span>
<span class="n">D</span> <span class="o">=</span> <span class="n">matrix</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>

<span class="n">C_eigen</span> <span class="o">=</span> <span class="n">matrix</span><span class="p">(</span><span class="n">GF</span><span class="p">(</span><span class="n">p</span><span class="p">),</span> <span class="p">[</span><span class="n">vector</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="k">for</span> <span class="n">eig</span><span class="p">,</span> <span class="n">vecs</span><span class="p">,</span> <span class="n">alg_mult</span> <span class="ow">in</span> <span class="n">C</span><span class="p">.</span><span class="n">eigenvectors_left</span><span class="p">()</span> <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">vecs</span><span class="p">])</span>
<span class="n">C_Basis</span> <span class="o">=</span> <span class="n">C_eigen</span><span class="o">*</span><span class="n">C</span><span class="o">*</span><span class="n">C_eigen</span><span class="p">.</span><span class="n">inverse</span><span class="p">()</span>
<span class="n">D_Basis</span> <span class="o">=</span> <span class="n">C_eigen</span><span class="o">*</span><span class="n">D</span><span class="o">*</span><span class="n">C_eigen</span><span class="p">.</span><span class="n">inverse</span><span class="p">()</span>

<span class="n">n</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">m</span> <span class="o">=</span> <span class="p">[]</span>

<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">tqdm</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">)):</span>
    <span class="k">if</span> <span class="n">D_Basis</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">i</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">C_Basis</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">i</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">m_flag</span> <span class="o">=</span> <span class="n">discrete_log</span><span class="p">(</span><span class="n">P</span><span class="p">(</span><span class="n">D_Basis</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">i</span><span class="p">]),</span> <span class="n">P</span><span class="p">(</span><span class="n">C_Basis</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">i</span><span class="p">]))</span>
        <span class="n">m</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">m_flag</span><span class="p">)</span>
        <span class="n">n_order</span> <span class="o">=</span> <span class="n">P</span><span class="p">(</span><span class="n">C_Basis</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">i</span><span class="p">]).</span><span class="n">multiplicative_order</span><span class="p">()</span>
        <span class="n">n</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">n_order</span><span class="p">)</span>

<span class="n">key</span> <span class="o">=</span> <span class="n">crt</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>

<span class="n">key</span> <span class="o">=</span> <span class="n">pad</span><span class="p">(</span><span class="n">long_to_bytes</span><span class="p">(</span><span class="n">key</span><span class="p">),</span> <span class="mi">16</span><span class="p">)</span>
<span class="n">aes</span> <span class="o">=</span> <span class="n">AES</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="n">key</span><span class="p">,</span><span class="n">AES</span><span class="p">.</span><span class="n">MODE_ECB</span><span class="p">)</span>
<span class="n">flag</span> <span class="o">=</span> <span class="n">aes</span><span class="p">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span>

<span class="c1"># b'LILCTF{Are_y0u_5till_4wake_que5t1on_m4ker!}\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15'
</span></code></pre></div></div>

<h1 id="mcctf">mcctf</h1>

<p>当时我记得好像出了一个ez_adic和ez_lattice，有点忘记了当时为什么没有上ez_padic的题目，当时同时在赶几个比赛，时间比较紧凑，ez_adic简单考了<strong>p进数</strong>，可以通过中国剩余定理直接求出，ez_lattice算是问题比较大的一题，所以重新整理了一类题目，不过当时出现了一些严重的非预期，不需要LLL即可得到flag。</p>

<h2 id="ez_lattice">ez_lattice</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">uuid</span> <span class="kn">import</span> <span class="n">uuid4</span>

<span class="n">_flag</span> <span class="o">=</span> <span class="sa">b</span><span class="s">'mcctf{'</span><span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid4</span><span class="p">()).</span><span class="n">encode</span><span class="p">()</span> <span class="o">+</span> <span class="sa">b</span><span class="s">'}'</span>
<span class="n">v</span> <span class="o">=</span> <span class="mi">10</span>
<span class="n">len_flag</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">_flag</span><span class="p">)</span><span class="o">//</span><span class="n">v</span>
<span class="n">flag</span> <span class="o">=</span> <span class="p">[</span><span class="n">bytes_to_long</span><span class="p">(</span> <span class="n">_flag</span><span class="p">[</span><span class="n">len_flag</span><span class="o">*</span><span class="n">i</span><span class="p">:</span><span class="n">len_flag</span><span class="o">*</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)]</span> <span class="k">if</span> <span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="o">&lt;</span><span class="n">v</span> <span class="k">else</span> <span class="n">_flag</span><span class="p">[</span><span class="n">len_flag</span><span class="o">*</span><span class="n">i</span><span class="p">:]</span> <span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">v</span><span class="p">)]</span>

<span class="n">n</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
<span class="n">k</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">320</span><span class="p">)</span>
<span class="n">h</span> <span class="o">=</span> <span class="p">[(</span><span class="nb">pow</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span> <span class="o">*</span> <span class="n">k</span><span class="p">)</span> <span class="o">%</span> <span class="n">n</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">flag</span><span class="p">]</span>
<span class="k">print</span><span class="p">(</span><span class="s">'n ='</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">'h ='</span><span class="p">,</span> <span class="n">h</span><span class="p">)</span>

<span class="c1">#n = 101058037881577920580002375991533361443161573598172872401436929130908010655347634552777064174546568575027746607488492099154312267724394462943506690144947830040343315369562513570527692894685015573081207528621819747699733304080614793374057284273387848357708739112531677281801323793173090364390370736467003582917
#h = [65238694465386915975309840141683615649716012162296959248563569592374718661731701206400896806537952397410032261877378530686978759625292099657084619983375773255755144153781457417211674091516407534881571548771997217431814162001948536903510439216595988996202297986689400937900640116301788349788192250828531102128, 32068430839487144716294122362877372185693231094331598085462142396101367356886620469702732239532304931830205469549873073426114974524345753699104479003686428551918989837919692818874041699167857438504796702427222322750641837975840611428682636854000155270647980139296254355022602725831316373502464385756822509507, 48045538813319220884490922546018868575029946351799253696566675045038593914426407040185597260237676046539039366729571890778376978523204708113947916683959718708951574554301326506033685253589648114421528029323355988178699924863264060114597711724540199556277259170518549061045104668001222710528847166168767224549, 75123995948950968391603159591624639368414690146643442871589447787252191810497231696845253418339980365162413355185111520483921331823652266243697559776174240013810488917495610598469082493126712875223200656678886780170706766832861117452830161713449328056483280254149803408052080851148204725932967126493489495389, 42343824812526091206264281076069981510653655573870037741842182418474719039360760283698683250943728878536765635239317776400805788012233353293622608102030711446811052604409325460820893599261928948443614050545507085890105202716250838690843035633052646253790841787346488131868389877735682981371140434336342163669, 37628269352817676029356094741613805749594096808670358767615556155530757612666502454541938594622721603313749449559343049177509738095358796943332112708078541782706675648358891508089680020008921913219362413211208103447607363315907316039312691994345309495981824477958094292712571053294153865686883217285045072976, 73095252261793287281307332092278639250704283375416144614680921495193800381044097746018933097918509033128787939821334122567907138901258104948978871755972801343922472074421943147663482695952043375035475082008819785709339730299175470843123204596279944349658280821397882576553260815905563725407952447607089415633, 8361412049519617647068414326705006074844850312921172001754491320379019244806566558657382200324831784028297924464089518976736942901670220750313172374617027089856976338617784260689863433040095122712749142220670740521573738642943802961154307094774904173422138158314888817191233893356292405644600013350124816088, 62352524946552767010792198212753557220884107271554779577796506420796971189249469475111704305722210605467500390830564039781429821148651682920442985923243637249469873109032519540399258091710648539664160224041270628257896923843424376128648420038693104506093124335294407330397776591999820661062819804224881373090, 45213281711383478082421649210599256239528608897580799695344082282030442480159495245224471785682835728050988008519768665616995327124516724160052452164034157361068252085880379351444661551341271829125924017634986473455126215443151677035338594360564464453084451500811436155828884254112395862897223575590665873227]
</span></code></pre></div></div>

<p>题目算比较简单的格密码题型，稍微在上面做了点变式，将flag切分后在维度进行了扩展，已知将flag切分为10段，对每段进行：</p>

\[h_i = flag_i^{-1} \times k \mod{n}\]

<p>现在已知各行的h与n，我们可以构造一个矩阵求格计算出k，然后反代出flag，但是我忘记了因为各段之间没有联系，其实也可以直接分别将flag各段格出后再拼出flag：</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="o">*</span>

<span class="n">n</span> <span class="o">=</span> <span class="mi">101058037881577920580002375991533361443161573598172872401436929130908010655347634552777064174546568575027746607488492099154312267724394462943506690144947830040343315369562513570527692894685015573081207528621819747699733304080614793374057284273387848357708739112531677281801323793173090364390370736467003582917</span>

<span class="n">h</span> <span class="o">=</span> <span class="p">[</span>
        <span class="mi">65238694465386915975309840141683615649716012162296959248563569592374718661731701206400896806537952397410032261877378530686978759625292099657084619983375773255755144153781457417211674091516407534881571548771997217431814162001948536903510439216595988996202297986689400937900640116301788349788192250828531102128</span><span class="p">,</span> 
        <span class="mi">32068430839487144716294122362877372185693231094331598085462142396101367356886620469702732239532304931830205469549873073426114974524345753699104479003686428551918989837919692818874041699167857438504796702427222322750641837975840611428682636854000155270647980139296254355022602725831316373502464385756822509507</span><span class="p">,</span> 
        <span class="mi">48045538813319220884490922546018868575029946351799253696566675045038593914426407040185597260237676046539039366729571890778376978523204708113947916683959718708951574554301326506033685253589648114421528029323355988178699924863264060114597711724540199556277259170518549061045104668001222710528847166168767224549</span><span class="p">,</span> 
        <span class="mi">75123995948950968391603159591624639368414690146643442871589447787252191810497231696845253418339980365162413355185111520483921331823652266243697559776174240013810488917495610598469082493126712875223200656678886780170706766832861117452830161713449328056483280254149803408052080851148204725932967126493489495389</span><span class="p">,</span> 
        <span class="mi">42343824812526091206264281076069981510653655573870037741842182418474719039360760283698683250943728878536765635239317776400805788012233353293622608102030711446811052604409325460820893599261928948443614050545507085890105202716250838690843035633052646253790841787346488131868389877735682981371140434336342163669</span><span class="p">,</span> 
        <span class="mi">37628269352817676029356094741613805749594096808670358767615556155530757612666502454541938594622721603313749449559343049177509738095358796943332112708078541782706675648358891508089680020008921913219362413211208103447607363315907316039312691994345309495981824477958094292712571053294153865686883217285045072976</span><span class="p">,</span> 
        <span class="mi">73095252261793287281307332092278639250704283375416144614680921495193800381044097746018933097918509033128787939821334122567907138901258104948978871755972801343922472074421943147663482695952043375035475082008819785709339730299175470843123204596279944349658280821397882576553260815905563725407952447607089415633</span><span class="p">,</span> 
        <span class="mi">8361412049519617647068414326705006074844850312921172001754491320379019244806566558657382200324831784028297924464089518976736942901670220750313172374617027089856976338617784260689863433040095122712749142220670740521573738642943802961154307094774904173422138158314888817191233893356292405644600013350124816088</span><span class="p">,</span> 
        <span class="mi">62352524946552767010792198212753557220884107271554779577796506420796971189249469475111704305722210605467500390830564039781429821148651682920442985923243637249469873109032519540399258091710648539664160224041270628257896923843424376128648420038693104506093124335294407330397776591999820661062819804224881373090</span><span class="p">,</span> 
        <span class="mi">45213281711383478082421649210599256239528608897580799695344082282030442480159495245224471785682835728050988008519768665616995327124516724160052452164034157361068252085880379351444661551341271829125924017634986473455126215443151677035338594360564464453084451500811436155828884254112395862897223575590665873227</span>
        <span class="p">]</span>

<span class="n">flag</span> <span class="o">=</span> <span class="sa">b</span><span class="s">""</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">h</span><span class="p">:</span>
    <span class="n">M</span> <span class="o">=</span> <span class="n">matrix</span><span class="p">(</span>
        <span class="p">[[</span><span class="n">n</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> 
         <span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">]]</span>
    <span class="p">)</span>
    <span class="n">reduced</span> <span class="o">=</span> <span class="n">M</span><span class="p">.</span><span class="n">LLL</span><span class="p">()</span>
    <span class="n">flag</span> <span class="o">+=</span> <span class="n">long_to_bytes</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">reduced</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">]))</span>

<span class="c1"># b'mcctf{f670d7a5-80db-4b7a-86f3-466a0e1e7daf}'
</span></code></pre></div></div>

<p>当然我还忘记一个更大的问题，flag切分以后存在其中一段可以被预测，可以预测然后反代出k，进而计算flag：</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="o">*</span>

<span class="n">n</span> <span class="o">=</span> <span class="mi">101058037881577920580002375991533361443161573598172872401436929130908010655347634552777064174546568575027746607488492099154312267724394462943506690144947830040343315369562513570527692894685015573081207528621819747699733304080614793374057284273387848357708739112531677281801323793173090364390370736467003582917</span>
<span class="n">h</span> <span class="o">=</span> <span class="p">[</span>
        <span class="mi">65238694465386915975309840141683615649716012162296959248563569592374718661731701206400896806537952397410032261877378530686978759625292099657084619983375773255755144153781457417211674091516407534881571548771997217431814162001948536903510439216595988996202297986689400937900640116301788349788192250828531102128</span><span class="p">,</span> 
        <span class="mi">32068430839487144716294122362877372185693231094331598085462142396101367356886620469702732239532304931830205469549873073426114974524345753699104479003686428551918989837919692818874041699167857438504796702427222322750641837975840611428682636854000155270647980139296254355022602725831316373502464385756822509507</span><span class="p">,</span> 
        <span class="mi">48045538813319220884490922546018868575029946351799253696566675045038593914426407040185597260237676046539039366729571890778376978523204708113947916683959718708951574554301326506033685253589648114421528029323355988178699924863264060114597711724540199556277259170518549061045104668001222710528847166168767224549</span><span class="p">,</span> 
        <span class="mi">75123995948950968391603159591624639368414690146643442871589447787252191810497231696845253418339980365162413355185111520483921331823652266243697559776174240013810488917495610598469082493126712875223200656678886780170706766832861117452830161713449328056483280254149803408052080851148204725932967126493489495389</span><span class="p">,</span> 
        <span class="mi">42343824812526091206264281076069981510653655573870037741842182418474719039360760283698683250943728878536765635239317776400805788012233353293622608102030711446811052604409325460820893599261928948443614050545507085890105202716250838690843035633052646253790841787346488131868389877735682981371140434336342163669</span><span class="p">,</span> 
        <span class="mi">37628269352817676029356094741613805749594096808670358767615556155530757612666502454541938594622721603313749449559343049177509738095358796943332112708078541782706675648358891508089680020008921913219362413211208103447607363315907316039312691994345309495981824477958094292712571053294153865686883217285045072976</span><span class="p">,</span> 
        <span class="mi">73095252261793287281307332092278639250704283375416144614680921495193800381044097746018933097918509033128787939821334122567907138901258104948978871755972801343922472074421943147663482695952043375035475082008819785709339730299175470843123204596279944349658280821397882576553260815905563725407952447607089415633</span><span class="p">,</span> 
        <span class="mi">8361412049519617647068414326705006074844850312921172001754491320379019244806566558657382200324831784028297924464089518976736942901670220750313172374617027089856976338617784260689863433040095122712749142220670740521573738642943802961154307094774904173422138158314888817191233893356292405644600013350124816088</span><span class="p">,</span> 
        <span class="mi">62352524946552767010792198212753557220884107271554779577796506420796971189249469475111704305722210605467500390830564039781429821148651682920442985923243637249469873109032519540399258091710648539664160224041270628257896923843424376128648420038693104506093124335294407330397776591999820661062819804224881373090</span><span class="p">,</span> 
        <span class="mi">45213281711383478082421649210599256239528608897580799695344082282030442480159495245224471785682835728050988008519768665616995327124516724160052452164034157361068252085880379351444661551341271829125924017634986473455126215443151677035338594360564464453084451500811436155828884254112395862897223575590665873227</span>
        <span class="p">]</span>

<span class="n">m0</span> <span class="o">=</span> <span class="n">bytes_to_long</span><span class="p">(</span><span class="sa">b</span><span class="s">"mcct"</span><span class="p">)</span>
<span class="n">k</span>  <span class="o">=</span> <span class="p">(</span><span class="n">h</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="n">m0</span><span class="p">)</span> <span class="o">%</span> <span class="n">n</span>
<span class="n">flag</span> <span class="o">=</span> <span class="sa">b</span><span class="s">""</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">h</span><span class="p">:</span>
    <span class="n">m_i</span> <span class="o">=</span> <span class="n">long_to_bytes</span><span class="p">((</span><span class="nb">pow</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span> <span class="o">*</span> <span class="n">k</span><span class="p">)</span> <span class="o">%</span> <span class="n">n</span><span class="p">)</span>
    <span class="n">flag</span> <span class="o">+=</span> <span class="n">m_i</span>

<span class="k">print</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span>

<span class="c1">#b'mcctf{f670d7a5-80db-4b7a-86f3-466a0e1e7daf}'
</span></code></pre></div></div>

<p>（关键我还忘记最开始怎么准备的exp了，以后有时间试着做一做）</p>

<h1 id="ttpcup2026">Ttpcup2026</h1>

<p>好像也背了点锅，主要出了ClairautDH，后来发现存在重大bug又重新补了一道ClairautDH-Revenge，本来打算出两道题来着，后来确实燃尽了。ClairautDH确实应该算脑洞打开的一题，记得以前和其他师傅聊过AI冲击下很难出适合新生但能防范AI的题目，队伍进行选拔时很难区分选手的真实实力。刚好前段时间有人找我设计密码系统涉及到DH密钥交换，麻省理工的积分决赛也打完不久，之前看比赛时顺便自己顺便用AI简单求了一下积分，没求出来，于是有了将<strong>微积分应用于密钥交换</strong>的灵感。</p>

<h2 id="clairautdh-revenge">clairautdh-revenge</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># task.py
</span><span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">from</span> <span class="nn">sympy</span> <span class="kn">import</span> <span class="n">symbols</span><span class="p">,</span> <span class="n">diff</span><span class="p">,</span> <span class="n">simplify</span><span class="p">,</span> <span class="n">Integer</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.Padding</span> <span class="kn">import</span> <span class="n">pad</span><span class="p">,</span> <span class="n">unpad</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">long_to_bytes</span><span class="p">,</span> <span class="n">bytes_to_long</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">random</span>
<span class="kn">from</span> <span class="nn">secret</span> <span class="kn">import</span> <span class="n">flag</span><span class="p">,</span> <span class="n">f</span>

<span class="c1"># 共享函数和flag
</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">symbols</span><span class="p">(</span><span class="s">'x y'</span><span class="p">)</span>

<span class="s">'''
Bob and Alice share a function f(x, y). Whenever they need to generate a shared secret key, they can temporarily use the following method.
We provide a simple example.
'''</span>
<span class="c1">#f = x*y + x + y
</span>
<span class="k">def</span> <span class="nf">AES_enc</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
    <span class="n">key_hash</span> <span class="o">=</span> <span class="n">hashlib</span><span class="p">.</span><span class="n">sha256</span><span class="p">(</span><span class="n">long_to_bytes</span><span class="p">(</span><span class="n">key</span><span class="p">)).</span><span class="n">digest</span><span class="p">()</span>
    <span class="n">cipher</span> <span class="o">=</span> <span class="n">AES</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="n">key_hash</span><span class="p">[:</span><span class="mi">16</span><span class="p">],</span> <span class="n">AES</span><span class="p">.</span><span class="n">MODE_ECB</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">cipher</span><span class="p">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">pad</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">AES</span><span class="p">.</span><span class="n">block_size</span><span class="p">))</span>

<span class="k">def</span> <span class="nf">AES_dec</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
    <span class="n">key_hash</span> <span class="o">=</span> <span class="n">hashlib</span><span class="p">.</span><span class="n">sha256</span><span class="p">(</span><span class="n">long_to_bytes</span><span class="p">(</span><span class="n">key</span><span class="p">)).</span><span class="n">digest</span><span class="p">()</span>
    <span class="n">cipher</span> <span class="o">=</span> <span class="n">AES</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="n">key_hash</span><span class="p">[:</span><span class="mi">16</span><span class="p">],</span> <span class="n">AES</span><span class="p">.</span><span class="n">MODE_ECB</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">unpad</span><span class="p">(</span><span class="n">cipher</span><span class="p">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">msg</span><span class="p">),</span> <span class="n">AES</span><span class="p">.</span><span class="n">block_size</span><span class="p">)</span>

<span class="c1"># --- 第一步：Alice ---
</span><span class="n">alice_x</span> <span class="o">=</span> <span class="n">Integer</span><span class="p">(</span><span class="n">random</span><span class="p">.</span><span class="n">getrandbits</span><span class="p">(</span><span class="mi">128</span><span class="p">))</span>
<span class="n">f_x</span> <span class="o">=</span> <span class="n">diff</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">x</span><span class="p">).</span><span class="n">subs</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">alice_x</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\\</span><span class="s">partial F/ </span><span class="se">\\</span><span class="s">partial x: </span><span class="si">{</span><span class="n">simplify</span><span class="p">(</span><span class="n">f_x</span><span class="p">)</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

<span class="c1"># --- 第二步：Bob ---
</span><span class="n">bob_y</span> <span class="o">=</span> <span class="n">Integer</span><span class="p">(</span><span class="n">random</span><span class="p">.</span><span class="n">getrandbits</span><span class="p">(</span><span class="mi">128</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="n">diff</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">y</span><span class="p">))</span>
<span class="n">f_y</span> <span class="o">=</span> <span class="n">diff</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">y</span><span class="p">).</span><span class="n">subs</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">bob_y</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\\</span><span class="s">partial F/ </span><span class="se">\\</span><span class="s">partial y: </span><span class="si">{</span><span class="n">simplify</span><span class="p">(</span><span class="n">f_y</span><span class="p">)</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

<span class="c1"># --- 第三步：Alice ---
</span><span class="n">secret_scalar</span> <span class="o">=</span> <span class="nb">abs</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">diff</span><span class="p">(</span><span class="n">f_y</span><span class="p">,</span> <span class="n">x</span><span class="p">).</span><span class="n">subs</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">alice_x</span><span class="p">)))</span>
<span class="n">secret</span> <span class="o">=</span> <span class="n">AES_enc</span><span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="n">secret_scalar</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"secret: </span><span class="si">{</span><span class="n">bytes_to_long</span><span class="p">(</span><span class="n">secret</span><span class="p">)</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

<span class="c1"># --- 第四步：Bob ---
</span><span class="n">secret_scalar_bob</span> <span class="o">=</span> <span class="nb">abs</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">diff</span><span class="p">(</span><span class="n">f_x</span><span class="p">,</span> <span class="n">y</span><span class="p">).</span><span class="n">subs</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">bob_y</span><span class="p">)))</span>
<span class="n">decrypted_flag</span> <span class="o">=</span> <span class="n">AES_dec</span><span class="p">(</span><span class="n">secret</span><span class="p">,</span> <span class="n">secret_scalar_bob</span><span class="p">)</span>

<span class="c1"># 验证
</span><span class="k">assert</span> <span class="n">decrypted_flag</span> <span class="o">==</span> <span class="n">flag</span>
<span class="k">print</span><span class="p">(</span><span class="s">'Bob get flag.'</span><span class="p">)</span>
</code></pre></div></div>

<p>题目基于偏微分的克莱罗定理，对于连续可微函数的混合偏导数相等，密钥交换需要有一个正向容易逆向困难的计算方式保障个人生成的密钥安全，这里的体现是函数微分容易积分困难。</p>

<p>已知各偏导数表达式很容易还原方程，进而解出共享密钥，故在公开偏微分方程时进行降纬处理，原题目就变成了已知两个微分投影求出原始函数。</p>

<p>相比数学方法，求取积分更倾向于找感觉，我们可以通过偏导函数未进行微分的另一维度去猜测原始函数的大概轮廓，从而进行还原，例如如下输出：</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s">'''
 \partial F/ \partial x: 1091410879207163423527614718617914148888*y**3 + 81254019297725586260762901144707066777558658481431202628329889377193662772828317753114607046787850201807677669860192 - 1/y
\partial F/ \partial y: 677492876058731304548321124430382899202536309194603058276767059068971723406326*x**2 + x/112915479343121884091386854071730483200422718199100509712794509844828620567721 + 25706026840600906043088759983422158599436354716595565472703098295727374823141571327891394051094542563877396658316435605977006168485141809993256872220352031815049004360456983843517338282006837806
secret: 29541001074036648052457017922472446898167742481813256589556212172626042913295772830659172788048290288920622639932811
Bob get flag. 
'''</span>
</code></pre></div></div>

<p>通过\(\partial F/ \partial x\)可以大致窥见函数与\(my^3 - n/y\)有关，从\(\partial F/ \partial y\)可以猜测函数形似\(mx^2 + x/n\), 我们可以激进地猜测函数大致为</p>

\[mx^2y^3 - nx/y\]

<p>直接求导回推, 也可以谨慎对已知信息排查密钥（毕竟未进行取模运算），有个神奇的地方是gemini能够直接精准地还原函数（PS. 至今不明白它怎么知道我为了简化难度没带系数?函数选择是尽量精简过的而不是求导过程将复杂函数变简单的?）</p>

<p>以\(\partial F/ \partial y\)为例，保守计算可以猜测\(x^2\)处倾向为一个复合函数的计算结果，即：</p>

\[dy = f′(g(x))⋅g′(x)⋅dx\]

<p>结合x的偏导可以猜测系数与\(3(y^2)\)具有相关性,故有其中的EXP如下所示：</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">from</span> <span class="nn">sympy</span> <span class="kn">import</span> <span class="n">symbols</span><span class="p">,</span> <span class="n">diff</span><span class="p">,</span> <span class="n">root</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.Padding</span> <span class="kn">import</span> <span class="n">pad</span><span class="p">,</span> <span class="n">unpad</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">long_to_bytes</span><span class="p">,</span> <span class="n">bytes_to_long</span>

<span class="k">def</span> <span class="nf">AES_dec</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
    <span class="n">key_hash</span> <span class="o">=</span> <span class="n">hashlib</span><span class="p">.</span><span class="n">sha256</span><span class="p">(</span><span class="n">long_to_bytes</span><span class="p">(</span><span class="n">key</span><span class="p">)).</span><span class="n">digest</span><span class="p">()</span>
    <span class="n">cipher</span> <span class="o">=</span> <span class="n">AES</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="n">key_hash</span><span class="p">[:</span><span class="mi">16</span><span class="p">],</span> <span class="n">AES</span><span class="p">.</span><span class="n">MODE_ECB</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">unpad</span><span class="p">(</span><span class="n">cipher</span><span class="p">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">msg</span><span class="p">),</span> <span class="n">AES</span><span class="p">.</span><span class="n">block_size</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">find_y</span><span class="p">(</span><span class="n">_y</span><span class="p">):</span>
    <span class="n">n</span> <span class="o">=</span> <span class="mi">3</span>
    <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">_y</span> <span class="o">%</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="n">q</span> <span class="o">=</span> <span class="n">_y</span> <span class="o">//</span> <span class="n">n</span>
            <span class="n">y</span> <span class="o">=</span> <span class="n">root</span><span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">y</span> <span class="o">==</span> <span class="nb">int</span><span class="p">(</span><span class="n">y</span><span class="p">):</span>
                <span class="k">return</span> <span class="n">y</span>
        <span class="n">n</span> <span class="o">+=</span> <span class="mi">1</span>

<span class="n">y</span> <span class="o">=</span> <span class="n">symbols</span><span class="p">(</span><span class="s">"y"</span><span class="p">)</span>

<span class="n">f_x</span> <span class="o">=</span> <span class="mi">1091410879207163423527614718617914148888</span><span class="o">*</span><span class="n">y</span><span class="o">**</span><span class="mi">3</span> <span class="o">+</span> <span class="mi">81254019297725586260762901144707066777558658481431202628329889377193662772828317753114607046787850201807677669860192</span> <span class="o">-</span> <span class="mi">1</span><span class="o">/</span><span class="n">y</span>
<span class="n">secret</span> <span class="o">=</span> <span class="mi">29541001074036648052457017922472446898167742481813256589556212172626042913295772830659172788048290288920622639932811</span>

<span class="n">_y</span> <span class="o">=</span> <span class="mi">677492876058731304548321124430382899202536309194603058276767059068971723406326</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">find_y</span><span class="p">(</span><span class="n">_y</span><span class="p">)</span>
<span class="n">secret_scalar_bob</span> <span class="o">=</span> <span class="nb">abs</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">diff</span><span class="p">(</span><span class="n">f_x</span><span class="p">,</span> <span class="n">y</span><span class="p">).</span><span class="n">subs</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">result</span><span class="p">)))</span>
<span class="n">decrypted_flag</span> <span class="o">=</span> <span class="n">AES_dec</span><span class="p">(</span><span class="n">long_to_bytes</span><span class="p">(</span><span class="n">secret</span><span class="p">),</span> <span class="n">secret_scalar_bob</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">decrypted_flag</span><span class="p">)</span>
</code></pre></div></div>]]></content><author><name>CryingN</name><email>CryingNights7v@gmail.com</email></author><category term="网络安全" /><category term="CTF" /><category term="密码学" /><summary type="html"><![CDATA[AI时代确实很不适应，加上本身就菜，做不到像其他师傅那样可以抗着AI强度出大家都解决不了的0解题，简单总结一下自己一直以来在密码题上面的贡献，感觉也该找找新的地方做事了...]]></summary></entry><entry><title type="html">[AI学习笔记] 简单的AI类题目汇总.</title><link href="https://cryingn.github.io/posts/2025/03/ctf_ai/" rel="alternate" type="text/html" title="[AI学习笔记] 简单的AI类题目汇总." /><published>2025-03-10T00:00:00+08:00</published><updated>2025-03-10T00:00:00+08:00</updated><id>https://cryingn.github.io/posts/2025/03/ctf_ai</id><content type="html" xml:base="https://cryingn.github.io/posts/2025/03/ctf_ai/"><![CDATA[<h1 id="目录">目录</h1>

<ul>
  <li><a href="#前置概念">前置概念</a>
    <ul>
      <li><a href="#cnn">cnn</a></li>
    </ul>
  </li>
  <li><a href="#apoorvctf2025">apoorvctf2025</a>
    <ul>
      <li><a href="#professor_oak's_electric_misfortune">professor_oak’s_electric_misfortune</a></li>
    </ul>
  </li>
  <li><a href="#ghctf2025">ghctf2025</a>
    <ul>
      <li><a href="#mortis">mortis</a></li>
    </ul>
  </li>
  <li><a href="#参考文献">参考文献</a></li>
</ul>

<h1 id="前置概念">前置概念</h1>

<p>其实我本意是不太想记录AI类题目来着, 我用于训练AI的电脑被单独隔离开, 与打比赛的电脑分别单独存放, 但是学着写一点东西总是好的, 万一以后需要了呢(笑).</p>

<h2 id="cnn">cnn</h2>

<p>CNN又称卷积神经网络, 算是大部分入门AI的第一课, 我记得当时是看了3b1b的视频<sup id="fnref:3b1b" role="doc-noteref"><a href="#fn:3b1b" class="footnote" rel="footnote">1</a></sup>, 了解了个大概后自己按照一些相关博客试着用numpy搭建了一个简单的模型<sup id="fnref:numpy2cnn" role="doc-noteref"><a href="#fn:numpy2cnn" class="footnote" rel="footnote">2</a></sup>, 可惜识别效率太低, 就不分享了. 3b1b的可视化做得很好, 就不过多赘述了.</p>

<p>如果卷积的变量是序列\(x(n)\)和\(h(n)\)，则卷积的结果为:</p>

\[x(n) * h(n) = \sum{x(i)h(n-i)}\]

<p>卷积神经网络使用了卷积运算, 用于捕捉图像中的局部特征.</p>

<h1 id="apoorvctf2025">apoorvctf2025</h1>

<h2 id="professor_oaks_electric_misfortune">professor_oak’s_electric_misfortune</h2>

<p>实际上在比赛刚开始的时候我只看了这一题, 描述如下:</p>

<blockquote>
  <p>🔥 Welcome, Pokémon Trainer! 🔥 Hello there! Welcome to the world of Pokémon! 🌍⚡ I’m Professor Oak, the leading Pokémon researcher, and I’ve been working on an advanced Pokédex upgrade that can automatically classify Pokémon types using cutting-edge neural networks. This breakthrough could revolutionize how trainers understand their Pokémon! BUT… there’s been a slight hiccup in the lab. 😰 My Pikachu got a little too excited and—well, let’s just say a few crucial data files were shocked into oblivion. ⚡💥 Now, the entire system is scrambled, and I need your help to restore order and complete the classifier! Now.. For further details, access the PDF. Heads up!! It’s password protected. The password is the name of the pokemon Ash first captured. Good Luck Trainer !!!</p>
</blockquote>

<h3 id="题目">题目</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>UG9rZW1vbkNOTgrilJzilIDilIAgSW5pdGlhbCBJbnB1dDogKDI1NiwgMjU2LCA0KQrilIIK4pSc4pSA4pSAIEZlYXR1cmUgRXh0cmFjdGlvbiBMYXllcnMK4pSCICAg4pSc4pSA4pSAIENvbnYyRCAoNC0+MzIpCuKUgiAgIOKUnOKUgOKUgCBCYXRjaE5vcm0yRCAK4pSCICAg4pSc4pSA4pSAIFJlTFUgQWN0aXZhdGlvbgrilIIgICDilJzilIDilIAgTWF4UG9vbDJEKEsgU2l6ZSA9IDMpCuKUgiAgIOKUnOKUgOKUgCBEcm9wb3V0IChwPTAuMjUpCuKUggrilJzilIDilIAgRGVlcGVyIFByb2Nlc3NpbmcK4pSCICAg4pSc4pSA4pSAIENvbnYyRCgzMi0+NjQpCuKUgiAgIOKUnOKUgOKUgCBCYXRjaE5vcm0yRCAoNjQpCuKUgiAgIOKUnOKUgOKUgCBSZUxVIEFjdGl2YXRpb24K4pSCICAg4pSc4pSA4pSAIE1heFBvb2wyRChLIFNpemUgPSAzKQrilIIgICDilJzilIDilIAgRHJvcG91dCAocD0wLjI1KQrilIIK4pSc4pSA4pSAIE1vcmUgRmVhdHVyZSBFeHRyYWN0aW9uCuKUgiAgIOKUnOKUgOKUgCBDb252MkQoNjQtPjEyOCkK4pSCICAg4pSc4pSA4pSAIEJhdGNoTm9ybTJECuKUgiAgIOKUnOKUgOKUgCBSZUxVIEFjdGl2YXRpb24K4pSCICAg4pSc4pSA4pSAIE1heFBvb2wyRChLIFNpemUgPSAzKQrilIIgICDilJzilIDilIAgRHJvcG91dCAocD0wLjI1KQrilIIK4pSc4pSA4pSAIEZ1bGx5IENvbm5lY3RlZCBMYXllcnMK4pSCICAg4pSc4pSA4pSAIEZsYXR0ZW4K4pSCICAg4pSc4pSA4pSAIExpbmVhciAoNTEyIE5ldXJvbnMpCuKUgiAgIOKUnOKUgOKUgCBCYXRjaE5vcm0xRArilIIgICDilJzilIDilIAgRHJvcG91dCAocD0wLjUpCuKUgiAgIOKUnOKUgOKUgCBMaW5lYXIK4pSCICAg4pSc4pSA4pSAIFNvZnRtYXggQWN0aXZhdGlvbgrilIIK4pSU4pSA4pSAIE91dHB1dDogMTggY2xhc3Nlcw==
</code></pre></div></div>

<p>另外还有一个pdf文件, 密码为<code class="language-plaintext highlighter-rouge">caterpie</code>, 点开后有如下内容:</p>

<blockquote>
  <p>Welcome, Pokémon Trainer!</p>

  <p>Hello there! Welcome to the world of Pokémon!</p>

  <p>I’m Professor Oak, the leading Pokémon researcher, and I’ve been working on an advanced Pokédex upgrade that can automatically classify Pokémon types using cutting-edge neural networks. This breakthrough could revolutionize how trainers understand their Pokémon!</p>

  <p>BUT… there’s been a slight hiccup in the lab.</p>

  <p>My Pikachu got a little too excited and—well, let’s just say a few crucial data files were shocked into oblivion. Now, the entire system is scrambled, and I need your help to restore order and complete the classifier!</p>

  <p>Your mission: Train a CNN model to classify Pokémon by type and help me get the Pokédex back on track. Are you up for the challenge, Trainer? Let’s GO!</p>

  <p>Notebook link: https://www.kaggle.com/code/gl3mon/apoorvquestion 
Dataset link: https://www.kaggle.com/datasets/gl3mon/apoorvctf</p>
</blockquote>

<h3 id="分析">分析</h3>

<p>很遗憾当我得知密码是绿毛虫的时候已经找不到页面了, 所以直接简单复盘一下代码部分, 核心源码如下:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">PokemonCNN</span><span class="p">(</span><span class="n">nn</span><span class="p">.</span><span class="n">Module</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">().</span><span class="n">__init__</span><span class="p">()</span>

        <span class="bp">self</span><span class="p">.</span><span class="n">conv1</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">32</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">bn1</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">BatchNorm2d</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">relu</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">ReLU</span><span class="p">()</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">pool</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">MaxPool2d</span><span class="p">(</span><span class="n">kernel_size</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">drop1</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Dropout</span><span class="p">(</span><span class="mf">0.25</span><span class="p">)</span>

        <span class="bp">self</span><span class="p">.</span><span class="n">conv2</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="mi">32</span><span class="p">,</span> <span class="mi">64</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">bn2</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">BatchNorm2d</span><span class="p">(</span><span class="mi">64</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">relu2</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">ReLU</span><span class="p">()</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">pool2</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">MaxPool2d</span><span class="p">(</span><span class="n">kernel_size</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">drop2</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Dropout</span><span class="p">(</span><span class="mf">0.25</span><span class="p">)</span>

        <span class="bp">self</span><span class="p">.</span><span class="n">conv3</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="mi">64</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">bn3</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">BatchNorm2d</span><span class="p">(</span><span class="mi">128</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">relu3</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">ReLU</span><span class="p">()</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">pool3</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">MaxPool2d</span><span class="p">(</span><span class="n">kernel_size</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">drop3</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Dropout</span><span class="p">(</span><span class="mf">0.25</span><span class="p">)</span>

        <span class="bp">self</span><span class="p">.</span><span class="n">flatten</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Flatten</span><span class="p">()</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">fc1</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Linear</span><span class="p">(</span><span class="mi">10368</span><span class="p">,</span> <span class="mi">512</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">bn4</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">BatchNorm1d</span><span class="p">(</span><span class="mi">512</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">drop4</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Dropout</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">fc2</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Linear</span><span class="p">(</span><span class="mi">512</span><span class="p">,</span> <span class="mi">18</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">softmax</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Softmax</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">pool</span><span class="p">(</span><span class="n">F</span><span class="p">.</span><span class="n">relu</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">bn1</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">conv1</span><span class="p">(</span><span class="n">x</span><span class="p">))))</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">drop1</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>

        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">pool</span><span class="p">(</span><span class="n">F</span><span class="p">.</span><span class="n">relu</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">bn2</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">conv2</span><span class="p">(</span><span class="n">x</span><span class="p">))))</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">drop2</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>

        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">pool</span><span class="p">(</span><span class="n">F</span><span class="p">.</span><span class="n">relu</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">bn3</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">conv3</span><span class="p">(</span><span class="n">x</span><span class="p">))))</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">drop3</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>

        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">flatten</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">fc1</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">bn4</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">drop4</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">fc2</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">softmax</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">x</span>
</code></pre></div></div>

<p>emmmm, 题目好像有点复杂了, 据描述需要使用<strong>GPU T4x2</strong>, 不过结合之前学习deepseek的一些经验, 理论上是可以加入以下代码修改的:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">device</span> <span class="o">=</span> <span class="s">"cuda"</span> <span class="k">if</span> <span class="n">pt</span><span class="p">.</span><span class="n">cuda</span><span class="p">.</span><span class="n">is_available</span><span class="p">()</span> <span class="k">else</span> <span class="s">"cpu"</span>
        <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Using device: </span><span class="si">{</span><span class="bp">self</span><span class="p">.</span><span class="n">device</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
</code></pre></div></div>

<p>然后先进第一题:</p>

<blockquote>
  <p>Question 1: What is the seed of the given code?</p>
</blockquote>

<p>程序中给出了提示: <code class="language-plaintext highlighter-rouge">I have not mentioned the seed for security reasons. But I'll let you in on a little secret. It's the pokemon number for charizard.</code>, 但是理解不了, 复盘的时候我直接上了爆破:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">EXP.pwn</span> <span class="kn">import</span> <span class="o">*</span>

<span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">num</span><span class="p">):</span>
    <span class="n">io</span><span class="p">(</span><span class="s">"./test"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="n">r</span><span class="p">())</span>
    <span class="n">s</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">num</span><span class="p">).</span><span class="n">encode</span><span class="p">())</span>
    <span class="n">data</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">(</span><span class="n">r</span><span class="p">()</span> <span class="o">==</span> <span class="sa">b</span><span class="s">'&gt; Incorrect answer for question 1.</span><span class="se">\n</span><span class="s">'</span><span class="p">)</span>
    <span class="n">close</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">data</span>

<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10000</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">test</span><span class="p">(</span><span class="n">i</span><span class="p">):</span>
        <span class="k">continue</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
        <span class="k">break</span>

<span class="c1"># [*] Stopped process './test' (pid 613)
# 151
</span></code></pre></div></div>

<p>不是很理解喷火龙为什么是151总之, 但是拿到了种子编号, 可以直接修改为<code class="language-plaintext highlighter-rouge">pt.manual_seed(151)</code>.</p>

<blockquote>
  <p>Question 2: What’s the number of input features of the first linear layer?</p>
</blockquote>

<p>跑不出来, 直接放代码, 有时间再慢慢说.</p>

<h3 id="exp">EXP</h3>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">torch</span> <span class="k">as</span> <span class="n">pt</span>
<span class="kn">import</span> <span class="nn">torch.nn.functional</span> <span class="k">as</span> <span class="n">F</span>
<span class="kn">import</span> <span class="nn">torch.nn</span> <span class="k">as</span> <span class="n">nn</span>

<span class="n">pt</span><span class="p">.</span><span class="n">manual_seed</span><span class="p">(</span><span class="mi">151</span><span class="p">)</span> <span class="c1"># I have not mentioned the seed for security reasons. But I'll let you in on a little secret. It's the pokemon number for charizard.
</span>
<span class="kn">from</span> <span class="nn">torch.utils.data</span> <span class="kn">import</span> <span class="n">Dataset</span><span class="p">,</span> <span class="n">DataLoader</span>
<span class="kn">from</span> <span class="nn">torchvision</span> <span class="kn">import</span> <span class="n">datasets</span>
<span class="kn">from</span> <span class="nn">torchvision.transforms</span> <span class="kn">import</span> <span class="n">ToTensor</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>

<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="n">pd</span>
<span class="kn">from</span> <span class="nn">torchvision.io</span> <span class="kn">import</span> <span class="n">read_image</span>

<span class="k">class</span> <span class="nc">CTFDataset</span><span class="p">(</span><span class="n">Dataset</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">annotation_file</span><span class="p">,</span> <span class="n">img_dir</span><span class="p">,</span> <span class="n">transform</span> <span class="o">=</span> <span class="bp">None</span><span class="p">,</span> <span class="n">target_transform</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">img_labels</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">read_csv</span><span class="p">(</span><span class="n">annotation_file</span><span class="p">,</span> <span class="n">index_col</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">label_mapping</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s">'Bug'</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s">'Dark'</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s">'Dragon'</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="s">'Electric'</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="s">'Fairy'</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span>
            <span class="s">'Fighting'</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s">'Fire'</span><span class="p">:</span> <span class="mi">6</span><span class="p">,</span> <span class="s">'Flying'</span><span class="p">:</span> <span class="mi">7</span><span class="p">,</span> <span class="s">'Ghost'</span><span class="p">:</span> <span class="mi">8</span><span class="p">,</span> <span class="s">'Grass'</span><span class="p">:</span> <span class="mi">9</span><span class="p">,</span>
            <span class="s">'Ground'</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span> <span class="s">'Ice'</span><span class="p">:</span> <span class="mi">11</span><span class="p">,</span> <span class="s">'Normal'</span><span class="p">:</span> <span class="mi">12</span><span class="p">,</span> <span class="s">'Poison'</span><span class="p">:</span> <span class="mi">13</span><span class="p">,</span> <span class="s">'Psychic'</span><span class="p">:</span> <span class="mi">14</span><span class="p">,</span>
            <span class="s">'Rock'</span><span class="p">:</span> <span class="mi">15</span><span class="p">,</span> <span class="s">'Steel'</span><span class="p">:</span> <span class="mi">16</span><span class="p">,</span> <span class="s">'Water'</span><span class="p">:</span> <span class="mi">17</span>
        <span class="p">}</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">img_labels</span><span class="p">[</span><span class="s">'class'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">img_labels</span><span class="p">[</span><span class="s">'type'</span><span class="p">].</span><span class="nb">map</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">label_mapping</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">img_dir</span> <span class="o">=</span> <span class="n">img_dir</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">transform</span> <span class="o">=</span> <span class="n">transform</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">target_transform</span> <span class="o">=</span> <span class="n">target_transform</span>

    <span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">img_labels</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">idx</span><span class="p">):</span>
        <span class="n">img_path</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">img_dir</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">img_labels</span><span class="p">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">idx</span><span class="p">][</span><span class="s">'type'</span><span class="p">],</span> <span class="sa">f</span><span class="s">'</span><span class="si">{</span><span class="bp">self</span><span class="p">.</span><span class="n">img_labels</span><span class="p">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">idx</span><span class="p">][</span><span class="s">"pkn"</span><span class="p">]</span><span class="si">}</span><span class="s">'</span><span class="o">+</span><span class="s">'.png'</span><span class="p">)</span>
        <span class="n">image</span> <span class="o">=</span> <span class="bp">None</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">image</span> <span class="o">=</span> <span class="n">read_image</span><span class="p">(</span><span class="n">img_path</span><span class="p">).</span><span class="n">to</span><span class="p">(</span><span class="n">pt</span><span class="p">.</span><span class="n">float32</span><span class="p">)</span>
        <span class="k">except</span><span class="p">:</span>
            <span class="n">image</span> <span class="o">=</span> <span class="n">pt</span><span class="p">.</span><span class="n">zeros</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">256</span><span class="p">,</span> <span class="mi">256</span><span class="p">)</span>
        <span class="n">label</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">img_labels</span><span class="p">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">idx</span><span class="p">][</span><span class="s">'class'</span><span class="p">]</span>
        <span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">transform</span><span class="p">:</span>
            <span class="n">image</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">transform</span><span class="p">(</span><span class="n">image</span><span class="p">)</span>
        <span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">target_transform</span><span class="p">:</span>
                <span class="n">label</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">target_transform</span><span class="p">(</span><span class="n">label</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">image</span><span class="p">,</span> <span class="n">label</span>

<span class="n">ds</span> <span class="o">=</span> <span class="n">CTFDataset</span><span class="p">(</span>
    <span class="n">annotation_file</span> <span class="o">=</span> <span class="s">'/kaggle/input/apoorvctf/final_y.csv'</span><span class="p">,</span>
    <span class="n">img_dir</span> <span class="o">=</span> <span class="s">'/kaggle/input/apoorvctf/train'</span><span class="p">,</span>
<span class="p">)</span>

<span class="n">train_dataloader</span> <span class="o">=</span> <span class="n">DataLoader</span><span class="p">(</span><span class="n">ds</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">4</span><span class="p">,</span> <span class="n">shuffle</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">PokemonCNN</span><span class="p">(</span><span class="n">nn</span><span class="p">.</span><span class="n">Module</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">().</span><span class="n">__init__</span><span class="p">()</span>

        <span class="bp">self</span><span class="p">.</span><span class="n">conv1</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">32</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">bn1</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">BatchNorm2d</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">relu</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">ReLU</span><span class="p">()</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">pool</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">MaxPool2d</span><span class="p">(</span><span class="n">kernel_size</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">drop1</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Dropout</span><span class="p">(</span><span class="mf">0.25</span><span class="p">)</span>

        <span class="bp">self</span><span class="p">.</span><span class="n">conv2</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="mi">32</span><span class="p">,</span> <span class="mi">64</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">bn2</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">BatchNorm2d</span><span class="p">(</span><span class="mi">64</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">relu2</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">ReLU</span><span class="p">()</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">pool2</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">MaxPool2d</span><span class="p">(</span><span class="n">kernel_size</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">drop2</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Dropout</span><span class="p">(</span><span class="mf">0.25</span><span class="p">)</span>

        <span class="bp">self</span><span class="p">.</span><span class="n">conv3</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="mi">64</span><span class="p">,</span> <span class="mi">128</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">bn3</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">BatchNorm2d</span><span class="p">(</span><span class="mi">128</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">relu3</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">ReLU</span><span class="p">()</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">pool3</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">MaxPool2d</span><span class="p">(</span><span class="n">kernel_size</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">drop3</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Dropout</span><span class="p">(</span><span class="mf">0.25</span><span class="p">)</span>

        <span class="bp">self</span><span class="p">.</span><span class="n">flatten</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Flatten</span><span class="p">()</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">fc1</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Linear</span><span class="p">(</span><span class="mi">10368</span><span class="p">,</span> <span class="mi">512</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">bn4</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">BatchNorm1d</span><span class="p">(</span><span class="mi">512</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">drop4</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Dropout</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">fc2</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Linear</span><span class="p">(</span><span class="mi">512</span><span class="p">,</span> <span class="mi">18</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">softmax</span> <span class="o">=</span> <span class="n">nn</span><span class="p">.</span><span class="n">Softmax</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">pool</span><span class="p">(</span><span class="n">F</span><span class="p">.</span><span class="n">relu</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">bn1</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">conv1</span><span class="p">(</span><span class="n">x</span><span class="p">))))</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">drop1</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>

        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">pool</span><span class="p">(</span><span class="n">F</span><span class="p">.</span><span class="n">relu</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">bn2</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">conv2</span><span class="p">(</span><span class="n">x</span><span class="p">))))</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">drop2</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>

        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">pool</span><span class="p">(</span><span class="n">F</span><span class="p">.</span><span class="n">relu</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">bn3</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">conv3</span><span class="p">(</span><span class="n">x</span><span class="p">))))</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">drop3</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>

        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">flatten</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">fc1</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">bn4</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">drop4</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">fc2</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
        <span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">softmax</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">x</span>

<span class="nb">sum</span><span class="p">(</span><span class="nb">dict</span><span class="p">(</span><span class="n">pk</span><span class="p">.</span><span class="n">named_parameters</span><span class="p">())[</span><span class="s">"fc1.weight"</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span> <span class="o">=</span> <span class="n">tensor</span><span class="p">(</span><span class="o">-</span><span class="mf">3.6320</span><span class="p">,</span> <span class="n">grad_fn</span><span class="o">=&lt;</span><span class="n">AddBackward0</span><span class="o">&gt;</span><span class="p">)</span>
<span class="nb">dict</span><span class="p">(</span><span class="n">pk</span><span class="p">.</span><span class="n">named_parameters</span><span class="p">())[</span><span class="s">"fc2.weight"</span><span class="p">][</span><span class="mi">2</span><span class="p">][</span><span class="mi">15</span><span class="p">]</span> <span class="o">=</span> <span class="n">tensor</span><span class="p">(</span><span class="o">-</span><span class="mf">0.0241</span><span class="p">,</span> <span class="n">grad_fn</span><span class="o">=&lt;</span><span class="n">SelectBackward0</span><span class="o">&gt;</span><span class="p">)</span>

<span class="c1"># apoorvctf{P1k4chu_0ch0t0n4_pr1nc3ps}
</span></code></pre></div></div>

<h1 id="ghctf2025">ghctf2025</h1>

<p>没想到国内也有比赛单开了一个赛道, 有时间试着跟wp学习学习.</p>

<h2 id="mortis">mortis</h2>

<h1 id="参考文献">参考文献</h1>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:3b1b" role="doc-endnote">
      <p>3Blue1Brown.【官方双语】深度学习之神经网络的结构 Part 1 ver 2.0[EB/OL].bilibili.<a target="_blank" href="https://www.bilibili.com/video/BV1bx411M7Zx">https://www.bilibili.com/video/BV1bx411M7Zx</a>.2017-10-19 <a href="#fnref:3b1b" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:numpy2cnn" role="doc-endnote">
      <p>qxcheng.用numpy实现CNN卷积神经网络[EB/OL].博客园.<a target="_blank" href="https://www.cnblogs.com/qxcheng/p/11729773.html">https://www.cnblogs.com/qxcheng/p/11729773.html</a>.2019-10-23 <a href="#fnref:numpy2cnn" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>CryingN</name><email>CryingNights7v@gmail.com</email></author><category term="网络安全" /><category term="CTF" /><category term="AI" /><summary type="html"><![CDATA[不知道是不是因为开始关注起AI, 最近感觉AI类题型越来越多了...]]></summary></entry><entry><title type="html">[WriteUp] FMCTF2025密码题解</title><link href="https://cryingn.github.io/posts/2025/03/fmctf2025/" rel="alternate" type="text/html" title="[WriteUp] FMCTF2025密码题解" /><published>2025-03-10T00:00:00+08:00</published><updated>2025-03-10T00:00:00+08:00</updated><id>https://cryingn.github.io/posts/2025/03/fmctf2025</id><content type="html" xml:base="https://cryingn.github.io/posts/2025/03/fmctf2025/"><![CDATA[<h1 id="目录">目录</h1>

<ul>
  <li><a href="#brutalrsa">brutalrsa</a></li>
  <li><a href="#circular_maze">circular_maze</a></li>
  <li><a href="#ez_rsa">ez_rsa</a></li>
  <li><a href="#ezxor">ezxor</a></li>
  <li><a href="#robin_s_mystery">robin_s_mystery</a></li>
  <li><a href="#seal_the_deal">seal_the_deal</a></li>
  <li><a href="#superguesser">superguesser</a></li>
  <li><a href="#superguesser_v2">superguesser_v2</a></li>
  <li><a href="#参考文献">参考文献</a></li>
</ul>

<h2 id="题目">题目</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>c =  41371441628678749855341069318913940139183366190092850457791401944637484881722387130432528789403867120983310612023037050412981687401539375118177921234958241549652642148049464476777138721957300380163011255302922062871368980358844918698066643476906429304993326666393192819367202508911333287188748033044647
e =  3
n =  125533848452137763185016834412259349043987425043688722410453579918645013940088212764269073831951730407180201649381111989694930753816422349270797992511026080967667823475550286796327579680655909172631694714891168782703472181155691095137469432249992072921349964218538827606766136606019411932023475455088911
</code></pre></div></div>

<h2 id="分析">分析</h2>

<p><code class="language-plaintext highlighter-rouge">e</code>很小, 模n很大, 理论上可以直接开根求解.</p>

<h2 id="exp">EXP</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">gmpy2</span> <span class="kn">import</span> <span class="n">iroot</span>

<span class="n">c</span> <span class="o">=</span>  <span class="mi">41371441628678749855341069318913940139183366190092850457791401944637484881722387130432528789403867120983310612023037050412981687401539375118177921234958241549652642148049464476777138721957300380163011255302922062871368980358844918698066643476906429304993326666393192819367202508911333287188748033044647</span>
<span class="n">e</span> <span class="o">=</span>  <span class="mi">3</span>
<span class="n">n</span> <span class="o">=</span>  <span class="mi">125533848452137763185016834412259349043987425043688722410453579918645013940088212764269073831951730407180201649381111989694930753816422349270797992511026080967667823475550286796327579680655909172631694714891168782703472181155691095137469432249992072921349964218538827606766136606019411932023475455088911</span>

<span class="n">k</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
    <span class="c1">#c+k*n 开3次方
</span>    <span class="n">res</span> <span class="o">=</span> <span class="n">iroot</span><span class="p">(</span><span class="n">c</span><span class="o">+</span><span class="n">k</span><span class="o">*</span><span class="n">n</span><span class="p">,</span><span class="n">e</span><span class="p">)</span>
    <span class="k">if</span><span class="p">(</span><span class="n">res</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="bp">True</span><span class="p">):</span>
        <span class="k">print</span><span class="p">(</span><span class="sa">b</span><span class="s">'FMCTF'</span><span class="o">+</span><span class="n">long_to_bytes</span><span class="p">(</span><span class="n">res</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span><span class="o">+</span><span class="sa">b</span><span class="s">'}'</span><span class="p">)</span> <span class="c1">#转为字符串
</span>        <span class="k">break</span>
    <span class="n">k</span><span class="o">=</span><span class="n">k</span><span class="o">+</span><span class="mi">1</span>

<span class="c1">#b'FMCTFBru7ef0rce_1s_s0me71mes_4n_effective_W4y!!!}'
</span></code></pre></div></div>

<h1 id="circular_maze">circular_maze</h1>

<h2 id="题目-1">题目</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">flag</span> <span class="o">=</span> <span class="s">"FMCTF{REDACTED}"</span>


<span class="k">def</span> <span class="nf">enc</span><span class="p">(</span><span class="n">data</span> <span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
    <span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)):</span>
        <span class="n">result</span><span class="p">.</span><span class="n">append</span><span class="p">(</span>
                    <span class="p">(</span>
                        <span class="p">(</span>
                            <span class="nb">ord</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">])</span> <span class="o">+</span>
                            <span class="nb">ord</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">+</span> 
                        <span class="nb">ord</span><span class="p">(</span><span class="n">data</span><span class="p">[(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)])</span>
                     <span class="p">)</span> <span class="o">%</span> <span class="mi">256</span><span class="p">)</span>
                        <span class="p">.</span><span class="n">to_bytes</span><span class="p">()</span> 
                <span class="p">)</span>
                
    <span class="k">return</span> <span class="sa">b</span><span class="s">''</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">enc</span><span class="p">(</span><span class="n">flag</span><span class="p">))</span>
<span class="nb">open</span><span class="p">(</span><span class="s">"./flag.enc"</span><span class="p">,</span> <span class="s">"wb"</span><span class="p">).</span><span class="n">write</span><span class="p">(</span><span class="n">enc</span><span class="p">(</span><span class="n">flag</span><span class="p">))</span>
</code></pre></div></div>

<h2 id="分析-1">分析</h2>

<p>主要实现对每一位字符的前后两位进行加和后取模, 本质上只需要获取其中两位就可以获取剩余的字符, 难点主要可能是实现算法了.</p>

<h2 id="exp-1">EXP</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">flag</span> <span class="o">=</span> <span class="s">"FMCTF{REDACTED}"</span>
<span class="n">mess</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">"./flag.enc"</span><span class="p">,</span> <span class="s">"rb"</span><span class="p">).</span><span class="n">read</span><span class="p">()</span>

<span class="n">flag_1</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="n">flag</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">flag_2</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="n">flag</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">flag_3</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="n">flag</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
<span class="n">return_flag</span> <span class="o">=</span> <span class="s">'FM'</span>
<span class="n">n</span> <span class="o">=</span> <span class="mi">3</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">16</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">65</span><span class="p">,</span> <span class="mi">126</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">mess</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="p">(</span><span class="n">flag_1</span> <span class="o">+</span> <span class="n">flag_2</span> <span class="o">+</span> <span class="n">j</span><span class="p">)</span> <span class="o">%</span> <span class="mi">256</span><span class="p">:</span>
            <span class="n">return_flag</span> <span class="o">+=</span> <span class="nb">chr</span><span class="p">(</span><span class="n">j</span><span class="p">)</span>
            <span class="n">flag_1</span> <span class="o">=</span> <span class="n">flag_2</span>
            <span class="n">flag_2</span> <span class="o">=</span> <span class="n">j</span>
            <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">print</span><span class="p">(</span><span class="n">return_flag</span><span class="p">)</span>

<span class="c1"># FMCTF{broken_circle_is_not_fun_at_all}
</span></code></pre></div></div>

<h1 id="ez_rsa">ez_rsa</h1>

<h2 id="题目-2">题目</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">getPrime</span>
<span class="kn">import</span> <span class="nn">os</span>

<span class="n">flag</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">getenv</span><span class="p">(</span><span class="s">"FLAG"</span><span class="p">,</span> <span class="s">"FMCTF{F4K3_FL49}"</span><span class="p">)</span>
<span class="n">m</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">flag</span><span class="p">.</span><span class="n">encode</span><span class="p">().</span><span class="nb">hex</span><span class="p">(),</span> <span class="mi">16</span><span class="p">)</span>

<span class="n">p</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">512</span><span class="p">)</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">512</span><span class="p">)</span>

<span class="n">n</span> <span class="o">=</span> <span class="n">p</span><span class="o">*</span><span class="n">q</span>
<span class="n">e</span> <span class="o">=</span> <span class="mi">65537</span>
<span class="n">c</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>

<span class="n">hint</span> <span class="o">=</span> <span class="n">p</span><span class="o">+</span><span class="n">q</span>

<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">hint</span> <span class="o">=</span> <span class="si">}</span><span class="s">"</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">n</span> <span class="o">=</span> <span class="si">}</span><span class="s">"</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">c</span> <span class="o">=</span> <span class="si">}</span><span class="s">"</span><span class="p">)</span>

<span class="c1"># hint = 17469292153344571442220879753705314094982989674618803961044325274734902918518047825543639089360378046111761829828690097867206972174713085299385569035446604
# n = 72178676992512160441554160179592383158203955928083976740488546189244761660478121450369459709272987174826935459768807973546852656122370605905453926547673003297830819475396600384101353650933279529161854454268770358323854195264696322371766082303954604264551309576730976571309522883511488619775495703381232031179
# c = 58920849369961001974878540043377399205173235403895163231084588694712964281923344842680972991777380071418111292770515352012869237864259800540355713208626735820573601770413846338478651482053989341163751620131823006414875347921150338651475973491744075397194132475674270761198474531891598902225518350430719735601
</span></code></pre></div></div>

<h2 id="分析-2">分析</h2>

<p>经典数学问题, 已知:</p>

\[\left\{\begin{matrix}
p*q=n \\
p+q=hint
\end{matrix}\right.\]

<p>可以设p表达q, 然后解方程.</p>

<h2 id="exp-2">EXP</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="o">*</span>

<span class="n">e</span> <span class="o">=</span> <span class="mi">65537</span>
<span class="n">hint</span> <span class="o">=</span> <span class="mi">17469292153344571442220879753705314094982989674618803961044325274734902918518047825543639089360378046111761829828690097867206972174713085299385569035446604</span>
<span class="n">n</span> <span class="o">=</span> <span class="mi">72178676992512160441554160179592383158203955928083976740488546189244761660478121450369459709272987174826935459768807973546852656122370605905453926547673003297830819475396600384101353650933279529161854454268770358323854195264696322371766082303954604264551309576730976571309522883511488619775495703381232031179</span>
<span class="n">c</span> <span class="o">=</span> <span class="mi">58920849369961001974878540043377399205173235403895163231084588694712964281923344842680972991777380071418111292770515352012869237864259800540355713208626735820573601770413846338478651482053989341163751620131823006414875347921150338651475973491744075397194132475674270761198474531891598902225518350430719735601</span>

<span class="n">p_</span> <span class="o">=</span> <span class="n">var</span><span class="p">(</span><span class="s">'p_'</span><span class="p">)</span>
<span class="n">approx_p</span> <span class="o">=</span> <span class="nb">int</span><span class="p">((</span><span class="n">p_</span><span class="o">*</span><span class="p">(</span><span class="n">hint</span> <span class="o">-</span> <span class="n">p_</span><span class="p">)</span> <span class="o">-</span> <span class="n">n</span><span class="p">).</span><span class="n">roots</span><span class="p">()[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
<span class="n">p</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">approx_p</span><span class="p">)</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">n</span><span class="o">//</span><span class="n">p</span>
<span class="n">d</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="n">p</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">q</span><span class="o">-</span><span class="mi">1</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="n">long_to_bytes</span><span class="p">(</span><span class="nb">pow</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">n</span><span class="p">)))</span>

<span class="c1"># b'FMCTF{rSA_34SY_P34SY_L3M0N_5QU33ZY}'
</span></code></pre></div></div>

<h1 id="ezxor">ezxor</h1>

<h2 id="题目-3">题目</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">FLAG</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">environ</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">"FLAG"</span><span class="p">,</span> <span class="s">"FMCTF{F4K3_FL49}"</span><span class="p">).</span><span class="n">encode</span><span class="p">()</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">urandom</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
<span class="n">encryptedFlag</span> <span class="o">=</span> <span class="n">xor</span><span class="p">(</span><span class="n">FLAG</span><span class="p">,</span> <span class="n">key</span><span class="p">).</span><span class="nb">hex</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"encryptedFlag = </span><span class="si">{</span><span class="n">encryptedFlag</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
<span class="c1"># encryptedFlag = a850d725cb56b0de4fcb40de72a4df56a72ec06cafa75ecb41f51c95
</span></code></pre></div></div>

<h2 id="分析-3">分析</h2>

<p>key是随机生成的7位字符, 但是已知flag头有”FMCTF{}”, 可以反向求解出key, 然后解密.</p>

<h2 id="exp-3">EXP</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="n">xor</span>

<span class="c1"># 给定的加密后的十六进制字符串
</span><span class="n">encrypted_flag_hex</span> <span class="o">=</span> <span class="s">"a850d725cb56b0de4fcb40de72a4df56a72ec06cafa75ecb41f51c95"</span>
<span class="n">encrypted_flag</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">.</span><span class="n">fromhex</span><span class="p">(</span><span class="n">encrypted_flag_hex</span><span class="p">)</span>

<span class="n">known_prefix</span> <span class="o">=</span> <span class="sa">b</span><span class="s">"FMCTF{"</span>

<span class="n">key</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">6</span><span class="p">):</span>
    <span class="n">key_byte</span> <span class="o">=</span> <span class="n">encrypted_flag</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">^</span> <span class="n">known_prefix</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="n">key</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">key_byte</span><span class="p">)</span>

<span class="n">last_index</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">encrypted_flag</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<span class="n">key_byte_6</span> <span class="o">=</span> <span class="n">encrypted_flag</span><span class="p">[</span><span class="n">last_index</span><span class="p">]</span> <span class="o">^</span> <span class="mh">0x7D</span>  <span class="c1"># 0x7D是'}'
</span><span class="n">key</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">key_byte_6</span><span class="p">)</span>

<span class="n">full_key</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="n">decrypted</span> <span class="o">=</span> <span class="n">xor</span><span class="p">(</span><span class="n">encrypted_flag</span><span class="p">,</span> <span class="n">full_key</span><span class="p">)</span>

<span class="k">print</span><span class="p">(</span><span class="n">decrypted</span><span class="p">)</span>

<span class="c1"># b'FMCTF{X0R_1S_L1K3_MAGIC_0x1}'
</span></code></pre></div></div>

<h1 id="robin_s_mystery">robin_s_mystery</h1>

<h2 id="题目-4">题目</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">random</span>
<span class="kn">from</span> <span class="nn">Crypto.PublicKey</span> <span class="kn">import</span> <span class="n">RSA</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="o">*</span>

<span class="k">def</span> <span class="nf">nextPrime</span><span class="p">(</span><span class="n">prim</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">isPrime</span><span class="p">(</span><span class="n">prim</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">prim</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">nextPrime</span><span class="p">(</span><span class="n">prim</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>

<span class="n">p</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">512</span><span class="p">)</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">nextPrime</span><span class="p">(</span><span class="n">p</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
<span class="k">while</span> <span class="n">p</span><span class="o">%</span><span class="mi">4</span> <span class="o">!=</span> <span class="mi">3</span> <span class="ow">or</span> <span class="n">q</span><span class="o">%</span><span class="mi">4</span> <span class="o">!=</span><span class="mi">3</span><span class="p">:</span>
    <span class="n">p</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">512</span><span class="p">)</span>
    <span class="n">q</span> <span class="o">=</span> <span class="n">nextPrime</span><span class="p">(</span><span class="n">p</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>

<span class="n">n</span> <span class="o">=</span> <span class="n">p</span><span class="o">*</span><span class="n">q</span>
<span class="n">m</span> <span class="o">=</span> <span class="n">bytes_to_long</span><span class="p">(</span> <span class="nb">open</span><span class="p">(</span><span class="s">'flag.txt'</span><span class="p">,</span><span class="s">'rb'</span><span class="p">).</span><span class="n">read</span><span class="p">()</span> <span class="p">)</span>

<span class="n">c</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>

<span class="n">rsa</span> <span class="o">=</span> <span class="n">RSA</span><span class="p">.</span><span class="n">construct</span><span class="p">((</span><span class="n">n</span><span class="p">,</span> <span class="n">e</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="n">rsa</span><span class="p">.</span><span class="n">exportKey</span><span class="p">().</span><span class="n">decode</span><span class="p">())</span>
<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"cipher: </span><span class="si">{</span> <span class="n">long_to_bytes</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="si">}</span><span class="s">"</span><span class="p">)</span>

<span class="s">'''
-----BEGIN PUBLIC KEY-----
MIGcMA0GCSqGSIb3DQEBAQUAA4GKADCBhgKBgGjpRi/Hr5oN5NS219dZrq6nW7AC
Y7fUItXAvbgy0TtagVKO2goQiOssL331b7zRjMvdHkEBR4bTd+hHblmynO+2//fz
4DmVgdgMnrP54+2RSzguEGS1ONX4MpJonBsEGGc1IOiKECiwIbl4DkyTxl6AnFsz
ZI2E+lLDZnX5P44FAgEQ
-----END PUBLIC KEY-----
cipher: b'</span><span class="se">\x10\xc4\xbf\xfa</span><span class="s">pg</span><span class="se">\xee\x00\xe4\xcd\x00\xb4</span><span class="s">i</span><span class="se">\xf5\x80</span><span class="s">1</span><span class="se">\xdd\xaf</span><span class="s">m</span><span class="se">\xb1\xad\x8d</span><span class="s">y</span><span class="se">\x01\xaa\x14\xd1\xa3\x14</span><span class="s">[</span><span class="se">\xdf\xc8</span><span class="s">c</span><span class="se">\xb1\xf4\xcb\xcf\xf0\xf9\x83\x85</span><span class="s">%</span><span class="se">\x19\xd2</span><span class="s">d&gt;N</span><span class="se">\x9a</span><span class="s">R</span><span class="se">\xa4\xba\xc9\xda\xd8\xe4\xa2\x9c</span><span class="s">g%.</span><span class="se">\xac\xd7\xb5\x95\x7f\x87\x04</span><span class="s">?</span><span class="se">\xf7\xe4\x06</span><span class="s">(</span><span class="se">\xe7</span><span class="s">l</span><span class="se">\x1c</span><span class="s">"c</span><span class="se">\x95\x90</span><span class="s">z</span><span class="se">\xd4\x8b\x9f\x1b\x00\xc6</span><span class="s">7</span><span class="se">\xe4\x82</span><span class="s">g</span><span class="se">\xc4</span><span class="s">b</span><span class="se">\x10\x8c\xe7</span><span class="s">s[</span><span class="se">\x95</span><span class="s">-TB+Z;</span><span class="se">\xe4\x00\x11</span><span class="s">&lt;</span><span class="se">\xc5</span><span class="s">1K</span><span class="se">\xec\x94</span><span class="s">ZL</span><span class="se">\xb2\xf9\x7f</span><span class="s">p&lt;</span><span class="se">\xe6</span><span class="s">C</span><span class="se">\xf8\x7f\x90\x0b</span><span class="s">G</span><span class="se">\xcf</span><span class="s">'
'''</span>
</code></pre></div></div>

<h2 id="分析-4">分析</h2>

<p>这题涉及了基本的对rsa的pem文件使用, 可以使用Crypto库自带的解析工具直接获取n, e参数, 然后找到p, q相近, 可以直接开根去找相邻素数, 密码手快乐题了. 拿到结果后实际上是无法直接求出私钥的, 因为存在以下信息:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">p</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">512</span><span class="p">)</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">nextPrime</span><span class="p">(</span><span class="n">p</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
<span class="k">while</span> <span class="n">p</span><span class="o">%</span><span class="mi">4</span> <span class="o">!=</span> <span class="mi">3</span> <span class="ow">or</span> <span class="n">q</span><span class="o">%</span><span class="mi">4</span> <span class="o">!=</span><span class="mi">3</span><span class="p">:</span>
    <span class="n">p</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="mi">512</span><span class="p">)</span>
    <span class="n">q</span> <span class="o">=</span> <span class="n">nextPrime</span><span class="p">(</span><span class="n">p</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div></div>

<p>p, q均满足模4于3, 在获取e的时候会发现能被4整除, 在求phi时p-1, q-1也均能够被4整除, e与phi不互素, 无法直接使用其中一个素数取phi求解, 也就是说存在以下情况:</p>

\[\begin{matrix}
gcd(e, (q-1)) = 4 \\
gcd(e, (p-1)) = 4
\end{matrix}\]

<p>这里需要使用中国剩余定理直接取出flag, 可以使用以下方法获取p与q的根:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">find_res</span><span class="p">(</span><span class="n">gen</span><span class="p">):</span>
    <span class="n">R</span> <span class="o">=</span> <span class="n">PolynomialRing</span><span class="p">(</span><span class="n">Zmod</span><span class="p">(</span><span class="n">gen</span><span class="p">),</span> <span class="s">'x'</span><span class="p">)</span>
    <span class="n">x</span> <span class="o">=</span> <span class="n">R</span><span class="p">.</span><span class="n">gen</span><span class="p">()</span>
    <span class="n">f</span> <span class="o">=</span> <span class="n">x</span> <span class="o">**</span> <span class="n">e</span> <span class="o">-</span> <span class="n">c</span>
    <span class="n">f</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="n">monic</span><span class="p">()</span>
    <span class="n">res</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="n">roots</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">res</span>
</code></pre></div></div>

<p>函数求解的res是多项式\(f=x^e-c\)在模gen(即分别是p与q)意义下的根, 其中c是密文数据, \(x^e\mod{gen}\)中的x为模gen意义下的密文信息, 分别调用p, q可以得到不同模gen意义下与flag加密数据的差值, 多项式的sage函数可以参考sakana联队的维护sage文档<sup id="fnref:sagemath" role="doc-noteref"><a href="#fn:sagemath" class="footnote" rel="footnote">1</a></sup>. 求解如下所示:</p>

<h2 id="exp-4">EXP</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">Crypto.PublicKey</span> <span class="kn">import</span> <span class="n">RSA</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">gmpy2</span>

<span class="k">def</span> <span class="nf">find_res</span><span class="p">(</span><span class="n">gen</span><span class="p">):</span>
    <span class="n">R</span> <span class="o">=</span> <span class="n">PolynomialRing</span><span class="p">(</span><span class="n">Zmod</span><span class="p">(</span><span class="n">gen</span><span class="p">),</span> <span class="s">'x'</span><span class="p">)</span>
    <span class="n">x</span> <span class="o">=</span> <span class="n">R</span><span class="p">.</span><span class="n">gen</span><span class="p">()</span>
    <span class="n">f</span> <span class="o">=</span> <span class="n">x</span> <span class="o">**</span> <span class="n">e</span> <span class="o">-</span> <span class="n">c</span>
    <span class="n">f</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="n">monic</span><span class="p">()</span>
    <span class="n">res</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="n">roots</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">res</span>

<span class="n">rsa</span> <span class="o">=</span> <span class="s">'''-----BEGIN PUBLIC KEY-----
MIGcMA0GCSqGSIb3DQEBAQUAA4GKADCBhgKBgGjpRi/Hr5oN5NS219dZrq6nW7AC
Y7fUItXAvbgy0TtagVKO2goQiOssL331b7zRjMvdHkEBR4bTd+hHblmynO+2//fz
4DmVgdgMnrP54+2RSzguEGS1ONX4MpJonBsEGGc1IOiKECiwIbl4DkyTxl6AnFsz
ZI2E+lLDZnX5P44FAgEQ
-----END PUBLIC KEY-----
'''</span>

<span class="n">cipher</span> <span class="o">=</span> <span class="sa">b</span><span class="s">'</span><span class="se">\x10\xc4\xbf\xfa</span><span class="s">pg</span><span class="se">\xee\x00\xe4\xcd\x00\xb4</span><span class="s">i</span><span class="se">\xf5\x80</span><span class="s">1</span><span class="se">\xdd\xaf</span><span class="s">m</span><span class="se">\xb1\xad\x8d</span><span class="s">y</span><span class="se">\x01\xaa\x14\xd1\xa3\x14</span><span class="s">[</span><span class="se">\xdf\xc8</span><span class="s">c</span><span class="se">\xb1\xf4\xcb\xcf\xf0\xf9\x83\x85</span><span class="s">%</span><span class="se">\x19\xd2</span><span class="s">d&gt;N</span><span class="se">\x9a</span><span class="s">R</span><span class="se">\xa4\xba\xc9\xda\xd8\xe4\xa2\x9c</span><span class="s">g%.</span><span class="se">\xac\xd7\xb5\x95\x7f\x87\x04</span><span class="s">?</span><span class="se">\xf7\xe4\x06</span><span class="s">(</span><span class="se">\xe7</span><span class="s">l</span><span class="se">\x1c</span><span class="s">"c</span><span class="se">\x95\x90</span><span class="s">z</span><span class="se">\xd4\x8b\x9f\x1b\x00\xc6</span><span class="s">7</span><span class="se">\xe4\x82</span><span class="s">g</span><span class="se">\xc4</span><span class="s">b</span><span class="se">\x10\x8c\xe7</span><span class="s">s[</span><span class="se">\x95</span><span class="s">-TB+Z;</span><span class="se">\xe4\x00\x11</span><span class="s">&lt;</span><span class="se">\xc5</span><span class="s">1K</span><span class="se">\xec\x94</span><span class="s">ZL</span><span class="se">\xb2\xf9\x7f</span><span class="s">p&lt;</span><span class="se">\xe6</span><span class="s">C</span><span class="se">\xf8\x7f\x90\x0b</span><span class="s">G</span><span class="se">\xcf</span><span class="s">'</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">bytes_to_long</span><span class="p">(</span><span class="n">cipher</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">RSA</span><span class="p">.</span><span class="n">import_key</span><span class="p">(</span><span class="n">rsa</span><span class="p">)</span>
<span class="n">n</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">n</span>
<span class="n">e</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">e</span>

<span class="n">temp</span><span class="o">=</span><span class="n">gmpy2</span><span class="p">.</span><span class="n">iroot</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="mi">2</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">gmpy2</span><span class="p">.</span><span class="n">next_prime</span><span class="p">(</span><span class="n">temp</span><span class="p">)</span>
<span class="n">q</span> <span class="o">=</span> <span class="n">n</span><span class="o">//</span><span class="nb">int</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
<span class="n">phi</span> <span class="o">=</span> <span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">q</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>

<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">find_res</span><span class="p">(</span><span class="n">p</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="n">find_res</span><span class="p">(</span><span class="n">q</span><span class="p">):</span>
        <span class="c1"># 中国剩余定理
</span>        <span class="n">m</span> <span class="o">=</span><span class="n">crt</span><span class="p">([</span><span class="nb">int</span><span class="p">(</span><span class="n">i</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span><span class="nb">int</span><span class="p">(</span><span class="n">j</span><span class="p">[</span><span class="mi">0</span><span class="p">])],[</span><span class="n">p</span><span class="p">,</span><span class="n">q</span><span class="p">])</span>
        <span class="n">flag</span> <span class="o">=</span> <span class="n">long_to_bytes</span><span class="p">(</span><span class="n">m</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">flag</span><span class="p">.</span><span class="n">startswith</span><span class="p">(</span><span class="sa">b</span><span class="s">'FMCTF{'</span><span class="p">):</span>
            <span class="k">print</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span>

<span class="c1"># b'FMCTF{S0lv3d_w1th_R4b1n_fx777}'
</span></code></pre></div></div>

<h1 id="seal_the_deal">seal_the_deal</h1>

<h2 id="题目-5">题目</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">math</span> <span class="kn">import</span> <span class="n">gcd</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.number</span> <span class="kn">import</span> <span class="n">getPrime</span><span class="p">,</span> <span class="n">inverse</span>
<span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="n">randint</span>
<span class="kn">import</span> <span class="nn">secrets</span>
<span class="kn">import</span> <span class="nn">time</span>

<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">"flag.txt"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
    <span class="n">flag</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="n">readline</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">Paillier</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="p">):</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">bits</span> <span class="o">=</span> <span class="n">bits</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">pub</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">priv</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">keygen</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">lcm</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">a</span> <span class="o">*</span> <span class="n">b</span> <span class="o">//</span> <span class="n">gcd</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">keygen</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
            <span class="n">p</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">bits</span><span class="p">)</span>
            <span class="n">q</span> <span class="o">=</span> <span class="n">getPrime</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">bits</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">p</span> <span class="o">!=</span> <span class="n">q</span><span class="p">:</span>
                <span class="k">break</span>
        <span class="n">n</span> <span class="o">=</span> <span class="n">p</span> <span class="o">*</span> <span class="n">q</span>
        <span class="n">Lambda</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">lcm</span><span class="p">(</span><span class="n">p</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">q</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>  
        <span class="n">g</span> <span class="o">=</span> <span class="n">n</span> <span class="o">+</span> <span class="mi">1</span>  
        <span class="n">mu</span> <span class="o">=</span> <span class="n">inverse</span><span class="p">(</span><span class="n">Lambda</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span> 
        <span class="k">return</span> <span class="p">((</span><span class="n">n</span><span class="p">,</span> <span class="n">g</span><span class="p">),</span> <span class="p">(</span><span class="n">Lambda</span><span class="p">,</span> <span class="n">mu</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">encrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">m</span><span class="p">):</span>
        <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">pub</span>
        <span class="n">n_sq</span> <span class="o">=</span> <span class="n">n</span> <span class="o">*</span> <span class="n">n</span>
        <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
            <span class="n">r</span> <span class="o">=</span> <span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">gcd</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
                <span class="k">break</span>
        <span class="n">c</span> <span class="o">=</span> <span class="p">(</span><span class="nb">pow</span><span class="p">(</span><span class="n">g</span><span class="p">,</span> <span class="n">m</span><span class="p">,</span> <span class="n">n_sq</span><span class="p">)</span> <span class="o">*</span> <span class="nb">pow</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">n_sq</span><span class="p">))</span> <span class="o">%</span> <span class="n">n_sq</span>
        <span class="k">return</span> <span class="n">c</span>

    <span class="k">def</span> <span class="nf">decrypt</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">c</span><span class="p">):</span>
        <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">pub</span>
        <span class="p">(</span><span class="n">Lambda</span><span class="p">,</span> <span class="n">mu</span><span class="p">)</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">priv</span>
        <span class="n">n_sq</span> <span class="o">=</span> <span class="n">n</span> <span class="o">*</span> <span class="n">n</span>
        <span class="n">x</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">Lambda</span><span class="p">,</span> <span class="n">n_sq</span><span class="p">)</span>  
        <span class="n">m</span> <span class="o">=</span> <span class="p">(((</span><span class="n">x</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">//</span> <span class="n">n</span><span class="p">)</span> <span class="o">*</span> <span class="n">mu</span><span class="p">)</span> <span class="o">%</span> <span class="n">n</span>  
        <span class="k">return</span> <span class="n">m</span>

    <span class="k">def</span> <span class="nf">get_keys</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="p">.</span><span class="n">pub</span><span class="p">,</span> <span class="bp">self</span><span class="p">.</span><span class="n">priv</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>

    <span class="k">print</span><span class="p">(</span><span class="s">"Welcome to the Secure Gate Challenge!"</span><span class="p">)</span>
    <span class="n">paillier</span> <span class="o">=</span> <span class="n">Paillier</span><span class="p">(</span><span class="mi">256</span><span class="p">)</span>
    <span class="n">pub</span><span class="p">,</span> <span class="n">priv</span> <span class="o">=</span> <span class="n">paillier</span><span class="p">.</span><span class="n">get_keys</span><span class="p">()</span>
    <span class="k">print</span><span class="p">(</span><span class="s">'(n,g)='</span><span class="p">,</span> <span class="n">pub</span><span class="p">)</span>
    <span class="n">nums</span> <span class="o">=</span> <span class="p">[</span><span class="n">secrets</span><span class="p">.</span><span class="n">randbits</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">4</span><span class="p">)]</span>
    <span class="n">res</span> <span class="o">=</span> <span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">nums</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="o">+</span> <span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">-</span> <span class="n">nums</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span>

    <span class="n">ciphers</span> <span class="o">=</span> <span class="p">[</span><span class="n">paillier</span><span class="p">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">nums</span><span class="p">]</span> 
    <span class="k">print</span><span class="p">(</span><span class="s">'c1 ='</span><span class="p">,</span> <span class="n">ciphers</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
    <span class="k">print</span><span class="p">(</span><span class="s">'c2 ='</span><span class="p">,</span> <span class="n">ciphers</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
    <span class="k">print</span><span class="p">(</span><span class="s">'c3 ='</span><span class="p">,</span> <span class="n">ciphers</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
    <span class="k">print</span><span class="p">(</span><span class="s">'c4 ='</span><span class="p">,</span> <span class="n">ciphers</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="n">start_time</span> <span class="o">=</span> <span class="n">time</span><span class="p">.</span><span class="n">time</span><span class="p">()</span>
        <span class="n">pass_code</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s">"Can you open the gate? If so, insert the passcode fast: "</span><span class="p">))</span>
        <span class="k">if</span> <span class="n">time</span><span class="p">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">start_time</span> <span class="o">&gt;</span> <span class="mi">60</span><span class="p">:</span>  
            <span class="k">print</span><span class="p">(</span><span class="s">"Too slow! Time's up!"</span><span class="p">)</span>
            <span class="nb">exit</span><span class="p">()</span>
        <span class="n">pass_decode</span> <span class="o">=</span> <span class="n">paillier</span><span class="p">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">pass_code</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">res</span> <span class="o">==</span> <span class="n">pass_decode</span><span class="p">:</span>
            <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Wow! You opened it, The flag is: </span><span class="si">{</span><span class="n">flag</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">print</span><span class="p">(</span><span class="s">"Nope, Maybe next time :("</span><span class="p">)</span>
    <span class="k">except</span> <span class="nb">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="s">"Invalid input or error occurred:"</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
        <span class="nb">exit</span><span class="p">()</span>
</code></pre></div></div>

<h2 id="分析-5">分析</h2>

<p>Paillier同态加密问题<sup id="fnref:paillier" role="doc-noteref"><a href="#fn:paillier" class="footnote" rel="footnote">2</a></sup>, 运行题目可以得知需要使用给出的四个密文c1、c2、c3、c4计算出\(c1*c2*c3*c4^{-1}\mod {n^2}\), 然后把结果作为pass_code输入, 其中(n, g)是已知的, 可以直接提取计算<code class="language-plaintext highlighter-rouge">n_sq = n * n</code>, 求出密文. 值得注意的是里面进行了时间限制, 推荐使用pwntools直接交互.</p>

<h2 id="exp-5">EXP</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">re</span>

<span class="c1">#r = remote('seal-the-deal.fmc.tf',2003)
</span><span class="n">r</span> <span class="o">=</span> <span class="n">process</span><span class="p">([</span><span class="s">'python'</span><span class="p">,</span> <span class="s">'server.py'</span><span class="p">])</span>

<span class="n">r</span><span class="p">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="n">pub_line</span> <span class="o">=</span> <span class="n">r</span><span class="p">.</span><span class="n">recvline</span><span class="p">().</span><span class="n">decode</span><span class="p">().</span><span class="n">strip</span><span class="p">()</span>
<span class="n">n</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">re</span><span class="p">.</span><span class="n">findall</span><span class="p">(</span><span class="sa">r</span><span class="s">'\d+'</span><span class="p">,</span> <span class="n">pub_line</span><span class="p">))</span>

<span class="n">ciphers</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">4</span><span class="p">):</span>
    <span class="n">line</span> <span class="o">=</span> <span class="n">r</span><span class="p">.</span><span class="n">recvline</span><span class="p">().</span><span class="n">decode</span><span class="p">().</span><span class="n">strip</span><span class="p">()</span>
    <span class="n">c</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">line</span><span class="p">.</span><span class="n">split</span><span class="p">(</span><span class="s">' = '</span><span class="p">)[</span><span class="mi">1</span><span class="p">])</span>
    <span class="n">ciphers</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>

<span class="n">c1</span><span class="p">,</span> <span class="n">c2</span><span class="p">,</span> <span class="n">c3</span><span class="p">,</span> <span class="n">c4</span> <span class="o">=</span> <span class="n">ciphers</span>
<span class="n">n_sq</span> <span class="o">=</span> <span class="n">n</span> <span class="o">*</span> <span class="n">n</span>

<span class="n">product</span> <span class="o">=</span> <span class="p">(</span><span class="n">c1</span> <span class="o">*</span> <span class="n">c2</span><span class="p">)</span> <span class="o">%</span> <span class="n">n_sq</span>
<span class="n">product</span> <span class="o">=</span> <span class="p">(</span><span class="n">product</span> <span class="o">*</span> <span class="n">c3</span><span class="p">)</span> <span class="o">%</span> <span class="n">n_sq</span>

<span class="n">inv_c4</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">c4</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">n_sq</span><span class="p">)</span>
<span class="n">pass_code</span> <span class="o">=</span> <span class="p">(</span><span class="n">product</span> <span class="o">*</span> <span class="n">inv_c4</span><span class="p">)</span> <span class="o">%</span> <span class="n">n_sq</span>
<span class="n">r</span><span class="p">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">pass_code</span><span class="p">).</span><span class="n">encode</span><span class="p">())</span>

<span class="k">print</span><span class="p">(</span><span class="n">r</span><span class="p">.</span><span class="n">recvall</span><span class="p">())</span>

<span class="c1"># b'Can you open the gate? If so, insert the passcode fast: Wow! You opened it, The flag is: FMCTF{P41ll13r_h0m0m0rph1c_3n4bl35_c0mpu7at10n_0n_c1ph3r5}'
</span></code></pre></div></div>

<h1 id="superguesser">superguesser</h1>

<h2 id="题目-6">题目</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/local/bin/python
</span>
<span class="kn">import</span> <span class="nn">random</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.Padding</span> <span class="kn">import</span> <span class="n">pad</span>

<span class="n">MAX_ATTEMPTS</span> <span class="o">=</span> <span class="mi">1000</span>

<span class="k">def</span> <span class="nf">encrypt_flag</span><span class="p">(</span><span class="n">flag</span><span class="p">):</span>
    <span class="n">key</span> <span class="o">=</span> <span class="n">random</span><span class="p">.</span><span class="n">getrandbits</span><span class="p">(</span><span class="mi">128</span><span class="p">).</span><span class="n">to_bytes</span><span class="p">(</span><span class="mi">16</span><span class="p">,</span> <span class="s">'big'</span><span class="p">)</span>
    <span class="n">iv</span> <span class="o">=</span> <span class="n">random</span><span class="p">.</span><span class="n">getrandbits</span><span class="p">(</span><span class="mi">128</span><span class="p">).</span><span class="n">to_bytes</span><span class="p">(</span><span class="mi">16</span><span class="p">,</span> <span class="s">'big'</span><span class="p">)</span>
    <span class="n">cipher</span> <span class="o">=</span> <span class="n">AES</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">AES</span><span class="p">.</span><span class="n">MODE_CBC</span><span class="p">,</span> <span class="n">iv</span><span class="p">)</span>
    <span class="n">encrypted</span> <span class="o">=</span> <span class="n">cipher</span><span class="p">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">pad</span><span class="p">(</span><span class="n">flag</span><span class="p">.</span><span class="n">encode</span><span class="p">(),</span> <span class="n">AES</span><span class="p">.</span><span class="n">block_size</span><span class="p">))</span>
    <span class="k">return</span> <span class="n">encrypted</span>

<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">random</span><span class="p">.</span><span class="n">seed</span><span class="p">(</span><span class="n">time</span><span class="p">.</span><span class="n">time</span><span class="p">())</span>
    <span class="n">encrypted_flag</span> <span class="o">=</span> <span class="n">encrypt_flag</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s">'./flag.txt'</span><span class="p">).</span><span class="n">read</span><span class="p">())</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">✨ Welcome to the **Guess the Number Challenge v1**! ✨"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"🕵️‍♂️ Can you uncover the secret behind the encrypted flag?"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"📜 Use your intelligence, strategy, and the hints provided to succeed!"</span><span class="p">)</span>

    <span class="k">print</span><span class="p">(</span><span class="s">"Your task: Use your wits and strategy to uncover hints to decrypt the flag."</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\n</span><span class="s">Here is your encrypted flag: </span><span class="se">\n</span><span class="si">{</span><span class="n">encrypted_flag</span><span class="p">.</span><span class="nb">hex</span><span class="p">()</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">But don't worry, I'm generous. I've precomputed 1000 random hints for you!"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"You have </span><span class="si">{</span><span class="n">MAX_ATTEMPTS</span><span class="si">}</span><span class="s"> attempts to guess the right index.</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span>
    <span class="n">hints</span> <span class="o">=</span> <span class="p">[</span><span class="n">random</span><span class="p">.</span><span class="n">getrandbits</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1000</span><span class="p">)]</span>
    <span class="k">for</span> <span class="n">attempt</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">MAX_ATTEMPTS</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
        <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Attempt </span><span class="si">{</span><span class="n">attempt</span><span class="si">}</span><span class="s">/</span><span class="si">{</span><span class="n">MAX_ATTEMPTS</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">index</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s">"Enter an index (0-999): "</span><span class="p">).</span><span class="n">strip</span><span class="p">())</span>
            <span class="k">if</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">index</span> <span class="o">&lt;</span> <span class="mi">1000</span><span class="p">:</span>
                <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"🔑 Hint at index </span><span class="si">{</span><span class="n">index</span><span class="si">}</span><span class="s">: </span><span class="si">{</span><span class="n">hints</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">print</span><span class="p">(</span><span class="s">"❌ Invalid index! Please enter a number between 0 and 999.</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span>
        <span class="k">except</span> <span class="nb">ValueError</span><span class="p">:</span>
            <span class="k">print</span><span class="p">(</span><span class="s">"❌ Invalid input! Please enter a valid integer.</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">✨ Your attempts are over! But don't give up just yet."</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"✨ Your attempts are over! Good luck solving the challenge!</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"🔍 Don't forget: The key to solving the challenge lies in these random hints. Goodbye!"</span><span class="p">)</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</code></pre></div></div>

<h2 id="分析-6">分析</h2>

<p>这两题差不多, 可以直接参考下面.</p>

<h1 id="superguesser_v2">superguesser_v2</h1>

<h2 id="题目-7">题目</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/local/bin/python
</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">random</span>
<span class="kn">from</span> <span class="nn">Crypto.Cipher</span> <span class="kn">import</span> <span class="n">AES</span>
<span class="kn">from</span> <span class="nn">Crypto.Util.Padding</span> <span class="kn">import</span> <span class="n">pad</span>

<span class="n">MAX_ATTEMPTS</span> <span class="o">=</span> <span class="mi">10</span>

<span class="k">def</span> <span class="nf">encrypt_flag</span><span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="n">iv</span><span class="p">):</span>
    <span class="n">key</span> <span class="o">=</span> <span class="n">random</span><span class="p">.</span><span class="n">getrandbits</span><span class="p">(</span><span class="mi">128</span><span class="p">).</span><span class="n">to_bytes</span><span class="p">(</span><span class="mi">16</span><span class="p">,</span> <span class="s">'big'</span><span class="p">)</span>
    <span class="n">cipher</span> <span class="o">=</span> <span class="n">AES</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">AES</span><span class="p">.</span><span class="n">MODE_CBC</span><span class="p">,</span> <span class="n">iv</span><span class="o">*</span><span class="mi">2</span><span class="p">)</span>
    <span class="n">encrypted</span> <span class="o">=</span> <span class="n">cipher</span><span class="p">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">pad</span><span class="p">(</span><span class="n">flag</span><span class="p">.</span><span class="n">encode</span><span class="p">(),</span> <span class="n">AES</span><span class="p">.</span><span class="n">block_size</span><span class="p">))</span>
    <span class="k">return</span> <span class="n">encrypted</span>

<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">secureSeed</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">urandom</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
    <span class="n">random</span><span class="p">.</span><span class="n">seed</span><span class="p">(</span><span class="n">secureSeed</span><span class="p">)</span>
    <span class="n">hints</span> <span class="o">=</span> <span class="p">[</span><span class="n">random</span><span class="p">.</span><span class="n">getrandbits</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">624</span><span class="p">)]</span>
    <span class="n">encrypted_flag</span> <span class="o">=</span> <span class="n">encrypt_flag</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s">'./flag.txt'</span><span class="p">).</span><span class="n">read</span><span class="p">(),</span> <span class="n">secureSeed</span><span class="p">)</span>

    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">✨ Welcome to the **Guess the Number Challenge v2**! ✨"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"🕵️‍♂️ Your mission: Decode the encrypted flag by uncovering critical hints."</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"📊 We've precomputed 624 random numbers using a secure PRNG."</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"❗ But there's a catch: You can only access </span><span class="si">{</span><span class="n">MAX_ATTEMPTS</span><span class="si">}</span><span class="s"> of them."</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"🔑 Choose your indices wisely to uncover the key!"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">📜 Instructions:"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"1️⃣ You have 624 unique random numbers that are critical for decrypting the flag."</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"2️⃣ Enter an index (0-623) to reveal a hint."</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"3️⃣ You only have </span><span class="si">{</span><span class="n">MAX_ATTEMPTS</span><span class="si">}</span><span class="s"> attempts, so choose wisely!"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"4️⃣ Use your understanding of randomness to crack the secure seed."</span><span class="p">)</span>

    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\n</span><span class="s">🔒 Here is your encrypted flag: </span><span class="se">\n</span><span class="si">{</span><span class="n">encrypted_flag</span><span class="p">.</span><span class="nb">hex</span><span class="p">()</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\n</span><span class="s">Good luck! You have </span><span class="si">{</span><span class="n">MAX_ATTEMPTS</span><span class="si">}</span><span class="s"> attempts to guess the correct index.</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span>

    <span class="k">for</span> <span class="n">attempt</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">MAX_ATTEMPTS</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
        <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Attempt </span><span class="si">{</span><span class="n">attempt</span><span class="si">}</span><span class="s">/</span><span class="si">{</span><span class="n">MAX_ATTEMPTS</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">index</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s">"Enter an index (0-624): "</span><span class="p">).</span><span class="n">strip</span><span class="p">())</span>
            <span class="k">if</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">index</span> <span class="o">&lt;</span> <span class="mi">624</span><span class="p">:</span>
                <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Hint at index </span><span class="si">{</span><span class="n">index</span><span class="si">}</span><span class="s">: </span><span class="si">{</span><span class="n">hints</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="si">}</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">print</span><span class="p">(</span><span class="s">"❌ Invalid index! Please enter a number between 0 and 624.</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span>
        <span class="k">except</span> <span class="nb">ValueError</span><span class="p">:</span>
            <span class="k">print</span><span class="p">(</span><span class="s">"❌ Invalid input! Please enter a valid integer.</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"✨ Your attempts are over! Good luck solving the challenge!</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"🔍 Remember, the flag is encrypted. Use your hints wisely. Goodbye!"</span><span class="p">)</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</code></pre></div></div>

<h2 id="分析-7">分析</h2>

<p>可以使用<a href="https://github.com/StackeredSAS/python-random-playground/blob/main/recover_BytesV2Seed.py">random库POC脚本</a>进行攻击,<sup id="fnref:prng" role="doc-noteref"><a href="#fn:prng" class="footnote" rel="footnote">3</a></sup>, 有点麻烦, 刚好最近忙, 有时间单独开一个博客写.</p>

<h1 id="参考文献">参考文献</h1>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:sagemath" role="doc-endnote">
      <p>sakana_ctf.欢迎来到Sage社区[EB/OL].gitee.<a target="_blank" href="https://gitee.com/sakana_ctf/sagemath/blob/master/sakana/polynomial/basic.md">https://gitee.com/sakana_ctf/sagemath/blob/master/sakana/polynomial/basic.md</a>.2023-11-22 <a href="#fnref:sagemath" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:paillier" role="doc-endnote">
      <table>
        <tbody>
          <tr>
            <td>joey.应用密码学</td>
            <td>Paillier同态加密算法简介[EB/OL].gitee.<a target="_blank" href="https://zhuanlan.zhihu.com/p/557034854">https://zhuanlan.zhihu.com/p/557034854</a>.2023-08-29</td>
          </tr>
        </tbody>
      </table>
      <p><a href="#fnref:paillier" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:prng" role="doc-endnote">
      <p>StackeredSAS.Python random playground[EB/OL].github.<a target="_blank" href="https://github.com/StackeredSAS/python-random-playground">https://github.com/StackeredSAS/python-random-playground</a>.2024-04-16 <a href="#fnref:prng" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>CryingN</name><email>CryingNights7v@gmail.com</email></author><category term="CTF" /><category term="网络安全" /><category term="密码学" /><category term="非对称加密" /><category term="rsa" /><summary type="html"><![CDATA[对萌新挺友好的一场比赛, 抽时间刷了一下...]]></summary></entry><entry><title type="html">[electron] 魔改一个适合自己的Marktext.</title><link href="https://cryingn.github.io/posts/2025/03/vedal/" rel="alternate" type="text/html" title="[electron] 魔改一个适合自己的Marktext." /><published>2025-03-06T00:00:00+08:00</published><updated>2025-03-06T00:00:00+08:00</updated><id>https://cryingn.github.io/posts/2025/03/marktext</id><content type="html" xml:base="https://cryingn.github.io/posts/2025/03/vedal/"><![CDATA[<h1 id="目录">目录</h1>

<ul>
  <li><a href="#自定义marktext">自定义marktext</a>
    <ul>
      <li><a href="#修改主题">修改主题</a></li>
      <li><a href="#居中">居中</a></li>
      <li><a href="#导出文件配置">导出文件配置</a></li>
    </ul>
  </li>
  <li><a href="#原理分析">原理分析</a></li>
  <li><a href="#参考文献">参考文献</a></li>
</ul>

<h1 id="自定义marktext">自定义marktext</h1>

<p>与题主面临了差不多的困境, 搜索了一下刚好找到文章, 于是也学着修改并记录一下. 首先是解包, 看起来似乎是一个electron程序, chromium加一(悲):</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd </span>resources
<span class="c"># 解包asar文件</span>
npx asar extract app.asar app
<span class="c"># 打包asar文件</span>
npx asar pack app app.asar
</code></pre></div></div>

<p>这里的npx实际来自于nodejs的npm管理包, 但是我在archwiki上反应过archwsl1不兼容的问题<sup id="fnref:archwiki" role="doc-noteref"><a href="#fn:archwiki" class="footnote" rel="footnote">1</a></sup>, 虽然明确是二进制文件<code class="language-plaintext highlighter-rouge">/usr/sbin/node</code>存在问题, 但目前没能力解决, 当前使用的替代方案是直接在官网<a href="https://nodejs.cn/download/">下载</a>, 官网的包是直接包含npx的<sup id="fnref:npx" role="doc-noteref"><a href="#fn:npx" class="footnote" rel="footnote">2</a></sup>.</p>

<h2 id="修改主题">修改主题</h2>

<p>这里在学习时先照着改了一下功能, 直接找到<code class="language-plaintext highlighter-rouge">./app/dist/electron/main.js</code>文件, 其中有函数<code class="language-plaintext highlighter-rouge">function Bt(e)</code>, 测试了一下, 主题是有上限的(会出bug), 只能直接修改掉其他主题(这里是把one dark主题改掉了, 感觉属于很没什么用的主题):</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">Bt</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="p">{</span> <span class="na">theme</span><span class="p">:</span> <span class="nx">t</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">getAll</span><span class="p">();</span>
  <span class="k">return</span> <span class="p">{</span>
    <span class="na">label</span><span class="p">:</span> <span class="dl">"</span><span class="s2">&amp;Theme</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">id</span><span class="p">:</span> <span class="dl">"</span><span class="s2">themeMenu</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">submenu</span><span class="p">:</span> <span class="p">[</span>
      <span class="c1">//...</span>
      <span class="p">{</span>
        <span class="na">label</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Sakana Light</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">type</span><span class="p">:</span> <span class="dl">"</span><span class="s2">radio</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">id</span><span class="p">:</span> <span class="dl">"</span><span class="s2">graphite</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">checked</span><span class="p">:</span> <span class="dl">"</span><span class="s2">graphite</span><span class="dl">"</span> <span class="o">===</span> <span class="nx">t</span><span class="p">,</span>
        <span class="nx">click</span><span class="p">(</span><span class="nx">e</span><span class="p">,</span> <span class="nx">t</span><span class="p">)</span> <span class="p">{</span>
          <span class="nx">Oe</span><span class="p">(</span><span class="dl">"</span><span class="s2">graphite</span><span class="dl">"</span><span class="p">);</span>
        <span class="p">},</span>
      <span class="p">},</span>
    <span class="p">],</span>
  <span class="p">};</span>
<span class="p">}</span>
</code></pre></div></div>

<p>找到<code class="language-plaintext highlighter-rouge">./app/dist/electron/renderer.js</code>如下形式的文件:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">46024</span><span class="p">:</span> <span class="p">(</span><span class="nx">e</span><span class="p">,</span> <span class="nx">t</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="dl">"</span><span class="s2">use strict</span><span class="dl">"</span><span class="p">;</span>
        <span class="nx">i</span><span class="p">.</span><span class="nx">r</span><span class="p">(</span><span class="nx">t</span><span class="p">),</span> <span class="nx">i</span><span class="p">.</span><span class="nx">d</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="p">{</span> <span class="na">default</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">s</span> <span class="p">});</span>
        <span class="kd">var</span> <span class="nx">n</span> <span class="o">=</span> <span class="nx">i</span><span class="p">(</span><span class="mi">87537</span><span class="p">),</span>
          <span class="nx">o</span> <span class="o">=</span> <span class="nx">i</span><span class="p">.</span><span class="nx">n</span><span class="p">(</span><span class="nx">n</span><span class="p">),</span>
          <span class="nx">r</span> <span class="o">=</span> <span class="nx">i</span><span class="p">(</span><span class="mi">23645</span><span class="p">),</span>
          <span class="nx">a</span> <span class="o">=</span> <span class="nx">i</span><span class="p">.</span><span class="nx">n</span><span class="p">(</span><span class="nx">r</span><span class="p">)()(</span><span class="nx">o</span><span class="p">());</span>
        <span class="nx">a</span><span class="p">.</span><span class="nx">push</span><span class="p">([</span>
          <span class="nx">e</span><span class="p">.</span><span class="nx">id</span><span class="p">,</span>
          <span class="dl">"</span><span class="s2">:root {...</span><span class="dl">"</span><span class="p">,</span> <span class="c1">// 这里是对应的主题css信息, 虽然是一条长串, 不过可以通过一些特殊手法解决.</span>
          <span class="dl">""</span><span class="p">,</span>
          <span class="p">{</span>
            <span class="na">version</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
            <span class="na">sources</span><span class="p">:</span> <span class="p">[</span>
              <span class="dl">"</span><span class="s2">webpack://./src/renderer/assets/themes/one-dark.theme.css</span><span class="dl">"</span><span class="p">,</span>
            <span class="p">],</span>
            <span class="na">names</span><span class="p">:</span> <span class="p">[],</span>
            <span class="na">mappings</span><span class="p">:</span>
              <span class="dl">"</span><span class="s2">AAAA;EACE,SAAS...</span><span class="dl">"</span><span class="p">,</span>
            <span class="na">sourceRoot</span><span class="p">:</span> <span class="dl">""</span><span class="p">,</span>
          <span class="p">},</span>
        <span class="p">]);</span>
        <span class="kd">const</span> <span class="nx">s</span> <span class="o">=</span> <span class="nx">a</span><span class="p">;</span>
      <span class="p">},</span>
</code></pre></div></div>

<p>这里直接复制到新的css的信息到新的文件(比如<strong>theme.css</strong>), 因为存在格式化字符, 可以使用python完成格式化:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Reverse</span> <span class="o">=</span> <span class="bp">True</span><span class="c1">#False
</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">"theme.css"</span><span class="p">,</span> <span class="s">"r"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
    <span class="n">data</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="n">readlines</span><span class="p">()</span>
<span class="k">if</span> <span class="n">Reverse</span><span class="p">:</span>
    <span class="n">new_data</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">replace</span><span class="p">(</span><span class="s">'</span><span class="se">\\</span><span class="s">r'</span><span class="p">,</span><span class="s">'</span><span class="se">\r</span><span class="s">'</span><span class="p">).</span><span class="n">replace</span><span class="p">(</span><span class="s">'</span><span class="se">\\</span><span class="s">n'</span><span class="p">,</span> <span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
    <span class="n">new_data</span> <span class="o">=</span> <span class="s">''</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
        <span class="n">new_data</span> <span class="o">+=</span> <span class="n">i</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">].</span><span class="n">replace</span><span class="p">(</span><span class="s">'</span><span class="se">\r</span><span class="s">'</span><span class="p">,</span> <span class="s">'</span><span class="se">\\</span><span class="s">r'</span><span class="p">)</span>
        <span class="n">new_data</span> <span class="o">+=</span> <span class="s">'</span><span class="se">\\</span><span class="s">n'</span>
    <span class="n">new_data</span> <span class="o">=</span> <span class="n">new_data</span>

<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">"theme.css"</span><span class="p">,</span> <span class="s">"w"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
    <span class="n">f</span><span class="p">.</span><span class="n">write</span><span class="p">(</span><span class="n">new_data</span><span class="p">)</span>
</code></pre></div></div>

<p>将python文件保存在<strong>theme.css</strong>相同路径, 并通过修改Reverse为<code class="language-plaintext highlighter-rouge">True</code>和<code class="language-plaintext highlighter-rouge">False</code>实现还原文件格式.</p>

<h2 id="居中">居中</h2>

<p>我挺喜欢的居中来着, <code class="language-plaintext highlighter-rouge">UIysses</code>的标题居中其实做得挺好, 不过做的是只要属于标题一律居中, 我期望的是大标题居中, 小标题依然左对齐, 于是在编辑过程中可以添加上:</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="c">/* --- Font type ------------------------------------------------ */</span>
  <span class="nt">h1</span><span class="o">,</span> <span class="nt">h2</span><span class="o">,</span> <span class="nt">h3</span> <span class="p">{</span>
    <span class="nl">text-align</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span>
  <span class="p">}</span>
</code></pre></div></div>

<h2 id="导出文件配置">导出文件配置</h2>

<p>稍微改完主题以后稍微往上翻一下, 同样是<code class="language-plaintext highlighter-rouge">./app/dist/electron/renderer.js</code>中也存在导出配置的编辑内容, 我认为默认改为自己编写的导出的内容, 可以先定义到<code class="language-plaintext highlighter-rouge">if ("academic" === d)</code>位置, 重写成以下逻辑:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="dl">"</span><span class="s2">academic</span><span class="dl">"</span> <span class="o">===</span> <span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="p">{</span> <span class="na">userDataPath</span><span class="p">:</span> <span class="nx">e</span> <span class="p">}</span> <span class="o">=</span> <span class="nb">global</span><span class="p">.</span><span class="nx">marktext</span><span class="p">.</span><span class="nx">paths</span><span class="p">,</span>
    <span class="nx">t</span> <span class="o">=</span> <span class="nx">ne</span><span class="p">().</span><span class="nx">join</span><span class="p">(</span><span class="nx">e</span><span class="p">,</span> <span class="dl">"</span><span class="s2">themes/export</span><span class="dl">"</span><span class="p">,</span> <span class="nx">d</span><span class="p">);</span>
  <span class="k">if</span> <span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="nx">Bt</span><span class="p">.</span><span class="nx">zE</span><span class="p">)(</span><span class="nx">t</span><span class="p">))</span>
    <span class="k">try</span> <span class="p">{</span>
      <span class="nx">h</span> <span class="o">+=</span> <span class="nx">We</span><span class="p">().</span><span class="nx">readFileSync</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="dl">"</span><span class="s2">utf8</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{}</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="dl">"</span><span class="s2">liber</span><span class="dl">"</span> <span class="o">===</span> <span class="nx">d</span><span class="p">)</span> <span class="nx">h</span> <span class="o">+=</span> <span class="nx">TA</span><span class="p">();</span>
<span class="k">else</span> <span class="p">{</span>
  <span class="nx">h</span> <span class="o">+=</span> <span class="nx">SA</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>但是实际测试了一下并没有生效, 反而出现了奇怪的问题, 至于导出文件的模板可以直接参考<a href="#修改主题">修改主题</a>.</p>

<p>其实很多问题到后面反而没有解决, 最近一堆事情忙得不可开交, 也发现了默认博客的一堆局限, 有时间想重新偷个框架来慢慢改, 后续要是能把单文件打开的问题一起解决的话再好好重写一下这篇记录.</p>

<h1 id="参考文献">参考文献</h1>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:archwiki" role="doc-endnote">
      <p>CryingN.wsl1安装nodejs无法运行[EB/OL].archwiki.<a target="_blank" href="https://bbs.archlinuxcn.org/viewtopic.php?pid=62419#p62419">https://bbs.archlinuxcn.org/viewtopic.php?pid=62419#p62419</a>.2025-03-04 <a href="#fnref:archwiki" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:npx" role="doc-endnote">
      <p>古兰精.linux服务器安装nodeJS步骤及踩坑记录（解决node -v报错cannot execute binary file: Exec format error的问题 - 在Linux中安装适用于arm64位的nodejs）以及node环境项目部署[EB/OL].博客园.<a target="_blank" href="https://www.cnblogs.com/goloving/p/14788900.html">https://www.cnblogs.com/goloving/p/14788900.html</a>.2021-05-20 <a href="#fnref:npx" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>CryingN</name><email>CryingNights7v@gmail.com</email></author><category term="Reverse" /><category term="electron" /><category term="程序开发" /><category term="marktext" /><summary type="html"><![CDATA[授人以鱼不如授人以渔, 实现自定义Marktext可以说是程序员导出PDF的理想配置了...]]></summary></entry><entry><title type="html">[测试] 对南梁的基本研究</title><link href="https://cryingn.github.io/posts/2025/03/vedal/" rel="alternate" type="text/html" title="[测试] 对南梁的基本研究" /><published>2025-03-02T00:00:00+08:00</published><updated>2025-03-02T00:00:00+08:00</updated><id>https://cryingn.github.io/posts/2025/03/vedal</id><content type="html" xml:base="https://cryingn.github.io/posts/2025/03/vedal/"><![CDATA[<h1 id="目录">目录</h1>

<ul>
  <li><a href="#南梁的起源与发展">南梁的起源与发展</a>
    <ul>
      <li><a href="#起源">起源</a></li>
      <li><a href="#发展">发展</a></li>
    </ul>
  </li>
  <li><a href="#南梁的研究现状">南梁的研究现状</a>
    <ul>
      <li><a href="#现状">现状</a></li>
      <li><a href="#结论">结论</a></li>
    </ul>
  </li>
  <li><a href="#南梁的特征分析">南梁的特征分析</a>
    <ul>
      <li><a href="#个人体质">个人体质</a></li>
      <li><a href="#服装">服装</a></li>
      <li><a href="#姿态">姿态</a></li>
    </ul>
  </li>
  <li><a href="#总结">总结</a></li>
  <li><a href="#参考文献">参考文献</a></li>
</ul>

<h1 id="南梁的起源与发展">南梁的起源与发展</h1>

<h2 id="起源">起源</h2>

<p>“男娘”是一个源自日本的俚语，用于描绘男性在穿着或性格上展现出的女性特质。它既可以指代跨性别者，即那些生理上为男性但心理上认同为女性或具有女性特质的人，也涵盖那些出于爱好或表演需要而扮演女性角色的男性。在日本，男娘文化已经发展得相对成熟，并受到了一定的社会关注<sup id="fnref:female" role="doc-noteref"><a href="#fn:female" class="footnote" rel="footnote">1</a></sup>。</p>

<h2 id="发展">发展</h2>

<h3 id="文化扩散">文化扩散</h3>

<p>随着全球化的进程，男娘文化逐渐从日本传播到其他国家，包括中国等。在中国，男娘文化也逐渐受到一些年轻人的关注和追捧，特别是在二次元文化、cosplay等领域中。</p>

<h3 id="社会接受度变化">社会接受度变化</h3>

<p>男娘文化在不同国家和地区的社会接受度存在差异。在一些地方，男娘仍然被视为异类文化，受到社会的歧视和排斥。然而，在一些时尚和文化活动中，如cosplay和舞蹈演出等，男娘文化也受到了一定的欢迎和接受。</p>

<h3 id="群体特征">群体特征</h3>

<p>男娘群体通常具有一些共同的特征，如柔软的发丝、娇嫩的皮肤、小巧的身材等女性化的外表特征。他们的言谈举止也通常更加柔和、温暖，表现出女性的柔弱及美好。此外，男娘的爱好也更加多元化，可能包括看恋爱剧、购物、跳舞、唱歌和做手工艺品等女性化的爱好。</p>

<h3 id="心理因素">心理因素</h3>

<p>男娘现象的发展还受到多种心理因素的影响。例如，家庭环境、社会环境等对男性心理的影响可能导致一些男性在性别认同上产生困惑或偏差。变声期声调异常、环境雌激素等生理因素也可能对男性产生女性化倾向起到一定作用。</p>

<h3 id="社会根源与结构性问题">社会根源与结构性问题</h3>

<p>男娘现象不仅仅是对性别认同和表达的一种探索，更深刻反映了社会对男性和女性角色定位的刻板印象和束缚。在私有制为主导的经济体制下，青少年和年轻人普遍面临着就业竞争激烈、经济压力巨大的挑战。这些压力可能促使他们寻求一种能够暂时逃离现实的方式来舒缓内心的焦虑和矛盾。因此，“男娘”现象可以视为这些个体在面对社会现实和阶级差异时的一种自我表达和寻求认同的方式。</p>

<h1 id="南梁的研究现状">南梁的研究现状</h1>

<p>当前主要从社会学, 统计学和心理学等角度对南梁现象进行了一定的研究。</p>

<h2 id="现状">现状</h2>

<h3 id="统计学角度">统计学角度</h3>

<p>通过文献研究方法,从测量工具、调查过程和估计结果3个方面分别梳理了西方国家和中国的当前对于男娘现象的研究，这些研究试图通过收集男娘群体的基本信息（如年龄、性别认同、兴趣爱好等）来描绘这一群体的特征，然而，由于男娘群体相对小众且分散，数据收集的难度较大，导致目前关于男娘现象的统计数据相对有限，且可能存在偏差<sup id="fnref:yangxueyan" role="doc-noteref"><a href="#fn:yangxueyan" class="footnote" rel="footnote">2</a></sup>。</p>

<p>尽管数据有限，但一些研究仍然尝试对男娘现象进行趋势分析。例如，通过观察社交媒体上关于男娘话题的讨论热度、男娘相关产品的销量等数据，来推断男娘现象的流行程度和发展趋势。</p>

<p>这些分析表明，男娘现象在某些地区和群体中呈现出逐渐增长的趋势，尤其是在年轻一代中更为普遍。</p>

<h3 id="社会学角度">社会学角度</h3>

<p>统计学研究还关注男娘现象背后的社会背景和影响因素。例如，性别角色的模糊化、社会文化的多元化以及互联网的普及等因素都被认为是推动男娘现象发展的重要因素。</p>

<p>这些因素共同作用于社会结构之中，使得越来越多的男性开始探索和尝试不同的性别表达方式，包括男娘这种相对边缘化的性别表达方式。</p>

<h3 id="心理学角度">心理学角度</h3>

<p>心理学研究认为，男娘现象反映了部分男性在性别认同上的困惑和探索。这些男性可能对传统性别角色定位感到不满或压抑，因此通过男娘这种性别表达方式来寻求自我认同和内心满足。</p>

<p>心理动力学理论认为，男娘现象可能源于个体在成长过程中对性别角色的冲突和矛盾。这些冲突和矛盾在个体心理内部产生张力，进而推动个体去探索和尝试不同的性别表达方式。</p>

<h2 id="结论">结论</h2>

<p>对于男娘现象的研究仍然存在着一些局限。例如，数据收集的困难导致研究结果可能存在偏差；研究方法相对单一，缺乏跨学科的综合研究；对男娘现象的社会文化背景和深层次心理机制的探讨还不够深入等。</p>

<p>综上所述，当前对于男娘现象的研究在统计学和心理学等学术领域都取得了一定的进展，但仍然存在着一些局限和挑战。未来需要进一步加强跨学科的综合研究，采用更加多样化和创新性的研究方法，以全面深入地探讨男娘的现象。</p>

<h1 id="南梁的特征分析">南梁的特征分析</h1>

<p>以下参考个人体质, 服装, 姿态三个维度对男娘的特征进行分析<sup id="fnref:sanye" role="doc-noteref"><a href="#fn:sanye" class="footnote" rel="footnote">3</a></sup>.</p>

<h2 id="个人体质">个人体质</h2>

<p>男娘的个人体质可能因个体差异而异，但一般而言，他们可能更注重身体的保养和塑造，以适应女装的需求。一些男娘可能会通过健身、饮食调整等方式来改善身体线条，使自己更符合女性化的审美标准。</p>

<h3 id="健身训练">健身训练</h3>

<p>有氧运动是消耗卡路里、减少体脂的最佳选择，有助于全身脂肪的燃烧，减少体脂率，塑造健康的身体线条, 以跑步、游泳、跳绳、骑自行车等有氧运动为益, 力量训练可以通过提升肌肉量来塑造身体曲线，尤其是针对女性想要塑造的胸部、腰部和臀部曲线, 但是过度进行力量训练会导致肌肉线条过于硬朗，反而与女性化气质不符, 应考虑适当为益。</p>

<h3 id="饮食营养">饮食营养</h3>

<p>人体所需的七大营养素是指：碳水化合物、脂肪、蛋白质、水、微生素、矿物质和膳食纤维。这些营养素在人体的功效包括：提供能量、构成和修复机体组织、调节代谢以维持机体的正常生理和生化功能。可见，饮食营养的合理与否直接关系机体功能<sup id="fnref:yinshi" role="doc-noteref"><a href="#fn:yinshi" class="footnote" rel="footnote">4</a></sup>。</p>

<p>减脂阶段应当保持轻微的热量赤字，而增肌阶段则需要摄入适量的热量盈余, 可以通过计算每日基础代谢率（BMR）<sup id="fnref:lvhaihong" role="doc-noteref"><a href="#fn:lvhaihong" class="footnote" rel="footnote">5</a></sup>:</p>

\[基础代谢率 = ((脉率 + 脉压差) - 111) * 100\%\]

<p>并根据个人目标（减脂、增肌或保持体型）设定适合的热量摄入目标, 蛋白质是肌肉生长和修复的基础，对于塑造女性化身体线条至关重要, 建议每公斤体重摄入1.5-2克的优质蛋白质, 碳水化合物应适当控制在能够为运动提供能量即可，建议多选择谷物、蔬菜、水果等富含纤维的碳水来源, 脂肪有助于体内激素的分泌、皮肤的健康等，建议选择橄榄油、坚果、鱼类等富含不饱和脂肪的食品。</p>

<h3 id="皮肤保养">皮肤保养</h3>

<p>同时，男娘也应该关注自己的皮肤状况，保持肌肤的细腻和光滑，为化妆打下良好的基础, 为了提升男娘的整体形象，更加符合女性化的审美标准，化妆品的选择、化妆品的应用以及指甲护理都是非常重要的方面。以下是对这三个方面的详细分析。</p>

<h4 id="护肤">护肤</h4>

<p>其中洁面产品应选择温和、无刺激的洁面乳或洁面啫喱，以去除面部污垢和多余油脂，保持肌肤清洁, 使用含有保湿成分的爽肤水，以平衡肌肤水油平衡，为后续护肤打下良好基础, 根据肤质可以选择适合自己的面霜或乳液，以提供必要的滋润和保湿。</p>

<h4 id="底妆">底妆</h4>

<p>底妆可以选择质地轻薄、易于涂抹的BB霜或CC霜，以均匀肤色、遮盖瑕疵，使肌肤看起来更加细腻、有光泽, 瑕疵膏可以针对黑眼圈、痘痘、色斑等进行瑕疵，可以选择与自己肤色相近的遮瑕膏进行遮盖。</p>

<h4 id="彩妆">彩妆</h4>

<p>彩妆主要分为眼影、眼线、睫毛膏和唇膏等，以突出眼部轮廓、增加眼部立体感、放大眼睛效果以及增添唇部魅力, 其中可以进行如下选择:</p>

<ul>
  <li>眼影：选择自然、柔和的眼影颜色，如粉色、棕色等，以突出眼部轮廓，增加眼部立体感。</li>
  <li>眼线：使用眼线笔或眼线液，描绘出细长的眼线，使眼睛看起来更加有神、深邃。</li>
  <li>睫毛膏：使用透明或淡色的睫毛膏，使睫毛更加浓密、卷翘，从而放大眼睛效果。</li>
  <li>唇膏/口红：选择粉色、红色等女性化色彩的唇膏或口红，以增添唇部魅力，使整体妆容更加协调。</li>
</ul>

<h4 id="化妆品的应用">化妆品的应用</h4>

<p>在涂抹底妆产品时，可采用拍打或按压的方式，使产品更加贴合肌肤，避免产生厚重感。应该注意颈部与面部的色差，可选择与面部肤色相近的底妆产品，对颈部进行适当修饰，使整体肤色更加均匀。</p>

<p>在画眼影时，可采用渐变色的方式，从眼窝处向眼尾逐渐加深颜色，以营造出层次感。画眼线时，可沿着上眼睑轻轻描绘，注意保持线条流畅、自然。刷睫毛膏时，可采用Z字形刷法，从睫毛根部开始刷起，使睫毛更加浓密、卷翘。</p>

<p>在涂抹唇膏或口红前，可先使用润唇膏进行打底，以保持唇部滋润、柔软。根据个人肤色和喜好，选择合适的唇膏或口红颜色进行涂抹。涂抹时可采用从中间向两侧的方式，使唇色更加均匀、自然。</p>

<h4 id="指甲护理">指甲护理</h4>

<p>应该定期修剪指甲，保持指甲长度适中。过长的指甲容易断裂、感染，适度修剪可减少相关风险, 选用合适的产品温和去除手部死皮，通常一周一次即可。过度角化会导致指甲变厚、不平滑，影响外观及功能。</p>

<h2 id="服装">服装</h2>

<p>款式选择：男娘在服装选择上通常倾向于女性化的款式，如连衣裙、短裙、高跟鞋、丝袜等。他们可能会根据自己的喜好和身材特点来挑选合适的服装，以展现自己的女性魅力。</p>

<p>细节处理：男娘在服装细节上也十分讲究，如领口、袖口、裙摆等部位的设计和处理。他们可能会通过精致的细节来提升自己的整体形象，使自己更加符合女性化的审美标准。</p>

<h2 id="姿态">姿态</h2>
<p>身体语言：男娘在姿态上通常会注重女性化的身体语言，如优雅的坐姿、轻盈的步态等。他们可能会通过观察女性模特或学习女性舞蹈等方式来提升自己的姿态和气质。</p>

<p>表情管理：男娘在表情管理上也可能更注重女性化的表达，如微笑、眨眼等动作。这些表情的运用可以使他们看起来更加温柔、可爱，增强整体的女性化效果。</p>

<p>自信展现：最重要的是，男娘在姿态上会展现出一种自信和从容。他们不会因为自己的特殊喜好而感到尴尬或不安，而是敢于展示自己的个性和风格，成为自己人生舞台上的主角。</p>

<h3 id="总结">总结</h3>

<p>从学术角度研究，“男娘”现象作为日本起源的一种文化表达，描绘了男性在穿着与性格上展现的女性特质，涵盖了跨性别者与角色扮演者。该文化随着全球化进程传播至包括中国在内的多国，尤其在二次元与cosplay领域受到年轻群体的关注。社会接受度因地域而异，但逐渐在某些文化和时尚活动中获得认可。</p>

<p>男娘群体通常具有女性化的外表特征、言谈举止及多元化爱好，其发展受家庭、社会及生理因素影响，反映了性别认同的困惑与探索，以及对传统性别角色束缚的挑战。当前研究主要从社会学、统计学和心理学角度展开，面临数据收集困难、研究方法单一等局限。</p>

<p>男娘特征分析涉及个人体质（如健身、饮食、皮肤保养）、服装选择与细节处理，以及女性化的身体语言、表情管理和自信展现, 未来研究需加强跨学科综合，采用多样化方法，以全面深入探讨男娘现象。</p>

<h1 id="参考文献">参考文献</h1>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:female" role="doc-endnote">
      <p>大门向外开123.男娘伪娘越来越多[EB/OL].CSDN.<a target="_blank" href="https://baijiahao.baidu.com/s?id=1815392855789209159&amp;wfr=spider&amp;for=pc">https://baijiahao.baidu.com/s?id=1815392855789209159&amp;wfr=spider&amp;for=pc</a>.2024-11-11 <a href="#fnref:female" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:yangxueyan" role="doc-endnote">
      <p>杨雪燕.LGBT人群的数量估计:国际经验和中国挑战[J].中国性科学,2020,29(01):148-152. <a href="#fnref:yangxueyan" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:sanye" role="doc-endnote">
      <p>三叶.好想做个女孩子[M].一千零一夜COS剧社,2020. <a href="#fnref:sanye" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:yinshi" role="doc-endnote">
      <p>范龙泉,崔小珍.浅谈饮食营养与人体健康[J].智慧健康,2020,6(07):87-89.DOI:10.19335/j.cnki.2096-1219.2020.07.036. <a href="#fnref:yinshi" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:lvhaihong" role="doc-endnote">
      <p>吕海宏.新编内分泌代谢疾病实验室手册[J].甘肃民族出版社.2016.25 <a href="#fnref:lvhaihong" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>CryingN</name><email>CryingNights7v@gmail.com</email></author><category term="深度学习" /><category term="AI" /><category term="论文" /><summary type="html"><![CDATA[本文章采用AI辅助对无实际意义的课题进行编写, 用于测试AI辅助论文研究的进展...]]></summary></entry><entry><title type="html">[Crypto学习笔记] 梅森旋转预测类型题目</title><link href="https://cryingn.github.io/posts/2025/05/mt19337/" rel="alternate" type="text/html" title="[Crypto学习笔记] 梅森旋转预测类型题目" /><published>2025-03-02T00:00:00+08:00</published><updated>2025-03-02T00:00:00+08:00</updated><id>https://cryingn.github.io/posts/2025/05/mt19337</id><content type="html" xml:base="https://cryingn.github.io/posts/2025/05/mt19337/"><![CDATA[<h1 id="目录">目录</h1>

<ul>
  <li><a href="#前置概念">前置概念</a>
    <ul>
      <li><a href="#梅森旋转">梅森旋转</a></li>
    </ul>
  </li>
  <li><a href="#apoorvctf2025">tpctf</a>
    <ul>
      <li><a href="#randomized_random">randomized_random</a></li>
    </ul>
  </li>
  <li><a href="#ghctf2025">ghctf2025</a>
    <ul>
      <li><a href="#mortis">mortis</a></li>
    </ul>
  </li>
  <li><a href="#参考文献">参考文献</a></li>
</ul>

<h1 id="前置概念">前置概念</h1>

<h2 id="梅森旋转">梅森旋转</h2>

<p>以下是MT19937的实现代码<sup id="fnref:re" role="doc-noteref"><a href="#fn:re" class="footnote" rel="footnote">1</a></sup>:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">_int32</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
    <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="mh">0xFFFFFFFF</span> <span class="o">&amp;</span> <span class="n">x</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">MT19937</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">seed</span><span class="p">):</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">mt</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="mi">624</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">mt</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">seed</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">mti</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">624</span><span class="p">):</span>
            <span class="bp">self</span><span class="p">.</span><span class="n">mt</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">_int32</span><span class="p">(</span><span class="mi">1812433253</span> <span class="o">*</span> <span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">mt</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">^</span> <span class="bp">self</span><span class="p">.</span><span class="n">mt</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">&gt;&gt;</span> <span class="mi">30</span><span class="p">)</span> <span class="o">+</span> <span class="n">i</span><span class="p">)</span>
    <span class="k">def</span> <span class="nf">twist</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">624</span><span class="p">):</span>
            <span class="n">y</span> <span class="o">=</span> <span class="n">_int32</span><span class="p">((</span><span class="bp">self</span><span class="p">.</span><span class="n">mt</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&amp;</span> <span class="mh">0x80000000</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">mt</span><span class="p">[(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="mi">624</span><span class="p">]</span> <span class="o">&amp;</span> <span class="mh">0x7fffffff</span><span class="p">))</span>
            <span class="bp">self</span><span class="p">.</span><span class="n">mt</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">y</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">^</span> <span class="bp">self</span><span class="p">.</span><span class="n">mt</span><span class="p">[(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">397</span><span class="p">)</span> <span class="o">%</span> <span class="mi">624</span><span class="p">]</span>
            <span class="k">if</span> <span class="n">y</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
                <span class="bp">self</span><span class="p">.</span><span class="n">mt</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">mt</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">^</span> <span class="mh">0x9908b0df</span>
    <span class="k">def</span> <span class="nf">getstate</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">mti</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="bp">self</span><span class="p">.</span><span class="n">twist</span><span class="p">()</span>
        <span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">mt</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">mti</span><span class="p">]</span>
        <span class="n">y</span> <span class="o">=</span> <span class="n">y</span> <span class="o">^</span> <span class="n">y</span> <span class="o">&gt;&gt;</span> <span class="mi">11</span>
        <span class="n">y</span> <span class="o">=</span> <span class="n">y</span> <span class="o">^</span> <span class="n">y</span> <span class="o">&lt;&lt;</span> <span class="mi">7</span> <span class="o">&amp;</span> <span class="mi">2636928640</span>
        <span class="n">y</span> <span class="o">=</span> <span class="n">y</span> <span class="o">^</span> <span class="n">y</span> <span class="o">&lt;&lt;</span> <span class="mi">15</span> <span class="o">&amp;</span> <span class="mi">4022730752</span>
        <span class="n">y</span> <span class="o">=</span> <span class="n">y</span> <span class="o">^</span> <span class="n">y</span> <span class="o">&gt;&gt;</span> <span class="mi">18</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">mti</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">mti</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="mi">624</span>
        <span class="k">return</span> <span class="n">_int32</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
</code></pre></div></div>

<p>其中<code class="language-plaintext highlighter-rouge">_int32(x)</code>函数用于强制将数据取到32bits, MT19937类中的函数可以稍微花点时间分析一下.</p>

<h3 id="init">init</h3>

<p>初始函数<code class="language-plaintext highlighter-rouge">__init__()</code>中, 初始化624个32bits的随机数储存在mt列表中, 其中初始种子往后具有<code class="language-plaintext highlighter-rouge">(1812433253 * (self.mt[i - 1] ^ self.mt[i - 1] &gt;&gt; 30) + i) % 2^32</code>的随机关系, 置初始的mt列表指针<code class="language-plaintext highlighter-rouge">mti=0</code>.</p>

<h3 id="getstate">getstate</h3>

<p>生成32位的随机数y, 如果指针走完mt列表的一轮, 则调用<code class="language-plaintext highlighter-rouge">twist()</code>旋转mt列表, mti指针</p>

<p>如果能获得连续的624个32bits数据(或者说需要获取19968bits数据), 就可以获取算法的所有状态<sup id="fnref:mt19937inctf" role="doc-noteref"><a href="#fn:mt19937inctf" class="footnote" rel="footnote">2</a></sup>.</p>

<h1 id="tpctf">tpctf</h1>

<h2 id="randomized_random">randomized_random</h2>

<h1 id="参考文献">参考文献</h1>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:re" role="doc-endnote">
      <p>catalyst.梅森旋转算法(MT19937)及其逆向详解[EB/OL].知乎.<a target="_blank" href="https://zhuanlan.zhihu.com/p/599672127">https://zhuanlan.zhihu.com/p/599672127</a>.2024-02-05. <a href="#fnref:re" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:mt19937inctf" role="doc-endnote">
      <p>huangx607087.huangx607087对PRNG-MT19937的深一步学习[EB/OL].个人博客.<a target="_blank" href="https://huangx607087.online/2021/07/10/Explore-MT19937/#0x03-%E7%BB%99%E5%87%BA%E4%BB%BB%E6%84%8F19937%E4%B8%AAbit-upd-2025-01-22">https://huangx607087.online/2021/07/10/Explore-MT19937/#0x03-%E7%BB%99%E5%87%BA%E4%BB%BB%E6%84%8F19937%E4%B8%AAbit-upd-2025-01-22</a>.2021-07-10. <a href="#fnref:mt19937inctf" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>CryingN</name><email>CryingNights7v@gmail.com</email></author><category term="CTF" /><category term="网络安全" /><category term="密码学" /><category term="随机预测" /><category term="MT19937" /><summary type="html"><![CDATA[其实很早之前国内就在搞随机预测了, 只不过一直没有时间拿来好好沉淀, 现在打算重新捡一下了...]]></summary></entry><entry><title type="html">[VPN] Wireguard的基本使用方法</title><link href="https://cryingn.github.io/posts/2025/05/wireguard/" rel="alternate" type="text/html" title="[VPN] Wireguard的基本使用方法" /><published>2025-03-02T00:00:00+08:00</published><updated>2025-03-02T00:00:00+08:00</updated><id>https://cryingn.github.io/posts/2025/05/wireguard</id><content type="html" xml:base="https://cryingn.github.io/posts/2025/05/wireguard/"><![CDATA[<h1 id="目录">目录</h1>

<ul>
  <li><a href="#vpn的基本使用">vpn的基本使用</a>
    <ul>
      <li><a href="#服务端环境设置">服务端环境设置</a>
        <ul>
          <li><a href="#安装">安装</a></li>
          <li><a href="#配置">配置</a></li>
          <li><a href="#编辑配置文件">编辑配置文件</a></li>
          <li><a href="#基础开关功能">基础开关功能</a></li>
        </ul>
      </li>
      <li><a href="#客户端配置">客户端配置</a>
        <ul>
          <li><a href="#连接">连接</a></li>
          <li><a href="#检测">检测</a></li>
        </ul>
      </li>
    </ul>
  </li>
  <li><a href="#进阶部署">进阶部署</a>
    <ul>
      <li><a href="#全隧道">全隧道</a></li>
      <li><a href="#流量转发">流量转发</a></li>
      <li><a href="#net规则验证">net规则验证</a></li>
      <li><a href="#开机启动">开机启动</a></li>
    </ul>
  </li>
  <li><a href="#参考文献">参考文献</a></li>
</ul>

<h1 id="vpn的基本使用">VPN的基本使用</h1>

<p>VTF开发过程中我们想引入插件概念, 其中vpn实现内网功能是我们很在意其中一种插件, 于是我们决定从wireguard开始学习, 在学习之前更重要的是能把程序先用起来. 于是跟着学了一下部署流程. WireGuard与其他VPN项目相比，代码量小、性能高、配置简单, 是基于udp传输的高效vpn。</p>

<h2 id="服务端环境设置">服务端环境设置</h2>

<h3 id="安装">安装</h3>

<p>以debian为例安装wireguard:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install </span>wireguard
wg <span class="nt">-v</span>
wireguard-tools v1.0.20210914 - https://git.zx2c4.com/wireguard-tools/
</code></pre></div></div>

<p>除此以外还需要安装以下配置工具:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install </span>iptables
</code></pre></div></div>

<h3 id="配置">配置</h3>

<p>我认为在组内赋予满权限已经够了, 只给了770权限, 有时间慢慢研究一下最小权限分配应该怎么做好一点<sup id="fnref:csdn" role="doc-noteref"><a href="#fn:csdn" class="footnote" rel="footnote">1</a></sup>, 在<code class="language-plaintext highlighter-rouge">/etc/wireguard</code>生成服务器的公私钥对:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> /etc
<span class="nb">chmod </span>770 wireguard
<span class="nb">cd </span>wireguard
<span class="nb">umask </span>077
<span class="nb">mkdir </span>key
wg genkey | <span class="nb">tee </span>server_privatekey | wg pubkey <span class="o">&gt;</span> key/server_publickey
</code></pre></div></div>

<p>除此之外进行通信还需要配置对应的客户端公私钥对发起访问:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wg genkey | <span class="nb">tee </span>client[编号]_privatekey | wg pubkey <span class="o">&gt;</span> key/client[编号]_publickey
</code></pre></div></div>

<h3 id="编辑配置文件">编辑配置文件</h3>

<p>创建配置文件<code class="language-plaintext highlighter-rouge">/etc/wireguard/wg0.conf</code>:</p>

<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">echo</span> <span class="err">"</span><span class="nn">[Interface]</span>
<span class="py">Address</span> <span class="p">=</span> <span class="c"># ifconfig:ip/24 服务端虚拟网段
</span><span class="s">SaveConfig = true</span>
<span class="py">PrivateKey</span> <span class="p">=</span> <span class="s">$(cat server_privatekey)</span>
<span class="py">ListenPort</span> <span class="p">=</span> <span class="s">7890</span>

<span class="nn">[Peer]</span>
<span class="py">PublicKey</span> <span class="p">=</span> <span class="s">$(cat client_publickey)</span>
<span class="py">AllowedIPs</span> <span class="p">=</span> <span class="c"># ifconfig:ip + 1/32 client1虚拟网段
</span>
<span class="nn">[Peer]</span>
<span class="py">PublicKey</span> <span class="p">=</span> <span class="s">$(cat client_publickey)</span>
<span class="py">AllowedIPs</span> <span class="p">=</span> <span class="c"># ifconfig:ip + 1/32 client2虚拟网段
</span><span class="s">" &gt; wg0.conf
</span></code></pre></div></div>

<p>如果设置本地防火墙需要放行对应端口, 如上文配置需要放行<code class="language-plaintext highlighter-rouge">7890/udp</code>:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>ufw allow 7890/udp
</code></pre></div></div>

<p>这里采用了腾讯云服务器, 直接设置安全组放行对应端口即可.</p>

<h3 id="基础开关功能">基础开关功能</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 启动WireGuard</span>
wg-quick up wg0
<span class="c"># 停止WireGuard</span>
wg-quick down wg0
</code></pre></div></div>

<p>可以通过以下代码快速重启服务:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wg-quick down wg0 <span class="o">&amp;&amp;</span> wg-quick up wg0
</code></pre></div></div>

<h2 id="客户端配置">客户端配置</h2>

<h3 id="连接">连接</h3>

<p>客户端可以分别配置规则如下的配置文件:</p>

<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="err">echo</span> <span class="err">"</span><span class="nn">[Interface]</span>
<span class="py">PrivateKey</span> <span class="p">=</span> <span class="s">$(cat client_privatekey)</span>
<span class="py">Address</span> <span class="p">=</span> <span class="c"># ifconfig:ip+1/24 客户端对应预设的虚拟网段
</span><span class="s">ListenPort = 8080</span>
<span class="py">DNS</span> <span class="p">=</span> <span class="s">8.8.8.8</span>

<span class="nn">[Peer]</span>
<span class="py">PublicKey</span> <span class="p">=</span> <span class="s">$(cat server_publickey)</span>
<span class="py">Endpoint</span> <span class="p">=</span> <span class="s">[服务器IP地址]:7890</span>
<span class="py">AllowedIPs</span> <span class="p">=</span> <span class="s">[VPN虚拟网段]/24, [内网资源网段]/24</span>
<span class="py">PersistentKeepalive</span> <span class="p">=</span> <span class="s">25" &gt; client.conf</span>
</code></pre></div></div>

<h3 id="检测">检测</h3>

<p>我们可以通过访问内网资源的ip测试连接是否成功:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ping <span class="o">[</span>内网IP]
</code></pre></div></div>

<p>如果发包成功则说明基础的VPN搭建成功.</p>

<h1 id="进阶部署">进阶部署</h1>

<h2 id="全隧道">全隧道</h2>

<p>在VPN部署中存在让客户端的所有网络流量都经由服务器的公网出口进行访问的手段, 这种功能被称为全隧道模式, 全隧道模式需要做到虚拟网段搭建、流量转发、NET地址伪造3个部分, 为了使流量通经由服务器访问, 需要设置客户端配置:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>AllowedIPs <span class="o">=</span> 0.0.0.0/0
</code></pre></div></div>

<h2 id="流量转发">流量转发</h2>

<p>在服务器中可以通过以下方式设置流量转发:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> <span class="s2">"net.ipv4.ip_forward = 1"</span> <span class="o">&gt;&gt;</span> /etc/sysctl.conf
sysctl <span class="nt">-p</span>
</code></pre></div></div>

<h2 id="net规则验证">net规则验证</h2>

<p>在配置项可以对配置文件<code class="language-plaintext highlighter-rouge">/etc/wireguard/wg0.conf</code>进行以下预设:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PostUp <span class="o">=</span> iptables <span class="nt">-t</span> nat <span class="nt">-A</span> POSTROUTING <span class="o">!</span> <span class="nt">-o</span> wg0 <span class="nt">-j</span> MASQUERADE
PostDown <span class="o">=</span> iptables <span class="nt">-t</span> nat <span class="nt">-D</span> POSTROUTING <span class="o">!</span> <span class="nt">-o</span> wg0 <span class="nt">-j</span> MASQUERADE
</code></pre></div></div>

<p>用于在开启或结束时自动配置NET中MASQUERADE的转发规则.</p>

<p>有时候反复设置往往会使规则出现问题, 以至于无法有效转发流量, 可以通过以下脚本验证net规则:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>iptables <span class="nt">-t</span> nat <span class="nt">-L</span> <span class="nt">-n</span> <span class="nt">-v</span>
</code></pre></div></div>

<p>可以检查POSTROUTING段是否有一条固定的规则在正常转发, 如果出现冲突需要进行重设, 以下提供一个最基础的方法清理所有POSTROUTING规则:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>iptables <span class="nt">-t</span> nat <span class="nt">-F</span> POSTROUTING
</code></pre></div></div>

<h2 id="开机启动">开机启动</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl <span class="nb">enable </span>wg-quick@wg0
</code></pre></div></div>

<h1 id="参考文献">参考文献</h1>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:csdn" role="doc-endnote">
      <p>杨林伟.组网神器WireGuard安装与配置教程（超详细）[EB/OL].CSDN.<a target="_blank" href="https://blog.csdn.net/qq_20042935/article/details/127089626">https://blog.csdn.net/qq_20042935/article/details/127089626</a>.2022-09-28. <a href="#fnref:csdn" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>CryingN</name><email>CryingNights7v@gmail.com</email></author><category term="linux" /><category term="vpn" /><summary type="html"><![CDATA[VTF开发过程中我们想引入插件概念, 其中vpn实现内网功能是我们很在意其中一种插件, 于是我们决定从wireguard开始学习...]]></summary></entry><entry><title type="html">[Deepseek-r1] 从源码部署问题分析</title><link href="https://cryingn.github.io/posts/2025/01/deepseek-r1/" rel="alternate" type="text/html" title="[Deepseek-r1] 从源码部署问题分析" /><published>2025-01-14T00:00:00+08:00</published><updated>2025-01-14T00:00:00+08:00</updated><id>https://cryingn.github.io/posts/2025/01/deepseek-r1</id><content type="html" xml:base="https://cryingn.github.io/posts/2025/01/deepseek-r1/"><![CDATA[<h1 id="目录">目录</h1>

<ul>
  <li><a href="#前言">前言</a></li>
  <li><a href="#下载">下载</a></li>
  <li><a href="#数据源问题">数据源问题</a></li>
  <li><a href="#数据格式问题">数据格式问题</a></li>
  <li><a href="#小结">小结</a></li>
  <li><a href="#参考文献">参考文献</a></li>
</ul>

<h1 id="前言">前言</h1>

<p>想养女儿了, 结果只是想让女儿能听见就好困难, 作为一个微调苦手, 后来想了一下, 还是好好地重新开始从deepseek-r1学习, 才发现在进行小模型部署中存在了大量正常情况不会面临的问题, 于是打算在解决过程中把情况记录一下, 方便大家解决问题. 作为开源产品, 相比起望而却步不如先用起来.</p>

<h1 id="下载">下载</h1>

<p>这也是一个比较抽象的问题, 数据源比较容易, 直接在<a href="https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B">huggingface</a>找到最小模型, 考虑到大部分人难以下载, 也可以从镜像源进行拉取, 以下提供了<a href="https://hf-mirror.com/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B">hf-mirror</a>. 但是源码在GitHub找到<a href="https://github.com/deepseek-ai/DeepSeek-R1">deepseek-r1</a>会发现里面竟然只有论文, 喵了个咪, 谁教你这么用仓库的. 但是问题不大, 说明书有如下提示:</p>

<blockquote>
  <p>DeepSeek-R1 Models
Please visit DeepSeek-V3 repo for more information about running DeepSeek-R1 locally.</p>

  <p>NOTE: Hugging Face’s Transformers has not been directly supported yet.</p>
</blockquote>

<p>注意了, 官方有说撇开责任说: <strong>没有直接支持</strong>, 这是人干的事吗?! 可以先去<a href="https://github.com/deepseek-ai/DeepSeek-V3">deepseek-v3</a>获取源码及相关说明书, 然后根据说明书调试下载的r1数据, 出问题的话就是后话了.</p>

<h1 id="数据源问题">数据源问题</h1>

<h2 id="报错信息">报错信息</h2>

<p>跟随运行调整数据:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>python convert.py <span class="nt">--hf-ckpt-path</span> /app/inference/DeepSeek-V3 <span class="nt">--save-path</span> /app/inference/DeepSeek-V3-Demo <span class="nt">--n-experts</span> 128 <span class="nt">--model-parallel</span> 4
</code></pre></div></div>

<p>可能会面临以下情况:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">0</span><span class="o">%|</span> <span class="o">|</span> <span class="mi">0</span><span class="o">/</span><span class="mi">163</span> <span class="p">[</span><span class="mi">00</span><span class="p">:</span><span class="mi">00</span><span class="o">&lt;</span><span class="err">?</span><span class="p">,</span> <span class="err">?</span><span class="n">it</span><span class="o">/</span><span class="n">s</span><span class="p">]</span>
<span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s">"convert.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">96</span><span class="p">,</span> <span class="ow">in</span>
<span class="n">main</span><span class="p">(</span><span class="n">args</span><span class="p">.</span><span class="n">hf_ckpt_path</span><span class="p">,</span> <span class="n">args</span><span class="p">.</span><span class="n">save_path</span><span class="p">,</span> <span class="n">args</span><span class="p">.</span><span class="n">n_experts</span><span class="p">,</span> <span class="n">args</span><span class="p">.</span><span class="n">model_parallel</span><span class="p">)</span>
<span class="n">File</span> <span class="s">"convert.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">51</span><span class="p">,</span> <span class="ow">in</span> <span class="n">main</span>
<span class="k">with</span> <span class="n">safe_open</span><span class="p">(</span><span class="n">file_path</span><span class="p">,</span> <span class="n">framework</span><span class="o">=</span><span class="s">"pt"</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="s">"cpu"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">safetensors_rust</span><span class="p">.</span><span class="n">SafetensorError</span><span class="p">:</span> <span class="n">Error</span> <span class="k">while</span> <span class="n">deserializing</span> <span class="n">header</span><span class="p">:</span> <span class="n">HeaderTooLarge</span>
</code></pre></div></div>

<h2 id="解决方法">解决方法</h2>

<p>我在<a href="https://github.com/deepseek-ai/DeepSeek-V3/issues/557">#557</a>上有帮忙过这个问题, 根源是git-lfs插件没有使用好, 导致<code class="language-plaintext highlighter-rouge">.safetensors</code>文件下载失败(或者假成功, 可以比较以下文件大小和hash), 可以通过下载lfs插件进行拉取:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt <span class="nb">install </span>git git-lfs
git lfs <span class="nb">install
</span>git lfs clone https://...
</code></pre></div></div>

<p>对于archlinux可以使用:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>pacman <span class="nt">-S</span> git git-lfs
git lfs <span class="nb">install
</span>git clone https://...
</code></pre></div></div>

<p>或者直接在源上一个一个下载数据文件, 好处是到底有没有下载成功是明显能看见的, 解决以后应该可以正常处理了(吗?)</p>

<h1 id="数据格式问题">数据格式问题</h1>

<h2 id="报错信息-1">报错信息</h2>

<p>可以参考<a href="https://github.com/deepseek-ai/DeepSeek-V3/issues/330">#330</a>, 很遗憾我注意到的时候这个issues已经关闭了, 我们可以分析一下错误信息:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">file</span><span class="p">:</span> <span class="n">convert</span><span class="p">.</span><span class="n">py</span><span class="p">.</span> <span class="n">line</span> <span class="mi">63</span><span class="p">:</span> <span class="k">assert</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">mapping</span>
</code></pre></div></div>

<h2 id="分析">分析</h2>

<p>这是在使用<code class="language-plaintext highlighter-rouge">convert.py</code>脚本的过程中爆出的经典错误, 对<code class="language-plaintext highlighter-rouge">main()</code>函数(实际上函数内传入了4个变量, 不过因为只是对错误进行整理, 且官方代码中已经对变量进行了解释, 我们无需对变量进行研究)进行分析, 通过调试可以发现在model中R1的<code class="language-plaintext highlighter-rouge">key</code>模型节点相比R3预设中多了<code class="language-plaintext highlighter-rouge">k_proj</code>和<code class="language-plaintext highlighter-rouge">v_proj</code>节点, 我第一反应是找ds问个明白, 得到提示模型可能是其他的架构(如LLaMA).</p>

<blockquote>
  <p>这里有个小插曲, 朋友有使用oLLama快速部署了一个简单的模型, 但因为是被封装好的, 自行调整这一步相对会变得麻烦, 我还是想试试能不能尽可能透明地处理好属于自己的模型.</p>

  <p>关键是”LLama”这个东西, 因为ds提出了在我认知中重合的东西, 且这个名字在其他deepseek-r1的相关数据模型中也存在过, 于是我尝试去了解了Llama, Llama是由Meta开源出来的一个大模型.</p>

</blockquote>

<p>我们的思路应该换一换, 现在来认识一下DeepSeek-r1数据源的名字吧:</p>

<ul>
  <li>deepseek-ai
    <ul>
      <li>DeepSeek-R1: 在R1-Zero基础上解决可读性差和语言混合的模型</li>
      <li>DeepSeek-R1-Zero: 以V3-Base为基础采用GRPO作为RL框架提高推理性能的模型</li>
      <li>DeepSeek-R1-Distill-Llama-70B: 使用Llama模型的70B(十亿)数据蒸馏的模型</li>
      <li>DeepSeek-R1-Distill-Qwen-32B: 使用Qwen模型的32B(十亿)数据蒸馏的模型</li>
      <li>DeepSeek-R1-Distill-Qwen-14B: 使用Qwen模型的14B(十亿)数据蒸馏的模型</li>
      <li>DeepSeek-R1-Distill-Llama-8B: 使用Llama模型的8B(十亿)数据蒸馏的模型</li>
      <li>DeepSeek-R1-Distill-Qwen-7B: 使用Qwen模型的7B(十亿)数据蒸馏的模型</li>
      <li>DeepSeek-R1-Distill-Qwen-1.5B: 使用Qwen模型的1.5B(十亿)数据蒸馏的模型</li>
    </ul>
  </li>
</ul>

<p>很遗憾Qwen的官方群并没有给出一个明确的回复(可能负责答疑的人也不理解那些节点到底是用来做什么的吧, 笑), 不过我找到了这样一段代码<sup id="fnref:qwen1_5B" role="doc-noteref"><a href="#fn:qwen1_5B" class="footnote" rel="footnote">1</a></sup>:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">transformers</span> <span class="kn">import</span> <span class="n">AutoTokenizer</span><span class="p">,</span> <span class="n">AutoModelForCausalLM</span>
<span class="kn">import</span> <span class="nn">torch</span>

<span class="k">class</span> <span class="nc">DeepSeekModel</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">model_path</span><span class="o">=</span><span class="s">"./DeepSeek-R1-Distill-Qwen-1.5B"</span><span class="p">):</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">device</span> <span class="o">=</span> <span class="s">"cuda"</span> <span class="k">if</span> <span class="n">torch</span><span class="p">.</span><span class="n">cuda</span><span class="p">.</span><span class="n">is_available</span><span class="p">()</span> <span class="k">else</span> <span class="s">"cpu"</span>
        <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Using device: </span><span class="si">{</span><span class="bp">self</span><span class="p">.</span><span class="n">device</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
        
        <span class="c1"># 加载tokenizer和模型
</span>        <span class="bp">self</span><span class="p">.</span><span class="n">tokenizer</span> <span class="o">=</span> <span class="n">AutoTokenizer</span><span class="p">.</span><span class="n">from_pretrained</span><span class="p">(</span><span class="n">model_path</span><span class="p">,</span> <span class="n">trust_remote_code</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
        <span class="bp">self</span><span class="p">.</span><span class="n">model</span> <span class="o">=</span> <span class="n">AutoModelForCausalLM</span><span class="p">.</span><span class="n">from_pretrained</span><span class="p">(</span>
            <span class="n">model_path</span><span class="p">,</span>
            <span class="n">trust_remote_code</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span>
            <span class="n">torch_dtype</span><span class="o">=</span><span class="n">torch</span><span class="p">.</span><span class="n">float16</span> <span class="k">if</span> <span class="bp">self</span><span class="p">.</span><span class="n">device</span> <span class="o">==</span> <span class="s">"cuda"</span> <span class="k">else</span> <span class="n">torch</span><span class="p">.</span><span class="n">float32</span>
        <span class="p">).</span><span class="n">to</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">device</span><span class="p">)</span>
        
        <span class="c1"># 设置模型为评估模式
</span>        <span class="bp">self</span><span class="p">.</span><span class="n">model</span><span class="p">.</span><span class="nb">eval</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">generate_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">prompt</span><span class="p">,</span> <span class="n">max_length</span><span class="o">=</span><span class="mi">2048</span><span class="p">,</span> <span class="n">temperature</span><span class="o">=</span><span class="mf">0.7</span><span class="p">):</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="c1"># 对输入进行编码
</span>            <span class="n">inputs</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">tokenizer</span><span class="p">(</span><span class="n">prompt</span><span class="p">,</span> <span class="n">return_tensors</span><span class="o">=</span><span class="s">"pt"</span><span class="p">).</span><span class="n">to</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">device</span><span class="p">)</span>
            
            <span class="c1"># 生成回答
</span>            <span class="k">with</span> <span class="n">torch</span><span class="p">.</span><span class="n">no_grad</span><span class="p">():</span>
                <span class="n">outputs</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">model</span><span class="p">.</span><span class="n">generate</span><span class="p">(</span>
                    <span class="o">**</span><span class="n">inputs</span><span class="p">,</span>
                    <span class="n">max_length</span><span class="o">=</span><span class="n">max_length</span><span class="p">,</span>
                    <span class="n">temperature</span><span class="o">=</span><span class="n">temperature</span><span class="p">,</span>
                    <span class="n">top_p</span><span class="o">=</span><span class="mf">0.9</span><span class="p">,</span>
                    <span class="n">pad_token_id</span><span class="o">=</span><span class="bp">self</span><span class="p">.</span><span class="n">tokenizer</span><span class="p">.</span><span class="n">pad_token_id</span><span class="p">,</span>
                    <span class="n">eos_token_id</span><span class="o">=</span><span class="bp">self</span><span class="p">.</span><span class="n">tokenizer</span><span class="p">.</span><span class="n">eos_token_id</span>
                <span class="p">)</span>
            
            <span class="c1"># 解码输出
</span>            <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="p">.</span><span class="n">tokenizer</span><span class="p">.</span><span class="n">decode</span><span class="p">(</span><span class="n">outputs</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">skip_special_tokens</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">response</span>
        
        <span class="k">except</span> <span class="nb">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
            <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"生成回答时发生错误: </span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
            <span class="k">return</span> <span class="bp">None</span>

<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="c1"># 初始化模型
</span>    <span class="n">model</span> <span class="o">=</span> <span class="n">DeepSeekModel</span><span class="p">()</span>
    
    <span class="c1"># 测试对话
</span>    <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
        <span class="n">user_input</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">请输入您的问题 (输入 'quit' 退出): "</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">user_input</span><span class="p">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s">'quit'</span><span class="p">:</span>
            <span class="k">break</span>
            
        <span class="n">response</span> <span class="o">=</span> <span class="n">model</span><span class="p">.</span><span class="n">generate_response</span><span class="p">(</span><span class="n">user_input</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">response</span><span class="p">:</span>
            <span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">DeepSeek:"</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</code></pre></div></div>

<p>当然在正式运行的时候最好根据自己的系统情况改善到适合运行, 但是我们应该明确重要的是, 至少现在我们可以用上这些我们不知道用途的数据了, 接下来 需要以这些代码为基础进行调试, (下次接着写).</p>

<h1 id="解决方法-1">解决方法</h1>

<p>很遗憾我曾以为这个问题能很快解决, 但是需要进行更麻烦的处理, 在一切成功后我会尝试重新整理一份源码以供使用.</p>

<h1 id="小结">小结</h1>

<p>很恨自己什么都不会, 每当看见身边的人努力后就能取得成绩, 相比之下自己是真的糟糕透了. 之前一场比赛因为自己的问题什么都没拿到, 结束后很痛苦, 有人问我以后有什么打算, 我说想好好学习一下AI了, 实际上一篇论文也没看懂.</p>

<p>后来刚好有deepseek的声音, 于是决定自己亲自部署一个(在此之前只是摸了一下minigpt, 源码看起来一言难尽), 过程中其实遇到了很多问题, 包括微调, 资源限制, 空闲时间太少等等等等, 我想起一位师傅说过: “要拼命地去学”, 实际上我也做不到拼命, 我太会逃避了, 不过很多人也是这样. 因为自己以往的一些经验, 遭遇错误后我尝试一点一点进行了排查, 才慢慢有了这篇文章, 往好了说我现在能够继续往下走了, 可是实际上从简历上看我也还是什么都没做到.</p>

<p>人生是一场痛苦的马拉松, 之前聊剧本的时候我想夹带一点私货, 我提出一个场景: 让女朋友抱着他说”没事了, 可以不用继续痛苦了”, 后来讨论了一下, 我们认为这个场景应该在死去以后以意识流的形式呈现. 虽然看起来有点地狱, 但是我有想过, 其实对于大部分人的痛苦是看不到尽头的.</p>

<p>越是温柔, 看到的越多, 也就越容易沉浸在绝望之中, 不想继续痛苦估计只有在一切结束了吧.</p>

<h1 id="参考文献">参考文献</h1>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:qwen1_5B" role="doc-endnote">
      <p>llama.本地化部署DeepSeek-R1-Distill-Qwen-1.5B[EB/OL].CSDN.<a target="_blank" href="https://blog.csdn.net/harebert/article/details/145392582">https://blog.csdn.net/harebert/article/details/145392582</a>.2025.01.29 <a href="#fnref:qwen1_5B" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>CryingN</name><email>CryingNights7v@gmail.com</email></author><category term="深度学习" /><category term="AI" /><category term="python" /><summary type="html"><![CDATA[微调苦手, 后来想了一下, 还是好好地重新开始学习deepseek-r1, 才发现在进行小模型部署中存在了大量正常情况不会面临的问题...]]></summary></entry><entry><title type="html">[awdp学习笔记] 密码系统类题目</title><link href="https://cryingn.github.io/posts/2025/01/crypto_system/" rel="alternate" type="text/html" title="[awdp学习笔记] 密码系统类题目" /><published>2025-01-02T00:00:00+08:00</published><updated>2025-01-02T00:00:00+08:00</updated><id>https://cryingn.github.io/posts/2025/01/crypto_system</id><content type="html" xml:base="https://cryingn.github.io/posts/2025/01/crypto_system/"><![CDATA[<h1 id="目录">目录</h1>

<ul>
  <li><a href="#第六届强网杯">第七届西湖论剑</a>
    <ul>
      <li><a href="#ezdja">ezdja</a></li>
      <li><a href="#found_cms">found_cms</a></li>
    </ul>
  </li>
  <li><a href="#网鼎杯线下赛">网鼎杯线下赛</a>
    <ul>
      <li><a href="#alicewebsite">alicewebsite</a></li>
      <li><a href="#fake">fake</a></li>
    </ul>
  </li>
  <li><a href="#十七届ciscn总决赛">十七届ciscn总决赛</a>
    <ul>
      <li><a href="#anime">anime</a></li>
      <li><a href="#ezheap">ezheap</a></li>
      <li><a href="#chr">chr</a></li>
    </ul>
  </li>
  <li><a href="#参考文献">参考文献</a></li>
</ul>

<h1 id="第六届强网杯">第六届强网杯</h1>

<p>第六届青少赛线下AWDP, 参考末心师傅的文档<sup id="fnref:moxin" role="doc-noteref"><a href="#fn:moxin" class="footnote" rel="footnote">1</a></sup>, fix部分主要题目有四道:</p>

<h2 id="ezdja">ezdja</h2>

<p>经典的python类DJango框架, 文件结构为:</p>

<ul>
  <li><strong>app01</strong>
    <ul>
      <li>主要的app文件</li>
    </ul>
  </li>
  <li><strong>easypy</strong></li>
  <li><strong>static</strong>
    <ul>
      <li>前端文件</li>
    </ul>
  </li>
  <li><strong>templates</strong>
    <ul>
      <li>前端文件</li>
    </ul>
  </li>
  <li>manage.py (服务脚本)</li>
  <li>requirements.txt</li>
</ul>

<p>服务脚本用于定义Django框架, 直接找到<strong>app01/myfunc.py</strong>, 很容易可以找到简单的sql注入的waf:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">waf</span><span class="p">(</span><span class="n">sql</span><span class="p">):</span>
    <span class="n">blacklists</span> <span class="o">=</span> <span class="p">[</span><span class="s">'union select'</span><span class="p">,</span> <span class="s">'sleep'</span><span class="p">,</span> <span class="s">'benchmark'</span><span class="p">,</span> <span class="s">'columns'</span><span class="p">,</span> <span class="s">'load_file'</span><span class="p">,</span> <span class="s">'local'</span><span class="p">,</span> <span class="s">'outfile'</span><span class="p">,</span> <span class="s">'dumpfile'</span><span class="p">,</span> <span class="s">'file'</span><span class="p">]</span>
    <span class="k">for</span> <span class="n">blacklist</span> <span class="ow">in</span> <span class="n">blacklists</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">blacklist</span> <span class="ow">in</span> <span class="n">sql</span><span class="p">:</span>
            <span class="k">print</span><span class="p">(</span><span class="n">blacklist</span><span class="p">)</span>
            <span class="k">return</span> <span class="bp">False</span>
        <span class="k">return</span> <span class="bp">True</span>
</code></pre></div></div>

<p>除此之外还有其他几个waf函数, 那么要想防止注入, 需要从可能的注口下手, 在vim中直接进行<code class="language-plaintext highlighter-rouge">:/waf</code>搜索找到对应的位置, 检查到在index类中存在一段函数:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">sql</span> <span class="o">=</span> <span class="s">"select * from app01_user where username = '"</span><span class="o">+</span><span class="n">login_username</span><span class="o">+</span><span class="s">"';"</span>
<span class="n">xiaoxi</span> <span class="o">=</span> <span class="s">""</span>
<span class="k">if</span> <span class="n">waf</span><span class="p">(</span><span class="n">login_username</span><span class="p">):</span>
    <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql</span><span class="p">)</span>
    <span class="n">result</span> <span class="o">=</span> <span class="n">cursor</span><span class="p">.</span><span class="n">fettchall</span><span class="p">()</span>
    <span class="k">if</span> <span class="n">result</span><span class="p">:</span>
        <span class="n">xiaoxi</span> <span class="o">=</span> <span class="n">result</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">3</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
    <span class="n">xiaoxi</span> <span class="o">=</span> <span class="s">"No NO N0!"</span>
</code></pre></div></div>

<p>很暴力的一个方法, 顺便学了一手, 除了<code class="language-plaintext highlighter-rouge">eval</code>以外<code class="language-plaintext highlighter-rouge">execute</code>函数也应该是一个要被重点检查的函数.</p>

<p>陌心师傅提供了一个基本的修复方法, 直接增强waf(这大概需要考察web手在处理手段的基本素养了, 多出题还是有好处的):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>def waf(sql):
    blacklists = ["union select", "sleep", "benchmark","columns","load_file","local","outfile","dumpfile","file","union","select",
"select","and","*","x09","x0a","x0b","x0c","x0d","xa0","x00","x26","x7c","or","into","from","where","join","sleexml","extractvalue","+","regex","copy","read","file","create","grand","dir","insert","link","server","drop","=","&gt;","&lt;",";"]
    for blacklist in blacklists:
        if blacklist in sql:
            print(blacklist)
            return False
    return True
</code></pre></div></div>

<p>上了php的通防脚本, 防御成功了, 有时间我也写点自己的逆天想法(所以现在先鸽着).</p>

<h2 id="found_cms">found_cms</h2>

<h2 id="easygo">easygo</h2>

<p>golang会编译为二进制文件, 需要有强大的patch技巧, 这里只进行记录:</p>

<p>IDA64打开easygo文件, 找到<code class="language-plaintext highlighter-rouge">loc_49B5DE</code>处汇编显示:</p>

<pre><code class="language-asm">loc__49B5DE:
xchg    ax, ax
call    main_backdoor
jmp     short loc_49B5E9
</code></pre>

<p>继续追踪, 发现有调用<code class="language-plaintext highlighter-rouge">cat /flag</code>和<code class="language-plaintext highlighter-rouge">/bin/bash</code>两个部分, 既然是AWDP, 不难想象出官方的EXP, 直接暴力修改db部分, 将<code class="language-plaintext highlighter-rouge">cat /flag</code>修改为<code class="language-plaintext highlighter-rouge">echo 1234</code>, 个人思考了一下, 直接用retdec逆出来然后暴力改文件可能也是可以的?</p>

<h2 id="php通防">PHP通防</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">function</span> <span class="n">wafrce</span><span class="p">(</span><span class="err">$</span><span class="nb">str</span><span class="p">){</span>
	<span class="k">return</span> <span class="err">!</span><span class="n">preg_match</span><span class="p">(</span><span class="s">"/openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|scandir|assert|pcntl_exec|fwrite|curl|system|eval|assert|flag|passthru|exec|chroot|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore/i"</span><span class="p">,</span> <span class="err">$</span><span class="nb">str</span><span class="p">);</span>
<span class="p">}</span>

<span class="n">function</span> <span class="n">wafsqli</span><span class="p">(</span><span class="err">$</span><span class="nb">str</span><span class="p">){</span>
	<span class="k">return</span> <span class="err">!</span><span class="n">preg_match</span><span class="p">(</span><span class="s">"/select|and|\*|</span><span class="se">\x09</span><span class="s">|</span><span class="se">\x0a</span><span class="s">|</span><span class="se">\x0b</span><span class="s">|</span><span class="se">\x0c</span><span class="s">|</span><span class="se">\x0d</span><span class="s">|</span><span class="se">\xa0</span><span class="s">|</span><span class="se">\x00</span><span class="s">|</span><span class="se">\x26</span><span class="s">|</span><span class="se">\x7c</span><span class="s">|or|into|from|where|join|sleexml|extractvalue|+|regex|copy|read|file|create|grand|dir|insert|link|server|drop|=|&gt;|&lt;|;|</span><span class="se">\"</span><span class="s">|</span><span class="se">\'</span><span class="s">|\^|\|/i"</span><span class="p">,</span> <span class="err">$</span><span class="nb">str</span><span class="p">);</span>
<span class="p">}</span>

<span class="n">function</span> <span class="n">wafxss</span><span class="p">(</span><span class="err">$</span><span class="nb">str</span><span class="p">){</span>
	<span class="k">return</span> <span class="err">!</span><span class="n">preg_match</span><span class="p">(</span><span class="s">"/</span><span class="se">\'</span><span class="s">|http|</span><span class="se">\"</span><span class="s">|\`|cookie|&lt;|&gt;|script/i"</span><span class="p">,</span> <span class="err">$</span><span class="nb">str</span><span class="p">);</span>
<span class="p">}</span>


<span class="n">function</span> <span class="n">waf</span><span class="p">(</span><span class="err">$</span><span class="n">s</span><span class="p">){</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">preg_match</span><span class="p">(</span><span class="s">"/select|flag|union|</span><span class="se">\\</span><span class="s">$|'|"</span><span class="o">|--|</span><span class="c1">#|\0|into|alert|img|prompt|set|/*|x09|x0a|x0b|x0c|x0d|xa0|%|&lt;|&gt;|^|x00|#|x23|[0-9]|file|=|or|x7c|select|and|flag|into|where|x26|'|"|union|`|sleep|benchmark|regexp|from|count|procedure|and|ascii|substr|substring|left|right|union|if|case|pow|exp|order|sleep|benchmark|into|load|outfile|dumpfile|load_file|join|show|select|update|set|concat|delete|alter|insert|create|union|or|drop|not|for|join|is|between|group_concat|like|where|user|ascii|greatest|mid|substr|left|right|char|hex|ord|case|limit|conv|table|mysql_history|flag|count|rpad|&amp;|*|.|/is",$s)||strlen($s)&gt;50){
</span>    <span class="n">header</span><span class="p">(</span><span class="s">"Location: /"</span><span class="p">);</span>
    <span class="n">die</span><span class="p">();</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h1 id="网鼎杯线下赛">网鼎杯线下赛</h1>

<p>然后是kar3a师傅在网鼎杯的记录, 据说有点像ciscn, 有时间也看看那边的题目<sup id="fnref:kar3a" role="doc-noteref"><a href="#fn:kar3a" class="footnote" rel="footnote">2</a></sup>.</p>

<h2 id="alicewebsite">alicewebsite</h2>

<p>php题, 直接丢D盾里面, 找到可疑引用:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
        <span class="nv">$action</span> <span class="o">=</span> <span class="p">(</span><span class="k">isset</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s1">'action'</span><span class="p">])</span> <span class="o">?</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s1">'action'</span><span class="p">]</span> <span class="o">:</span> <span class="s1">'home.php'</span><span class="p">);</span>
        <span class="k">if</span> <span class="p">(</span><span class="nb">file_exists</span><span class="p">(</span><span class="nv">$action</span><span class="p">))</span> <span class="p">{</span>
            <span class="k">include</span> <span class="nv">$action</span><span class="p">;</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">echo</span> <span class="s2">"File not found!"</span><span class="p">;</span>
        <span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>

<p>D盾其实在长城杯半决赛过程中我们有配置过, 现在看来awd和awdp还是共通的, 只不过没了搅混水的过程(不过某种意义上添加一点选手间后期的斗智斗勇会更有意思, 个人感觉), 发现用户传入的<code class="language-plaintext highlighter-rouge">$action</code>没有进行过滤, 可以直接通过目录穿越, payload:<code class="language-plaintext highlighter-rouge">?action=../../../../flag</code></p>

<p>防御手段是构造一个黑名单防止目录穿越:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
        <span class="nv">$action</span> <span class="o">=</span> <span class="p">(</span><span class="k">isset</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s1">'action'</span><span class="p">])</span> <span class="o">?</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s1">'action'</span><span class="p">]</span> <span class="o">:</span> <span class="s1">'home.php'</span><span class="p">);</span>
		<span class="nv">$deny_ext</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s2">".."</span><span class="p">,</span><span class="s2">"../"</span><span class="p">);</span>
		<span class="k">if</span> <span class="p">(</span><span class="nb">in_array</span><span class="p">(</span><span class="nv">$action</span><span class="p">,</span> <span class="nv">$deny_ext</span><span class="p">)){</span>
            <span class="k">if</span> <span class="p">(</span><span class="nb">file_exists</span><span class="p">(</span><span class="nv">$action</span><span class="p">))</span> <span class="p">{</span>
                <span class="k">include</span> <span class="nv">$action</span><span class="p">;</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="k">echo</span> <span class="s2">"File not found!"</span><span class="p">;</span>
            <span class="p">}</span>
		<span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>

<h2 id="fake">fake</h2>

<p>buu上有原题, <code class="language-plaintext highlighter-rouge">/admin</code>进入后台, 是目录穿越:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">downloadBak</span><span class="p">()</span> <span class="p">{</span>
        <span class="nv">$file_name</span> <span class="o">=</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s1">'file'</span><span class="p">];</span>
        <span class="nv">$file_dir</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">config</span><span class="p">[</span><span class="s1">'path'</span><span class="p">];</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">file_exists</span><span class="p">(</span><span class="nv">$file_dir</span> <span class="mf">.</span> <span class="s2">"/"</span> <span class="mf">.</span> <span class="nv">$file_name</span><span class="p">))</span> <span class="p">{</span> <span class="c1">//检查文件是否存在</span>
            <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
            <span class="k">exit</span><span class="p">;</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="nv">$file</span> <span class="o">=</span> <span class="nb">fopen</span><span class="p">(</span><span class="nv">$file_dir</span> <span class="mf">.</span> <span class="s2">"/"</span> <span class="mf">.</span> <span class="nv">$file_name</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">);</span> <span class="c1">// 打开文件</span>
            <span class="c1">// 输入文件标签</span>
            <span class="nb">header</span><span class="p">(</span><span class="s1">'Content-Encoding: none'</span><span class="p">);</span>
            <span class="nb">header</span><span class="p">(</span><span class="s2">"Content-type: application/octet-stream"</span><span class="p">);</span>
            <span class="nb">header</span><span class="p">(</span><span class="s2">"Accept-Ranges: bytes"</span><span class="p">);</span>
            <span class="nb">header</span><span class="p">(</span><span class="s2">"Accept-Length: "</span> <span class="mf">.</span> <span class="nb">filesize</span><span class="p">(</span><span class="nv">$file_dir</span> <span class="mf">.</span> <span class="s2">"/"</span> <span class="mf">.</span> <span class="nv">$file_name</span><span class="p">));</span>
            <span class="nb">header</span><span class="p">(</span><span class="s1">'Content-Transfer-Encoding: binary'</span><span class="p">);</span>
            <span class="nb">header</span><span class="p">(</span><span class="s2">"Content-Disposition: attachment; filename="</span> <span class="mf">.</span> <span class="nv">$file_name</span><span class="p">);</span>  <span class="c1">//以真实文件名提供给浏览器下载</span>
            <span class="nb">header</span><span class="p">(</span><span class="s1">'Pragma: no-cache'</span><span class="p">);</span>
            <span class="nb">header</span><span class="p">(</span><span class="s1">'Expires: 0'</span><span class="p">);</span>
            <span class="c1">//输出文件内容</span>
            <span class="k">echo</span> <span class="nb">fread</span><span class="p">(</span><span class="nv">$file</span><span class="p">,</span> <span class="nb">filesize</span><span class="p">(</span><span class="nv">$file_dir</span> <span class="mf">.</span> <span class="s2">"/"</span> <span class="mf">.</span> <span class="nv">$file_name</span><span class="p">));</span>
            <span class="nb">fclose</span><span class="p">(</span><span class="nv">$file</span><span class="p">);</span>
            <span class="k">exit</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
</code></pre></div></div>

<h1 id="参考文献">参考文献</h1>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:moxin" role="doc-endnote">
      <p>【强网杯】第六届强网杯青少年线下赛AWDP复盘[EB/OL].个人博客.<a target="_blank" href="https://moxin1044.github.io/articles/57061.html">https://moxin1044.github.io/articles/57061.html</a>.2024.10.28. <a href="#fnref:moxin" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:kar3a" role="doc-endnote">
      <p>一次awdplus经历（网鼎杯线下赛）[EB/OL].个人博客.<a target="_blank" href="https://www.cnblogs.com/karsa/p/14062819.html">https://www.cnblogs.com/karsa/p/14062819.html</a>.2020.11.30 <a href="#fnref:kar3a" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>CryingN</name><email>CryingNights7v@gmail.com</email></author><category term="网络安全" /><category term="CTF" /><category term="密码学" /><category term="算法" /><category term="密码系统" /><summary type="html"><![CDATA[密码系统一般是一类比较特殊的考察方式...]]></summary></entry><entry><title type="html">[awdp学习笔记] fix部分</title><link href="https://cryingn.github.io/posts/2024/12/awdp/" rel="alternate" type="text/html" title="[awdp学习笔记] fix部分" /><published>2024-12-27T00:00:00+08:00</published><updated>2024-12-27T00:00:00+08:00</updated><id>https://cryingn.github.io/posts/2024/12/awdp</id><content type="html" xml:base="https://cryingn.github.io/posts/2024/12/awdp/"><![CDATA[<h1 id="目录">目录</h1>

<ul>
  <li><a href="#第六届强网杯">第六届强网杯</a>
    <ul>
      <li><a href="#ezdja">ezdja</a></li>
      <li><a href="#found_cms">found_cms</a></li>
    </ul>
  </li>
  <li><a href="#网鼎杯线下赛">网鼎杯线下赛</a>
    <ul>
      <li><a href="#alicewebsite">alicewebsite</a></li>
      <li><a href="#fake">fake</a></li>
    </ul>
  </li>
  <li><a href="#十七届ciscn总决赛">十七届ciscn总决赛</a>
    <ul>
      <li><a href="#anime">anime</a></li>
      <li><a href="#ezheap">ezheap</a></li>
      <li><a href="#chr">chr</a></li>
    </ul>
  </li>
  <li><a href="#参考文献">参考文献</a></li>
</ul>

<h1 id="第六届强网杯">第六届强网杯</h1>

<p>第六届青少赛线下AWDP, 参考末心师傅的文档<sup id="fnref:moxin" role="doc-noteref"><a href="#fn:moxin" class="footnote" rel="footnote">1</a></sup>, fix部分主要题目有四道:</p>

<h2 id="ezdja">ezdja</h2>

<p>经典的python类DJango框架, 文件结构为:</p>

<ul>
  <li><strong>app01</strong>
    <ul>
      <li>主要的app文件</li>
    </ul>
  </li>
  <li><strong>easypy</strong></li>
  <li><strong>static</strong>
    <ul>
      <li>前端文件</li>
    </ul>
  </li>
  <li><strong>templates</strong>
    <ul>
      <li>前端文件</li>
    </ul>
  </li>
  <li>manage.py (服务脚本)</li>
  <li>requirements.txt</li>
</ul>

<p>服务脚本用于定义Django框架, 直接找到<strong>app01/myfunc.py</strong>, 很容易可以找到简单的sql注入的waf:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">waf</span><span class="p">(</span><span class="n">sql</span><span class="p">):</span>
    <span class="n">blacklists</span> <span class="o">=</span> <span class="p">[</span><span class="s">'union select'</span><span class="p">,</span> <span class="s">'sleep'</span><span class="p">,</span> <span class="s">'benchmark'</span><span class="p">,</span> <span class="s">'columns'</span><span class="p">,</span> <span class="s">'load_file'</span><span class="p">,</span> <span class="s">'local'</span><span class="p">,</span> <span class="s">'outfile'</span><span class="p">,</span> <span class="s">'dumpfile'</span><span class="p">,</span> <span class="s">'file'</span><span class="p">]</span>
    <span class="k">for</span> <span class="n">blacklist</span> <span class="ow">in</span> <span class="n">blacklists</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">blacklist</span> <span class="ow">in</span> <span class="n">sql</span><span class="p">:</span>
            <span class="k">print</span><span class="p">(</span><span class="n">blacklist</span><span class="p">)</span>
            <span class="k">return</span> <span class="bp">False</span>
        <span class="k">return</span> <span class="bp">True</span>
</code></pre></div></div>

<p>除此之外还有其他几个waf函数, 那么要想防止注入, 需要从可能的注口下手, 在vim中直接进行<code class="language-plaintext highlighter-rouge">:/waf</code>搜索找到对应的位置, 检查到在index类中存在一段函数:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">sql</span> <span class="o">=</span> <span class="s">"select * from app01_user where username = '"</span><span class="o">+</span><span class="n">login_username</span><span class="o">+</span><span class="s">"';"</span>
<span class="n">xiaoxi</span> <span class="o">=</span> <span class="s">""</span>
<span class="k">if</span> <span class="n">waf</span><span class="p">(</span><span class="n">login_username</span><span class="p">):</span>
    <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql</span><span class="p">)</span>
    <span class="n">result</span> <span class="o">=</span> <span class="n">cursor</span><span class="p">.</span><span class="n">fettchall</span><span class="p">()</span>
    <span class="k">if</span> <span class="n">result</span><span class="p">:</span>
        <span class="n">xiaoxi</span> <span class="o">=</span> <span class="n">result</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">3</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
    <span class="n">xiaoxi</span> <span class="o">=</span> <span class="s">"No NO N0!"</span>
</code></pre></div></div>

<p>很暴力的一个方法, 顺便学了一手, 除了<code class="language-plaintext highlighter-rouge">eval</code>以外<code class="language-plaintext highlighter-rouge">execute</code>函数也应该是一个要被重点检查的函数.</p>

<p>陌心师傅提供了一个基本的修复方法, 直接增强waf(这大概需要考察web手在处理手段的基本素养了, 多出题还是有好处的):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>def waf(sql):
    blacklists = ["union select", "sleep", "benchmark","columns","load_file","local","outfile","dumpfile","file","union","select",
"select","and","*","x09","x0a","x0b","x0c","x0d","xa0","x00","x26","x7c","or","into","from","where","join","sleexml","extractvalue","+","regex","copy","read","file","create","grand","dir","insert","link","server","drop","=","&gt;","&lt;",";"]
    for blacklist in blacklists:
        if blacklist in sql:
            print(blacklist)
            return False
    return True
</code></pre></div></div>

<p>上了php的通防脚本, 防御成功了, 有时间我也写点自己的逆天想法(所以现在先鸽着).</p>

<h2 id="found_cms">found_cms</h2>

<h2 id="easygo">easygo</h2>

<p>golang会编译为二进制文件, 需要有强大的patch技巧, 这里只进行记录:</p>

<p>IDA64打开easygo文件, 找到<code class="language-plaintext highlighter-rouge">loc_49B5DE</code>处汇编显示:</p>

<pre><code class="language-asm">loc__49B5DE:
xchg    ax, ax
call    main_backdoor
jmp     short loc_49B5E9
</code></pre>

<p>继续追踪, 发现有调用<code class="language-plaintext highlighter-rouge">cat /flag</code>和<code class="language-plaintext highlighter-rouge">/bin/bash</code>两个部分, 既然是AWDP, 不难想象出官方的EXP, 直接暴力修改db部分, 将<code class="language-plaintext highlighter-rouge">cat /flag</code>修改为<code class="language-plaintext highlighter-rouge">echo 1234</code>, 个人思考了一下, 直接用retdec逆出来然后暴力改文件可能也是可以的?</p>

<h2 id="php通防">PHP通防</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">function</span> <span class="n">wafrce</span><span class="p">(</span><span class="err">$</span><span class="nb">str</span><span class="p">){</span>
	<span class="k">return</span> <span class="err">!</span><span class="n">preg_match</span><span class="p">(</span><span class="s">"/openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|scandir|assert|pcntl_exec|fwrite|curl|system|eval|assert|flag|passthru|exec|chroot|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore/i"</span><span class="p">,</span> <span class="err">$</span><span class="nb">str</span><span class="p">);</span>
<span class="p">}</span>

<span class="n">function</span> <span class="n">wafsqli</span><span class="p">(</span><span class="err">$</span><span class="nb">str</span><span class="p">){</span>
	<span class="k">return</span> <span class="err">!</span><span class="n">preg_match</span><span class="p">(</span><span class="s">"/select|and|\*|</span><span class="se">\x09</span><span class="s">|</span><span class="se">\x0a</span><span class="s">|</span><span class="se">\x0b</span><span class="s">|</span><span class="se">\x0c</span><span class="s">|</span><span class="se">\x0d</span><span class="s">|</span><span class="se">\xa0</span><span class="s">|</span><span class="se">\x00</span><span class="s">|</span><span class="se">\x26</span><span class="s">|</span><span class="se">\x7c</span><span class="s">|or|into|from|where|join|sleexml|extractvalue|+|regex|copy|read|file|create|grand|dir|insert|link|server|drop|=|&gt;|&lt;|;|</span><span class="se">\"</span><span class="s">|</span><span class="se">\'</span><span class="s">|\^|\|/i"</span><span class="p">,</span> <span class="err">$</span><span class="nb">str</span><span class="p">);</span>
<span class="p">}</span>

<span class="n">function</span> <span class="n">wafxss</span><span class="p">(</span><span class="err">$</span><span class="nb">str</span><span class="p">){</span>
	<span class="k">return</span> <span class="err">!</span><span class="n">preg_match</span><span class="p">(</span><span class="s">"/</span><span class="se">\'</span><span class="s">|http|</span><span class="se">\"</span><span class="s">|\`|cookie|&lt;|&gt;|script/i"</span><span class="p">,</span> <span class="err">$</span><span class="nb">str</span><span class="p">);</span>
<span class="p">}</span>


<span class="n">function</span> <span class="n">waf</span><span class="p">(</span><span class="err">$</span><span class="n">s</span><span class="p">){</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">preg_match</span><span class="p">(</span><span class="s">"/select|flag|union|</span><span class="se">\\</span><span class="s">$|'|"</span><span class="o">|--|</span><span class="c1">#|\0|into|alert|img|prompt|set|/*|x09|x0a|x0b|x0c|x0d|xa0|%|&lt;|&gt;|^|x00|#|x23|[0-9]|file|=|or|x7c|select|and|flag|into|where|x26|'|"|union|`|sleep|benchmark|regexp|from|count|procedure|and|ascii|substr|substring|left|right|union|if|case|pow|exp|order|sleep|benchmark|into|load|outfile|dumpfile|load_file|join|show|select|update|set|concat|delete|alter|insert|create|union|or|drop|not|for|join|is|between|group_concat|like|where|user|ascii|greatest|mid|substr|left|right|char|hex|ord|case|limit|conv|table|mysql_history|flag|count|rpad|&amp;|*|.|/is",$s)||strlen($s)&gt;50){
</span>    <span class="n">header</span><span class="p">(</span><span class="s">"Location: /"</span><span class="p">);</span>
    <span class="n">die</span><span class="p">();</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h1 id="网鼎杯线下赛">网鼎杯线下赛</h1>

<p>然后是kar3a师傅在网鼎杯的记录, 据说有点像ciscn, 有时间也看看那边的题目<sup id="fnref:kar3a" role="doc-noteref"><a href="#fn:kar3a" class="footnote" rel="footnote">2</a></sup>.</p>

<h2 id="alicewebsite">alicewebsite</h2>

<p>php题, 直接丢D盾里面, 找到可疑引用:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
        <span class="nv">$action</span> <span class="o">=</span> <span class="p">(</span><span class="k">isset</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s1">'action'</span><span class="p">])</span> <span class="o">?</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s1">'action'</span><span class="p">]</span> <span class="o">:</span> <span class="s1">'home.php'</span><span class="p">);</span>
        <span class="k">if</span> <span class="p">(</span><span class="nb">file_exists</span><span class="p">(</span><span class="nv">$action</span><span class="p">))</span> <span class="p">{</span>
            <span class="k">include</span> <span class="nv">$action</span><span class="p">;</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">echo</span> <span class="s2">"File not found!"</span><span class="p">;</span>
        <span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>

<p>D盾其实在长城杯半决赛过程中我们有配置过, 现在看来awd和awdp还是共通的, 只不过没了搅混水的过程(不过某种意义上添加一点选手间后期的斗智斗勇会更有意思, 个人感觉), 发现用户传入的<code class="language-plaintext highlighter-rouge">$action</code>没有进行过滤, 可以直接通过目录穿越, payload:<code class="language-plaintext highlighter-rouge">?action=../../../../flag</code></p>

<p>防御手段是构造一个黑名单防止目录穿越:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?php</span>
        <span class="nv">$action</span> <span class="o">=</span> <span class="p">(</span><span class="k">isset</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s1">'action'</span><span class="p">])</span> <span class="o">?</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s1">'action'</span><span class="p">]</span> <span class="o">:</span> <span class="s1">'home.php'</span><span class="p">);</span>
		<span class="nv">$deny_ext</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s2">".."</span><span class="p">,</span><span class="s2">"../"</span><span class="p">);</span>
		<span class="k">if</span> <span class="p">(</span><span class="nb">in_array</span><span class="p">(</span><span class="nv">$action</span><span class="p">,</span> <span class="nv">$deny_ext</span><span class="p">)){</span>
            <span class="k">if</span> <span class="p">(</span><span class="nb">file_exists</span><span class="p">(</span><span class="nv">$action</span><span class="p">))</span> <span class="p">{</span>
                <span class="k">include</span> <span class="nv">$action</span><span class="p">;</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="k">echo</span> <span class="s2">"File not found!"</span><span class="p">;</span>
            <span class="p">}</span>
		<span class="p">}</span>
<span class="cp">?&gt;</span>
</code></pre></div></div>

<h2 id="fake">fake</h2>

<p>buu上有原题, <code class="language-plaintext highlighter-rouge">/admin</code>进入后台, 是目录穿越:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">downloadBak</span><span class="p">()</span> <span class="p">{</span>
        <span class="nv">$file_name</span> <span class="o">=</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s1">'file'</span><span class="p">];</span>
        <span class="nv">$file_dir</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">config</span><span class="p">[</span><span class="s1">'path'</span><span class="p">];</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">file_exists</span><span class="p">(</span><span class="nv">$file_dir</span> <span class="mf">.</span> <span class="s2">"/"</span> <span class="mf">.</span> <span class="nv">$file_name</span><span class="p">))</span> <span class="p">{</span> <span class="c1">//检查文件是否存在</span>
            <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
            <span class="k">exit</span><span class="p">;</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="nv">$file</span> <span class="o">=</span> <span class="nb">fopen</span><span class="p">(</span><span class="nv">$file_dir</span> <span class="mf">.</span> <span class="s2">"/"</span> <span class="mf">.</span> <span class="nv">$file_name</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">);</span> <span class="c1">// 打开文件</span>
            <span class="c1">// 输入文件标签</span>
            <span class="nb">header</span><span class="p">(</span><span class="s1">'Content-Encoding: none'</span><span class="p">);</span>
            <span class="nb">header</span><span class="p">(</span><span class="s2">"Content-type: application/octet-stream"</span><span class="p">);</span>
            <span class="nb">header</span><span class="p">(</span><span class="s2">"Accept-Ranges: bytes"</span><span class="p">);</span>
            <span class="nb">header</span><span class="p">(</span><span class="s2">"Accept-Length: "</span> <span class="mf">.</span> <span class="nb">filesize</span><span class="p">(</span><span class="nv">$file_dir</span> <span class="mf">.</span> <span class="s2">"/"</span> <span class="mf">.</span> <span class="nv">$file_name</span><span class="p">));</span>
            <span class="nb">header</span><span class="p">(</span><span class="s1">'Content-Transfer-Encoding: binary'</span><span class="p">);</span>
            <span class="nb">header</span><span class="p">(</span><span class="s2">"Content-Disposition: attachment; filename="</span> <span class="mf">.</span> <span class="nv">$file_name</span><span class="p">);</span>  <span class="c1">//以真实文件名提供给浏览器下载</span>
            <span class="nb">header</span><span class="p">(</span><span class="s1">'Pragma: no-cache'</span><span class="p">);</span>
            <span class="nb">header</span><span class="p">(</span><span class="s1">'Expires: 0'</span><span class="p">);</span>
            <span class="c1">//输出文件内容</span>
            <span class="k">echo</span> <span class="nb">fread</span><span class="p">(</span><span class="nv">$file</span><span class="p">,</span> <span class="nb">filesize</span><span class="p">(</span><span class="nv">$file_dir</span> <span class="mf">.</span> <span class="s2">"/"</span> <span class="mf">.</span> <span class="nv">$file_name</span><span class="p">));</span>
            <span class="nb">fclose</span><span class="p">(</span><span class="nv">$file</span><span class="p">);</span>
            <span class="k">exit</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
</code></pre></div></div>

<h1 id="参考文献">参考文献</h1>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:moxin" role="doc-endnote">
      <p>【强网杯】第六届强网杯青少年线下赛AWDP复盘[EB/OL].个人博客.<a target="_blank" href="https://moxin1044.github.io/articles/57061.html">https://moxin1044.github.io/articles/57061.html</a>.2024.10.28. <a href="#fnref:moxin" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:kar3a" role="doc-endnote">
      <p>一次awdplus经历（网鼎杯线下赛）[EB/OL].个人博客.<a target="_blank" href="https://www.cnblogs.com/karsa/p/14062819.html">https://www.cnblogs.com/karsa/p/14062819.html</a>.2020.11.30 <a href="#fnref:kar3a" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>CryingN</name><email>CryingNights7v@gmail.com</email></author><category term="网络安全" /><category term="CTF" /><category term="AWD" /><category term="AWDP" /><category term="fix" /><summary type="html"><![CDATA[马上要参加决赛了, 学习一下相关知识...]]></summary></entry></feed>