<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2025-10-21T16:02:51+00:00</updated><id>/feed.xml</id><title type="html">ZenHack Team</title><subtitle>Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</subtitle><entry><title type="html">01_ _fidler</title><link href="/rev/2020/10/28/01_-_fidler.html" rel="alternate" type="text/html" title="01_ _fidler" /><published>2020-10-28T00:00:00+00:00</published><updated>2020-10-28T00:00:00+00:00</updated><id>/rev/2020/10/28/01_-_fidler</id><content type="html" xml:base="/rev/2020/10/28/01_-_fidler.html"><![CDATA[<blockquote>
  <p>Welcome to the Seventh Flare-On Challenge!</p>

  <p>This is a simple game. Win it by any means necessary and the victory screen will reveal the flag. Enter the flag here on this site to score and move on to the next level.</p>

  <p>This challenge is written in Python and is distributed as a runnable EXE and matching source code for your convenience. You can run the source code directly on any Python platform with PyGame if you would prefer.</p>
</blockquote>

<p>The challenge consists of a simple game written in python, you are given both the precompiled executable and python source code.</p>

<p>First of all the challenge ask you for a password, by opening <code class="language-plaintext highlighter-rouge">fidler.py</code> it’s easy to see the <code class="language-plaintext highlighter-rouge">check_password</code> function that asks you to input <code class="language-plaintext highlighter-rouge">ghost</code>.</p>

<p>Once the password is checked the game starts.</p>

<p><img src="/assets/writeups/FlareOn7/fidler/game.png" alt="Game Screenshot" /></p>

<p>To obtain the flag you have to reach 100 Bln clicks, you can buy auto-clickers paying already done clicks. Even with auto-clickers, reaching 100 Bln clicks, it’s obviously a stupid idea and not the intended solution.</p>

<p>Looking in the source code, in <code class="language-plaintext highlighter-rouge">fidler.py</code>, there is a function:</p>

<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">decode_flag</span><span class="p">(</span><span class="n">frob</span><span class="p">):</span>
  <span class="n">last_value</span> <span class="o">=</span> <span class="n">frob</span>
  <span class="n">encoded_flag</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1135</span><span class="p">,</span> <span class="mi">1038</span><span class="p">,</span> <span class="mi">1126</span><span class="p">,</span> <span class="mi">1028</span><span class="p">,</span> <span class="mi">1117</span><span class="p">,</span> <span class="mi">1071</span><span class="p">,</span> <span class="mi">1094</span><span class="p">,</span> <span class="mi">1077</span><span class="p">,</span> <span class="mi">1121</span><span class="p">,</span> <span class="mi">1087</span><span class="p">,</span> <span class="mi">1110</span><span class="p">,</span> <span class="mi">1092</span><span class="p">,</span> <span class="mi">1072</span><span class="p">,</span> <span class="mi">1095</span><span class="p">,</span> <span class="mi">1090</span><span class="p">,</span> <span class="mi">1027</span><span class="p">,</span><span class="mi">1127</span><span class="p">,</span> <span class="mi">1040</span><span class="p">,</span> <span class="mi">1137</span><span class="p">,</span> <span class="mi">1030</span><span class="p">,</span> <span class="mi">1127</span><span class="p">,</span> <span class="mi">1099</span><span class="p">,</span> <span class="mi">1062</span><span class="p">,</span> <span class="mi">1101</span><span class="p">,</span> <span class="mi">1123</span><span class="p">,</span> <span class="mi">1027</span><span class="p">,</span> <span class="mi">1136</span><span class="p">,</span> <span class="mi">1054</span><span class="p">]</span>
  <span class="n">decoded_flag</span> <span class="o">=</span> <span class="p">[]</span>

  <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">encoded_flag</span><span class="p">)):</span>
    <span class="n">c</span> <span class="o">=</span> <span class="n">encoded_flag</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
    <span class="n">val</span> <span class="o">=</span> <span class="p">(</span><span class="n">c</span> <span class="o">-</span> <span class="p">((</span><span class="n">i</span><span class="o">%</span><span class="mi">2</span><span class="p">)</span><span class="o">*</span><span class="mi">1</span> <span class="o">+</span> <span class="p">(</span><span class="n">i</span><span class="o">%</span><span class="mi">3</span><span class="p">)</span><span class="o">*</span><span class="mi">2</span><span class="p">))</span> <span class="o">^</span> <span class="n">last_value</span>
    <span class="n">decoded_flag</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">val</span><span class="p">)</span>
    <span class="n">last_value</span> <span class="o">=</span> <span class="n">c</span>

  <span class="k">return</span> <span class="s">''</span><span class="p">.</span><span class="n">join</span><span class="p">([</span><span class="nb">chr</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">decoded_flag</span><span class="p">])</span>
</code></pre></div></div>

<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">victory_screen</span><span class="p">(</span><span class="n">token</span><span class="p">):</span>
  <span class="p">...</span>
  <span class="n">flag_content_label</span><span class="p">.</span><span class="n">change_text</span><span class="p">(</span><span class="n">decode_flag</span><span class="p">(</span><span class="n">token</span><span class="p">))</span>
  <span class="p">...</span>
</code></pre></div></div>

<p>The function <code class="language-plaintext highlighter-rouge">victory_screen</code> is called as follows:</p>

<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">victory_screen</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">current_coins</span> <span class="o">/</span> <span class="mi">10</span><span class="o">**</span><span class="mi">8</span><span class="p">))</span>
</code></pre></div></div>

<p>Where current_coins is the number of clicks done.
So retrieving the flag could be done by calling the <code class="language-plaintext highlighter-rouge">decode_flag</code> function.</p>

<p><strong><code class="language-plaintext highlighter-rouge">idle_with_kitty@flare-on.com</code></strong></p>]]></content><author><name>Firpo7</name></author><category term="rev" /><category term="ctf" /><category term="challenge" /><category term="write-up" /><category term="binary" /><category term="reverse engineer" /><category term="Malware Analysis" /><summary type="html"><![CDATA[Welcome to the Seventh Flare-On Challenge! This is a simple game. Win it by any means necessary and the victory screen will reveal the flag. Enter the flag here on this site to score and move on to the next level. This challenge is written in Python and is distributed as a runnable EXE and matching source code for your convenience. You can run the source code directly on any Python platform with PyGame if you would prefer.]]></summary></entry><entry><title type="html">02_ _garbage</title><link href="/rev/2020/10/28/02_-_garbage.html" rel="alternate" type="text/html" title="02_ _garbage" /><published>2020-10-28T00:00:00+00:00</published><updated>2020-10-28T00:00:00+00:00</updated><id>/rev/2020/10/28/02_-_garbage</id><content type="html" xml:base="/rev/2020/10/28/02_-_garbage.html"><![CDATA[<blockquote>
  <p>One of our team members developed a Flare-On challenge but accidentally deleted it. We recovered it using extreme digital forensic techniques but it seems to be corrupted. We would fix it but we are too busy solving today’s most important information security threats affecting our global economy. You should be able to get it working again, reverse engineer it, and acquire the flag.</p>
</blockquote>

<p>The challenge provides a corrupted PE file, trying to opening it with some tools will lead to a crash of them. The goal of the challenge was to reconstruct the PE and run it to obtain the flag.</p>

<p><img src="/assets/writeups/FlareOn7/garbage/start.png" alt="Garbage Errors" /></p>

<p>I decided to open the file with 010Editor to check what was corrupted. The first thing I noticed is that it is a UPX packed executable, then I noticed that something at the end was missing.</p>

<p>The first thing I made was to unpack the file using a UpxUnpacker, then I adjusted some metadata (i.e. Imports) using CFF Explorer and finally ran it using wine to find the flag!</p>

<p><strong><code class="language-plaintext highlighter-rouge">C0rruptGarbag3@flare-on.com</code></strong></p>]]></content><author><name>Firpo7</name></author><category term="rev" /><category term="ctf" /><category term="challenge" /><category term="write-up" /><category term="binary" /><category term="reverse engineer" /><category term="Malware Analysis" /><summary type="html"><![CDATA[One of our team members developed a Flare-On challenge but accidentally deleted it. We recovered it using extreme digital forensic techniques but it seems to be corrupted. We would fix it but we are too busy solving today’s most important information security threats affecting our global economy. You should be able to get it working again, reverse engineer it, and acquire the flag.]]></summary></entry><entry><title type="html">03_ _wednesday</title><link href="/rev/2020/10/28/03_-_wednesday.html" rel="alternate" type="text/html" title="03_ _wednesday" /><published>2020-10-28T00:00:00+00:00</published><updated>2020-10-28T00:00:00+00:00</updated><id>/rev/2020/10/28/03_-_wednesday</id><content type="html" xml:base="/rev/2020/10/28/03_-_wednesday.html"><![CDATA[<blockquote>
  <p>Be the wednesday. Unlike challenge 1, you probably won’t be able to beat this game the old fashioned way. Read the README.txt file, it is very important.</p>
</blockquote>

<p>This challenge consists of a simple game. This game is similar to “Dino Runner”, where the character will run forward and you have to avoid obstacles by jumping them or slipping below.</p>

<p><img src="/assets/writeups/FlareOn7/wednesday/down.png" alt="Game Screenshot" /></p>

<p>After a few runs, it’s noticeable that the jumps and the slipping are always the same. So they could either generated in a deterministic way or they are hardcoded.</p>

<p>After searching around in the code how the obstacles were generated I found in the executable what they seem to be the bytes that determine how the obstacles should be avoided.</p>

<p>They are an array of zeroes and ones, where zeroes mean that the obstacle should be avoided by passing below while the ones mean that the obstacle should be jumped.</p>

<p><img src="/assets/writeups/FlareOn7/wednesday/binary_obstacles.png" alt="Hex View of Obstacles" /></p>

<p>The flag could be found by treating those bytes as bits and converting them into characters.</p>

<p><strong><code class="language-plaintext highlighter-rouge">1t_i5_wEdn3sd4y_mY_Dud3s@flare-on.com</code></strong></p>]]></content><author><name>Firpo7</name></author><category term="rev" /><category term="ctf" /><category term="challenge" /><category term="write-up" /><category term="binary" /><category term="reverse engineer" /><category term="Malware Analysis" /><summary type="html"><![CDATA[Be the wednesday. Unlike challenge 1, you probably won’t be able to beat this game the old fashioned way. Read the README.txt file, it is very important.]]></summary></entry><entry><title type="html">04_ _report</title><link href="/rev/2020/10/28/04_-_report.html" rel="alternate" type="text/html" title="04_ _report" /><published>2020-10-28T00:00:00+00:00</published><updated>2020-10-28T00:00:00+00:00</updated><id>/rev/2020/10/28/04_-_report</id><content type="html" xml:base="/rev/2020/10/28/04_-_report.html"><![CDATA[<blockquote>
  <p>Nobody likes analyzing infected documents, but it pays the bills. Reverse this macro thrill-ride to discover how to get it to show you the key.</p>
</blockquote>

<p>For challenge provides only an Excel document is provided. Also from the description is clear it has to do with macros.</p>

<p><img src="/assets/writeups/FlareOn7/report/start.png" alt="Infected Document" /></p>

<p>Dumping the macros from the document will lead you to find only an mp3. This mp3 is not useless though, as it has a hint inside it. In fact, the metadata author of the mp3 audio is <code class="language-plaintext highlighter-rouge">P. Code</code>, suggesting you to try to take a look at the p-code of the document.</p>

<p>Analyzing the p-code turns out that it does a different thing than the VBA source code, what’s happened is called <cite><a href="https://medium.com/walmartglobaltech/vba-stomping-advanced-maldoc-techniques-612c484ab278">VBA stomping</a></cite>.</p>

<p>The author of the challenge has modified the VBA source code leaving the compiled version in the document, known as p-code, unchanged.</p>

<p>To retrieve back the source code can be used <code class="language-plaintext highlighter-rouge">pcode2code.exe</code> as follows:</p>
<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">pcode2code.exe</span><span class="w">  </span><span class="o">.</span><span class="nx">\report.xls</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="nx">output.txt</span><span class="w">
</span></code></pre></div></div>

<p>Analyzing the resulting code will lead to finding an image containing the flag:
<img src="/assets/writeups/FlareOn7/report/solved.png" alt="Result Image" /></p>

<p><strong><code class="language-plaintext highlighter-rouge">thi5_cou1d_h4v3_b33n_b4d@flare-on.com</code></strong></p>]]></content><author><name>Firpo7</name></author><category term="rev" /><category term="ctf" /><category term="challenge" /><category term="write-up" /><category term="binary" /><category term="reverse engineer" /><category term="Malware Analysis" /><summary type="html"><![CDATA[Nobody likes analyzing infected documents, but it pays the bills. Reverse this macro thrill-ride to discover how to get it to show you the key.]]></summary></entry><entry><title type="html">05_ _tkapp</title><link href="/rev/2020/10/28/05_-_TKApp.html" rel="alternate" type="text/html" title="05_ _tkapp" /><published>2020-10-28T00:00:00+00:00</published><updated>2020-10-28T00:00:00+00:00</updated><id>/rev/2020/10/28/05_-_TKApp</id><content type="html" xml:base="/rev/2020/10/28/05_-_TKApp.html"><![CDATA[<blockquote>
  <p>Now you can play Flare-On on your watch! As long as you still have an arm left to put a watch on, or emulate the watch’s operating system with sophisticated developer tools.</p>
</blockquote>

<p>This challenge gives you a TPK file. A TPK file is a Tizen Application Package file and it is used on watches running Tizen OS.</p>

<p>As for Android applications, we can unzip it to take a look at the components. Inside the <code class="language-plaintext highlighter-rouge">bin</code> folder can be found a bunch of dlls, they were written and compiled in C# so dnSpy can be used to analyze them.</p>

<p>During the analysis of <code class="language-plaintext highlighter-rouge">TKApp.dll</code> I noticed a sort of “anomaly”. The MainPage class has a GetImage method that is going to read and decipher a resource called “<code class="language-plaintext highlighter-rouge">Runtime.Runtime_dll</code>”.</p>

<p><img src="/assets/writeups/FlareOn7/tkapp/strange_code.png" alt="Strange Code" /></p>

<p>So I decided to decipher the content of that resource as it does the application. The key used to decipher the flag is generated by hashing the <code class="language-plaintext highlighter-rouge">text</code> variable, generated as follows:</p>

<p><img src="/assets/writeups/FlareOn7/tkapp/key_generation.png" alt="Strange Code" /></p>

<p>All the variables used are initialized in other points of the application upon specific circumstances, so to check that I was using the right values I found another point in the code where I could test these variables.</p>

<p><img src="/assets/writeups/FlareOn7/tkapp/test_variables.png" alt="Test Variables" /></p>

<p>As shown in the image they are used to generate a hash that must be equal to the one hardcoded.</p>

<p>Once found the right variables the <code class="language-plaintext highlighter-rouge">Runtime_dll</code> resource can be decrypted.</p>

<p><img src="/assets/writeups/FlareOn7/tkapp/Runtime.png" alt="Flag" /></p>

<p><strong><code class="language-plaintext highlighter-rouge">n3ver_go1ng_to_recov3r@flare-on.com</code></strong></p>]]></content><author><name>Firpo7</name></author><category term="rev" /><category term="ctf" /><category term="challenge" /><category term="write-up" /><category term="binary" /><category term="reverse engineer" /><category term="Malware Analysis" /><summary type="html"><![CDATA[Now you can play Flare-On on your watch! As long as you still have an arm left to put a watch on, or emulate the watch’s operating system with sophisticated developer tools.]]></summary></entry><entry><title type="html">06_ _codeit</title><link href="/rev/2020/10/28/06_-_codeit.html" rel="alternate" type="text/html" title="06_ _codeit" /><published>2020-10-28T00:00:00+00:00</published><updated>2020-10-28T00:00:00+00:00</updated><id>/rev/2020/10/28/06_-_codeit</id><content type="html" xml:base="/rev/2020/10/28/06_-_codeit.html"><![CDATA[<blockquote>
  <p>Reverse engineer this little compiled script to figure out what you need to do to make it give you the flag (as a QR code).</p>
</blockquote>

<p>The challenge provides you with an executable, the program asks you for input and then generates a QR code based on it. The goal of the challenge is to let the program meet a condition so that the generated QR code contains the flag.</p>

<p><img src="/assets/writeups/FlareOn7/codeit/start.png" alt="CodeIt Program" /></p>

<p>The name of the challenge suggests it could be an AutoIt3 compiled executable. Looking with pestudio and searching for the string <code class="language-plaintext highlighter-rouge">AU3!EA06</code> at the and of the code section confirmed the hypothesis.</p>

<p>Fortunately, there are tools that decompile AutoIt3 executable for you. The output code obtained is obfuscated, so I made other operations to it in order to make it much more readable.</p>

<p>The decompiler tool will output also a <code class="language-plaintext highlighter-rouge">qr_encoder.dll</code> and a <code class="language-plaintext highlighter-rouge">sprite.bmp</code>.</p>

<p>The first thing done, to try to deobfuscate the code, was to replace the variables instantiated for each number used inside the code with the numbers themselves, using a parser that I’ve written for this challenge.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">regex</span> <span class="o">=</span> <span class="sa">r</span><span class="s">'([a-z]+) = Number\(" ([0-9]+) "'</span>

<span class="n">content</span> <span class="o">=</span> <span class="s">''</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">FILE_OBFUSCATED</span><span class="p">,</span> <span class="s">"r"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
    <span class="n">content</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">r1</span> <span class="o">=</span> <span class="n">re</span><span class="p">.</span><span class="n">findall</span><span class="p">(</span><span class="n">regex</span><span class="p">,</span><span class="n">content</span><span class="p">)</span>

<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">num</span> <span class="ow">in</span> <span class="n">r1</span><span class="p">:</span>
    <span class="n">content</span> <span class="o">=</span> <span class="n">content</span><span class="p">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">f</span><span class="s">"$</span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s">"</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">num</span><span class="p">))</span>
</code></pre></div></div>

<p>After that was much easier to deobfuscate all the strings. They are saved as hexadecimal strings in an array and then decoded runtime.
Replacing the call to the function that does these operations, with the deobfuscated strings, will result in a much more clear code.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for</span> <span class="n">n</span><span class="p">,</span><span class="n">c</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">hexencoded_strings_array</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">c</span> <span class="o">==</span> <span class="s">''</span><span class="p">:</span>
        <span class="n">content</span> <span class="o">=</span> <span class="n">content</span><span class="p">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">f</span><span class="s">"decoder($os[</span><span class="si">{</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span><span class="si">}</span><span class="s">])"</span><span class="p">,</span> <span class="s">"''"</span><span class="p">)</span>
        <span class="k">continue</span>

    <span class="n">content</span> <span class="o">=</span> <span class="n">content</span><span class="p">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">f</span><span class="s">"decoder($os[</span><span class="si">{</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span><span class="si">}</span><span class="s">])"</span><span class="p">,</span> <span class="sa">f</span><span class="s">'"</span><span class="si">{</span><span class="n">libnum</span><span class="p">.</span><span class="n">n2s</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">c</span><span class="p">,</span><span class="mi">16</span><span class="p">))</span><span class="si">}</span><span class="s">"'</span><span class="p">)</span>

</code></pre></div></div>

<p>What the challenge does is to take our input and transform it into a QR code.
Once the code it’s more clear it can be seen that, when the program meets a certain condition, it substitute the input with a decrypted string.</p>

<p>The string gets decrypted using a key generated from the computer name. Analyzing the function that processes the computer name turns out that it reads some bytes from <code class="language-plaintext highlighter-rouge">sprite.bmp</code>, getting only the bit of them, grouping the bits each 7, sum them with the bytes of our computer name and then divide the result by 2.</p>

<p>Converting the 7 bits groups, obtained from the <code class="language-plaintext highlighter-rouge">sprite.bmp</code>, in ASCII will decode the string <code class="language-plaintext highlighter-rouge">aut01tfan1999</code>. So if we put as computer name that string what the above algorithm will do is to multiply each byte of 2 (as the characters it is summing are the same) and then dividing them by 2, resulting in an unchanged string. These string, as explained before, will be used to decipher the flag that will be then encoded in a QR code.</p>

<p>To solve the challenge it is needed only to change the computer name to <code class="language-plaintext highlighter-rouge">aut01tfan1999</code> and then generate a QR code with any input string, also empty.</p>

<p><img src="/assets/writeups/FlareOn7/codeit/flag_qrcode.png" alt="QR Code Flag" /></p>

<p><strong><code class="language-plaintext highlighter-rouge">L00ks_L1k3_Y0u_D1dnt_Run_Aut0_Tim3_0n_Th1s_0ne!@flare-on.com</code></strong></p>]]></content><author><name>Firpo7</name></author><category term="rev" /><category term="ctf" /><category term="challenge" /><category term="write-up" /><category term="binary" /><category term="reverse engineer" /><category term="Malware Analysis" /><summary type="html"><![CDATA[Reverse engineer this little compiled script to figure out what you need to do to make it give you the flag (as a QR code).]]></summary></entry><entry><title type="html">07_ _re_crowd</title><link href="/rev/2020/10/28/07_-_re_crowd.html" rel="alternate" type="text/html" title="07_ _re_crowd" /><published>2020-10-28T00:00:00+00:00</published><updated>2020-10-28T00:00:00+00:00</updated><id>/rev/2020/10/28/07_-_re_crowd</id><content type="html" xml:base="/rev/2020/10/28/07_-_re_crowd.html"><![CDATA[<blockquote>
  <p>Hello,</p>

  <p>Here at Reynholm Industries we pride ourselves on everything.
It’s not easy to admit, but recently one of our most valuable servers was breached.
We don’t believe in host monitoring so all we have is a network packet capture.
We need you to investigate and determine what data was extracted from the server, if any.</p>

  <p>Thank you</p>
</blockquote>

<p>The challenge provides only a captured network traffic, of a malicious attack, and asks to investigate what data was stolen from the server of the Reynholm Industries. The flag it’s inside these data.</p>

<p><img src="/assets/writeups/FlareOn7/re_crowd/start.png" alt="Network Capture" /></p>

<p>The network traffic has captured an exploit of CVE-2017-7269, this vulnerability exploits a buffer overflow present in the WebDAV service in Internet Information Services (IIS) 6.0 in Microsoft Windows Server 2003. This CVE allows remote attackers to execute arbitrary code via a long header beginning with “<code class="language-plaintext highlighter-rouge">If: &lt;http://</code>” in a PROPFIND request.</p>

<p>In the network traffic captured there are a lot of HTTP requests, against a Microsoft IIS 6.0 server, each one differs only on the length of padding until it guesses the correct one that will start the ROP chain that will lead to an RCE.</p>

<p><img src="/assets/writeups/FlareOn7/re_crowd/bruteforce_padding.png" alt="Request Bruteforcing" /></p>

<p>The code to be executed is inside the request and it is encoded in an alphanumeric string, created using the Metasploit encoder ‘AlphanumUnicodeMixed’. Metasploit alphanumeric payloads have an initial decoder STUB that will decode the rest of the payload.</p>

<p><img src="/assets/writeups/FlareOn7/re_crowd/dump_exploit.png" alt="Hexdump Exploit" /></p>

<p>If the attack goes well then the server will establish a new connection to the attacker’s port 4444, followed by another one on port 1337.</p>

<p>The new connections established with the server seem to be encrypted in some way, so to see what’s inside that communication first it is needed to understand what all those requests do.</p>

<p>Starting to debug the first payload it can be seen that it loads functions library by using a technique that consists of calculating a sort of hash code of the dll names, if one match with the one it is searching for then it continues with the same technique for each function inside that library. Once it found the right function then it saves its pointer, ready to be used during the rest of the execution.</p>

<p>By using the functions loaded, it will open a connection to the IP 192.168.68.21 on port 4444, there it will wait to receive any data. Arrived at this point I decided to change the IP of my virtual machine to 192.168.68.21, using a python script to wait for the connection and sends back the same bytes extracted from the captured connection that the server has received at the same time. Once send those bytes my python script will wait for a connection at port 1337.</p>

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

<span class="n">EXTRACTED_RESPONSE</span> <span class="o">=</span> <span class="s">"</span><span class="se">\x9c\x5c\x4f\x52</span><span class="s">..."</span>

<span class="n">l</span>  <span class="o">=</span> <span class="n">listen</span><span class="p">(</span><span class="mi">4444</span><span class="p">)</span>
<span class="n">l2</span> <span class="o">=</span> <span class="n">listen</span><span class="p">(</span><span class="mi">1337</span><span class="p">)</span>

<span class="n">l</span><span class="p">.</span><span class="n">wait_for_connection</span><span class="p">()</span>
<span class="k">print</span><span class="p">()</span>

<span class="nb">raw_input</span><span class="p">(</span><span class="s">"received a connection on 4444! press a key to continue..."</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">"continuing..."</span><span class="p">)</span>

<span class="n">l</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="n">EXTRACTED_RESPONSE</span><span class="p">)</span>

<span class="n">l2</span><span class="p">.</span><span class="n">wait_for_connection</span><span class="p">()</span>

<span class="n">s</span> <span class="o">=</span> <span class="n">l</span><span class="p">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="c1"># receive some bytes
</span><span class="k">print</span><span class="p">(</span><span class="s">"l  "</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
</code></pre></div></div>

<p>The bytes received will be stored in a VirtualAlloced area, decrypted, and then continued the execution into it.</p>

<p>Inside this second payload, it will use the same technique used before to load some function that will use for this last part. The functions are for example “CreateFile”, “ReadFile” and other functions useful to establish socket connections.</p>

<p>The CreateFile function will be used to access the file “C:\accounts.txt”, then it will read the content, encrypt it by xoring with a generated key and finally sends the content to port 1337 of the attacker. By debugging this part the xoring key could be dumped and used to retrieve back the original file send xored and captured in the network traffic!</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>roy:h4ve_you_tri3d_turning_1t_0ff_and_0n_ag4in@flare-on.com:goat
moss:Pot-Pocket-Pigeon-Hunt-8:narwhal
jen:Straighten-Effective-Gift-Pity-1:bunny
richmond:Inventor-Hut-Autumn-Tray-6:bird
denholm:123:dog
</code></pre></div></div>]]></content><author><name>Firpo7</name></author><category term="rev" /><category term="ctf" /><category term="challenge" /><category term="write-up" /><category term="binary" /><category term="reverse engineer" /><category term="Malware Analysis" /><summary type="html"><![CDATA[Hello, Here at Reynholm Industries we pride ourselves on everything. It’s not easy to admit, but recently one of our most valuable servers was breached. We don’t believe in host monitoring so all we have is a network packet capture. We need you to investigate and determine what data was extracted from the server, if any. Thank you]]></summary></entry><entry><title type="html">08_ _aardvark</title><link href="/rev/2020/10/28/08_-_Aardvark.html" rel="alternate" type="text/html" title="08_ _aardvark" /><published>2020-10-28T00:00:00+00:00</published><updated>2020-10-28T00:00:00+00:00</updated><id>/rev/2020/10/28/08_-_Aardvark</id><content type="html" xml:base="/rev/2020/10/28/08_-_Aardvark.html"><![CDATA[<blockquote>
  <p>Expect difficulty running this one. I suggest investigating why each error is occuring. Or not, whatever. You do you.</p>
</blockquote>

<p>The challenge consists in a Tic-Tac-Toe game between you and an AI. The goal of the challenge was to beat the AI.</p>

<p><img src="/assets/writeups/FlareOn7/aardvark/start.png" alt="Tic-Tac-Toe" /></p>

<p>While you run the code on a windows machine, the AI was deployed automatically on WSL, using COMs, and so it is an ELF executable. The AI was impossible to beat fairly, so I modified the ELF executable.</p>

<p>My solution was to swap the move of the AI with my one, so instead of putting ‘<code class="language-plaintext highlighter-rouge">X</code>’ I modified the executable such that the AI will put an ‘<code class="language-plaintext highlighter-rouge">O</code>’.</p>

<p>This will lead to the win and to the flag.</p>

<p><strong><code class="language-plaintext highlighter-rouge">c1ArF/P2CjiDXQIZ@flare-on.com</code></strong></p>

<p>As you can see the flag seems weird but, after running the program some times on different machines and briefly looking at how it generates it, trying to submitting it will confirm that it is the right one.</p>]]></content><author><name>Firpo7</name></author><category term="rev" /><category term="ctf" /><category term="challenge" /><category term="write-up" /><category term="binary" /><category term="reverse engineer" /><category term="Malware Analysis" /><summary type="html"><![CDATA[Expect difficulty running this one. I suggest investigating why each error is occuring. Or not, whatever. You do you.]]></summary></entry><entry><title type="html">09_ _crackinstaller</title><link href="/rev/2020/10/28/09_-_crackinstaller.html" rel="alternate" type="text/html" title="09_ _crackinstaller" /><published>2020-10-28T00:00:00+00:00</published><updated>2020-10-28T00:00:00+00:00</updated><id>/rev/2020/10/28/09_-_crackinstaller</id><content type="html" xml:base="/rev/2020/10/28/09_-_crackinstaller.html"><![CDATA[<blockquote>
  <p>What kind of crackme doesn’t even ask for the password? We need to work on our COMmunication skills.</p>

  <ul>
    <li>Bug Notice: Avoid a possible blue-screen by debugging this on a single core VM</li>
  </ul>
</blockquote>

<p>The challenge provides you with an executable <code class="language-plaintext highlighter-rouge">crackinstaller.exe</code>, it was a kind of crackme that doesn’t ask you for input but you have to provide the “password” through registers. The goal was to find the right password so that it decrypts the flag.</p>

<p>The first thing done was to setup an environment to analyze the behavior of the program. Using Procmon it can be seen that it creates and interacts with the register:</p>

<p><code class="language-plaintext highlighter-rouge">HKEY_CLASSES_ROOT\CLSID\{CEEACC6E-CCB2-4C4F-BCF6-D2176037A9A7}</code></p>

<p><img src="/assets/writeups/FlareOn7/crackinstaller/com.png" alt="COM register" /></p>

<p>This register refers to a COM object which implementation could be found in the dll pointed by the key <code class="language-plaintext highlighter-rouge">InProcServer32\Default</code>.</p>

<p>Furthermore, there is also a <code class="language-plaintext highlighter-rouge">Config</code> key containing two subkeys <em>Flag</em> and <em>Password</em>.</p>

<p><img src="/assets/writeups/FlareOn7/crackinstaller/flag_pwd_reg.png" alt="Flag and Password keys" /></p>

<p>The <code class="language-plaintext highlighter-rouge">credHelper.dll</code> exposes two interfaces, one it’s the most generic one <code class="language-plaintext highlighter-rouge">IUnkown</code> while the other one is not provided. By looking at the objects in the executable containing the function pointers of the interfaces, can be inferred that there are other 2 functions.</p>

<p>Reverse engineering those functions it can be retrieved that the second interface is something like:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="n">object</span><span class="p">,</span> <span class="n">uuid</span><span class="p">(</span><span class="n">e27297b0</span><span class="o">-</span><span class="mf">1e98</span><span class="o">-</span><span class="mi">4033</span><span class="o">-</span><span class="n">b389</span><span class="o">-</span><span class="mi">24</span><span class="n">eca246002a</span><span class="p">),</span>
<span class="n">oleautomation</span><span class="p">,</span> <span class="n">helpstring</span><span class="p">(</span><span class="s">"CustomInterface"</span><span class="p">)]</span>
<span class="n">interface</span> <span class="n">ICustomInterface</span> <span class="o">:</span> <span class="n">IUnknown</span>
<span class="p">{</span>
    <span class="n">HRESULT</span> <span class="n">GetAndProcessPassword</span><span class="p">([</span><span class="n">in</span><span class="p">,</span> <span class="n">out</span><span class="p">]</span> <span class="n">byte</span><span class="o">*</span> <span class="n">param</span><span class="p">);</span>
    <span class="n">HRESULT</span> <span class="n">ProcessAndSetFlag</span><span class="p">([</span><span class="n">in</span><span class="p">,</span> <span class="n">out</span><span class="p">]</span> <span class="n">byte</span><span class="o">*</span> <span class="n">param</span><span class="p">);</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Procmon also reveals that the program creates another file, <code class="language-plaintext highlighter-rouge">C:\Windows\System32\cfs.dll</code>. Looking at the interactions with this file suggests that it is a driver. IDA itself detected also it was a driver and the imports of the dll confirmed the assumption.</p>

<p>Debugging a driver needs to enter in kernel debugging by putting the VM in Test Mode and then attaching a remote WinDbg debugger to it. After that the following steps let me break to the first instruction of the driver:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">sxe ld cfs.dll</code> : break the execution when cfs.dll will be loaded in memory</li>
  <li><code class="language-plaintext highlighter-rouge">lm</code> : once stopped this command will show you the address where the driver is loaded</li>
  <li><code class="language-plaintext highlighter-rouge">bp &lt;base_driver_address&gt; + &lt;offset_to_the_entrypoint&gt;</code> : this will put a breakpoint to the first instruction of the entrypoint</li>
  <li><code class="language-plaintext highlighter-rouge">g</code> : continue the execution until it encounters the breakpoint set before</li>
</ul>

<p><img src="/assets/writeups/FlareOn7/crackinstaller/windbg.png" alt="WinDbg Driver Debugging" /></p>

<p>Following the execution of the driver will jump back to <code class="language-plaintext highlighter-rouge">crackinstaller.exe</code> at offset 0x2a10. By debugging carefully this part of the execution the string <code class="language-plaintext highlighter-rouge">H@n $h0t FiRst!</code> show up in memory after some decryptions.</p>

<p>Trying to set the Password key in the COM register and write a COM client to interact with <code class="language-plaintext highlighter-rouge">credHelper.dll</code>, after doing a <code class="language-plaintext highlighter-rouge">GetAndProcessPassword</code> and passing the bytes obtained to the <code class="language-plaintext highlighter-rouge">ProcessAndSetFlag</code> in memory we can found the flag.</p>

<p><strong><code class="language-plaintext highlighter-rouge">S0_m@ny_cl@sse$_in_th3_Reg1stry@flare-on.com</code></strong></p>]]></content><author><name>Firpo7</name></author><category term="rev" /><category term="ctf" /><category term="challenge" /><category term="write-up" /><category term="binary" /><category term="reverse engineer" /><category term="Malware Analysis" /><summary type="html"><![CDATA[What kind of crackme doesn’t even ask for the password? We need to work on our COMmunication skills. Bug Notice: Avoid a possible blue-screen by debugging this on a single core VM]]></summary></entry><entry><title type="html">10_ _break</title><link href="/rev/2020/10/28/10_-_break.html" rel="alternate" type="text/html" title="10_ _break" /><published>2020-10-28T00:00:00+00:00</published><updated>2020-10-28T00:00:00+00:00</updated><id>/rev/2020/10/28/10_-_break</id><content type="html" xml:base="/rev/2020/10/28/10_-_break.html"><![CDATA[<blockquote>
  <p>As a reward for making it this far in Flare-On, we’ve decided to give you a break. Welcome to the land of sunshine and rainbows!</p>
</blockquote>

<p>The challenge provides with an executable, it was obfuscated using a technique known as nanomites. Nanomites is an anti-debugging and anti-dumping technique that consists of having two or more processes to perform a task together by interacting with each other using ptraces. In this case, there were three processes where the second ptrace-attach to the first, and the third that will ptrace-attach to the second. The goal of the challenge was to insert the correct flag as input.</p>

<p>Starting the analysis from the main program seems simple.</p>

<p>The flag seems to be <code class="language-plaintext highlighter-rouge">sunsh1n3_4nd_r41nb0ws@flare-on.com</code>. Let’s test it:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ./break
welcome to the land of sunshine and rainbows!
as a reward for getting this far in FLARE-ON, we've decided to make this one soooper easy

please enter a password friend :) sunsh1n3_4nd_r41nb0ws@flare-on.com
sorry, but 'sorry i stole your input :)' is not correct

</code></pre></div></div>

<p>Obviously no…. It also says to have stolen our input… Where <code class="language-plaintext highlighter-rouge">sorry i stole your input :)</code> comes from?</p>

<p>Trying to run <code class="language-plaintext highlighter-rouge">ltrace</code> against the program we can see a <code class="language-plaintext highlighter-rouge">fork()</code>, looking at the references it was first called in the <code class="language-plaintext highlighter-rouge">init1</code> function.</p>

<p>In the <code class="language-plaintext highlighter-rouge">init1</code> function, after the <code class="language-plaintext highlighter-rouge">fork()</code>, if the process continues in the parent then it modifies the process permissions to let children attaching using a ptrace to him and then do a nanosleep and continuing then to the main.</p>

<p>If the process continues to the child instead it starts a whole new function. In this function, the child process will attach to the parent using ptrace. Once attached, using PTRACE_POKEDATA, it modifies the firsts 2 bytes at the address <code class="language-plaintext highlighter-rouge">0x08048cdb</code> with 0x0f0b. That address is the function charged to check the password and it is modifying the firsts 2 bytes by putting the defined <code class="language-plaintext highlighter-rouge">undefined instruction</code> (<code class="language-plaintext highlighter-rouge">ud2</code>). What will happen when the father enters to that function will be to raise an Illegal Instruction Signal, that will be handled by the child process as it is ptracing him.</p>

<p>But let’s take a step back. After doing this modification the child will spawn another process, that will be discussed later, and then do a <strong><code class="language-plaintext highlighter-rouge">PTRACE_SYSEMU</code></strong>.</p>

<p>This particular ptrace request was designed to stop the execution of the ptraced process when it encounter a syscall, to emulate it. Every time the ptraced process will stop, the waitpid in the debugger will receive 2 bytes in the wstatus parameter, to have a full understanding of what these 2 bytes mean I suggest you take a look at the waitstatus.h source code.</p>

<p>What it is mainly useful for this challenge is that when the parent stops the lower byte of <code class="language-plaintext highlighter-rouge">wstatus</code> will be set to 0x7f, while the higher one to the signal that makes it stops. When the parent encounters a syscall it will generate a <code class="language-plaintext highlighter-rouge">SIGTRAP</code> signal, that will move the control to the child process, that will handle the syscall in a customized way. The syscall called by the parent process is defined by the <code class="language-plaintext highlighter-rouge">eax</code> register that the ptracer will take, along with the other registers, using the <code class="language-plaintext highlighter-rouge">PTRACE_GETREGS</code> request.</p>

<p>What is said in the block above will be much clear in this image.
<img src="/assets/writeups/FlareOn7/break/dochild_syscalls.png" alt="Child SIG Handling" /></p>

<p>The <code class="language-plaintext highlighter-rouge">eax</code> of the father will be processed as to obfuscate which will be the code that will handle the syscalls. For example, as it can be seen in the image, the <code class="language-plaintext highlighter-rouge">pivot_root</code> syscall code (217) will become <code class="language-plaintext highlighter-rouge">0xe8135594</code> and it will do, in the memory space of the father, something like:</p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">*</span><span class="n">ebx</span> <span class="o">=</span> <span class="n">ecx</span>
</code></pre></div></div>

<p>Returning to the father execution, when it is inside the main function it will print some strings. As explained before, EACH syscall will be handled by the second process so when the father prints something the write syscall will be handled by the child.</p>

<p><img src="/assets/writeups/FlareOn7/break/write.png" alt="Write Syscall handler" /></p>

<p>Fortunately, the “write handler” will do a write without any customization.</p>

<p>But after the prints, the parent will do a read and if you remember the first test of the program it says it has stolen our input.</p>

<p><img src="/assets/writeups/FlareOn7/break/read.png" alt="Read Syscall handler" /></p>

<p>As we can see the read will be emulated by a fgets inside the second process. It will save our string in a global variable and then it will decode the string <code class="language-plaintext highlighter-rouge">sorry i stole your input :)</code> to be inserted in the read buffer of the father.</p>

<p>After the read, the parent will go into the check flag function that the second process has modified before, so what will happen is that the first process will generate an Illegal Instruction Signal that will be handled by the child as follows:</p>

<p><img src="/assets/writeups/FlareOn7/break/0f0b_handler.png" alt="SIGILL Handler" /></p>

<p>In this piece of code, the second process is going to copy in the memory space of the father the input taken by the fgets, at the same address. Then it substitutes the <code class="language-plaintext highlighter-rouge">eip</code> of the father with the address of another function and set as first parameter the address of the buffer where it has just copied our input.</p>

<p>This means that the execution of the parent will go to check our flag in another function, precisely this one:</p>

<p><img src="/assets/writeups/FlareOn7/break/real_check_flag.png" alt="Real Check Flag" /></p>

<p>Before analyzing this function I need to introduce the <code class="language-plaintext highlighter-rouge">nice</code> function. Looking at the syscalls of Linux 32-bit there is a <code class="language-plaintext highlighter-rouge">nice</code> syscall, but if you test this library function in a program, using <code class="language-plaintext highlighter-rouge">strace</code> you will discover that it calls only setpriority and getpriority syscalls. What the handlers of these two calls do together in the child process is returning the negated address of a bunch of bytes decoded. In fact, as we can see in the image above, it is passing the negated address of the return value of the nice at the next function.</p>

<p>Considering that all these parts are static and don’t depend on our input we can try to intercept the <code class="language-plaintext highlighter-rouge">memcmp</code> to see what it expect as the first part of our input. The problem now is that the first process cannot be debugged, as it has already a process attached to it.</p>

<p>To bypass this problem I hooked the function using <code class="language-plaintext highlighter-rouge">LD_PRELOAD</code>.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">memcmp</span><span class="p">(</span><span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">s1</span><span class="p">,</span> <span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">s2</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">n</span><span class="p">)</span> <span class="p">{</span>
     <span class="k">static</span> <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">memcmp_real</span><span class="p">)(</span><span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">s1</span><span class="p">,</span> <span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">s2</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">n</span><span class="p">)</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
     <span class="kt">int</span> <span class="n">ret</span><span class="p">;</span>

     <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">memcmp_real</span><span class="p">)</span>
         <span class="n">memcmp_real</span> <span class="o">=</span> <span class="n">dlsym</span><span class="p">(</span><span class="n">RTLD_NEXT</span><span class="p">,</span> <span class="s">"memcmp"</span><span class="p">);</span>

     <span class="n">ret</span> <span class="o">=</span> <span class="n">memcmp_real</span><span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">,</span> <span class="n">n</span><span class="p">);</span>

     <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"memcmp(</span><span class="se">\"</span><span class="s">%s</span><span class="se">\"</span><span class="s">, </span><span class="se">\"</span><span class="s">%s</span><span class="se">\"</span><span class="s">, %d) = 0x%x</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">ret</span><span class="p">);</span>

     <span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Fun fact, as explained above EACH syscall of the parent process is intercepted and so the fprintf in our <code class="language-plaintext highlighter-rouge">memcmp</code> too. Fortunately, it does not change anything but using <code class="language-plaintext highlighter-rouge">LD_PRELOAD</code> in this context should be done carefully.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ LD_PRELOAD=./ch10_preload.so ./break
welcome to the land of sunshine and rainbows!
as a reward for getting this far in FLARE-ON, we've decided to make this one soooper easy

please enter a password friend :) sunsh1n3_4nd_r41nb0ws@flare-on.com
memcmp("sunsh1n3_4nd_r41nb0ws@flare-on.com", "w3lc0mE_t0_Th3_l", 16) = 0xffffffff
sorry, but 'sorry i stole your input :)' is not correct
</code></pre></div></div>

<p>Perfect! The first part of the flag is <code class="language-plaintext highlighter-rouge">w3lc0mE_t0_Th3_l</code>!</p>

<p>The second part of the flag will be checked inside the function at 0x08048f05, in the image above named “TF_checkSecondPart”.</p>

<p><img src="/assets/writeups/FlareOn7/break/checkSecondPart.png" alt="Check Second Part" /></p>

<p>The first thing done by this function is generating 2 constants, starting from the return value of the <code class="language-plaintext highlighter-rouge">nice(0xa4)</code>, using the function <code class="language-plaintext highlighter-rouge">FUN_0804bfed</code>.
Then, in the while, it processes 8 bytes at a time where it has stored the second part of our input. The strange thing here is the while loop of 40000 for 32 bytes of the second part of the flag.</p>

<p>Below the function charged to process the bytes.</p>

<p><img src="/assets/writeups/FlareOn7/break/fun369.png" alt="Decryption Function" /></p>

<p><img src="/assets/writeups/FlareOn7/break/fun217.png" alt="Initialize Buffer" /></p>

<p>In this part of the executable, many library calls will lead to syscalls, so the interactions between the first and the second process will be a lot.</p>

<p>Another technique to pass the execution to the second process used in this part of the execution it’s by calling a pointer <code class="language-plaintext highlighter-rouge">NULL</code>ed. The variable named <code class="language-plaintext highlighter-rouge">GENERATE_TRAP</code> was charged to generate a <code class="language-plaintext highlighter-rouge">SIGSEGV</code> and in the child process it will be handled as follows:</p>

<p><img src="/assets/writeups/FlareOn7/break/sigsegv_handler.png" alt="SIGSEGV" /></p>

<p>It is an implementation of a loop, where it jumps at the address passed as the first argument and will increment the counter until 0x10, which address was passed as the second parameter. The addresses where the two loops iterate are shown in the images above.</p>

<p>At the end of <code class="language-plaintext highlighter-rouge">TF_checkSecondPart</code> there is a call to truncate.</p>

<p><img src="/assets/writeups/FlareOn7/break/truncate.png" alt="Truncate Handler" /></p>

<p>What it is doing is storing all the 40000 decrypted bytes in a buffer (<code class="language-plaintext highlighter-rouge">local_3f50</code>) and checking how many bytes of the flag we guessed by comparing the result against the bytes at <code class="language-plaintext highlighter-rouge">0x081a5100</code>.</p>

<p>Aware of the <code class="language-plaintext highlighter-rouge">while</code> masked as <code class="language-plaintext highlighter-rouge">SIGSEGV</code>, it’s more clear that this was a decryption function, probably of a known algorithm. Since I didn’t recognize which algorithm it was I decided to patch the executable in order to let angr to the job to find back the bytes of the second part.</p>

<p>What I have done is firstly <code class="language-plaintext highlighter-rouge">nop</code> the fork and the other calls in the <code class="language-plaintext highlighter-rouge">init</code>, then changing the call to fake check flag to <code class="language-plaintext highlighter-rouge">TF_checkSecondPart</code> and then substituting all the library calls, until the truncate, with the code that the child is going to perform. During this part, the second process will pass the execution to the third one.</p>

<p>To explain better how the patch was performed let’s take as an example the call to <code class="language-plaintext highlighter-rouge">pivot_root</code> seen before in assembly.</p>

<pre><code class="language-asm">sub esp, 8      ; align the stack
push ecx        ; this will be the ecx of the syscall
push eax        ; ebx of the syscall
call pivot_root
add esp, 0x10
</code></pre>

<p>I have substituted all these instructions with:</p>
<pre><code class="language-asm">mov dword [eax], ecx
</code></pre>

<p><code class="language-plaintext highlighter-rouge">nop</code>ping all the other bytes.</p>

<p>For bigger parts of the code, such as the <code class="language-plaintext highlighter-rouge">mlockall</code>, I had to put a call to that part of the code and reconstructing a stack there.</p>

<p>After all these patches I had only one process doing the checks for the second part. Since the decryption was performed on 8 bytes at a time I instrumented <code class="language-plaintext highlighter-rouge">angr</code> and patched the executable to input 8 bytes per execution. To provide to angr a successful address and a failure one I had to put also an “if”.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">angr</span>
<span class="kn">import</span> <span class="nn">claripy</span>

<span class="n">SUCESS_ADDR</span> <span class="o">=</span> <span class="mh">0x08049cf4</span>
<span class="n">FAILITURE_ADDR</span> <span class="o">=</span> <span class="mh">0x08049d11</span>
<span class="n">FLAG_LEN</span> <span class="o">=</span> <span class="mi">8</span>

<span class="n">project</span> <span class="o">=</span> <span class="n">angr</span><span class="p">.</span><span class="n">Project</span><span class="p">(</span><span class="s">"./break_ANGR"</span><span class="p">)</span>
<span class="n">flag_chars</span> <span class="o">=</span> <span class="p">[</span><span class="n">claripy</span><span class="p">.</span><span class="n">BVS</span><span class="p">(</span><span class="s">'flag_%d'</span> <span class="o">%</span> <span class="n">i</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">FLAG_LEN</span><span class="p">)]</span>
<span class="n">flag</span> <span class="o">=</span> <span class="n">claripy</span><span class="p">.</span><span class="n">Concat</span><span class="p">(</span> <span class="o">*</span><span class="n">flag_chars</span> <span class="o">+</span> <span class="p">[</span><span class="n">claripy</span><span class="p">.</span><span class="n">BVV</span><span class="p">(</span><span class="sa">b</span><span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="p">)])</span>

<span class="n">state</span> <span class="o">=</span> <span class="n">project</span><span class="p">.</span><span class="n">factory</span><span class="p">.</span><span class="n">full_init_state</span><span class="p">(</span>
    <span class="n">args</span><span class="o">=</span><span class="p">[</span><span class="s">'./break_ANGR'</span><span class="p">],</span>
    <span class="n">add_options</span><span class="o">=</span><span class="n">angr</span><span class="p">.</span><span class="n">options</span><span class="p">.</span><span class="n">unicorn</span><span class="p">,</span>
    <span class="n">stdin</span><span class="o">=</span><span class="n">flag</span>
    <span class="p">)</span>

<span class="k">for</span> <span class="n">i</span><span class="p">,</span><span class="n">k</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">flag_chars</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">8</span><span class="p">:</span>
        <span class="n">state</span><span class="p">.</span><span class="n">solver</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">k</span> <span class="o">&gt;=</span> <span class="mh">0x20</span><span class="p">)</span>
        <span class="n">state</span><span class="p">.</span><span class="n">solver</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">k</span> <span class="o">&lt;=</span> <span class="mh">0x7f</span><span class="p">)</span>

<span class="n">simulation_manager</span> <span class="o">=</span> <span class="n">project</span><span class="p">.</span><span class="n">factory</span><span class="p">.</span><span class="n">simulation_manager</span><span class="p">(</span><span class="n">state</span><span class="p">)</span>
<span class="n">simulation_manager</span><span class="p">.</span><span class="n">explore</span><span class="p">(</span><span class="n">find</span><span class="o">=</span><span class="n">SUCESS_ADDR</span><span class="p">,</span><span class="n">avoid</span><span class="o">=</span><span class="n">FAILITURE_ADDR</span><span class="p">)</span>

<span class="k">if</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">simulation_manager</span><span class="p">.</span><span class="n">found</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">found</span> <span class="ow">in</span> <span class="n">simulation_manager</span><span class="p">.</span><span class="n">found</span><span class="p">:</span>
            <span class="k">print</span><span class="p">(</span><span class="n">found</span><span class="p">.</span><span class="n">posix</span><span class="p">.</span><span class="n">dumps</span><span class="p">(</span><span class="mi">0</span><span class="p">))</span>
</code></pre></div></div>

<p>Running more than one instance at a time, in about 1 hour, it was able to retrieve all the second part of the flag:</p>

<p><code class="language-plaintext highlighter-rouge">4nD_0f_De4th_4nd_d3strUct1oN_4nd</code></p>

<p>As explained above, during the truncate, it will store all the 40000 bytes in <code class="language-plaintext highlighter-rouge">local_3f50</code>, the problem is that this buffer has a size of 16000 bytes! So it was going to overflow overwriting the other variables. Since, normally, the second process will not reach a return, the overwriting of the return pointer should be excluded. Immediately after the while, there is a call to the <code class="language-plaintext highlighter-rouge">GENERATE_TRAP</code> variable, which is stored above the buffer and it will be overwritten with <code class="language-plaintext highlighter-rouge">0x08053b70</code>.</p>

<p><img src="/assets/writeups/FlareOn7/break/overwritten_addr.png" alt="Overwritten Address" /></p>

<p>This address’s inside the decrypted bytes at the offset of the <code class="language-plaintext highlighter-rouge">GENERATE_TRAP</code> variable. Dumping that address reveals the last part of code, where it checks for the last part.</p>

<p>During this part, there are no ptraces except for one at the start and one at the end, that could be both nopped for the moment. Once inserted those decrypted bytes in the executable and nopped the ptraces, the call to the fake check could be modified again to jump at this new function. This lets us debug this part of the challenge.</p>

<p>What it is doing in this part is handling big numbers. At the start of the function, it will get 4 bignumbers from the memory and uses them to perform an equation against the last part of our input, to finally check the result.</p>

<p><img src="/assets/writeups/FlareOn7/break/last_equation.png" alt="BigIntegers Equation" /></p>

<p>What it will do is:
<code class="language-plaintext highlighter-rouge">RESULT_TO_CHECK == bignum_1</code></p>

<p>And, as shown in the image above:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>RESULT_TO_CHECK = ( last_part_input * bignum_2 ) % bignum_4
</code></pre></div></div>

<p>The last part of the flag could be retrieved by multiplying the expected result (<code class="language-plaintext highlighter-rouge">bignum_1</code>) by the modular inverse of <code class="language-plaintext highlighter-rouge">bignum_2</code> modulo <code class="language-plaintext highlighter-rouge">bignum_4</code>.</p>

<p><code class="language-plaintext highlighter-rouge">_n0_puppi3s@flare-on.com</code></p>

<p>The flag is:</p>

<p><strong><code class="language-plaintext highlighter-rouge">w3lc0mE_t0_Th3_l4nD_0f_De4th_4nd_d3strUct1oN_4nd_n0_puppi3s@flare-on.com</code></strong></p>]]></content><author><name>Firpo7</name></author><category term="rev" /><category term="ctf" /><category term="challenge" /><category term="write-up" /><category term="binary" /><category term="reverse engineer" /><category term="Malware Analysis" /><summary type="html"><![CDATA[As a reward for making it this far in Flare-On, we’ve decided to give you a break. Welcome to the land of sunshine and rainbows!]]></summary></entry></feed>