<?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="https://jiva.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://jiva.io/" rel="alternate" type="text/html" /><updated>2026-03-19T12:58:57+00:00</updated><id>https://jiva.io/feed.xml</id><title type="html">jiva</title><subtitle>jiva&apos;s homepage</subtitle><entry><title type="html">Microcorruption CTF Jakarta Write-up</title><link href="https://jiva.io/blog/microcorruption-ctf-writeup-jakarta" rel="alternate" type="text/html" title="Microcorruption CTF Jakarta Write-up" /><published>2018-06-24T15:20:00+00:00</published><updated>2018-06-24T15:20:00+00:00</updated><id>https://jiva.io/blog/microcorruption-ctf-writeup-jakarta</id><content type="html" xml:base="https://jiva.io/blog/microcorruption-ctf-writeup-jakarta"><![CDATA[<h2 id="summary">Summary:</h2>

<p>This is a write-up of my solution to the <a href="https://microcorruption.com/">Microcorruption CTF</a> challenge “Jakarta” (<code class="language-plaintext highlighter-rouge">LOCKIT PRO r b.06</code>).</p>

<p>From the challenge overview, they indicate that input length checking has been
beefed up some more:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>OVERVIEW
    - A firmware update further rejects passwords which are too long.
    - This lock is attached the the LockIT Pro HSM-1.
</code></pre></div></div>

<p>Let’s dissect the code and see what they’re up to.</p>

<style type="text/css">
  .gist-file
  .gist-data {max-height: 500px;}
</style>

<noscript><pre>0010 &lt;__trap_interrupt&gt;
0010:  3041           ret
4400 &lt;__init_stack&gt;
4400:  3140 0044      mov	#0x4400, sp
4404 &lt;__low_level_init&gt;
4404:  1542 5c01      mov	&amp;0x015c, r5
4408:  75f3           and.b	#-0x1, r5
440a:  35d0 085a      bis	#0x5a08, r5
440e &lt;__do_copy_data&gt;
440e:  3f40 0200      mov	#0x2, r15
4412:  0f93           tst	r15
4414:  0724           jz	#0x4424 &lt;__do_clear_bss+0x0&gt;
4416:  8245 5c01      mov	r5, &amp;0x015c
441a:  2f83           decd	r15
441c:  9f4f 0a47 0024 mov	0x470a(r15), 0x2400(r15)
4422:  f923           jnz	#0x4416 &lt;__do_copy_data+0x8&gt;
4424 &lt;__do_clear_bss&gt;
4424:  3f40 0004      mov	#0x400, r15
4428:  0f93           tst	r15
442a:  0624           jz	#0x4438 &lt;main+0x0&gt;
442c:  8245 5c01      mov	r5, &amp;0x015c
4430:  1f83           dec	r15
4432:  cf43 0224      mov.b	#0x0, 0x2402(r15)
4436:  fa23           jnz	#0x442c &lt;__do_clear_bss+0x8&gt;
4438 &lt;main&gt;
4438:  3150 18fc      add	#0xfc18, sp
443c:  b012 6045      call	#0x4560 &lt;login&gt;
4440:  0f43           clr	r15
4442 &lt;__stop_progExec__&gt;
4442:  32d0 f000      bis	#0xf0, sr
4446:  fd3f           jmp	#0x4442 &lt;__stop_progExec__+0x0&gt;
4448 &lt;__ctors_end&gt;
4448:  3040 0847      br	#0x4708 &lt;_unexpected_&gt;
444c &lt;unlock_door&gt;
444c:  3012 7f00      push	#0x7f
4450:  b012 6446      call	#0x4664 &lt;INT&gt;
4454:  2153           incd	sp
4456:  3041           ret
4458 &lt;test_username_and_password_valid&gt;
4458:  0412           push	r4
445a:  0441           mov	sp, r4
445c:  2453           incd	r4
445e:  2183           decd	sp
4460:  c443 fcff      mov.b	#0x0, -0x4(r4)
4464:  3e40 fcff      mov	#0xfffc, r14
4468:  0e54           add	r4, r14
446a:  0e12           push	r14
446c:  0f12           push	r15
446e:  3012 7d00      push	#0x7d
4472:  b012 6446      call	#0x4664 &lt;INT&gt;
4476:  5f44 fcff      mov.b	-0x4(r4), r15
447a:  8f11           sxt	r15
447c:  3152           add	#0x8, sp
447e:  3441           pop	r4
4480:  3041           ret
4482 .strings:
4482: &quot;Authentication requires a username and password.&quot;
44b3: &quot;Your username and password together may be no more than 32 characters.&quot;
44fa: &quot;Please enter your username:&quot;
4516: &quot;Please enter your password:&quot;
4532: &quot;Access granted.&quot;
4542: &quot;That password is not correct.&quot;
4560 &lt;login&gt;
4560:  0b12           push	r11
4562:  3150 deff      add	#0xffde, sp
4566:  3f40 8244      mov	#0x4482 &quot;Authentication requires a username and password.&quot;, r15
456a:  b012 c846      call	#0x46c8 &lt;puts&gt;
456e:  3f40 b344      mov	#0x44b3 &quot;Your username and password together may be no more than 32 characters.&quot;, r15
4572:  b012 c846      call	#0x46c8 &lt;puts&gt;
4576:  3f40 fa44      mov	#0x44fa &quot;Please enter your username:&quot;, r15
457a:  b012 c846      call	#0x46c8 &lt;puts&gt;
457e:  3e40 ff00      mov	#0xff, r14
4582:  3f40 0224      mov	#0x2402, r15
4586:  b012 b846      call	#0x46b8 &lt;getsn&gt;
458a:  3f40 0224      mov	#0x2402, r15
458e:  b012 c846      call	#0x46c8 &lt;puts&gt;
4592:  3f40 0124      mov	#0x2401, r15
4596:  1f53           inc	r15
4598:  cf93 0000      tst.b	0x0(r15)
459c:  fc23           jnz	#0x4596 &lt;login+0x36&gt;
459e:  0b4f           mov	r15, r11
45a0:  3b80 0224      sub	#0x2402, r11
45a4:  3e40 0224      mov	#0x2402, r14
45a8:  0f41           mov	sp, r15
45aa:  b012 f446      call	#0x46f4 &lt;strcpy&gt;
45ae:  7b90 2100      cmp.b	#0x21, r11
45b2:  0628           jnc	#0x45c0 &lt;login+0x60&gt;
45b4:  1f42 0024      mov	&amp;0x2400, r15
45b8:  b012 c846      call	#0x46c8 &lt;puts&gt;
45bc:  3040 4244      br	#0x4442 &lt;__stop_progExec__&gt;
45c0:  3f40 1645      mov	#0x4516 &quot;Please enter your password:&quot;, r15
45c4:  b012 c846      call	#0x46c8 &lt;puts&gt;
45c8:  3e40 1f00      mov	#0x1f, r14
45cc:  0e8b           sub	r11, r14
45ce:  3ef0 ff01      and	#0x1ff, r14
45d2:  3f40 0224      mov	#0x2402, r15
45d6:  b012 b846      call	#0x46b8 &lt;getsn&gt;
45da:  3f40 0224      mov	#0x2402, r15
45de:  b012 c846      call	#0x46c8 &lt;puts&gt;
45e2:  3e40 0224      mov	#0x2402, r14
45e6:  0f41           mov	sp, r15
45e8:  0f5b           add	r11, r15
45ea:  b012 f446      call	#0x46f4 &lt;strcpy&gt;
45ee:  3f40 0124      mov	#0x2401, r15
45f2:  1f53           inc	r15
45f4:  cf93 0000      tst.b	0x0(r15)
45f8:  fc23           jnz	#0x45f2 &lt;login+0x92&gt;
45fa:  3f80 0224      sub	#0x2402, r15
45fe:  0f5b           add	r11, r15
4600:  7f90 2100      cmp.b	#0x21, r15
4604:  0628           jnc	#0x4612 &lt;login+0xb2&gt;
4606:  1f42 0024      mov	&amp;0x2400, r15
460a:  b012 c846      call	#0x46c8 &lt;puts&gt;
460e:  3040 4244      br	#0x4442 &lt;__stop_progExec__&gt;
4612:  0f41           mov	sp, r15
4614:  b012 5844      call	#0x4458 &lt;test_username_and_password_valid&gt;
4618:  0f93           tst	r15
461a:  0524           jz	#0x4626 &lt;login+0xc6&gt;
461c:  b012 4c44      call	#0x444c &lt;unlock_door&gt;
4620:  3f40 3245      mov	#0x4532 &quot;Access granted.&quot;, r15
4624:  023c           jmp	#0x462a &lt;login+0xca&gt;
4626:  3f40 4245      mov	#0x4542 &quot;That password is not correct.&quot;, r15
462a:  b012 c846      call	#0x46c8 &lt;puts&gt;
462e:  3150 2200      add	#0x22, sp
4632:  3b41           pop	r11
4634:  3041           ret
4636 &lt;__do_nothing&gt;
4636:  3041           ret
4638:  496e           addc.b	r14, r9
463a:  7661           addc.b	@sp+, r6
463c:  6c69           addc.b	@r9, r12
463e:  6420           jnz	#0x4708 &lt;_unexpected_+0x0&gt;
4640:  5061 7373      addc.b	0x7373(sp), pc
4644:  776f           addc.b	@r15+, r7
4646:  7264           addc.b	@r4+, sr
4648:  204c           br	@r12
464a:  656e           addc.b	@r14, r5
464c:  6774           subc.b	@r4, r7
464e:  683a           jl	#0x4320 &lt;__none__+0x4320&gt;
4650:  2070           subc	@pc, pc
4652:  6173           subc.b	#0x2, sp
4654:  7377           .word	0x7773
4656:  6f72           subc.b	#0x4, r15
4658:  6420           jnz	#0x4722 &lt;_unexpected_+0x1a&gt;
465a:  746f           addc.b	@r15+, r4
465c:  6f20           jnz	#0x473c &lt;_unexpected_+0x34&gt;
465e:  6c6f           addc.b	@r15, r12
4660:  6e67           addc.b	@r7, r14
4662:  2e00           .word	0x002e
4664 &lt;INT&gt;
4664:  1e41 0200      mov	0x2(sp), r14
4668:  0212           push	sr
466a:  0f4e           mov	r14, r15
466c:  8f10           swpb	r15
466e:  024f           mov	r15, sr
4670:  32d0 0080      bis	#0x8000, sr
4674:  b012 1000      call	#0x10
4678:  3241           pop	sr
467a:  3041           ret
467c &lt;putchar&gt;
467c:  2183           decd	sp
467e:  0f12           push	r15
4680:  0312           push	#0x0
4682:  814f 0400      mov	r15, 0x4(sp)
4686:  b012 6446      call	#0x4664 &lt;INT&gt;
468a:  1f41 0400      mov	0x4(sp), r15
468e:  3150 0600      add	#0x6, sp
4692:  3041           ret
4694 &lt;getchar&gt;
4694:  0412           push	r4
4696:  0441           mov	sp, r4
4698:  2453           incd	r4
469a:  2183           decd	sp
469c:  3f40 fcff      mov	#0xfffc, r15
46a0:  0f54           add	r4, r15
46a2:  0f12           push	r15
46a4:  1312           push	#0x1
46a6:  b012 6446      call	#0x4664 &lt;INT&gt;
46aa:  5f44 fcff      mov.b	-0x4(r4), r15
46ae:  8f11           sxt	r15
46b0:  3150 0600      add	#0x6, sp
46b4:  3441           pop	r4
46b6:  3041           ret
46b8 &lt;getsn&gt;
46b8:  0e12           push	r14
46ba:  0f12           push	r15
46bc:  2312           push	#0x2
46be:  b012 6446      call	#0x4664 &lt;INT&gt;
46c2:  3150 0600      add	#0x6, sp
46c6:  3041           ret
46c8 &lt;puts&gt;
46c8:  0b12           push	r11
46ca:  0b4f           mov	r15, r11
46cc:  073c           jmp	#0x46dc &lt;puts+0x14&gt;
46ce:  1b53           inc	r11
46d0:  8f11           sxt	r15
46d2:  0f12           push	r15
46d4:  0312           push	#0x0
46d6:  b012 6446      call	#0x4664 &lt;INT&gt;
46da:  2152           add	#0x4, sp
46dc:  6f4b           mov.b	@r11, r15
46de:  4f93           tst.b	r15
46e0:  f623           jnz	#0x46ce &lt;puts+0x6&gt;
46e2:  3012 0a00      push	#0xa
46e6:  0312           push	#0x0
46e8:  b012 6446      call	#0x4664 &lt;INT&gt;
46ec:  2152           add	#0x4, sp
46ee:  0f43           clr	r15
46f0:  3b41           pop	r11
46f2:  3041           ret
46f4 &lt;strcpy&gt;
46f4:  0d4f           mov	r15, r13
46f6:  023c           jmp	#0x46fc &lt;strcpy+0x8&gt;
46f8:  1e53           inc	r14
46fa:  1d53           inc	r13
46fc:  6c4e           mov.b	@r14, r12
46fe:  cd4c 0000      mov.b	r12, 0x0(r13)
4702:  4c93           tst.b	r12
4704:  f923           jnz	#0x46f8 &lt;strcpy+0x4&gt;
4706:  3041           ret
4708 &lt;_unexpected_&gt;
4708:  0013           reti	pc</pre></noscript>
<script src="https://gist.github.com/jiva/fcb00ce864e606553ae02badfb398ebf.js"> </script>

<p>In the <code class="language-plaintext highlighter-rouge">main()</code> function we see a similar call to <code class="language-plaintext highlighter-rouge">login()</code>. However in this 
program, we’re presented with a message indicating that we need to provide a username and password. Additionally, they indicate that a length restriction
is in place:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Authentication requires a username and password.
Your username and password together may be no more than 32 characters.
</code></pre></div></div>

<p>Further down, we see multiple call to <code class="language-plaintext highlighter-rouge">puts()</code>, two calls to <code class="language-plaintext highlighter-rouge">strcpy()</code> and then some code that surrounds a call to <code class="language-plaintext highlighter-rouge">unlock_door()</code>.</p>

<p>Let’s run the program and see how the stack looks like after the first <code class="language-plaintext highlighter-rouge">strcpy()</code>…</p>

<p class="video"><iframe width="640" height="360" src="https://player.vimeo.com/video/276522664?color=6abd45&amp;title=0&amp;byline=0&amp;portrait=0" frameborder="0" allowfullscreen=""></iframe></p>

<p>We’ll start off by entering <code class="language-plaintext highlighter-rouge">AAAAAAAAAA</code> as the username and setting breakpoints before and after the first <code class="language-plaintext highlighter-rouge">strcpy()</code>.
We see that the username is copied to the stack starting at address <code class="language-plaintext highlighter-rouge">3ff2</code>. Also note, there appears to be a return address not too far away from our input on the stack, located at address <code class="language-plaintext highlighter-rouge">4016</code> and containing <code class="language-plaintext highlighter-rouge">4440</code>. This is the return address from the call to <code class="language-plaintext highlighter-rouge">login()</code> from <code class="language-plaintext highlighter-rouge">main()</code>. Also pay attention to the instructions starting at address <code class="language-plaintext highlighter-rouge">45c8</code> - we’ll discuss this in a bit.</p>

<p>Before we move on to the second <code class="language-plaintext highlighter-rouge">strcpy()</code>, let’s see what happens when we try to overflow the return address with a long username…</p>

<p class="video"><iframe width="640" height="360" src="https://player.vimeo.com/video/276524638?color=6abd45&amp;title=0&amp;byline=0&amp;portrait=0" frameborder="0" allowfullscreen=""></iframe></p>

<p>The offset to the return address is 36-bytes. We input <code class="language-plaintext highlighter-rouge">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABB</code> and watch as the return address is replaced with <code class="language-plaintext highlighter-rouge">4242</code>. However, the program errors out because we failed the <code class="language-plaintext highlighter-rouge">cmp.b #0x21, r11</code> check. Bummer, I guess we have to keep trying :frowning:.</p>

<p>Notice from the first video what was happening at <code class="language-plaintext highlighter-rouge">45c8</code>, where we passed the first length check and stepped through the following code:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>45c8:  3e40 1f00      mov   #0x1f, r14
45cc:  0e8b           sub   r11, r14
45ce:  3ef0 ff01      and   #0x1ff, r14
45d2:  3f40 0224      mov   #0x2402, r15
45d6:  b012 b846      call  #0x46b8 &lt;getsn&gt;
</code></pre></div></div>

<p>The program loads the value <code class="language-plaintext highlighter-rouge">0x1f</code> into <code class="language-plaintext highlighter-rouge">r14</code> then subtracts <code class="language-plaintext highlighter-rouge">r11</code> (the length of the username) from it, which effectively gives us the allowed length of the password. Once <code class="language-plaintext highlighter-rouge">getsn()</code> is called, <code class="language-plaintext highlighter-rouge">r14</code> and <code class="language-plaintext highlighter-rouge">r15</code> is pushed on to the stack, and then we’re prompted to enter in a password. It’s not clear from the code, but <code class="language-plaintext highlighter-rouge">r14</code> appears to contain an upper limit of the number of bytes that can be read in from <code class="language-plaintext highlighter-rouge">getsn()</code> into the input buffer (which is located at <code class="language-plaintext highlighter-rouge">2402</code> and pointed to by <code class="language-plaintext highlighter-rouge">r15</code>).</p>

<p>This means that we’ll be unable to read in more than <code class="language-plaintext highlighter-rouge">0x1f</code>-<code class="language-plaintext highlighter-rouge">len(username)</code> number of bytes… Or does it? Let’s see what happens when we input 32-bytes:</p>

<p class="video"><iframe width="640" height="360" src="https://player.vimeo.com/video/276522797?color=6abd45&amp;title=0&amp;byline=0&amp;portrait=0" frameborder="0" allowfullscreen=""></iframe></p>

<p>Because of an integer-underflow vulnerability, we’re able to increase the password buffer read-limit from <code class="language-plaintext highlighter-rouge">0x1f</code>-<code class="language-plaintext highlighter-rouge">len(username)</code> to 511 bytes (<code class="language-plaintext highlighter-rouge">0x01ff</code>), all while staying within the length check (<code class="language-plaintext highlighter-rouge">cmp.b #0x21, r11</code>) - sweet!</p>

<p>Now that we’re able to get more than 32 bytes onto the stack, let’s try to overflow the return address (located at <code class="language-plaintext highlighter-rouge">4016</code>) with a 6-byte password…</p>

<p class="video"><iframe width="640" height="360" src="https://player.vimeo.com/video/276724246?color=6abd45&amp;title=0&amp;byline=0&amp;portrait=0" frameborder="0" allowfullscreen=""></iframe></p>

<p>Although we’re able to successfully overwrite the return address, the program calls <code class="language-plaintext highlighter-rouge">__stop_progExec__</code> before returning. :pouting_cat:</p>

<p>Stepping through the code, we can see that there’s an additional length check occurring at <code class="language-plaintext highlighter-rouge">45ee</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>45ee:  3f40 0124      mov   #0x2401, r15
45f2:  1f53           inc   r15
45f4:  cf93 0000      tst.b 0x0(r15)
45f8:  fc23           jnz   #0x45f2 &lt;login+0x92&gt;
45fa:  3f80 0224      sub   #0x2402, r15
45fe:  0f5b           add   r11, r15
4600:  7f90 2100      cmp.b #0x21, r15
</code></pre></div></div>

<p>After our password is copied onto the stack, the code iterates over the password that’s in the input buffer (which is not on the stack), and calculates the combined length of the username and password which will be stored in <code class="language-plaintext highlighter-rouge">r15</code>.
Then, if the calculated length is greater than <code class="language-plaintext highlighter-rouge">0x21</code>, the program exits without returning.
However, pay close attention to the comparison instruction being used: <code class="language-plaintext highlighter-rouge">cmp</code><em><code class="language-plaintext highlighter-rouge">.b</code></em></p>

<p>According to the <a href="/assets/files/slau049f.pdf">MSP430 manual</a>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>All single-operand and dual-operand instructions can be byte or word
instructions by using .B or .W extensions. Byte instructions are used to access
byte data or byte peripherals. Word instructions are used to access word data
or word peripherals. If no extension is used, the instruction is a word
instruction.
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">.b</code> means that the comparison is performed on the lower byte of <code class="language-plaintext highlighter-rouge">r15</code>!
What if we were able to roll the length past <code class="language-plaintext highlighter-rouge">0xff</code>? Remember that we were able to
find a bug that increased the password read length to 511. I think we’re on to something :smirk_cat: …</p>

<p class="video"><iframe width="640" height="360" src="https://player.vimeo.com/video/276733634?color=6abd45&amp;title=0&amp;byline=0&amp;portrait=0" frameborder="0" allowfullscreen=""></iframe></p>

<p>We’re able to control PC! By using a 224-byte password (with the 5th and 6th byte overwriting the return address), we’ll roll the final value in <code class="language-plaintext highlighter-rouge">r15</code> when it gets added to <code class="language-plaintext highlighter-rouge">r11</code> (i.e. <code class="language-plaintext highlighter-rouge">0x20</code> + <code class="language-plaintext highlighter-rouge">224</code> == <code class="language-plaintext highlighter-rouge">256</code> == <code class="language-plaintext highlighter-rouge">0x100</code>), and when the <code class="language-plaintext highlighter-rouge">cmp.b</code> instruction is performed, we’ll effectively bypass the length comparison. Then instead of exiting out of the program, the code finishes until it returns. Let’s try jumping execution to <code class="language-plaintext highlighter-rouge">unlock_door()</code> instead of <code class="language-plaintext highlighter-rouge">4141</code>…</p>

<p class="img"><img src="/assets/images/writeups/microcorruption_jakarta_solve.png" alt="Jakarta Solve" /></p>

<p>Aw yeah :boom:</p>

<div class="spoiler">
<p>Username: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</p>
<p>Password: 
<br />BBBBLDBBBBBBBBBBBBBBBBBBBBBBBBBB
<br />BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
<br />BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
<br />BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
<br />BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
<br />BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
<br />BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB</p>
<p>Note that `LD` translates to `4c44` which in <br />little-endian is `444c` which is the location of `unlock_door`</p>
</div>]]></content><author><name>jiva</name></author><category term="blog" /><category term="microcorruption" /><category term="CTF" /><category term="writeup" /><category term="reverse engineering" /><category term="assembly" /><category term="hacking" /><summary type="html"><![CDATA[Microcorruption CTF Jakarta Write-up]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jiva.io/assets/images/writeups/microcorruption.png" /><media:content medium="image" url="https://jiva.io/assets/images/writeups/microcorruption.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Microcorruption CTF Montevideo Write-up</title><link href="https://jiva.io/blog/microcorruption-ctf-writeup-montevideo" rel="alternate" type="text/html" title="Microcorruption CTF Montevideo Write-up" /><published>2018-06-20T20:30:00+00:00</published><updated>2018-06-20T20:30:00+00:00</updated><id>https://jiva.io/blog/microcorruption-ctf-writeup-montevideo</id><content type="html" xml:base="https://jiva.io/blog/microcorruption-ctf-writeup-montevideo"><![CDATA[<h2 id="summary">Summary:</h2>

<p>This is a write-up of my solution to the <a href="https://microcorruption.com/">Microcorruption CTF</a> challenge “Montevideo” (<code class="language-plaintext highlighter-rouge">LOCKIT PRO r c.03</code>).</p>

<p>In the manual, they claim to have increased their security practices:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>OVERVIEW
    - Lockitall developers  have rewritten the code  to conform to the
      internal secure development process.
    - This lock is attached the the LockIT Pro HSM-2.
</code></pre></div></div>

<p>We’ll see about that :wink:. Let’s take a look at the code.</p>

<style type="text/css">
  .gist-file
  .gist-data {max-height: 500px;}
</style>

<noscript><pre>0010 &lt;__trap_interrupt&gt;
0010:  3041           ret
4400 &lt;__init_stack&gt;
4400:  3140 0044      mov	#0x4400, sp
4404 &lt;__low_level_init&gt;
4404:  1542 5c01      mov	&amp;0x015c, r5
4408:  75f3           and.b	#-0x1, r5
440a:  35d0 085a      bis	#0x5a08, r5
440e &lt;__do_copy_data&gt;
440e:  3f40 0000      clr	r15
4412:  0f93           tst	r15
4414:  0724           jz	#0x4424 &lt;__do_clear_bss+0x0&gt;
4416:  8245 5c01      mov	r5, &amp;0x015c
441a:  2f83           decd	r15
441c:  9f4f 5846 0024 mov	0x4658(r15), 0x2400(r15)
4422:  f923           jnz	#0x4416 &lt;__do_copy_data+0x8&gt;
4424 &lt;__do_clear_bss&gt;
4424:  3f40 6400      mov	#0x64, r15
4428:  0f93           tst	r15
442a:  0624           jz	#0x4438 &lt;main+0x0&gt;
442c:  8245 5c01      mov	r5, &amp;0x015c
4430:  1f83           dec	r15
4432:  cf43 0024      mov.b	#0x0, 0x2400(r15)
4436:  fa23           jnz	#0x442c &lt;__do_clear_bss+0x8&gt;
4438 &lt;main&gt;
4438:  b012 f444      call	#0x44f4 &lt;login&gt;
443c &lt;__stop_progExec__&gt;
443c:  32d0 f000      bis	#0xf0, sr
4440:  fd3f           jmp	#0x443c &lt;__stop_progExec__+0x0&gt;
4442 &lt;__ctors_end&gt;
4442:  3040 5646      br	#0x4656 &lt;_unexpected_&gt;
4446 &lt;conditional_unlock_door&gt;
4446:  0412           push	r4
4448:  0441           mov	sp, r4
444a:  2453           incd	r4
444c:  2183           decd	sp
444e:  c443 fcff      mov.b	#0x0, -0x4(r4)
4452:  3e40 fcff      mov	#0xfffc, r14
4456:  0e54           add	r4, r14
4458:  0e12           push	r14
445a:  0f12           push	r15
445c:  3012 7e00      push	#0x7e
4460:  b012 4c45      call	#0x454c &lt;INT&gt;
4464:  5f44 fcff      mov.b	-0x4(r4), r15
4468:  8f11           sxt	r15
446a:  3152           add	#0x8, sp
446c:  3441           pop	r4
446e:  3041           ret
4470 .strings:
4470: &quot;Enter the password to continue.&quot;
4490: &quot;Remember: passwords are between 8 and 16 characters.&quot;
44c5: &quot;Access granted.&quot;
44d5: &quot;That password is not correct.&quot;
44f3: &quot;&quot;
44f4 &lt;login&gt;
44f4:  3150 f0ff      add	#0xfff0, sp
44f8:  3f40 7044      mov	#0x4470 &quot;Enter the password to continue.&quot;, r15
44fc:  b012 b045      call	#0x45b0 &lt;puts&gt;
4500:  3f40 9044      mov	#0x4490 &quot;Remember: passwords are between 8 and 16 characters.&quot;, r15
4504:  b012 b045      call	#0x45b0 &lt;puts&gt;
4508:  3e40 3000      mov	#0x30, r14
450c:  3f40 0024      mov	#0x2400, r15
4510:  b012 a045      call	#0x45a0 &lt;getsn&gt;
4514:  3e40 0024      mov	#0x2400, r14
4518:  0f41           mov	sp, r15
451a:  b012 dc45      call	#0x45dc &lt;strcpy&gt;
451e:  3d40 6400      mov	#0x64, r13
4522:  0e43           clr	r14
4524:  3f40 0024      mov	#0x2400, r15
4528:  b012 f045      call	#0x45f0 &lt;memset&gt;
452c:  0f41           mov	sp, r15
452e:  b012 4644      call	#0x4446 &lt;conditional_unlock_door&gt;
4532:  0f93           tst	r15
4534:  0324           jz	#0x453c &lt;login+0x48&gt;
4536:  3f40 c544      mov	#0x44c5 &quot;Access granted.&quot;, r15
453a:  023c           jmp	#0x4540 &lt;login+0x4c&gt;
453c:  3f40 d544      mov	#0x44d5 &quot;That password is not correct.&quot;, r15
4540:  b012 b045      call	#0x45b0 &lt;puts&gt;
4544:  3150 1000      add	#0x10, sp
4548:  3041           ret
454a &lt;__do_nothing&gt;
454a:  3041           ret
454c &lt;INT&gt;
454c:  1e41 0200      mov	0x2(sp), r14
4550:  0212           push	sr
4552:  0f4e           mov	r14, r15
4554:  8f10           swpb	r15
4556:  024f           mov	r15, sr
4558:  32d0 0080      bis	#0x8000, sr
455c:  b012 1000      call	#0x10
4560:  3241           pop	sr
4562:  3041           ret
4564 &lt;putchar&gt;
4564:  2183           decd	sp
4566:  0f12           push	r15
4568:  0312           push	#0x0
456a:  814f 0400      mov	r15, 0x4(sp)
456e:  b012 4c45      call	#0x454c &lt;INT&gt;
4572:  1f41 0400      mov	0x4(sp), r15
4576:  3150 0600      add	#0x6, sp
457a:  3041           ret
457c &lt;getchar&gt;
457c:  0412           push	r4
457e:  0441           mov	sp, r4
4580:  2453           incd	r4
4582:  2183           decd	sp
4584:  3f40 fcff      mov	#0xfffc, r15
4588:  0f54           add	r4, r15
458a:  0f12           push	r15
458c:  1312           push	#0x1
458e:  b012 4c45      call	#0x454c &lt;INT&gt;
4592:  5f44 fcff      mov.b	-0x4(r4), r15
4596:  8f11           sxt	r15
4598:  3150 0600      add	#0x6, sp
459c:  3441           pop	r4
459e:  3041           ret
45a0 &lt;getsn&gt;
45a0:  0e12           push	r14
45a2:  0f12           push	r15
45a4:  2312           push	#0x2
45a6:  b012 4c45      call	#0x454c &lt;INT&gt;
45aa:  3150 0600      add	#0x6, sp
45ae:  3041           ret
45b0 &lt;puts&gt;
45b0:  0b12           push	r11
45b2:  0b4f           mov	r15, r11
45b4:  073c           jmp	#0x45c4 &lt;puts+0x14&gt;
45b6:  1b53           inc	r11
45b8:  8f11           sxt	r15
45ba:  0f12           push	r15
45bc:  0312           push	#0x0
45be:  b012 4c45      call	#0x454c &lt;INT&gt;
45c2:  2152           add	#0x4, sp
45c4:  6f4b           mov.b	@r11, r15
45c6:  4f93           tst.b	r15
45c8:  f623           jnz	#0x45b6 &lt;puts+0x6&gt;
45ca:  3012 0a00      push	#0xa
45ce:  0312           push	#0x0
45d0:  b012 4c45      call	#0x454c &lt;INT&gt;
45d4:  2152           add	#0x4, sp
45d6:  0f43           clr	r15
45d8:  3b41           pop	r11
45da:  3041           ret
45dc &lt;strcpy&gt;
45dc:  0d4f           mov	r15, r13
45de:  023c           jmp	#0x45e4 &lt;strcpy+0x8&gt;
45e0:  1e53           inc	r14
45e2:  1d53           inc	r13
45e4:  6c4e           mov.b	@r14, r12
45e6:  cd4c 0000      mov.b	r12, 0x0(r13)
45ea:  4c93           tst.b	r12
45ec:  f923           jnz	#0x45e0 &lt;strcpy+0x4&gt;
45ee:  3041           ret
45f0 &lt;memset&gt;
45f0:  0b12           push	r11
45f2:  0a12           push	r10
45f4:  0912           push	r9
45f6:  0812           push	r8
45f8:  0b4f           mov	r15, r11
45fa:  3d90 0600      cmp	#0x6, r13
45fe:  082c           jc	#0x4610 &lt;memset+0x20&gt;
4600:  043c           jmp	#0x460a &lt;memset+0x1a&gt;
4602:  cb4e 0000      mov.b	r14, 0x0(r11)
4606:  1b53           inc	r11
4608:  3d53           add	#-0x1, r13
460a:  0d93           tst	r13
460c:  fa23           jnz	#0x4602 &lt;memset+0x12&gt;
460e:  1e3c           jmp	#0x464c &lt;memset+0x5c&gt;
4610:  4a4e           mov.b	r14, r10
4612:  0a93           tst	r10
4614:  0324           jz	#0x461c &lt;memset+0x2c&gt;
4616:  0c4a           mov	r10, r12
4618:  8c10           swpb	r12
461a:  0adc           bis	r12, r10
461c:  1fb3           bit	#0x1, r15
461e:  0524           jz	#0x462a &lt;memset+0x3a&gt;
4620:  3d53           add	#-0x1, r13
4622:  cf4e 0000      mov.b	r14, 0x0(r15)
4626:  0b4f           mov	r15, r11
4628:  1b53           inc	r11
462a:  0c4d           mov	r13, r12
462c:  12c3           clrc
462e:  0c10           rrc	r12
4630:  084b           mov	r11, r8
4632:  094c           mov	r12, r9
4634:  884a 0000      mov	r10, 0x0(r8)
4638:  2853           incd	r8
463a:  3953           add	#-0x1, r9
463c:  fb23           jnz	#0x4634 &lt;memset+0x44&gt;
463e:  0c5c           add	r12, r12
4640:  0c5b           add	r11, r12
4642:  1df3           and	#0x1, r13
4644:  0d99           cmp	r9, r13
4646:  0224           jeq	#0x464c &lt;memset+0x5c&gt;
4648:  cc4e 0000      mov.b	r14, 0x0(r12)
464c:  3841           pop	r8
464e:  3941           pop	r9
4650:  3a41           pop	r10
4652:  3b41           pop	r11
4654:  3041           ret
4656 &lt;_unexpected_&gt;
4656:  0013           reti	pc</pre></noscript>
<script src="https://gist.github.com/jiva/01290b5c5f456f5089e026c02f9d0711.js"> </script>

<p>Looking at the <code class="language-plaintext highlighter-rouge">main()</code> function, we can see that a single function named <code class="language-plaintext highlighter-rouge">login()</code> is called.
Inside of <code class="language-plaintext highlighter-rouge">login()</code>, we see that after a password prompt, a call to <code class="language-plaintext highlighter-rouge">strcpy()</code> is made. The password prompt itself, “Remember: passwords are between 8 and 16 characters.”, implies that there’s some sort of length checking in place. Let’s play around in the debugger and see if this is actually the case.</p>

<p class="video"><iframe width="640" height="360" src="https://player.vimeo.com/video/276322106?color=6abd45&amp;title=0&amp;byline=0&amp;portrait=0" frameborder="0" allowfullscreen=""></iframe></p>

<p>After setting breakpoints before and after the call to <code class="language-plaintext highlighter-rouge">strcpy()</code>, we run the program and enter <code class="language-plaintext highlighter-rouge">AAAAAAAAAA</code> as the input. We keep an eye the address pointed to by the stackpointer (<code class="language-plaintext highlighter-rouge">sp</code> == <code class="language-plaintext highlighter-rouge">43ee</code>) and watch the function place our input onto the stack.</p>

<p>Pay close attention to the bytes soon after our input ends: <code class="language-plaintext highlighter-rouge">3c44</code>. If you stepped through the program from the beginning, you’ll notice that this value on the stack is actually the return address (<code class="language-plaintext highlighter-rouge">443c</code>) that was pushed as a result of the call to <code class="language-plaintext highlighter-rouge">login()</code> from <code class="language-plaintext highlighter-rouge">main()</code> originally! Let’s try overwriting these bytes (which are at offset 17 and 18), and see if we can control the program counter…</p>

<p class="video"><iframe width="640" height="360" src="https://player.vimeo.com/video/276337972?color=6abd45&amp;title=0&amp;byline=0&amp;portrait=0" frameborder="0" allowfullscreen=""></iframe></p>

<p>We try the input <code class="language-plaintext highlighter-rouge">BBBBBBBBBBBBBBBBAA</code> and watch the memory address containing the return address get overwritten. After continuing execution past the second breakpoint, we see the program crash and <code class="language-plaintext highlighter-rouge">pc</code> contain <code class="language-plaintext highlighter-rouge">4141</code>! :feelsgood:</p>

<p>Now that we’ve confirmed a stack buffer overflow vulnerability exists, we need to find a way exploit it.
In classical buffer overflow exploit examples, the payload (usually shellcode) is stuffed at the beginning of the buffer that we’re overflowing.
Then, the return address is overwritten so that it points back to the start of our buffer.
When the executing function returns, the address of the buffer is popped into the program counter and our payload gets executed.
If we were to try something similar here, that means we’d have to stuff our payload into 16 bytes (because the 17th and 18th byte map to the return address on the stack). That’s not that much room :thinking:. Oh and don’t forget, if the payload includes any null bytes, <code class="language-plaintext highlighter-rouge">strcpy()</code> won’t copy the entire input to the stack :worried:.</p>

<p>Since this program contains the familiar <code class="language-plaintext highlighter-rouge">conditional_unlock_door()</code> function which pushes (a useless) <code class="language-plaintext highlighter-rouge">0x7e</code> to the stack before calling the interrupt, I decided to write shellcode that will overwrite the <code class="language-plaintext highlighter-rouge">0x7e</code> with <code class="language-plaintext highlighter-rouge">0x7f</code> (the code to unlock the door).</p>

<p>After some careful trial and error with the assembler, I meticulously wrote the following code:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mov   #0x7f01, r12    # load 0x7f01 into r12
add   #-0x1, r12      # subtract 0x01 from r12 (resulting in 0x7f00)
swpb  r12             # swap the two bytes (resulting in 0x007f)
mov   r12, 0x445e(r6) # write 0x007f into 0x445e
call  #0x4446         # call to conditional_unlock_door()
</code></pre></div></div>

<p>My shellcode will essentially put the value of <code class="language-plaintext highlighter-rouge">0x7f</code> into register <code class="language-plaintext highlighter-rouge">r12</code> (by performing some byte manipulations in order to avoid null-bytes in my payload), and will then replace the <code class="language-plaintext highlighter-rouge">0x7e</code> in <code class="language-plaintext highlighter-rouge">conditional_unlock_door()</code> with <code class="language-plaintext highlighter-rouge">0x7f</code>. After the overwrite happens, a call to <code class="language-plaintext highlighter-rouge">conditional_unlock_door()</code> is made…</p>

<p class="img"><img src="/assets/images/writeups/microcorruption_montevideo_solve.png" alt="Montevideo Solve" /></p>

<p>Great Success! :boom:</p>

<div class="spoiler"><p>3c40017f3c538c10864c5e44b0124644ee43</p><p>Note that the shellcode is exactly 16 bytes :sweat_smile:</p></div>]]></content><author><name>jiva</name></author><category term="blog" /><category term="microcorruption" /><category term="CTF" /><category term="writeup" /><category term="reverse engineering" /><category term="assembly" /><category term="hacking" /><summary type="html"><![CDATA[Microcorruption CTF Montevideo Write-up]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jiva.io/assets/images/writeups/microcorruption.png" /><media:content medium="image" url="https://jiva.io/assets/images/writeups/microcorruption.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Microcorruption CTF Novosibirsk Write-up</title><link href="https://jiva.io/blog/microcorruption-ctf-writeup-novosibirsk" rel="alternate" type="text/html" title="Microcorruption CTF Novosibirsk Write-up" /><published>2018-02-10T18:04:00+00:00</published><updated>2018-02-10T18:04:00+00:00</updated><id>https://jiva.io/blog/microcorruption-ctf-writeup-novosibirsk</id><content type="html" xml:base="https://jiva.io/blog/microcorruption-ctf-writeup-novosibirsk"><![CDATA[<h2 id="summary">Summary:</h2>

<p>This is a write-up of my solution to the <a href="https://microcorruption.com/">Microcorruption CTF</a> challenge “Novosibirsk” (<code class="language-plaintext highlighter-rouge">LOCKIT PRO r c.02</code>).</p>

<p>In this challenge, we’re giving a hint right from the start:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>OVERVIEW
    - This lock is attached the the LockIT Pro HSM-2.
    - We have added features from b.03 to the new hardware.
</code></pre></div></div>

<p>If you recall from the <code class="language-plaintext highlighter-rouge">b.03</code> challenge (<a href="/blog/microcorruption-ctf-writeup-addis-ababa">Addis Ababa</a>), we had to exploit a <code class="language-plaintext highlighter-rouge">printf()</code> vulnerability using <code class="language-plaintext highlighter-rouge">%n</code> to write to an arbitrary memory location.</p>

<p>Let’s see if we need to do something similar in this challenge…</p>
<style type="text/css">
  .gist-file
  .gist-data {max-height: 500px;}
</style>

<noscript><pre>0010 &lt;__trap_interrupt&gt;
0010:  3041           ret
4400 &lt;__init_stack&gt;
4400:  3140 0044      mov   #0x4400, sp
4404 &lt;__low_level_init&gt;
4404:  1542 5c01      mov   &amp;0x015c, r5
4408:  75f3           and.b #-0x1, r5
440a:  35d0 085a      bis   #0x5a08, r5
440e &lt;__do_copy_data&gt;
440e:  3f40 0000      clr   r15
4412:  0f93           tst   r15
4414:  0724           jz    #0x4424 &lt;__do_clear_bss+0x0&gt;
4416:  8245 5c01      mov   r5, &amp;0x015c
441a:  2f83           decd  r15
441c:  9f4f f246 0024 mov   0x46f2(r15), 0x2400(r15)
4422:  f923           jnz   #0x4416 &lt;__do_copy_data+0x8&gt;
4424 &lt;__do_clear_bss&gt;
4424:  3f40 f401      mov   #0x1f4, r15
4428:  0f93           tst   r15
442a:  0624           jz    #0x4438 &lt;main+0x0&gt;
442c:  8245 5c01      mov   r5, &amp;0x015c
4430:  1f83           dec   r15
4432:  cf43 0024      mov.b #0x0, 0x2400(r15)
4436:  fa23           jnz   #0x442c &lt;__do_clear_bss+0x8&gt;
4438 &lt;main&gt;
4438:  0441           mov   sp, r4
443a:  2453           incd  r4
443c:  3150 0cfe      add   #0xfe0c, sp
4440:  3012 da44      push  #0x44da &quot;Enter your username below to authenticate.\n&quot;
4444:  b012 c645      call  #0x45c6 &lt;printf&gt;
4448:  b140 0645 0000 mov   #0x4506 &quot;&gt;&gt; &quot;, 0x0(sp)
444e:  b012 c645      call  #0x45c6 &lt;printf&gt;
4452:  2153           incd  sp
4454:  3e40 f401      mov   #0x1f4, r14
4458:  3f40 0024      mov   #0x2400, r15
445c:  b012 8a45      call  #0x458a &lt;getsn&gt;
4460:  3e40 0024      mov   #0x2400, r14
4464:  0f44           mov   r4, r15
4466:  3f50 0afe      add   #0xfe0a, r15
446a:  b012 dc46      call  #0x46dc &lt;strcpy&gt;
446e:  3f40 0afe      mov   #0xfe0a, r15
4472:  0f54           add   r4, r15
4474:  0f12           push  r15
4476:  b012 c645      call  #0x45c6 &lt;printf&gt;
447a:  2153           incd  sp
447c:  3f40 0a00      mov   #0xa, r15
4480:  b012 4e45      call  #0x454e &lt;putchar&gt;
4484:  0f44           mov   r4, r15
4486:  3f50 0afe      add   #0xfe0a, r15
448a:  b012 b044      call  #0x44b0 &lt;conditional_unlock_door&gt;
448e:  0f93           tst   r15
4490:  0324           jz    #0x4498 &lt;main+0x60&gt;
4492:  3012 0a45      push  #0x450a &quot;Access Granted!&quot;
4496:  023c           jmp   #0x449c &lt;main+0x64&gt;
4498:  3012 1a45      push  #0x451a &quot;That username is not valid.&quot;
449c:  b012 c645      call  #0x45c6 &lt;printf&gt;
44a0:  0f43           clr   r15
44a2:  3150 f601      add   #0x1f6, sp
44a6 &lt;__stop_progExec__&gt;
44a6:  32d0 f000      bis   #0xf0, sr
44aa:  fd3f           jmp   #0x44a6 &lt;__stop_progExec__+0x0&gt;
44ac &lt;__ctors_end&gt;
44ac:  3040 f046      br    #0x46f0 &lt;_unexpected_&gt;
44b0 &lt;conditional_unlock_door&gt;
44b0:  0412           push  r4
44b2:  0441           mov   sp, r4
44b4:  2453           incd  r4
44b6:  2183           decd  sp
44b8:  c443 fcff      mov.b #0x0, -0x4(r4)
44bc:  3e40 fcff      mov   #0xfffc, r14
44c0:  0e54           add   r4, r14
44c2:  0e12           push  r14
44c4:  0f12           push  r15
44c6:  3012 7e00      push  #0x7e
44ca:  b012 3645      call  #0x4536 &lt;INT&gt;
44ce:  5f44 fcff      mov.b -0x4(r4), r15
44d2:  8f11           sxt   r15
44d4:  3152           add   #0x8, sp
44d6:  3441           pop   r4
44d8:  3041           ret
44da .strings:
44da: &quot;Enter your username below to authenticate.\n&quot;
4506: &quot;&gt;&gt; &quot;
450a: &quot;Access Granted!&quot;
451a: &quot;That username is not valid.&quot;
4536 &lt;INT&gt;
4536:  1e41 0200      mov   0x2(sp), r14
453a:  0212           push  sr
453c:  0f4e           mov   r14, r15
453e:  8f10           swpb  r15
4540:  024f           mov   r15, sr
4542:  32d0 0080      bis   #0x8000, sr
4546:  b012 1000      call  #0x10
454a:  3241           pop   sr
454c:  3041           ret
454e &lt;putchar&gt;
454e:  2183           decd  sp
4550:  0f12           push  r15
4552:  0312           push  #0x0
4554:  814f 0400      mov   r15, 0x4(sp)
4558:  b012 3645      call  #0x4536 &lt;INT&gt;
455c:  1f41 0400      mov   0x4(sp), r15
4560:  3150 0600      add   #0x6, sp
4564:  3041           ret
4566 &lt;getchar&gt;
4566:  0412           push  r4
4568:  0441           mov   sp, r4
456a:  2453           incd  r4
456c:  2183           decd  sp
456e:  3f40 fcff      mov   #0xfffc, r15
4572:  0f54           add   r4, r15
4574:  0f12           push  r15
4576:  1312           push  #0x1
4578:  b012 3645      call  #0x4536 &lt;INT&gt;
457c:  5f44 fcff      mov.b -0x4(r4), r15
4580:  8f11           sxt   r15
4582:  3150 0600      add   #0x6, sp
4586:  3441           pop   r4
4588:  3041           ret
458a &lt;getsn&gt;
458a:  0e12           push  r14
458c:  0f12           push  r15
458e:  2312           push  #0x2
4590:  b012 3645      call  #0x4536 &lt;INT&gt;
4594:  3150 0600      add   #0x6, sp
4598:  3041           ret
459a &lt;puts&gt;
459a:  0b12           push  r11
459c:  0b4f           mov   r15, r11
459e:  073c           jmp   #0x45ae &lt;puts+0x14&gt;
45a0:  1b53           inc   r11
45a2:  8f11           sxt   r15
45a4:  0f12           push  r15
45a6:  0312           push  #0x0
45a8:  b012 3645      call  #0x4536 &lt;INT&gt;
45ac:  2152           add   #0x4, sp
45ae:  6f4b           mov.b @r11, r15
45b0:  4f93           tst.b r15
45b2:  f623           jnz   #0x45a0 &lt;puts+0x6&gt;
45b4:  3012 0a00      push  #0xa
45b8:  0312           push  #0x0
45ba:  b012 3645      call  #0x4536 &lt;INT&gt;
45be:  2152           add   #0x4, sp
45c0:  0f43           clr   r15
45c2:  3b41           pop   r11
45c4:  3041           ret
45c6 &lt;printf&gt;
45c6:  0b12           push  r11
45c8:  0a12           push  r10
45ca:  0912           push  r9
45cc:  0812           push  r8
45ce:  0712           push  r7
45d0:  0412           push  r4
45d2:  0441           mov   sp, r4
45d4:  3450 0c00      add   #0xc, r4
45d8:  2183           decd  sp
45da:  1b44 0200      mov   0x2(r4), r11
45de:  8441 f2ff      mov   sp, -0xe(r4)
45e2:  0f4b           mov   r11, r15
45e4:  0e43           clr   r14
45e6:  0b3c           jmp   #0x45fe &lt;printf+0x38&gt;
45e8:  1f53           inc   r15
45ea:  7d90 2500      cmp.b #0x25, r13
45ee:  0720           jne   #0x45fe &lt;printf+0x38&gt;
45f0:  6d9f           cmp.b @r15, r13
45f2:  0320           jne   #0x45fa &lt;printf+0x34&gt;
45f4:  1f53           inc   r15
45f6:  0d43           clr   r13
45f8:  013c           jmp   #0x45fc &lt;printf+0x36&gt;
45fa:  1d43           mov   #0x1, r13
45fc:  0e5d           add   r13, r14
45fe:  6d4f           mov.b @r15, r13
4600:  4d93           tst.b r13
4602:  f223           jnz   #0x45e8 &lt;printf+0x22&gt;
4604:  0f4e           mov   r14, r15
4606:  0f5f           add   r15, r15
4608:  2f53           incd  r15
460a:  018f           sub   r15, sp
460c:  0941           mov   sp, r9
460e:  0c44           mov   r4, r12
4610:  2c52           add   #0x4, r12
4612:  0f41           mov   sp, r15
4614:  0d43           clr   r13
4616:  053c           jmp   #0x4622 &lt;printf+0x5c&gt;
4618:  af4c 0000      mov   @r12, 0x0(r15)
461c:  1d53           inc   r13
461e:  2f53           incd  r15
4620:  2c53           incd  r12
4622:  0d9e           cmp   r14, r13
4624:  f93b           jl    #0x4618 &lt;printf+0x52&gt;
4626:  0a43           clr   r10
4628:  3740 0900      mov   #0x9, r7
462c:  4a3c           jmp   #0x46c2 &lt;printf+0xfc&gt;
462e:  084b           mov   r11, r8
4630:  1853           inc   r8
4632:  7f90 2500      cmp.b #0x25, r15
4636:  0624           jeq   #0x4644 &lt;printf+0x7e&gt;
4638:  1a53           inc   r10
463a:  0b48           mov   r8, r11
463c:  8f11           sxt   r15
463e:  b012 4e45      call  #0x454e &lt;putchar&gt;
4642:  3f3c           jmp   #0x46c2 &lt;printf+0xfc&gt;
4644:  6e48           mov.b @r8, r14
4646:  4e9f           cmp.b r15, r14
4648:  0620           jne   #0x4656 &lt;printf+0x90&gt;
464a:  1a53           inc   r10
464c:  3f40 2500      mov   #0x25, r15
4650:  b012 4e45      call  #0x454e &lt;putchar&gt;
4654:  333c           jmp   #0x46bc &lt;printf+0xf6&gt;
4656:  7e90 7300      cmp.b #0x73, r14
465a:  0b20           jne   #0x4672 &lt;printf+0xac&gt;
465c:  2b49           mov   @r9, r11
465e:  053c           jmp   #0x466a &lt;printf+0xa4&gt;
4660:  1a53           inc   r10
4662:  1b53           inc   r11
4664:  8f11           sxt   r15
4666:  b012 4e45      call  #0x454e &lt;putchar&gt;
466a:  6f4b           mov.b @r11, r15
466c:  4f93           tst.b r15
466e:  f823           jnz   #0x4660 &lt;printf+0x9a&gt;
4670:  253c           jmp   #0x46bc &lt;printf+0xf6&gt;
4672:  7e90 7800      cmp.b #0x78, r14
4676:  1c20           jne   #0x46b0 &lt;printf+0xea&gt;
4678:  2b49           mov   @r9, r11
467a:  173c           jmp   #0x46aa &lt;printf+0xe4&gt;
467c:  0f4b           mov   r11, r15
467e:  8f10           swpb  r15
4680:  3ff0 ff00      and   #0xff, r15
4684:  12c3           clrc
4686:  0f10           rrc   r15
4688:  0f11           rra   r15
468a:  0f11           rra   r15
468c:  0f11           rra   r15
468e:  1a53           inc   r10
4690:  079f           cmp   r15, r7
4692:  0338           jl    #0x469a &lt;printf+0xd4&gt;
4694:  3f50 3000      add   #0x30, r15
4698:  023c           jmp   #0x469e &lt;printf+0xd8&gt;
469a:  3f50 5700      add   #0x57, r15
469e:  b012 4e45      call  #0x454e &lt;putchar&gt;
46a2:  0b5b           add   r11, r11
46a4:  0b5b           add   r11, r11
46a6:  0b5b           add   r11, r11
46a8:  0b5b           add   r11, r11
46aa:  0b93           tst   r11
46ac:  e723           jnz   #0x467c &lt;printf+0xb6&gt;
46ae:  063c           jmp   #0x46bc &lt;printf+0xf6&gt;
46b0:  7e90 6e00      cmp.b #0x6e, r14
46b4:  0320           jne   #0x46bc &lt;printf+0xf6&gt;
46b6:  2f49           mov   @r9, r15
46b8:  8f4a 0000      mov   r10, 0x0(r15)
46bc:  2953           incd  r9
46be:  0b48           mov   r8, r11
46c0:  1b53           inc   r11
46c2:  6f4b           mov.b @r11, r15
46c4:  4f93           tst.b r15
46c6:  b323           jnz   #0x462e &lt;printf+0x68&gt;
46c8:  1144 f2ff      mov   -0xe(r4), sp
46cc:  2153           incd  sp
46ce:  3441           pop   r4
46d0:  3741           pop   r7
46d2:  3841           pop   r8
46d4:  3941           pop   r9
46d6:  3a41           pop   r10
46d8:  3b41           pop   r11
46da:  3041           ret
46dc &lt;strcpy&gt;
46dc:  0d4f           mov   r15, r13
46de:  023c           jmp   #0x46e4 &lt;strcpy+0x8&gt;
46e0:  1e53           inc   r14
46e2:  1d53           inc   r13
46e4:  6c4e           mov.b @r14, r12
46e6:  cd4c 0000      mov.b r12, 0x0(r13)
46ea:  4c93           tst.b r12
46ec:  f923           jnz   #0x46e0 &lt;strcpy+0x4&gt;
46ee:  3041           ret
46f0 &lt;_unexpected_&gt;
46f0:  0013           reti  pc</pre></noscript>
<script src="https://gist.github.com/jiva/876e3697c5e3c44c2641664fd2841284.js"> </script>

<p>Inside <code class="language-plaintext highlighter-rouge">main()</code>, we can see that <code class="language-plaintext highlighter-rouge">printf()</code> is called a few times as well as <code class="language-plaintext highlighter-rouge">strcpy()</code>. Let’s try entering <code class="language-plaintext highlighter-rouge">AB%x</code> and see what the program outputs.</p>

<p class="img"><img src="/assets/images/writeups/microcorruption_novosibirsk_testinput1.png" alt="Novosibirsk Test Input 1" /></p>

<p>We get back <code class="language-plaintext highlighter-rouge">AB4241</code> - which means our input was placed into <code class="language-plaintext highlighter-rouge">printf()</code>. Awesome! Recall from <a href="/blog/microcorruption-ctf-writeup-addis-ababa">Addis Ababa</a> that we were able to use <code class="language-plaintext highlighter-rouge">%n</code> to write at arbitrary locations in memory. We’ll leave out the details of how to exploit format-string vulnerabilities, but if you need a primer, I recommend reading <a href="/assets/files/formatstring-1.2.pdf">scut’s whitepaper “Exploiting Format String Vulnerabilities”</a>.</p>

<p>Let’s check out the program again and figure out where we can write stuff to in order to unlock the door. Here’s the code for <code class="language-plaintext highlighter-rouge">conditional_unlock_door()</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>44b0 &lt;conditional_unlock_door&gt;
44b0:  0412           push	r4
44b2:  0441           mov	sp, r4
44b4:  2453           incd	r4
44b6:  2183           decd	sp
44b8:  c443 fcff      mov.b	#0x0, -0x4(r4)
44bc:  3e40 fcff      mov	#0xfffc, r14
44c0:  0e54           add	r4, r14
44c2:  0e12           push	r14
44c4:  0f12           push	r15
44c6:  3012 7e00      push	#0x7e
44ca:  b012 3645      call	#0x4536 &lt;INT&gt;
44ce:  5f44 fcff      mov.b	-0x4(r4), r15
44d2:  8f11           sxt	r15
44d4:  3152           add	#0x8, sp
44d6:  3441           pop	r4
44d8:  3041           ret
</code></pre></div></div>

<p>From <a href="/blog/microcorruption-ctf-writeup-whitehorse">Whitehorse</a> we learned that <code class="language-plaintext highlighter-rouge">0x7f</code> is required to be pushed to the stack 
(before the interrupt call) in order for the door to unlock. However we can see here that <code class="language-plaintext highlighter-rouge">0x7e</code> gets pushed to the stack instead.
Thankfully, we can use the format <code class="language-plaintext highlighter-rouge">%n</code>, which will write the number of bytes read before it, to a location of our choosing. More specifically,
let’s write <code class="language-plaintext highlighter-rouge">0x7f</code> to address <code class="language-plaintext highlighter-rouge">44c8</code> by using 127 (<code class="language-plaintext highlighter-rouge">0x74</code>) characters and an <code class="language-plaintext highlighter-rouge">%n</code>…</p>

<p class="img"><img src="/assets/images/writeups/microcorruption_novosibirsk_solve.png" alt="Novosibirsk Test Solve" /></p>

<p>:boom:</p>

<h3 id="flag-mouse-over-to-reveal">Flag (mouse over to reveal)</h3>
<div class="spoiler"><p>c8444141414141414141414141414141414141414141414141414141414141414141414141414141414141</p><p>41414141414141414141414141414141414141414141414141414141414141414141414141414141414141</p><p>4141414141414141414141414141414141414141414141414141414141414141414141414141414141256e</p></div>]]></content><author><name>jiva</name></author><category term="blog" /><category term="microcorruption" /><category term="CTF" /><category term="writeup" /><category term="reverse engineering" /><category term="assembly" /><category term="hacking" /><summary type="html"><![CDATA[Microcorruption CTF Novosibirsk Write-up]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jiva.io/assets/images/writeups/microcorruption.png" /><media:content medium="image" url="https://jiva.io/assets/images/writeups/microcorruption.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Microcorruption CTF Whitehorse Write-up</title><link href="https://jiva.io/blog/microcorruption-ctf-writeup-whitehorse" rel="alternate" type="text/html" title="Microcorruption CTF Whitehorse Write-up" /><published>2017-09-13T15:25:00+00:00</published><updated>2017-09-13T15:25:00+00:00</updated><id>https://jiva.io/blog/microcorruption-ctf-writeup-whitehorse</id><content type="html" xml:base="https://jiva.io/blog/microcorruption-ctf-writeup-whitehorse"><![CDATA[<h2 id="summary">Summary:</h2>

<p>This is a write-up of my solution to the <a href="https://microcorruption.com/">Microcorruption CTF</a>
challenge “Whitehorse” (<code class="language-plaintext highlighter-rouge">LOCKIT PRO r c.01</code>).</p>

<p>I found this challenge to be relatively straightforward and easy to solve. Let’s check out what the program is doing.</p>

<style type="text/css">
  .gist-file
  .gist-data {max-height: 500px;}
</style>

<noscript><pre>0010 &lt;__trap_interrupt&gt;
0010:  3041           ret
4400 &lt;__init_stack&gt;
4400:  3140 863e      mov	#0x3e86, sp
4404 &lt;__low_level_init&gt;
4404:  1542 5c01      mov	&amp;0x015c, r5
4408:  75f3           and.b	#-0x1, r5
440a:  35d0 085a      bis	#0x5a08, r5
440e &lt;__do_copy_data&gt;
440e:  3f40 0000      clr	r15
4412:  0f93           tst	r15
4414:  0724           jz	#0x4424 &lt;__do_clear_bss+0x0&gt;
4416:  8245 5c01      mov	r5, &amp;0x015c
441a:  2f83           decd	r15
441c:  9f4f c445 0024 mov	0x45c4(r15), 0x2400(r15)
4422:  f923           jnz	#0x4416 &lt;__do_copy_data+0x8&gt;
4424 &lt;__do_clear_bss&gt;
4424:  3f40 0000      clr	r15
4428:  0f93           tst	r15
442a:  0624           jz	#0x4438 &lt;main+0x0&gt;
442c:  8245 5c01      mov	r5, &amp;0x015c
4430:  1f83           dec	r15
4432:  cf43 0024      mov.b	#0x0, 0x2400(r15)
4436:  fa23           jnz	#0x442c &lt;__do_clear_bss+0x8&gt;
4438 &lt;main&gt;
4438:  b012 f444      call	#0x44f4 &lt;login&gt;
443c &lt;__stop_progExec__&gt;
443c:  32d0 f000      bis	#0xf0, sr
4440:  fd3f           jmp	#0x443c &lt;__stop_progExec__+0x0&gt;
4442 &lt;__ctors_end&gt;
4442:  3040 c245      br	#0x45c2 &lt;_unexpected_&gt;
4446 &lt;conditional_unlock_door&gt;
4446:  0412           push	r4
4448:  0441           mov	sp, r4
444a:  2453           incd	r4
444c:  2183           decd	sp
444e:  c443 fcff      mov.b	#0x0, -0x4(r4)
4452:  3e40 fcff      mov	#0xfffc, r14
4456:  0e54           add	r4, r14
4458:  0e12           push	r14
445a:  0f12           push	r15
445c:  3012 7e00      push	#0x7e
4460:  b012 3245      call	#0x4532 &lt;INT&gt;
4464:  5f44 fcff      mov.b	-0x4(r4), r15
4468:  8f11           sxt	r15
446a:  3152           add	#0x8, sp
446c:  3441           pop	r4
446e:  3041           ret
4470 .strings:
4470: &quot;Enter the password to continue.&quot;
4490: &quot;Remember: passwords are between 8 and 16 characters.&quot;
44c5: &quot;Access granted.&quot;
44d5: &quot;That password is not correct.&quot;
44f3: &quot;&quot;
44f4 &lt;login&gt;
44f4:  3150 f0ff      add	#0xfff0, sp
44f8:  3f40 7044      mov	#0x4470 &quot;Enter the password to continue.&quot;, r15
44fc:  b012 9645      call	#0x4596 &lt;puts&gt;
4500:  3f40 9044      mov	#0x4490 &quot;Remember: passwords are between 8 and 16 characters.&quot;, r15
4504:  b012 9645      call	#0x4596 &lt;puts&gt;
4508:  3e40 3000      mov	#0x30, r14
450c:  0f41           mov	sp, r15
450e:  b012 8645      call	#0x4586 &lt;getsn&gt;
4512:  0f41           mov	sp, r15
4514:  b012 4644      call	#0x4446 &lt;conditional_unlock_door&gt;
4518:  0f93           tst	r15
451a:  0324           jz	#0x4522 &lt;login+0x2e&gt;
451c:  3f40 c544      mov	#0x44c5 &quot;Access granted.&quot;, r15
4520:  023c           jmp	#0x4526 &lt;login+0x32&gt;
4522:  3f40 d544      mov	#0x44d5 &quot;That password is not correct.&quot;, r15
4526:  b012 9645      call	#0x4596 &lt;puts&gt;
452a:  3150 1000      add	#0x10, sp
452e:  3041           ret
4530 &lt;__do_nothing&gt;
4530:  3041           ret
4532 &lt;INT&gt;
4532:  1e41 0200      mov	0x2(sp), r14
4536:  0212           push	sr
4538:  0f4e           mov	r14, r15
453a:  8f10           swpb	r15
453c:  024f           mov	r15, sr
453e:  32d0 0080      bis	#0x8000, sr
4542:  b012 1000      call	#0x10
4546:  3241           pop	sr
4548:  3041           ret
454a &lt;putchar&gt;
454a:  2183           decd	sp
454c:  0f12           push	r15
454e:  0312           push	#0x0
4550:  814f 0400      mov	r15, 0x4(sp)
4554:  b012 3245      call	#0x4532 &lt;INT&gt;
4558:  1f41 0400      mov	0x4(sp), r15
455c:  3150 0600      add	#0x6, sp
4560:  3041           ret
4562 &lt;getchar&gt;
4562:  0412           push	r4
4564:  0441           mov	sp, r4
4566:  2453           incd	r4
4568:  2183           decd	sp
456a:  3f40 fcff      mov	#0xfffc, r15
456e:  0f54           add	r4, r15
4570:  0f12           push	r15
4572:  1312           push	#0x1
4574:  b012 3245      call	#0x4532 &lt;INT&gt;
4578:  5f44 fcff      mov.b	-0x4(r4), r15
457c:  8f11           sxt	r15
457e:  3150 0600      add	#0x6, sp
4582:  3441           pop	r4
4584:  3041           ret
4586 &lt;getsn&gt;
4586:  0e12           push	r14
4588:  0f12           push	r15
458a:  2312           push	#0x2
458c:  b012 3245      call	#0x4532 &lt;INT&gt;
4590:  3150 0600      add	#0x6, sp
4594:  3041           ret
4596 &lt;puts&gt;
4596:  0b12           push	r11
4598:  0b4f           mov	r15, r11
459a:  073c           jmp	#0x45aa &lt;puts+0x14&gt;
459c:  1b53           inc	r11
459e:  8f11           sxt	r15
45a0:  0f12           push	r15
45a2:  0312           push	#0x0
45a4:  b012 3245      call	#0x4532 &lt;INT&gt;
45a8:  2152           add	#0x4, sp
45aa:  6f4b           mov.b	@r11, r15
45ac:  4f93           tst.b	r15
45ae:  f623           jnz	#0x459c &lt;puts+0x6&gt;
45b0:  3012 0a00      push	#0xa
45b4:  0312           push	#0x0
45b6:  b012 3245      call	#0x4532 &lt;INT&gt;
45ba:  2152           add	#0x4, sp
45bc:  0f43           clr	r15
45be:  3b41           pop	r11
45c0:  3041           ret
45c2 &lt;_unexpected_&gt;
45c2:  0013           reti	pc</pre></noscript>
<script src="https://gist.github.com/jiva/41adb80f6be758c9d432877de66aa255.js"> </script>

<p>After the call to <code class="language-plaintext highlighter-rouge">main()</code> and then <code class="language-plaintext highlighter-rouge">login()</code>, we see a new function named <code class="language-plaintext highlighter-rouge">conditional_unlock_door()</code> is being called.
After this call returns and if <code class="language-plaintext highlighter-rouge">r15</code> is not <code class="language-plaintext highlighter-rouge">0x0</code>, the message “Access granted” is printed and we return out of the function.</p>

<p>Let’s try some input and examine the state of the memory.</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_whitehorse_input_break.png" alt="Whitehorse Input Break" /></p>

<p>Our input <code class="language-plaintext highlighter-rouge">AAAAAAAAAA</code> is placed onto the stack. Following the password buffer, we can see the return address to <code class="language-plaintext highlighter-rouge">0x443c</code> for when we return out of <code class="language-plaintext highlighter-rouge">login()</code>.</p>

<p>After returning from <code class="language-plaintext highlighter-rouge">getsn()</code>, the stack pointer address <code class="language-plaintext highlighter-rouge">sp</code> is moved into register <code class="language-plaintext highlighter-rouge">r15</code> and the program calls <code class="language-plaintext highlighter-rouge">conditional_unlock_door()</code>.</p>
<noscript><pre>4446 &lt;conditional_unlock_door&gt;
4446:  0412           push	r4
4448:  0441           mov	sp, r4
444a:  2453           incd	r4
444c:  2183           decd	sp
444e:  c443 fcff      mov.b	#0x0, -0x4(r4)
4452:  3e40 fcff      mov	#0xfffc, r14
4456:  0e54           add	r4, r14
4458:  0e12           push	r14
445a:  0f12           push	r15
445c:  3012 7e00      push	#0x7e
4460:  b012 3245      call	#0x4532 &lt;INT&gt;
4464:  5f44 fcff      mov.b	-0x4(r4), r15
4468:  8f11           sxt	r15
446a:  3152           add	#0x8, sp
446c:  3441           pop	r4
446e:  3041           ret</pre></noscript>
<script src="https://gist.github.com/jiva/d7b0932ffd0533806dae127865f26466.js"> </script>

<p>The code will move some values around in the registers, and call the interrupt
with code <code class="language-plaintext highlighter-rouge">0x7e</code> (?) and before returning, will execute the instruction
<code class="language-plaintext highlighter-rouge">mov.b  -0x4(r4), r15</code> which will move a null byte from before our password
buffer into <code class="language-plaintext highlighter-rouge">r15</code>. Because of this, the <code class="language-plaintext highlighter-rouge">tst  r15</code> instruction in <code class="language-plaintext highlighter-rouge">login()</code> will
fail.</p>

<p>Two things to note. First, we should be able to overwrite the return address <code class="language-plaintext highlighter-rouge">0x443c</code>. Second, <code class="language-plaintext highlighter-rouge">conditional_unlock_door()</code> (the way it’s coded) will actually never
unlock the door. From the previous challenges, we learned that the code to the interrupt was <code class="language-plaintext highlighter-rouge">0x7f</code>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>444a &lt;unlock_door&gt;
444a:  3012 7f00      push  #0x7f
444e:  b012 c446      call  #0x46c4 &lt;INT&gt;
4452:  2153           incd  sp
4454:  3041           ret
</code></pre></div></div>

<p>However, <code class="language-plaintext highlighter-rouge">conditional_unlock_door()</code> uses the code <code class="language-plaintext highlighter-rouge">0x7e</code>, which doesn’t actually unlock the door. Bummer.</p>

<p>But… what if we injected the instructions to the old <code class="language-plaintext highlighter-rouge">unlock_door()</code> onto the stack
(via our password buffer) and returned execution to it? After all, it’s only 12 bytes
long and should fit in the buffer with room to spare before we reach the return 
address.
Let’s whip up our new payload, making sure we fix the address of the call to <code class="language-plaintext highlighter-rouge">INT()</code>
give it a shot…</p>

<p class="img"><img src="/assets/images/writeups/microcorruption_whitehorse_solve.png" alt="Whitehorse solve" /></p>

<p>:+1: :beers:</p>

<h3 id="flag-mouse-over-to-reveal">Flag (mouse over to reveal)</h3>
<div class="spoiler"><p>30127f00b01232452153304141414141743e</p></div>]]></content><author><name>jiva</name></author><category term="blog" /><category term="microcorruption" /><category term="CTF" /><category term="writeup" /><category term="reverse engineering" /><category term="assembly" /><category term="hacking" /><summary type="html"><![CDATA[Microcorruption CTF Whitehorse Write-up]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jiva.io/assets/images/writeups/microcorruption.png" /><media:content medium="image" url="https://jiva.io/assets/images/writeups/microcorruption.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Microcorruption CTF Santa Cruz Write-up</title><link href="https://jiva.io/blog/microcorruption-ctf-writeup-santa-cruz" rel="alternate" type="text/html" title="Microcorruption CTF Santa Cruz Write-up" /><published>2017-09-10T21:05:00+00:00</published><updated>2017-09-10T21:05:00+00:00</updated><id>https://jiva.io/blog/microcorruption-ctf-writeup-santa-cruz</id><content type="html" xml:base="https://jiva.io/blog/microcorruption-ctf-writeup-santa-cruz"><![CDATA[<h2 id="summary">Summary:</h2>

<p>This is a write-up of my solution to the <a href="https://microcorruption.com/">Microcorruption CTF</a>
challenge “Santa Cruz” (<code class="language-plaintext highlighter-rouge">LOCKIT PRO r b.05</code>).</p>

<p>This challenge required a few tricks in order to unlock the door, so let’s get down to it.</p>

<style type="text/css">
  .gist-file
  .gist-data {max-height: 500px;}
</style>

<noscript><pre>0010 &lt;__trap_interrupt&gt;
0010:  3041           ret
4400 &lt;__init_stack&gt;
4400:  3140 0044      mov	#0x4400, sp
4404 &lt;__low_level_init&gt;
4404:  1542 5c01      mov	&amp;0x015c, r5
4408:  75f3           and.b	#-0x1, r5
440a:  35d0 085a      bis	#0x5a08, r5
440e &lt;__do_copy_data&gt;
440e:  3f40 0400      mov	#0x4, r15
4412:  0f93           tst	r15
4414:  0724           jz	#0x4424 &lt;__do_clear_bss+0x0&gt;
4416:  8245 5c01      mov	r5, &amp;0x015c
441a:  2f83           decd	r15
441c:  9f4f 6a47 0024 mov	0x476a(r15), 0x2400(r15)
4422:  f923           jnz	#0x4416 &lt;__do_copy_data+0x8&gt;
4424 &lt;__do_clear_bss&gt;
4424:  3f40 6400      mov	#0x64, r15
4428:  0f93           tst	r15
442a:  0624           jz	#0x4438 &lt;main+0x0&gt;
442c:  8245 5c01      mov	r5, &amp;0x015c
4430:  1f83           dec	r15
4432:  cf43 0424      mov.b	#0x0, 0x2404(r15)
4436:  fa23           jnz	#0x442c &lt;__do_clear_bss+0x8&gt;
4438 &lt;main&gt;
4438:  3150 ceff      add	#0xffce, sp
443c:  b012 5045      call	#0x4550 &lt;login&gt;
4440 &lt;__stop_progExec__&gt;
4440:  32d0 f000      bis	#0xf0, sr
4444:  fd3f           jmp	#0x4440 &lt;__stop_progExec__+0x0&gt;
4446 &lt;__ctors_end&gt;
4446:  3040 6847      br	#0x4768 &lt;_unexpected_&gt;
444a &lt;unlock_door&gt;
444a:  3012 7f00      push	#0x7f
444e:  b012 c446      call	#0x46c4 &lt;INT&gt;
4452:  2153           incd	sp
4454:  3041           ret
4456 &lt;test_username_and_password_valid&gt;
4456:  0412           push	r4
4458:  0441           mov	sp, r4
445a:  2453           incd	r4
445c:  2183           decd	sp
445e:  c443 fcff      mov.b	#0x0, -0x4(r4)
4462:  3d40 fcff      mov	#0xfffc, r13
4466:  0d54           add	r4, r13
4468:  0d12           push	r13
446a:  0e12           push	r14
446c:  0f12           push	r15
446e:  3012 7d00      push	#0x7d
4472:  b012 c446      call	#0x46c4 &lt;INT&gt;
4476:  5f44 fcff      mov.b	-0x4(r4), r15
447a:  8f11           sxt	r15
447c:  3150 0a00      add	#0xa, sp
4480:  3441           pop	r4
4482:  3041           ret
4484 .strings:
4484: &quot;Authentication now requires a username and password.&quot;
44b9: &quot;Remember: both are between 8 and 16 characters.&quot;
44e9: &quot;Please enter your username:&quot;
4505: &quot;Please enter your password:&quot;
4521: &quot;Access granted.&quot;
4531: &quot;That password is not correct.&quot;
454f: &quot;&quot;
4550 &lt;login&gt;
4550:  0b12           push	r11
4552:  0412           push	r4
4554:  0441           mov	sp, r4
4556:  2452           add	#0x4, r4
4558:  3150 d8ff      add	#0xffd8, sp
455c:  c443 faff      mov.b	#0x0, -0x6(r4)
4560:  f442 e7ff      mov.b	#0x8, -0x19(r4)
4564:  f440 1000 e8ff mov.b	#0x10, -0x18(r4)
456a:  3f40 8444      mov	#0x4484 &quot;Authentication now requires a username and password.&quot;, r15
456e:  b012 2847      call	#0x4728 &lt;puts&gt;
4572:  3f40 b944      mov	#0x44b9 &quot;Remember: both are between 8 and 16 characters.&quot;, r15
4576:  b012 2847      call	#0x4728 &lt;puts&gt;
457a:  3f40 e944      mov	#0x44e9 &quot;Please enter your username:&quot;, r15
457e:  b012 2847      call	#0x4728 &lt;puts&gt;
4582:  3e40 6300      mov	#0x63, r14
4586:  3f40 0424      mov	#0x2404, r15
458a:  b012 1847      call	#0x4718 &lt;getsn&gt;
458e:  3f40 0424      mov	#0x2404, r15
4592:  b012 2847      call	#0x4728 &lt;puts&gt;
4596:  3e40 0424      mov	#0x2404, r14
459a:  0f44           mov	r4, r15
459c:  3f50 d6ff      add	#0xffd6, r15
45a0:  b012 5447      call	#0x4754 &lt;strcpy&gt;
45a4:  3f40 0545      mov	#0x4505 &quot;Please enter your password:&quot;, r15
45a8:  b012 2847      call	#0x4728 &lt;puts&gt;
45ac:  3e40 6300      mov	#0x63, r14
45b0:  3f40 0424      mov	#0x2404, r15
45b4:  b012 1847      call	#0x4718 &lt;getsn&gt;
45b8:  3f40 0424      mov	#0x2404, r15
45bc:  b012 2847      call	#0x4728 &lt;puts&gt;
45c0:  0b44           mov	r4, r11
45c2:  3b50 e9ff      add	#0xffe9, r11
45c6:  3e40 0424      mov	#0x2404, r14
45ca:  0f4b           mov	r11, r15
45cc:  b012 5447      call	#0x4754 &lt;strcpy&gt;
45d0:  0f4b           mov	r11, r15
45d2:  0e44           mov	r4, r14
45d4:  3e50 e8ff      add	#0xffe8, r14
45d8:  1e53           inc	r14
45da:  ce93 0000      tst.b	0x0(r14)
45de:  fc23           jnz	#0x45d8 &lt;login+0x88&gt;
45e0:  0b4e           mov	r14, r11
45e2:  0b8f           sub	r15, r11
45e4:  5f44 e8ff      mov.b	-0x18(r4), r15
45e8:  8f11           sxt	r15
45ea:  0b9f           cmp	r15, r11
45ec:  0628           jnc	#0x45fa &lt;login+0xaa&gt;
45ee:  1f42 0024      mov	&amp;0x2400, r15
45f2:  b012 2847      call	#0x4728 &lt;puts&gt;
45f6:  3040 4044      br	#0x4440 &lt;__stop_progExec__&gt;
45fa:  5f44 e7ff      mov.b	-0x19(r4), r15
45fe:  8f11           sxt	r15
4600:  0b9f           cmp	r15, r11
4602:  062c           jc	#0x4610 &lt;login+0xc0&gt;
4604:  1f42 0224      mov	&amp;0x2402, r15
4608:  b012 2847      call	#0x4728 &lt;puts&gt;
460c:  3040 4044      br	#0x4440 &lt;__stop_progExec__&gt;
4610:  c443 d4ff      mov.b	#0x0, -0x2c(r4)
4614:  3f40 d4ff      mov	#0xffd4, r15
4618:  0f54           add	r4, r15
461a:  0f12           push	r15
461c:  0f44           mov	r4, r15
461e:  3f50 e9ff      add	#0xffe9, r15
4622:  0f12           push	r15
4624:  3f50 edff      add	#0xffed, r15
4628:  0f12           push	r15
462a:  3012 7d00      push	#0x7d
462e:  b012 c446      call	#0x46c4 &lt;INT&gt;
4632:  3152           add	#0x8, sp
4634:  c493 d4ff      tst.b	-0x2c(r4)
4638:  0524           jz	#0x4644 &lt;login+0xf4&gt;
463a:  b012 4a44      call	#0x444a &lt;unlock_door&gt;
463e:  3f40 2145      mov	#0x4521 &quot;Access granted.&quot;, r15
4642:  023c           jmp	#0x4648 &lt;login+0xf8&gt;
4644:  3f40 3145      mov	#0x4531 &quot;That password is not correct.&quot;, r15
4648:  b012 2847      call	#0x4728 &lt;puts&gt;
464c:  c493 faff      tst.b	-0x6(r4)
4650:  0624           jz	#0x465e &lt;login+0x10e&gt;
4652:  1f42 0024      mov	&amp;0x2400, r15
4656:  b012 2847      call	#0x4728 &lt;puts&gt;
465a:  3040 4044      br	#0x4440 &lt;__stop_progExec__&gt;
465e:  3150 2800      add	#0x28, sp
4662:  3441           pop	r4
4664:  3b41           pop	r11
4666:  3041           ret
4668 &lt;__do_nothing&gt;
4668:  3041           ret
466a:  496e           addc.b	r14, r9
466c:  7661           addc.b	@sp+, r6
466e:  6c69           addc.b	@r9, r12
4670:  6420           jnz	#0x473a &lt;puts+0x12&gt;
4672:  5061 7373      addc.b	0x7373(sp), pc
4676:  776f           addc.b	@r15+, r7
4678:  7264           addc.b	@r4+, sr
467a:  204c           br	@r12
467c:  656e           addc.b	@r14, r5
467e:  6774           subc.b	@r4, r7
4680:  683a           jl	#0x4352 &lt;__none__+0x4352&gt;
4682:  2070           subc	@pc, pc
4684:  6173           subc.b	#0x2, sp
4686:  7377           .word	0x7773
4688:  6f72           subc.b	#0x4, r15
468a:  6420           jnz	#0x4754 &lt;strcpy+0x0&gt;
468c:  746f           addc.b	@r15+, r4
468e:  6f20           jnz	#0x476e &lt;_unexpected_+0x6&gt;
4690:  6c6f           addc.b	@r15, r12
4692:  6e67           addc.b	@r7, r14
4694:  2e00           .word	0x002e
4696:  496e           addc.b	r14, r9
4698:  7661           addc.b	@sp+, r6
469a:  6c69           addc.b	@r9, r12
469c:  6420           jnz	#0x4766 &lt;strcpy+0x12&gt;
469e:  5061 7373      addc.b	0x7373(sp), pc
46a2:  776f           addc.b	@r15+, r7
46a4:  7264           addc.b	@r4+, sr
46a6:  204c           br	@r12
46a8:  656e           addc.b	@r14, r5
46aa:  6774           subc.b	@r4, r7
46ac:  683a           jl	#0x437e &lt;__none__+0x437e&gt;
46ae:  2070           subc	@pc, pc
46b0:  6173           subc.b	#0x2, sp
46b2:  7377           .word	0x7773
46b4:  6f72           subc.b	#0x4, r15
46b6:  6420           jnz	#0x4780 &lt;_unexpected_+0x18&gt;
46b8:  746f           addc.b	@r15+, r4
46ba:  6f20           jnz	#0x479a &lt;_unexpected_+0x32&gt;
46bc:  7368           .word	0x6873
46be:  6f72           subc.b	#0x4, r15
46c0:  742e           jc	#0x43aa &lt;__none__+0x43aa&gt;
...
46c4 &lt;INT&gt;
46c4:  1e41 0200      mov	0x2(sp), r14
46c8:  0212           push	sr
46ca:  0f4e           mov	r14, r15
46cc:  8f10           swpb	r15
46ce:  024f           mov	r15, sr
46d0:  32d0 0080      bis	#0x8000, sr
46d4:  b012 1000      call	#0x10
46d8:  3241           pop	sr
46da:  3041           ret
46dc &lt;putchar&gt;
46dc:  2183           decd	sp
46de:  0f12           push	r15
46e0:  0312           push	#0x0
46e2:  814f 0400      mov	r15, 0x4(sp)
46e6:  b012 c446      call	#0x46c4 &lt;INT&gt;
46ea:  1f41 0400      mov	0x4(sp), r15
46ee:  3150 0600      add	#0x6, sp
46f2:  3041           ret
46f4 &lt;getchar&gt;
46f4:  0412           push	r4
46f6:  0441           mov	sp, r4
46f8:  2453           incd	r4
46fa:  2183           decd	sp
46fc:  3f40 fcff      mov	#0xfffc, r15
4700:  0f54           add	r4, r15
4702:  0f12           push	r15
4704:  1312           push	#0x1
4706:  b012 c446      call	#0x46c4 &lt;INT&gt;
470a:  5f44 fcff      mov.b	-0x4(r4), r15
470e:  8f11           sxt	r15
4710:  3150 0600      add	#0x6, sp
4714:  3441           pop	r4
4716:  3041           ret
4718 &lt;getsn&gt;
4718:  0e12           push	r14
471a:  0f12           push	r15
471c:  2312           push	#0x2
471e:  b012 c446      call	#0x46c4 &lt;INT&gt;
4722:  3150 0600      add	#0x6, sp
4726:  3041           ret
4728 &lt;puts&gt;
4728:  0b12           push	r11
472a:  0b4f           mov	r15, r11
472c:  073c           jmp	#0x473c &lt;puts+0x14&gt;
472e:  1b53           inc	r11
4730:  8f11           sxt	r15
4732:  0f12           push	r15
4734:  0312           push	#0x0
4736:  b012 c446      call	#0x46c4 &lt;INT&gt;
473a:  2152           add	#0x4, sp
473c:  6f4b           mov.b	@r11, r15
473e:  4f93           tst.b	r15
4740:  f623           jnz	#0x472e &lt;puts+0x6&gt;
4742:  3012 0a00      push	#0xa
4746:  0312           push	#0x0
4748:  b012 c446      call	#0x46c4 &lt;INT&gt;
474c:  2152           add	#0x4, sp
474e:  0f43           clr	r15
4750:  3b41           pop	r11
4752:  3041           ret
4754 &lt;strcpy&gt;
4754:  0d4f           mov	r15, r13
4756:  023c           jmp	#0x475c &lt;strcpy+0x8&gt;
4758:  1e53           inc	r14
475a:  1d53           inc	r13
475c:  6c4e           mov.b	@r14, r12
475e:  cd4c 0000      mov.b	r12, 0x0(r13)
4762:  4c93           tst.b	r12
4764:  f923           jnz	#0x4758 &lt;strcpy+0x4&gt;
4766:  3041           ret
4768 &lt;_unexpected_&gt;
4768:  0013           reti	pc</pre></noscript>
<script src="https://gist.github.com/jiva/9d3d433f73f8d4d9f3c2cded096ce7aa.js"> </script>

<p>The meat of the logic lives inside <code class="language-plaintext highlighter-rouge">login()</code>, and there’s substantially more going on here than compared
with the previous challenges. Let’s dissect it and learn what it’s doing…</p>

<noscript><pre>4550:  0b12           push	r11
4552:  0412           push	r4
4554:  0441           mov	sp, r4
4556:  2452           add	#0x4, r4
4558:  3150 d8ff      add	#0xffd8, sp
455c:  c443 faff      mov.b	#0x0, -0x6(r4)
4560:  f442 e7ff      mov.b	#0x8, -0x19(r4)
4564:  f440 1000 e8ff mov.b	#0x10, -0x18(r4)
456a:  3f40 8444      mov	#0x4484 &quot;Authentication now requires a username and password.&quot;, r15
456e:  b012 2847      call	#0x4728 &lt;puts&gt;
4572:  3f40 b944      mov	#0x44b9 &quot;Remember: both are between 8 and 16 characters.&quot;, r15
4576:  b012 2847      call	#0x4728 &lt;puts&gt;</pre></noscript>
<script src="https://gist.github.com/jiva/669d3a5080076ef319c652e9659f8399.js"> </script>

<p>The first part of <code class="language-plaintext highlighter-rouge">login()</code> outputs a message to the user indicating that a username and password are both required.</p>

<noscript><pre>457a:  3f40 e944      mov	#0x44e9 &quot;Please enter your username:&quot;, r15
457e:  b012 2847      call	#0x4728 &lt;puts&gt;
4582:  3e40 6300      mov	#0x63, r14
4586:  3f40 0424      mov	#0x2404, r15
458a:  b012 1847      call	#0x4718 &lt;getsn&gt;
458e:  3f40 0424      mov	#0x2404, r15
4592:  b012 2847      call	#0x4728 &lt;puts&gt;
4596:  3e40 0424      mov	#0x2404, r14
459a:  0f44           mov	r4, r15
459c:  3f50 d6ff      add	#0xffd6, r15
45a0:  b012 5447      call	#0x4754 &lt;strcpy&gt;</pre></noscript>
<script src="https://gist.github.com/jiva/c1ff4c6f2ec463902d7a76467230705c.js"> </script>

<p>The second part of <code class="language-plaintext highlighter-rouge">login()</code> prompts a message asking for a username. After submitting the username, the code prints
it back to the user, and then it is copied onto the stack.</p>

<noscript><pre>45a4:  3f40 0545      mov	#0x4505 &quot;Please enter your password:&quot;, r15
45a8:  b012 2847      call	#0x4728 &lt;puts&gt;
45ac:  3e40 6300      mov	#0x63, r14
45b0:  3f40 0424      mov	#0x2404, r15
45b4:  b012 1847      call	#0x4718 &lt;getsn&gt;
45b8:  3f40 0424      mov	#0x2404, r15
45bc:  b012 2847      call	#0x4728 &lt;puts&gt;
45c0:  0b44           mov	r4, r11
45c2:  3b50 e9ff      add	#0xffe9, r11
45c6:  3e40 0424      mov	#0x2404, r14
45ca:  0f4b           mov	r11, r15
45cc:  b012 5447      call	#0x4754 &lt;strcpy&gt;</pre></noscript>
<script src="https://gist.github.com/jiva/79d4a79d0f076e3f731c9c11c5f0e6c9.js"> </script>

<p>The third part of <code class="language-plaintext highlighter-rouge">login()</code>, similar to the last one, prompts a message asking for a password. After submitting the password,
the code will print it back to the user, and will go on to copy the password onto the stack.</p>

<p>Let’s go into the debugger and pause execution at this point and observe what the memory looks like (I’ll use 10 <code class="language-plaintext highlighter-rouge">A</code> for
the username and 10 <code class="language-plaintext highlighter-rouge">B</code> for the password)…</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_santacruz_prompt_break.png" alt="Santa Cruz break after prompts" /></p>

<p>We can see that after the second call to <code class="language-plaintext highlighter-rouge">strcpy()</code>, our username was copied onto the stack starting at <code class="language-plaintext highlighter-rouge">0x43a2</code>, and our password
was copied onto the stack starting at <code class="language-plaintext highlighter-rouge">0x43b5</code>. Notice that the program left 16 bytes on the stack for the username, 
in addition to a null byte. Then we see two bytes, <code class="language-plaintext highlighter-rouge">0x08</code> and <code class="language-plaintext highlighter-rouge">0x10</code>, followed by our password. 
Also note that about 6 bytes after the end of the password
buffer, we see the bytes <code class="language-plaintext highlighter-rouge">0x4044</code>, which looks like the return address from the <code class="language-plaintext highlighter-rouge">login()</code> call inside <code class="language-plaintext highlighter-rouge">main()</code>.
Let’s keep this in mind and continue dissecting <code class="language-plaintext highlighter-rouge">login()</code>.</p>

<noscript><pre>45d0:  0f4b           mov	r11, r15
45d2:  0e44           mov	r4, r14
45d4:  3e50 e8ff      add	#0xffe8, r14
45d8:  1e53           inc	r14
45da:  ce93 0000      tst.b	0x0(r14)
45de:  fc23           jnz	#0x45d8 &lt;login+0x88&gt;</pre></noscript>
<script src="https://gist.github.com/jiva/f61e23b7ffa47d2d8d8c9b00c2ea3a84.js"> </script>

<p>After the second call to <code class="language-plaintext highlighter-rouge">strcpy()</code>, this part of the code will loop through the bytes of the password while at the same time
incrementing a byte offset pointer which is located in <code class="language-plaintext highlighter-rouge">r14</code>. If the value at the address location of <code class="language-plaintext highlighter-rouge">r14</code> is <code class="language-plaintext highlighter-rouge">0x0</code>, 
the <code class="language-plaintext highlighter-rouge">jnz</code> will not be executed.</p>

<noscript><pre>45e0:  0b4e           mov	r14, r11
45e2:  0b8f           sub	r15, r11
45e4:  5f44 e8ff      mov.b	-0x18(r4), r15
45e8:  8f11           sxt	r15
45ea:  0b9f           cmp	r15, r11
45ec:  0628           jnc	#0x45fa &lt;login+0xaa&gt;
45ee:  1f42 0024      mov	&amp;0x2400, r15
45f2:  b012 2847      call	#0x4728 &lt;puts&gt;
45f6:  3040 4044      br	#0x4440 &lt;__stop_progExec__&gt;</pre></noscript>
<script src="https://gist.github.com/jiva/5535f6dc34599f7222e4f01c3f4d83ad.js"> </script>

<p>At this point, the length of the password will be calculated by subtracting the byte offset pointer located in <code class="language-plaintext highlighter-rouge">r14</code> with the pointer
to the beginning of password located in <code class="language-plaintext highlighter-rouge">r15</code>. This length will be stored in <code class="language-plaintext highlighter-rouge">r11</code>. This is where things get a little interesting.
The instruction <code class="language-plaintext highlighter-rouge">mov.b  -0x18(r4), r15</code> will move the byte <code class="language-plaintext highlighter-rouge">0x10</code> from the memory located between the username and the password
on the stack into <code class="language-plaintext highlighter-rouge">r15</code>. Then <code class="language-plaintext highlighter-rouge">sxt  r15</code> will perform a sign-extend on <code class="language-plaintext highlighter-rouge">r15</code>, and after this, <code class="language-plaintext highlighter-rouge">cmp  r15, r11</code> will compare the two
registers (in our example, <code class="language-plaintext highlighter-rouge">r11</code> == <code class="language-plaintext highlighter-rouge">0x000a</code> and <code class="language-plaintext highlighter-rouge">r15</code> == <code class="language-plaintext highlighter-rouge">0x0010</code>). The following <code class="language-plaintext highlighter-rouge">jnc</code> instruction will jump execution to 
<code class="language-plaintext highlighter-rouge">0x45fa</code> if <code class="language-plaintext highlighter-rouge">r11</code> is greater than <code class="language-plaintext highlighter-rouge">r15</code>, else, an “Invalid Password Length” error will be printed and execution will be halted.
It’s clear that <code class="language-plaintext highlighter-rouge">0x10</code> is a length value that we can potentially control with an overflow… Let’s continue.</p>

<noscript><pre>45fa:  5f44 e7ff      mov.b	-0x19(r4), r15
45fe:  8f11           sxt	r15
4600:  0b9f           cmp	r15, r11
4602:  062c           jc	#0x4610 &lt;login+0xc0&gt;
4604:  1f42 0224      mov	&amp;0x2402, r15
4608:  b012 2847      call	#0x4728 &lt;puts&gt;
460c:  3040 4044      br	#0x4440 &lt;__stop_progExec__&gt;</pre></noscript>
<script src="https://gist.github.com/jiva/49adb82634284cc5be895b13c1288811.js"> </script>

<p>This next chunk of code will move the byte located at <code class="language-plaintext highlighter-rouge">r4</code> - <code class="language-plaintext highlighter-rouge">0x19</code> (the <code class="language-plaintext highlighter-rouge">0x08</code> before the <code class="language-plaintext highlighter-rouge">0x10</code>) into <code class="language-plaintext highlighter-rouge">r15</code>, will do a 
sign-extend on <code class="language-plaintext highlighter-rouge">r15</code>, and then will <code class="language-plaintext highlighter-rouge">cmp  r15, r11</code> (<code class="language-plaintext highlighter-rouge">r5</code> == <code class="language-plaintext highlighter-rouge">0x08</code>, <code class="language-plaintext highlighter-rouge">r11</code> == <code class="language-plaintext highlighter-rouge">0x000a</code>). If <code class="language-plaintext highlighter-rouge">r11</code> is less than <code class="language-plaintext highlighter-rouge">r15</code>, the
program will print an error message indicating the password length was too short, and will exit.</p>

<p>We now know that the two bytes between the username and password buffers are length fields that we can potentially control.</p>

<p>Let’s figure out the last part of the <code class="language-plaintext highlighter-rouge">login()</code> function…</p>
<noscript><pre>4610:  c443 d4ff      mov.b	#0x0, -0x2c(r4)
4614:  3f40 d4ff      mov	#0xffd4, r15
4618:  0f54           add	r4, r15
461a:  0f12           push	r15
461c:  0f44           mov	r4, r15
461e:  3f50 e9ff      add	#0xffe9, r15
4622:  0f12           push	r15
4624:  3f50 edff      add	#0xffed, r15
4628:  0f12           push	r15
462a:  3012 7d00      push	#0x7d
462e:  b012 c446      call	#0x46c4 &lt;INT&gt;
4632:  3152           add	#0x8, sp
4634:  c493 d4ff      tst.b	-0x2c(r4)
4638:  0524           jz	#0x4644 &lt;login+0xf4&gt;
463a:  b012 4a44      call	#0x444a &lt;unlock_door&gt;
463e:  3f40 2145      mov	#0x4521 &quot;Access granted.&quot;, r15
4642:  023c           jmp	#0x4648 &lt;login+0xf8&gt;
4644:  3f40 3145      mov	#0x4531 &quot;That password is not correct.&quot;, r15
4648:  b012 2847      call	#0x4728 &lt;puts&gt;
464c:  c493 faff      tst.b	-0x6(r4)
4650:  0624           jz	#0x465e &lt;login+0x10e&gt;
4652:  1f42 0024      mov	&amp;0x2400, r15
4656:  b012 2847      call	#0x4728 &lt;puts&gt;
465a:  3040 4044      br	#0x4440 &lt;__stop_progExec__&gt;
465e:  3150 2800      add	#0x28, sp
4662:  3441           pop	r4
4664:  3b41           pop	r11
4666:  3041           ret</pre></noscript>
<script src="https://gist.github.com/jiva/21a7d41bd3ba118dbdbbd9616ef50e69.js"> </script>

<p>The instructions between <code class="language-plaintext highlighter-rouge">0x4610</code> and <code class="language-plaintext highlighter-rouge">0x462a</code> are manipulating registers in various ways and are pushing
various addresses (related to the username and password buffers)
onto the stack. After the call to the interrupt, things become interesting. Let’s set a breakpoint on the <code class="language-plaintext highlighter-rouge">tst.b</code> instruction
at <code class="language-plaintext highlighter-rouge">0x4634</code> and examine the stack…</p>

<p class="img"><img src="/assets/images/writeups/microcorruption_santacruz_tst_break.png" alt="Santa Cruz tst break" /></p>
<p>Notice how the program is going to test the memory location at <code class="language-plaintext highlighter-rouge">r4</code> - <code class="language-plaintext highlighter-rouge">0x2c</code> (<code class="language-plaintext highlighter-rouge">0x43a0</code> a.k.a. <code class="language-plaintext highlighter-rouge">sp</code>) for <code class="language-plaintext highlighter-rouge">0x0</code>, and
if it is, will continue to jump to <code class="language-plaintext highlighter-rouge">0x4644</code> which will eventually exit the code. This is
strange because it appears that this memory is never going to contain anything <em>besides</em> <code class="language-plaintext highlighter-rouge">0x0</code>, due to the fact that 
earlier in the code, the instruction <code class="language-plaintext highlighter-rouge">mov.b  #0x0, -0x2c(r4)</code> was executed.</p>

<p>After printing out the message “That password is not correct”, we encounter another <code class="language-plaintext highlighter-rouge">tst.b</code> instruction, however
this time, we are checking the address <code class="language-plaintext highlighter-rouge">r4</code> - <code class="language-plaintext highlighter-rouge">0x6</code>. If these two <code class="language-plaintext highlighter-rouge">tst</code> instructions pass, we will eventually
return out of the function. So what can we do with this?</p>

<p>Remember the return address pushed onto the stack from the call to <code class="language-plaintext highlighter-rouge">login()</code> from <code class="language-plaintext highlighter-rouge">main()</code>? Check out the memory dump
and the location in relation to the password buffer. Surely we can reach it by overflowing one of the buffers! However,
we must account for a number of checks that are in place. Let’s recap:</p>

<ol>
  <li>The byte value <code class="language-plaintext highlighter-rouge">0x10</code> (address <code class="language-plaintext highlighter-rouge">0x43b4</code>) will be used to check the max length of the password.</li>
  <li>The byte value <code class="language-plaintext highlighter-rouge">0x08</code> (address <code class="language-plaintext highlighter-rouge">0x43b3</code>) will be used to check the min length of the password.</li>
  <li>The memory address <code class="language-plaintext highlighter-rouge">0x43a0</code> (<code class="language-plaintext highlighter-rouge">tst.b r4 - 0x2c</code>) must contain <code class="language-plaintext highlighter-rouge">0x0</code>.</li>
  <li>The memory address <code class="language-plaintext highlighter-rouge">0x43c6</code> (<code class="language-plaintext highlighter-rouge">tst.b r4 - 0x6</code>) must contain <code class="language-plaintext highlighter-rouge">0x0</code>.</li>
</ol>

<p>If we can satisfy these conditions, then we can cleanly reach the location of the return address on the stack, while
at the same time avoiding any premature calls to <code class="language-plaintext highlighter-rouge">__stop_progExec__()</code>. Sweet!</p>

<p>We should be able to safely ignore the check happening at <code class="language-plaintext highlighter-rouge">#3</code>; this area is towards the top of the stack, and 
the parts that we are going to modify are below this. Our payload will be split across two strings.</p>

<p>The username will overwrite both the min-length byte and the max-length byte, and we need to make sure that the
max-length byte is <code class="language-plaintext highlighter-rouge">&gt;=</code> the length of whatever password we decide. The min-length byte needs to be <code class="language-plaintext highlighter-rouge">&lt;=</code> the password
we choose.</p>

<p>We need to overwrite the return address located at <code class="language-plaintext highlighter-rouge">r4</code>, however <code class="language-plaintext highlighter-rouge">#4</code> requires that a byte between the end of the
original password buffer and the return address must be <code class="language-plaintext highlighter-rouge">0x0</code>. Because <code class="language-plaintext highlighter-rouge">strcpy()</code> terminates the copy on null bytes,
we cannot have any null bytes in our payload, therefore, we cannot overflow the password buffer to overwrite the return
address. However, we <em>can</em> overflow the username buffer and not only overwrite the length values, but write all the way 
until we overflow the return address. So how will we write the null byte to satisfy requirement <code class="language-plaintext highlighter-rouge">#4</code>? Well we can just have
<code class="language-plaintext highlighter-rouge">strcpy()</code> null terminate the string for us, right where we need the null byte! Let’s craft our payloads and cross our 
fingers…</p>

<p class="img"><img src="/assets/images/writeups/microcorruption_santacruz_solve.png" alt="Santa Cruz solve" /></p>

<p>:+1: :beers:</p>

<h3 id="flag-mouse-over-to-reveal">Flag (mouse over to reveal)</h3>
<div class="spoiler"><p>4141414141414141414141414141414141022042424242424242424242424242424242424242424242423a46</p><p>4242424242424242424242424242424242</p></div>]]></content><author><name>jiva</name></author><category term="blog" /><category term="microcorruption" /><category term="CTF" /><category term="writeup" /><category term="reverse engineering" /><category term="assembly" /><category term="hacking" /><summary type="html"><![CDATA[Microcorruption CTF Santa Cruz Write-up]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jiva.io/assets/images/writeups/microcorruption.png" /><media:content medium="image" url="https://jiva.io/assets/images/writeups/microcorruption.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Microcorruption CTF Johannesburg Write-up</title><link href="https://jiva.io/blog/microcorruption-ctf-writeup-johannesburg" rel="alternate" type="text/html" title="Microcorruption CTF Johannesburg Write-up" /><published>2017-09-05T22:22:00+00:00</published><updated>2017-09-05T22:22:00+00:00</updated><id>https://jiva.io/blog/microcorruption-ctf-writeup-johannesburg</id><content type="html" xml:base="https://jiva.io/blog/microcorruption-ctf-writeup-johannesburg"><![CDATA[<h2 id="summary">Summary:</h2>

<p>This is a write-up of my solution to the <a href="https://microcorruption.com/">Microcorruption CTF</a>
challenge “Johannesburg” (<code class="language-plaintext highlighter-rouge">LOCKIT PRO r b.04</code>).</p>

<p>This challenge does away with <code class="language-plaintext highlighter-rouge">printf()</code> altogether. Probably for the best.
Let’s check out what they have up their sleeve for this one.</p>
<style type="text/css">
  .gist-file
  .gist-data {max-height: 500px;}
</style>

<noscript><pre>0010 &lt;__trap_interrupt&gt;
0010:  3041           ret
4400 &lt;__init_stack&gt;
4400:  3140 0044      mov	#0x4400, sp
4404 &lt;__low_level_init&gt;
4404:  1542 5c01      mov	&amp;0x015c, r5
4408:  75f3           and.b	#-0x1, r5
440a:  35d0 085a      bis	#0x5a08, r5
440e &lt;__do_copy_data&gt;
440e:  3f40 0000      clr	r15
4412:  0f93           tst	r15
4414:  0724           jz	#0x4424 &lt;__do_clear_bss+0x0&gt;
4416:  8245 5c01      mov	r5, &amp;0x015c
441a:  2f83           decd	r15
441c:  9f4f 3a46 0024 mov	0x463a(r15), 0x2400(r15)
4422:  f923           jnz	#0x4416 &lt;__do_copy_data+0x8&gt;
4424 &lt;__do_clear_bss&gt;
4424:  3f40 6400      mov	#0x64, r15
4428:  0f93           tst	r15
442a:  0624           jz	#0x4438 &lt;main+0x0&gt;
442c:  8245 5c01      mov	r5, &amp;0x015c
4430:  1f83           dec	r15
4432:  cf43 0024      mov.b	#0x0, 0x2400(r15)
4436:  fa23           jnz	#0x442c &lt;__do_clear_bss+0x8&gt;
4438 &lt;main&gt;
4438:  b012 2c45      call	#0x452c &lt;login&gt;
443c &lt;__stop_progExec__&gt;
443c:  32d0 f000      bis	#0xf0, sr
4440:  fd3f           jmp	#0x443c &lt;__stop_progExec__+0x0&gt;
4442 &lt;__ctors_end&gt;
4442:  3040 3846      br	#0x4638 &lt;_unexpected_&gt;
4446 &lt;unlock_door&gt;
4446:  3012 7f00      push	#0x7f
444a:  b012 9445      call	#0x4594 &lt;INT&gt;
444e:  2153           incd	sp
4450:  3041           ret
4452 &lt;test_password_valid&gt;
4452:  0412           push	r4
4454:  0441           mov	sp, r4
4456:  2453           incd	r4
4458:  2183           decd	sp
445a:  c443 fcff      mov.b	#0x0, -0x4(r4)
445e:  3e40 fcff      mov	#0xfffc, r14
4462:  0e54           add	r4, r14
4464:  0e12           push	r14
4466:  0f12           push	r15
4468:  3012 7d00      push	#0x7d
446c:  b012 9445      call	#0x4594 &lt;INT&gt;
4470:  5f44 fcff      mov.b	-0x4(r4), r15
4474:  8f11           sxt	r15
4476:  3152           add	#0x8, sp
4478:  3441           pop	r4
447a:  3041           ret
447c .strings:
447c: &quot;Enter the password to continue.&quot;
449c: &quot;Remember: passwords are between 8 and 16 characters.&quot;
44d1: &quot;Access granted.&quot;
44e1: &quot;That password is not correct.&quot;
44ff: &quot;Invalid Password Length: password too long.&quot;
452b: &quot;&quot;
452c &lt;login&gt;
452c:  3150 eeff      add	#0xffee, sp
4530:  f140 ec00 1100 mov.b	#0xec, 0x11(sp)
4536:  3f40 7c44      mov	#0x447c &quot;Enter the password to continue.&quot;, r15
453a:  b012 f845      call	#0x45f8 &lt;puts&gt;
453e:  3f40 9c44      mov	#0x449c &quot;Remember: passwords are between 8 and 16 characters.&quot;, r15
4542:  b012 f845      call	#0x45f8 &lt;puts&gt;
4546:  3e40 3f00      mov	#0x3f, r14
454a:  3f40 0024      mov	#0x2400, r15
454e:  b012 e845      call	#0x45e8 &lt;getsn&gt;
4552:  3e40 0024      mov	#0x2400, r14
4556:  0f41           mov	sp, r15
4558:  b012 2446      call	#0x4624 &lt;strcpy&gt;
455c:  0f41           mov	sp, r15
455e:  b012 5244      call	#0x4452 &lt;test_password_valid&gt;
4562:  0f93           tst	r15
4564:  0524           jz	#0x4570 &lt;login+0x44&gt;
4566:  b012 4644      call	#0x4446 &lt;unlock_door&gt;
456a:  3f40 d144      mov	#0x44d1 &quot;Access granted.&quot;, r15
456e:  023c           jmp	#0x4574 &lt;login+0x48&gt;
4570:  3f40 e144      mov	#0x44e1 &quot;That password is not correct.&quot;, r15
4574:  b012 f845      call	#0x45f8 &lt;puts&gt;
4578:  f190 ec00 1100 cmp.b	#0xec, 0x11(sp)
457e:  0624           jeq	#0x458c &lt;login+0x60&gt;
4580:  3f40 ff44      mov	#0x44ff &quot;Invalid Password Length: password too long.&quot;, r15
4584:  b012 f845      call	#0x45f8 &lt;puts&gt;
4588:  3040 3c44      br	#0x443c &lt;__stop_progExec__&gt;
458c:  3150 1200      add	#0x12, sp
4590:  3041           ret
4592 &lt;__do_nothing&gt;
4592:  3041           ret
4594 &lt;INT&gt;
4594:  1e41 0200      mov	0x2(sp), r14
4598:  0212           push	sr
459a:  0f4e           mov	r14, r15
459c:  8f10           swpb	r15
459e:  024f           mov	r15, sr
45a0:  32d0 0080      bis	#0x8000, sr
45a4:  b012 1000      call	#0x10
45a8:  3241           pop	sr
45aa:  3041           ret
45ac &lt;putchar&gt;
45ac:  2183           decd	sp
45ae:  0f12           push	r15
45b0:  0312           push	#0x0
45b2:  814f 0400      mov	r15, 0x4(sp)
45b6:  b012 9445      call	#0x4594 &lt;INT&gt;
45ba:  1f41 0400      mov	0x4(sp), r15
45be:  3150 0600      add	#0x6, sp
45c2:  3041           ret
45c4 &lt;getchar&gt;
45c4:  0412           push	r4
45c6:  0441           mov	sp, r4
45c8:  2453           incd	r4
45ca:  2183           decd	sp
45cc:  3f40 fcff      mov	#0xfffc, r15
45d0:  0f54           add	r4, r15
45d2:  0f12           push	r15
45d4:  1312           push	#0x1
45d6:  b012 9445      call	#0x4594 &lt;INT&gt;
45da:  5f44 fcff      mov.b	-0x4(r4), r15
45de:  8f11           sxt	r15
45e0:  3150 0600      add	#0x6, sp
45e4:  3441           pop	r4
45e6:  3041           ret
45e8 &lt;getsn&gt;
45e8:  0e12           push	r14
45ea:  0f12           push	r15
45ec:  2312           push	#0x2
45ee:  b012 9445      call	#0x4594 &lt;INT&gt;
45f2:  3150 0600      add	#0x6, sp
45f6:  3041           ret
45f8 &lt;puts&gt;
45f8:  0b12           push	r11
45fa:  0b4f           mov	r15, r11
45fc:  073c           jmp	#0x460c &lt;puts+0x14&gt;
45fe:  1b53           inc	r11
4600:  8f11           sxt	r15
4602:  0f12           push	r15
4604:  0312           push	#0x0
4606:  b012 9445      call	#0x4594 &lt;INT&gt;
460a:  2152           add	#0x4, sp
460c:  6f4b           mov.b	@r11, r15
460e:  4f93           tst.b	r15
4610:  f623           jnz	#0x45fe &lt;puts+0x6&gt;
4612:  3012 0a00      push	#0xa
4616:  0312           push	#0x0
4618:  b012 9445      call	#0x4594 &lt;INT&gt;
461c:  2152           add	#0x4, sp
461e:  0f43           clr	r15
4620:  3b41           pop	r11
4622:  3041           ret
4624 &lt;strcpy&gt;
4624:  0d4f           mov	r15, r13
4626:  023c           jmp	#0x462c &lt;strcpy+0x8&gt;
4628:  1e53           inc	r14
462a:  1d53           inc	r13
462c:  6c4e           mov.b	@r14, r12
462e:  cd4c 0000      mov.b	r12, 0x0(r13)
4632:  4c93           tst.b	r12
4634:  f923           jnz	#0x4628 &lt;strcpy+0x4&gt;
4636:  3041           ret
4638 &lt;_unexpected_&gt;
4638:  0013           reti	pc</pre></noscript>
<script src="https://gist.github.com/jiva/80397fb01a37e305dc521a92eb81fc55.js"> </script>

<p>Let’s try running the program with <code class="language-plaintext highlighter-rouge">AAAAAAAAAAAAAAAAAAAA</code> and see what happens…</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_johannesburg_20a.png" alt="Johannesburg 20A" /></p>

<p>We see the message <code class="language-plaintext highlighter-rouge">Invalid Password Length: password too long</code>. It appears as if they
may have finally implemented proper bounds checking. I’m still a little suspicious. Let’s
try a lot more <code class="language-plaintext highlighter-rouge">A's</code> (like 100 or so)…</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_johannesburg_100a.png" alt="Johannesburg 100A" /></p>

<p>In addition to the password length message, we notice a few more things:</p>
<ul>
  <li>More than 16 bytes were allowed to be input</li>
  <li>We actually overwrote part of the data segment in memory (e.g. see <code class="language-plaintext highlighter-rouge">[overwritten]</code>)</li>
  <li>The user input is actually being copied to a higher location in memory</li>
</ul>

<p>Since <code class="language-plaintext highlighter-rouge">main()</code> only calls <code class="language-plaintext highlighter-rouge">login()</code>, let’s dissect it and see how it works:</p>
<noscript><pre>452c &lt;login&gt;
452c:  3150 eeff      add	#0xffee, sp
4530:  f140 ec00 1100 mov.b	#0xec, 0x11(sp)
4536:  3f40 7c44      mov	#0x447c &quot;Enter the password to continue.&quot;, r15
453a:  b012 f845      call	#0x45f8 &lt;puts&gt;
453e:  3f40 9c44      mov	#0x449c &quot;Remember: passwords are between 8 and 16 characters.&quot;, r15
4542:  b012 f845      call	#0x45f8 &lt;puts&gt;
4546:  3e40 3f00      mov	#0x3f, r14
454a:  3f40 0024      mov	#0x2400, r15
454e:  b012 e845      call	#0x45e8 &lt;getsn&gt;
4552:  3e40 0024      mov	#0x2400, r14
4556:  0f41           mov	sp, r15
4558:  b012 2446      call	#0x4624 &lt;strcpy&gt;
455c:  0f41           mov	sp, r15
455e:  b012 5244      call	#0x4452 &lt;test_password_valid&gt;
4562:  0f93           tst	r15
4564:  0524           jz	#0x4570 &lt;login+0x44&gt;
4566:  b012 4644      call	#0x4446 &lt;unlock_door&gt;
456a:  3f40 d144      mov	#0x44d1 &quot;Access granted.&quot;, r15
456e:  023c           jmp	#0x4574 &lt;login+0x48&gt;
4570:  3f40 e144      mov	#0x44e1 &quot;That password is not correct.&quot;, r15
4574:  b012 f845      call	#0x45f8 &lt;puts&gt;
4578:  f190 ec00 1100 cmp.b	#0xec, 0x11(sp)
457e:  0624           jeq	#0x458c &lt;login+0x60&gt;
4580:  3f40 ff44      mov	#0x44ff &quot;Invalid Password Length: password too long.&quot;, r15
4584:  b012 f845      call	#0x45f8 &lt;puts&gt;
4588:  3040 3c44      br	#0x443c &lt;__stop_progExec__&gt;
458c:  3150 1200      add	#0x12, sp
4590:  3041           ret</pre></noscript>
<script src="https://gist.github.com/jiva/44f89a44a03914c7e87432d1b0ea84d6.js"> </script>

<p>After prompting the user for input, <code class="language-plaintext highlighter-rouge">strcpy()</code> is eventually called 
and our user input is copied onto the stack. This is where things get a little interesting.
After returning from the call to <code class="language-plaintext highlighter-rouge">test_password_valid()</code>, we eventually execute the <code class="language-plaintext highlighter-rouge">jz #0x4570</code>
instruction which will jump us to <code class="language-plaintext highlighter-rouge">0x4570</code>, which will execute a <code class="language-plaintext highlighter-rouge">puts()</code> call
on the string <code class="language-plaintext highlighter-rouge">That password is not correct</code>. Immediately after, we execute the instruction 
<code class="language-plaintext highlighter-rouge">cmp.b  #0xec, 0x11(sp)</code>, and then <code class="language-plaintext highlighter-rouge">jeq #0x458c &lt;login+0x60&gt;</code>. That’s a really strange <code class="language-plaintext highlighter-rouge">cmp</code>
instruction - the code is checking to see if the memory location after the buffer on
the stack is <code class="language-plaintext highlighter-rouge">0xec</code>, and if it <em>isn’t</em>, proceeds to call <code class="language-plaintext highlighter-rouge">puts()</code> on
<code class="language-plaintext highlighter-rouge">Invalid Password Length: password too long</code>. Let’s set a break point on that <code class="language-plaintext highlighter-rouge">cmp</code> instruction
and check out what the debugger looks like when it pauses. We’ll try using 10 <code class="language-plaintext highlighter-rouge">A's</code> this time,
so as to not corrupt any memory…</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_johannesburg_10a_break_cmp.png" alt="Johannesburg 10A Break cmp" /></p>

<p>It looks like the code is using a hard-coded stack canary (which lives at <code class="language-plaintext highlighter-rouge">0x43fd</code>)!
If the canary is over-written, the program uses this logic to assume that the length of the 
user input was too long. However, we can control what’s overwritten memory location of the stack canary - Great!</p>

<p>Right after the location of the stack canary in memory, we see another interesting pair of bytes:
<code class="language-plaintext highlighter-rouge">0x3c44</code> (or when reversed, <code class="language-plaintext highlighter-rouge">0x44c3</code>). Recall the memory values after the call to <code class="language-plaintext highlighter-rouge">main()</code>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>4438 &lt;main&gt;
4438:  b012 2c45      call	#0x452c &lt;login&gt;
443c &lt;__stop_progExec__&gt;
443c:  32d0 f000      bis	#0xf0, sr
</code></pre></div></div>

<p>As it turns out, <code class="language-plaintext highlighter-rouge">0x443c</code> is the return address pushed onto the stack from the call to <code class="language-plaintext highlighter-rouge">login()</code>
from <code class="language-plaintext highlighter-rouge">main()</code>, which is conveniently placed <em>right after</em> the value of the stack canary in memory!
Sounds like we’re ready to craft our exploit. We’ll load up the buffer with <code class="language-plaintext highlighter-rouge">A's</code>, place the
stack canary value <code class="language-plaintext highlighter-rouge">0x3c</code> at the 18th byte offset, and we’ll overwrite the return address to <code class="language-plaintext highlighter-rouge">0x4566</code>
(the call to <code class="language-plaintext highlighter-rouge">unlock_door()</code> from <code class="language-plaintext highlighter-rouge">login()</code>)…</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_johannesburg_solve.png" alt="Johannesburg solve" /></p>

<p>:+1: :beers:</p>

<h3 id="flag-mouse-over-to-reveal">Flag (mouse over to reveal)</h3>
<div class="spoiler"><p>4141414141414141414141414141414141ec6645</p></div>]]></content><author><name>jiva</name></author><category term="blog" /><category term="microcorruption" /><category term="CTF" /><category term="writeup" /><category term="reverse engineering" /><category term="assembly" /><category term="hacking" /><summary type="html"><![CDATA[Microcorruption CTF Johannesburg Write-up]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jiva.io/assets/images/writeups/microcorruption.png" /><media:content medium="image" url="https://jiva.io/assets/images/writeups/microcorruption.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Microcorruption CTF Addis Ababa Write-up</title><link href="https://jiva.io/blog/microcorruption-ctf-writeup-addis-ababa" rel="alternate" type="text/html" title="Microcorruption CTF Addis Ababa Write-up" /><published>2017-09-03T18:04:00+00:00</published><updated>2017-09-03T18:04:00+00:00</updated><id>https://jiva.io/blog/microcorruption-ctf-writeup-addis-ababa</id><content type="html" xml:base="https://jiva.io/blog/microcorruption-ctf-writeup-addis-ababa"><![CDATA[<h2 id="summary">Summary:</h2>

<p>This is a write-up of my solution to the <a href="https://microcorruption.com/">Microcorruption CTF</a> challenge “Addis Ababa” (<code class="language-plaintext highlighter-rouge">LOCKIT PRO r b.03</code>).</p>

<p>Right off the bat, in the description of the challenge, we get a hint dropped:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>OVERVIEW
    - We have verified passwords can not be too long.
    - Usernames are printed back to the user for verification.
    - This lock is attached the the LockIT Pro HSM-1.
</code></pre></div></div>

<p>Let’s see exactly how the program is going to print back the usernames to the user…</p>
<style type="text/css">
  .gist-file
  .gist-data {max-height: 500px;}
</style>

<noscript><pre>0010 &lt;__trap_interrupt&gt;
0010:  3041           ret
4400 &lt;__init_stack&gt;
4400:  3140 da40      mov	#0x40da, sp
4404 &lt;__low_level_init&gt;
4404:  1542 5c01      mov	&amp;0x015c, r5
4408:  75f3           and.b	#-0x1, r5
440a:  35d0 085a      bis	#0x5a08, r5
440e &lt;__do_copy_data&gt;
440e:  3f40 0000      clr	r15
4412:  0f93           tst	r15
4414:  0724           jz	#0x4424 &lt;__do_clear_bss+0x0&gt;
4416:  8245 5c01      mov	r5, &amp;0x015c
441a:  2f83           decd	r15
441c:  9f4f f446 0024 mov	0x46f4(r15), 0x2400(r15)
4422:  f923           jnz	#0x4416 &lt;__do_copy_data+0x8&gt;
4424 &lt;__do_clear_bss&gt;
4424:  3f40 1400      mov	#0x14, r15
4428:  0f93           tst	r15
442a:  0624           jz	#0x4438 &lt;main+0x0&gt;
442c:  8245 5c01      mov	r5, &amp;0x015c
4430:  1f83           dec	r15
4432:  cf43 0024      mov.b	#0x0, 0x2400(r15)
4436:  fa23           jnz	#0x442c &lt;__do_clear_bss+0x8&gt;
4438 &lt;main&gt;
4438:  3150 eaff      add	#0xffea, sp
443c:  8143 0000      clr	0x0(sp)
4440:  3012 e644      push	#0x44e6 &quot;Login with username:password below to authenticate.\n&quot;
4444:  b012 c845      call	#0x45c8 &lt;printf&gt;
4448:  b140 1b45 0000 mov	#0x451b &quot;&gt;&gt; &quot;, 0x0(sp)
444e:  b012 c845      call	#0x45c8 &lt;printf&gt;
4452:  2153           incd	sp
4454:  3e40 1300      mov	#0x13, r14
4458:  3f40 0024      mov	#0x2400, r15
445c:  b012 8c45      call	#0x458c &lt;getsn&gt;
4460:  0b41           mov	sp, r11
4462:  2b53           incd	r11
4464:  3e40 0024      mov	#0x2400, r14
4468:  0f4b           mov	r11, r15
446a:  b012 de46      call	#0x46de &lt;strcpy&gt;
446e:  3f40 0024      mov	#0x2400, r15
4472:  b012 b044      call	#0x44b0 &lt;test_password_valid&gt;
4476:  814f 0000      mov	r15, 0x0(sp)
447a:  0b12           push	r11
447c:  b012 c845      call	#0x45c8 &lt;printf&gt;
4480:  2153           incd	sp
4482:  3f40 0a00      mov	#0xa, r15
4486:  b012 5045      call	#0x4550 &lt;putchar&gt;
448a:  8193 0000      tst	0x0(sp)
448e:  0324           jz	#0x4496 &lt;main+0x5e&gt;
4490:  b012 da44      call	#0x44da &lt;unlock_door&gt;
4494:  053c           jmp	#0x44a0 &lt;main+0x68&gt;
4496:  3012 1f45      push	#0x451f &quot;That entry is not valid.&quot;
449a:  b012 c845      call	#0x45c8 &lt;printf&gt;
449e:  2153           incd	sp
44a0:  0f43           clr	r15
44a2:  3150 1600      add	#0x16, sp
44a6 &lt;__stop_progExec__&gt;
44a6:  32d0 f000      bis	#0xf0, sr
44aa:  fd3f           jmp	#0x44a6 &lt;__stop_progExec__+0x0&gt;
44ac &lt;__ctors_end&gt;
44ac:  3040 f246      br	#0x46f2 &lt;_unexpected_&gt;
44b0 &lt;test_password_valid&gt;
44b0:  0412           push	r4
44b2:  0441           mov	sp, r4
44b4:  2453           incd	r4
44b6:  2183           decd	sp
44b8:  c443 fcff      mov.b	#0x0, -0x4(r4)
44bc:  3e40 fcff      mov	#0xfffc, r14
44c0:  0e54           add	r4, r14
44c2:  0e12           push	r14
44c4:  0f12           push	r15
44c6:  3012 7d00      push	#0x7d
44ca:  b012 3845      call	#0x4538 &lt;INT&gt;
44ce:  5f44 fcff      mov.b	-0x4(r4), r15
44d2:  8f11           sxt	r15
44d4:  3152           add	#0x8, sp
44d6:  3441           pop	r4
44d8:  3041           ret
44da &lt;unlock_door&gt;
44da:  3012 7f00      push	#0x7f
44de:  b012 3845      call	#0x4538 &lt;INT&gt;
44e2:  2153           incd	sp
44e4:  3041           ret
44e6 .strings:
44e6: &quot;Login with username:password below to authenticate.\n&quot;
451b: &quot;&gt;&gt; &quot;
451f: &quot;That entry is not valid.&quot;
4538 &lt;INT&gt;
4538:  1e41 0200      mov	0x2(sp), r14
453c:  0212           push	sr
453e:  0f4e           mov	r14, r15
4540:  8f10           swpb	r15
4542:  024f           mov	r15, sr
4544:  32d0 0080      bis	#0x8000, sr
4548:  b012 1000      call	#0x10
454c:  3241           pop	sr
454e:  3041           ret
4550 &lt;putchar&gt;
4550:  2183           decd	sp
4552:  0f12           push	r15
4554:  0312           push	#0x0
4556:  814f 0400      mov	r15, 0x4(sp)
455a:  b012 3845      call	#0x4538 &lt;INT&gt;
455e:  1f41 0400      mov	0x4(sp), r15
4562:  3150 0600      add	#0x6, sp
4566:  3041           ret
4568 &lt;getchar&gt;
4568:  0412           push	r4
456a:  0441           mov	sp, r4
456c:  2453           incd	r4
456e:  2183           decd	sp
4570:  3f40 fcff      mov	#0xfffc, r15
4574:  0f54           add	r4, r15
4576:  0f12           push	r15
4578:  1312           push	#0x1
457a:  b012 3845      call	#0x4538 &lt;INT&gt;
457e:  5f44 fcff      mov.b	-0x4(r4), r15
4582:  8f11           sxt	r15
4584:  3150 0600      add	#0x6, sp
4588:  3441           pop	r4
458a:  3041           ret
458c &lt;getsn&gt;
458c:  0e12           push	r14
458e:  0f12           push	r15
4590:  2312           push	#0x2
4592:  b012 3845      call	#0x4538 &lt;INT&gt;
4596:  3150 0600      add	#0x6, sp
459a:  3041           ret
459c &lt;puts&gt;
459c:  0b12           push	r11
459e:  0b4f           mov	r15, r11
45a0:  073c           jmp	#0x45b0 &lt;puts+0x14&gt;
45a2:  1b53           inc	r11
45a4:  8f11           sxt	r15
45a6:  0f12           push	r15
45a8:  0312           push	#0x0
45aa:  b012 3845      call	#0x4538 &lt;INT&gt;
45ae:  2152           add	#0x4, sp
45b0:  6f4b           mov.b	@r11, r15
45b2:  4f93           tst.b	r15
45b4:  f623           jnz	#0x45a2 &lt;puts+0x6&gt;
45b6:  3012 0a00      push	#0xa
45ba:  0312           push	#0x0
45bc:  b012 3845      call	#0x4538 &lt;INT&gt;
45c0:  2152           add	#0x4, sp
45c2:  0f43           clr	r15
45c4:  3b41           pop	r11
45c6:  3041           ret
45c8 &lt;printf&gt;
45c8:  0b12           push	r11
45ca:  0a12           push	r10
45cc:  0912           push	r9
45ce:  0812           push	r8
45d0:  0712           push	r7
45d2:  0412           push	r4
45d4:  0441           mov	sp, r4
45d6:  3450 0c00      add	#0xc, r4
45da:  2183           decd	sp
45dc:  1b44 0200      mov	0x2(r4), r11
45e0:  8441 f2ff      mov	sp, -0xe(r4)
45e4:  0f4b           mov	r11, r15
45e6:  0e43           clr	r14
45e8:  0b3c           jmp	#0x4600 &lt;printf+0x38&gt;
45ea:  1f53           inc	r15
45ec:  7d90 2500      cmp.b	#0x25, r13
45f0:  0720           jne	#0x4600 &lt;printf+0x38&gt;
45f2:  6d9f           cmp.b	@r15, r13
45f4:  0320           jne	#0x45fc &lt;printf+0x34&gt;
45f6:  1f53           inc	r15
45f8:  0d43           clr	r13
45fa:  013c           jmp	#0x45fe &lt;printf+0x36&gt;
45fc:  1d43           mov	#0x1, r13
45fe:  0e5d           add	r13, r14
4600:  6d4f           mov.b	@r15, r13
4602:  4d93           tst.b	r13
4604:  f223           jnz	#0x45ea &lt;printf+0x22&gt;
4606:  0f4e           mov	r14, r15
4608:  0f5f           add	r15, r15
460a:  2f53           incd	r15
460c:  018f           sub	r15, sp
460e:  0941           mov	sp, r9
4610:  0c44           mov	r4, r12
4612:  2c52           add	#0x4, r12
4614:  0f41           mov	sp, r15
4616:  0d43           clr	r13
4618:  053c           jmp	#0x4624 &lt;printf+0x5c&gt;
461a:  af4c 0000      mov	@r12, 0x0(r15)
461e:  1d53           inc	r13
4620:  2f53           incd	r15
4622:  2c53           incd	r12
4624:  0d9e           cmp	r14, r13
4626:  f93b           jl	#0x461a &lt;printf+0x52&gt;
4628:  0a43           clr	r10
462a:  3740 0900      mov	#0x9, r7
462e:  4a3c           jmp	#0x46c4 &lt;printf+0xfc&gt;
4630:  084b           mov	r11, r8
4632:  1853           inc	r8
4634:  7f90 2500      cmp.b	#0x25, r15
4638:  0624           jeq	#0x4646 &lt;printf+0x7e&gt;
463a:  1a53           inc	r10
463c:  0b48           mov	r8, r11
463e:  8f11           sxt	r15
4640:  b012 5045      call	#0x4550 &lt;putchar&gt;
4644:  3f3c           jmp	#0x46c4 &lt;printf+0xfc&gt;
4646:  6e48           mov.b	@r8, r14
4648:  4e9f           cmp.b	r15, r14
464a:  0620           jne	#0x4658 &lt;printf+0x90&gt;
464c:  1a53           inc	r10
464e:  3f40 2500      mov	#0x25, r15
4652:  b012 5045      call	#0x4550 &lt;putchar&gt;
4656:  333c           jmp	#0x46be &lt;printf+0xf6&gt;
4658:  7e90 7300      cmp.b	#0x73, r14
465c:  0b20           jne	#0x4674 &lt;printf+0xac&gt;
465e:  2b49           mov	@r9, r11
4660:  053c           jmp	#0x466c &lt;printf+0xa4&gt;
4662:  1a53           inc	r10
4664:  1b53           inc	r11
4666:  8f11           sxt	r15
4668:  b012 5045      call	#0x4550 &lt;putchar&gt;
466c:  6f4b           mov.b	@r11, r15
466e:  4f93           tst.b	r15
4670:  f823           jnz	#0x4662 &lt;printf+0x9a&gt;
4672:  253c           jmp	#0x46be &lt;printf+0xf6&gt;
4674:  7e90 7800      cmp.b	#0x78, r14
4678:  1c20           jne	#0x46b2 &lt;printf+0xea&gt;
467a:  2b49           mov	@r9, r11
467c:  173c           jmp	#0x46ac &lt;printf+0xe4&gt;
467e:  0f4b           mov	r11, r15
4680:  8f10           swpb	r15
4682:  3ff0 ff00      and	#0xff, r15
4686:  12c3           clrc
4688:  0f10           rrc	r15
468a:  0f11           rra	r15
468c:  0f11           rra	r15
468e:  0f11           rra	r15
4690:  1a53           inc	r10
4692:  079f           cmp	r15, r7
4694:  0338           jl	#0x469c &lt;printf+0xd4&gt;
4696:  3f50 3000      add	#0x30, r15
469a:  023c           jmp	#0x46a0 &lt;printf+0xd8&gt;
469c:  3f50 5700      add	#0x57, r15
46a0:  b012 5045      call	#0x4550 &lt;putchar&gt;
46a4:  0b5b           add	r11, r11
46a6:  0b5b           add	r11, r11
46a8:  0b5b           add	r11, r11
46aa:  0b5b           add	r11, r11
46ac:  0b93           tst	r11
46ae:  e723           jnz	#0x467e &lt;printf+0xb6&gt;
46b0:  063c           jmp	#0x46be &lt;printf+0xf6&gt;
46b2:  7e90 6e00      cmp.b	#0x6e, r14
46b6:  0320           jne	#0x46be &lt;printf+0xf6&gt;
46b8:  2f49           mov	@r9, r15
46ba:  8f4a 0000      mov	r10, 0x0(r15)
46be:  2953           incd	r9
46c0:  0b48           mov	r8, r11
46c2:  1b53           inc	r11
46c4:  6f4b           mov.b	@r11, r15
46c6:  4f93           tst.b	r15
46c8:  b323           jnz	#0x4630 &lt;printf+0x68&gt;
46ca:  1144 f2ff      mov	-0xe(r4), sp
46ce:  2153           incd	sp
46d0:  3441           pop	r4
46d2:  3741           pop	r7
46d4:  3841           pop	r8
46d6:  3941           pop	r9
46d8:  3a41           pop	r10
46da:  3b41           pop	r11
46dc:  3041           ret
46de &lt;strcpy&gt;
46de:  0d4f           mov	r15, r13
46e0:  023c           jmp	#0x46e6 &lt;strcpy+0x8&gt;
46e2:  1e53           inc	r14
46e4:  1d53           inc	r13
46e6:  6c4e           mov.b	@r14, r12
46e8:  cd4c 0000      mov.b	r12, 0x0(r13)
46ec:  4c93           tst.b	r12
46ee:  f923           jnz	#0x46e2 &lt;strcpy+0x4&gt;
46f0:  3041           ret
46f2 &lt;_unexpected_&gt;
46f2:  0013           reti	pc</pre></noscript>
<script src="https://gist.github.com/jiva/83e0fb5e80e3af9be15034d00509a0ce.js"> </script>

<p>This code is significantly larger than the last one. However, it’s very clear that they changed
one major thing: the use of <code class="language-plaintext highlighter-rouge">printf()</code> instead of <code class="language-plaintext highlighter-rouge">puts()</code>.</p>

<p>Let’s just play around with the inputs and see what the program spits back out…</p>

<p class="img"><img src="/assets/images/writeups/microcorruption_addis-ababa_testinput1.png" alt="Addis Ababa Test Input 1" /></p>
<p>It looks like whatever input string we give it (e.g. <code class="language-plaintext highlighter-rouge">AAA:BBB</code>), the program will print back. 
All signs are pointing to a format string vulnerability, but let’s verify that’s actually the case by
throwing a few <code class="language-plaintext highlighter-rouge">%x's</code> at it and seeing if we get anything interesting back…</p>

<p class="img"><img src="/assets/images/writeups/microcorruption_addis-ababa_testinput2.png" alt="Addis Ababa Test Input 2" /></p>
<p>Sweet! Upon inputting <code class="language-plaintext highlighter-rouge">AA%x%x</code>, we get the output <code class="language-plaintext highlighter-rouge">AA4141</code>, which means 
that we are reading two 1-byte hex-encoded parameters from the stack (i.e. the <code class="language-plaintext highlighter-rouge">A's</code> at the beginning of our input).
I won’t spend time explaining how format string vulnerabilities work in this writeup, but you can check out
<a href="/assets/files/formatstring-1.2.pdf">scut’s whitepaper “Exploiting Format String Vulnerabilities”</a> for a useful guide.</p>

<p>Now let’s try and see if we can use <code class="language-plaintext highlighter-rouge">%n</code> to write to a location in memory. I’ll use the input value
<code class="language-plaintext highlighter-rouge">BA%x%n</code> to start with. Also, I’ll set a breakpoint at memory location <code class="language-plaintext highlighter-rouge">0x46b2</code> inside of <code class="language-plaintext highlighter-rouge">login()</code>,
which is the <code class="language-plaintext highlighter-rouge">cmp.b   #0x6e, r14</code> instruction. This should allow us to break on the handling of the 
<code class="language-plaintext highlighter-rouge">%n</code> (<code class="language-plaintext highlighter-rouge">n</code> == <code class="language-plaintext highlighter-rouge">0x6e</code>) format string parameter and lets us examine the registers and memory during execution.</p>

<p class="video"><iframe width="640" height="360" src="https://player.vimeo.com/video/232296541?color=6abd45&amp;title=0&amp;byline=0&amp;portrait=0" frameborder="0" allowfullscreen=""></iframe></p>
<p>As you can see, by using the <code class="language-plaintext highlighter-rouge">%n</code> parameter, we were able to overwrite the memory address <code class="language-plaintext highlighter-rouge">0x4142</code> (e.g. <code class="language-plaintext highlighter-rouge">BA</code>, the first
two bytes of our input) with the value that was in register <code class="language-plaintext highlighter-rouge">r10</code>
(i.e. <code class="language-plaintext highlighter-rouge">0x2</code>, the number of bytes written out by <code class="language-plaintext highlighter-rouge">printf()</code>). Great!</p>

<p>Now, let’s take a step back and see exactly what we need to do to unlock the door…</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>4472:  b012 b044      call	#0x44b0 &lt;test_password_valid&gt;
4476:  814f 0000      mov	r15, 0x0(sp)
447a:  0b12           push	r11
447c:  b012 c845      call	#0x45c8 &lt;printf&gt;
4480:  2153           incd	sp
4482:  3f40 0a00      mov	#0xa, r15
4486:  b012 5045      call	#0x4550 &lt;putchar&gt;
448a:  8193 0000      tst	0x0(sp)
448e:  0324           jz	#0x4496 &lt;main+0x5e&gt;
4490:  b012 da44      call	#0x44da &lt;unlock_door&gt;
4494:  053c           jmp	#0x44a0 &lt;main+0x68&gt;
4496:  3012 1f45      push	#0x451f "That entry is not valid."
449a:  b012 c845      call	#0x45c8 &lt;printf&gt;
</code></pre></div></div>

<p>Inside of <code class="language-plaintext highlighter-rouge">main()</code>, we can see that after the call to <code class="language-plaintext highlighter-rouge">printf()</code> returns, the instruction <code class="language-plaintext highlighter-rouge">tst  0x0(sp)</code>
will execute. This instruction will test the <code class="language-plaintext highlighter-rouge">sp</code> register against <code class="language-plaintext highlighter-rouge">0x0</code>, and will <em>jump over</em> the 
<code class="language-plaintext highlighter-rouge">unlock_door()</code> call if it’s zero. Let’s set a breakpoint this on instruction and
input <code class="language-plaintext highlighter-rouge">AAAA</code> and see what the registers look like…</p>

<p class="img"><img src="/assets/images/writeups/microcorruption_addis-ababa_testinput3.png" alt="Addis Ababa Test Input 3" /></p>
<p>Looks like <code class="language-plaintext highlighter-rouge">0x40c4</code> has a <code class="language-plaintext highlighter-rouge">0x0</code> value and indeed prevents the call to <code class="language-plaintext highlighter-rouge">unlock_door()</code> from executing.
I wonder what will happen if we use our newly weaponized format string vulnerability and write
a non-zero value to the <code class="language-plaintext highlighter-rouge">sp</code> register (location <code class="language-plaintext highlighter-rouge">0x40c4</code>)…</p>

<p class="img"><img src="/assets/images/writeups/microcorruption_addis-ababa_solve.png" alt="Addis Ababa Solve" /></p>

<p>:+1: :beers:</p>

<h3 id="flag-mouse-over-to-reveal">Flag (mouse over to reveal)</h3>
<div class="spoiler"><p>c4402578256e</p></div>]]></content><author><name>jiva</name></author><category term="blog" /><category term="microcorruption" /><category term="CTF" /><category term="writeup" /><category term="reverse engineering" /><category term="assembly" /><category term="hacking" /><summary type="html"><![CDATA[Microcorruption CTF Addis Ababa Write-up]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jiva.io/assets/images/writeups/microcorruption.png" /><media:content medium="image" url="https://jiva.io/assets/images/writeups/microcorruption.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Microcorruption CTF Cusco Write-up</title><link href="https://jiva.io/blog/microcorruption-ctf-writeup-cusco" rel="alternate" type="text/html" title="Microcorruption CTF Cusco Write-up" /><published>2017-08-31T20:11:00+00:00</published><updated>2017-08-31T20:11:00+00:00</updated><id>https://jiva.io/blog/microcorruption-ctf-writeup-cusco</id><content type="html" xml:base="https://jiva.io/blog/microcorruption-ctf-writeup-cusco"><![CDATA[<h2 id="summary">Summary:</h2>

<p>This is a write-up of my solution to the <a href="https://microcorruption.com/">Microcorruption CTF</a> challenge “Cusco” (<code class="language-plaintext highlighter-rouge">LOCKIT PRO r b.02</code>).</p>

<p>This version claims to fix the conditional flag overwrite issue that we exploited in the last challenge:</p>

<figure class="highlight"><pre><code class="language-raw" data-lang="raw">This is Software Revision 02. We have improved the security of the
lock by  removing a conditional  flag that could  accidentally get
set by passwords that were too long.</code></pre></figure>

<p>This indeed appears to be the case.
Let’s check out the entire program and then see if we can figure out what’s going on:</p>
<noscript><pre>0010 &lt;__trap_interrupt&gt;
0010:  3041           ret
4400 &lt;__init_stack&gt;
4400:  3140 0044      mov	#0x4400, sp
4404 &lt;__low_level_init&gt;
4404:  1542 5c01      mov	&amp;0x015c, r5
4408:  75f3           and.b	#-0x1, r5
440a:  35d0 085a      bis	#0x5a08, r5
440e &lt;__do_copy_data&gt;
440e:  3f40 0000      clr	r15
4412:  0f93           tst	r15
4414:  0724           jz	#0x4424 &lt;__do_clear_bss+0x0&gt;
4416:  8245 5c01      mov	r5, &amp;0x015c
441a:  2f83           decd	r15
441c:  9f4f d445 0024 mov	0x45d4(r15), 0x2400(r15)
4422:  f923           jnz	#0x4416 &lt;__do_copy_data+0x8&gt;
4424 &lt;__do_clear_bss&gt;
4424:  3f40 0000      clr	r15
4428:  0f93           tst	r15
442a:  0624           jz	#0x4438 &lt;main+0x0&gt;
442c:  8245 5c01      mov	r5, &amp;0x015c
4430:  1f83           dec	r15
4432:  cf43 0024      mov.b	#0x0, 0x2400(r15)
4436:  fa23           jnz	#0x442c &lt;__do_clear_bss+0x8&gt;
4438 &lt;main&gt;
4438:  b012 0045      call	#0x4500 &lt;login&gt;
443c &lt;__stop_progExec__&gt;
443c:  32d0 f000      bis	#0xf0, sr
4440:  fd3f           jmp	#0x443c &lt;__stop_progExec__+0x0&gt;
4442 &lt;__ctors_end&gt;
4442:  3040 d245      br	#0x45d2 &lt;_unexpected_&gt;
4446 &lt;unlock_door&gt;
4446:  3012 7f00      push	#0x7f
444a:  b012 4245      call	#0x4542 &lt;INT&gt;
444e:  2153           incd	sp
4450:  3041           ret
4452 &lt;test_password_valid&gt;
4452:  0412           push	r4
4454:  0441           mov	sp, r4
4456:  2453           incd	r4
4458:  2183           decd	sp
445a:  c443 fcff      mov.b	#0x0, -0x4(r4)
445e:  3e40 fcff      mov	#0xfffc, r14
4462:  0e54           add	r4, r14
4464:  0e12           push	r14
4466:  0f12           push	r15
4468:  3012 7d00      push	#0x7d
446c:  b012 4245      call	#0x4542 &lt;INT&gt;
4470:  5f44 fcff      mov.b	-0x4(r4), r15
4474:  8f11           sxt	r15
4476:  3152           add	#0x8, sp
4478:  3441           pop	r4
447a:  3041           ret
447c .strings:
447c: &quot;Enter the password to continue.&quot;
449c: &quot;Remember: passwords are between 8 and 16 characters.&quot;
44d1: &quot;Access granted.&quot;
44e1: &quot;That password is not correct.&quot;
44ff: &quot;&quot;
4500 &lt;login&gt;
4500:  3150 f0ff      add	#0xfff0, sp
4504:  3f40 7c44      mov	#0x447c &quot;Enter the password to continue.&quot;, r15
4508:  b012 a645      call	#0x45a6 &lt;puts&gt;
450c:  3f40 9c44      mov	#0x449c &quot;Remember: passwords are between 8 and 16 characters.&quot;, r15
4510:  b012 a645      call	#0x45a6 &lt;puts&gt;
4514:  3e40 3000      mov	#0x30, r14
4518:  0f41           mov	sp, r15
451a:  b012 9645      call	#0x4596 &lt;getsn&gt;
451e:  0f41           mov	sp, r15
4520:  b012 5244      call	#0x4452 &lt;test_password_valid&gt;
4524:  0f93           tst	r15
4526:  0524           jz	#0x4532 &lt;login+0x32&gt;
4528:  b012 4644      call	#0x4446 &lt;unlock_door&gt;
452c:  3f40 d144      mov	#0x44d1 &quot;Access granted.&quot;, r15
4530:  023c           jmp	#0x4536 &lt;login+0x36&gt;
4532:  3f40 e144      mov	#0x44e1 &quot;That password is not correct.&quot;, r15
4536:  b012 a645      call	#0x45a6 &lt;puts&gt;
453a:  3150 1000      add	#0x10, sp
453e:  3041           ret
4540 &lt;__do_nothing&gt;
4540:  3041           ret
4542 &lt;INT&gt;
4542:  1e41 0200      mov	0x2(sp), r14
4546:  0212           push	sr
4548:  0f4e           mov	r14, r15
454a:  8f10           swpb	r15
454c:  024f           mov	r15, sr
454e:  32d0 0080      bis	#0x8000, sr
4552:  b012 1000      call	#0x10
4556:  3241           pop	sr
4558:  3041           ret
455a &lt;putchar&gt;
455a:  2183           decd	sp
455c:  0f12           push	r15
455e:  0312           push	#0x0
4560:  814f 0400      mov	r15, 0x4(sp)
4564:  b012 4245      call	#0x4542 &lt;INT&gt;
4568:  1f41 0400      mov	0x4(sp), r15
456c:  3150 0600      add	#0x6, sp
4570:  3041           ret
4572 &lt;getchar&gt;
4572:  0412           push	r4
4574:  0441           mov	sp, r4
4576:  2453           incd	r4
4578:  2183           decd	sp
457a:  3f40 fcff      mov	#0xfffc, r15
457e:  0f54           add	r4, r15
4580:  0f12           push	r15
4582:  1312           push	#0x1
4584:  b012 4245      call	#0x4542 &lt;INT&gt;
4588:  5f44 fcff      mov.b	-0x4(r4), r15
458c:  8f11           sxt	r15
458e:  3150 0600      add	#0x6, sp
4592:  3441           pop	r4
4594:  3041           ret
4596 &lt;getsn&gt;
4596:  0e12           push	r14
4598:  0f12           push	r15
459a:  2312           push	#0x2
459c:  b012 4245      call	#0x4542 &lt;INT&gt;
45a0:  3150 0600      add	#0x6, sp
45a4:  3041           ret
45a6 &lt;puts&gt;
45a6:  0b12           push	r11
45a8:  0b4f           mov	r15, r11
45aa:  073c           jmp	#0x45ba &lt;puts+0x14&gt;
45ac:  1b53           inc	r11
45ae:  8f11           sxt	r15
45b0:  0f12           push	r15
45b2:  0312           push	#0x0
45b4:  b012 4245      call	#0x4542 &lt;INT&gt;
45b8:  2152           add	#0x4, sp
45ba:  6f4b           mov.b	@r11, r15
45bc:  4f93           tst.b	r15
45be:  f623           jnz	#0x45ac &lt;puts+0x6&gt;
45c0:  3012 0a00      push	#0xa
45c4:  0312           push	#0x0
45c6:  b012 4245      call	#0x4542 &lt;INT&gt;
45ca:  2152           add	#0x4, sp
45cc:  0f43           clr	r15
45ce:  3b41           pop	r11
45d0:  3041           ret
45d2 &lt;_unexpected_&gt;
45d2:  0013           reti	pc</pre></noscript>
<script src="https://gist.github.com/jiva/2d4b6c4cf2aa662b6d7ecd37363b4fee.js"> </script>

<p>So I’ll admit, this one took me a little longer to figure out. Let’s go through the
basic steps I took to see where I got stumped:</p>

<h3 id="main">main()</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>4438 &lt;main&gt;
4438:  b012 0045      call	#0x4500 &lt;login&gt;
</code></pre></div></div>
<p>All <code class="language-plaintext highlighter-rouge">main()</code> does is make a call to <code class="language-plaintext highlighter-rouge">login()</code>. Let’s follow <code class="language-plaintext highlighter-rouge">login()</code>…</p>

<h3 id="login">login()</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>4500 &lt;login&gt;
4500:  3150 f0ff      add	#0xfff0, sp
4504:  3f40 7c44      mov	#0x447c "Enter the password to continue.", r15
4508:  b012 a645      call	#0x45a6 &lt;puts&gt;
450c:  3f40 9c44      mov	#0x449c "Remember: passwords are between 8 and 16 characters.", r15
4510:  b012 a645      call	#0x45a6 &lt;puts&gt;
4514:  3e40 3000      mov	#0x30, r14
4518:  0f41           mov	sp, r15
451a:  b012 9645      call	#0x4596 &lt;getsn&gt;
451e:  0f41           mov	sp, r15
4520:  b012 5244      call	#0x4452 &lt;test_password_valid&gt;
4524:  0f93           tst	r15
4526:  0524           jz	#0x4532 &lt;login+0x32&gt;
4528:  b012 4644      call	#0x4446 &lt;unlock_door&gt;
452c:  3f40 d144      mov	#0x44d1 "Access granted.", r15
4530:  023c           jmp	#0x4536 &lt;login+0x36&gt;
4532:  3f40 e144      mov	#0x44e1 "That password is not correct.", r15
4536:  b012 a645      call	#0x45a6 &lt;puts&gt;
453a:  3150 1000      add	#0x10, sp
453e:  3041           ret
</code></pre></div></div>
<p>After a few calls to <code class="language-plaintext highlighter-rouge">puts()</code> to print out the password prompt message,
the code makes a call to <code class="language-plaintext highlighter-rouge">test_password_valid()</code>. Upon returning, <code class="language-plaintext highlighter-rouge">login()</code>
tests the value of <code class="language-plaintext highlighter-rouge">r15</code> (at <code class="language-plaintext highlighter-rouge">0x4524</code>). If <code class="language-plaintext highlighter-rouge">r15</code> is not <code class="language-plaintext highlighter-rouge">0</code>, we skip the <code class="language-plaintext highlighter-rouge">jz</code> instruction
at <code class="language-plaintext highlighter-rouge">0x4526</code> and proceed to <code class="language-plaintext highlighter-rouge">unlock_door()</code>. Let’s pay attention to <code class="language-plaintext highlighter-rouge">r15</code> while 
<code class="language-plaintext highlighter-rouge">test_password_valid()</code> is executing…</p>

<h3 id="test_password_valid">test_password_valid()</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>4452 &lt;test_password_valid&gt;
4452:  0412           push	r4
4454:  0441           mov	sp, r4
4456:  2453           incd	r4
4458:  2183           decd	sp
445a:  c443 fcff      mov.b	#0x0, -0x4(r4)
445e:  3e40 fcff      mov	#0xfffc, r14
4462:  0e54           add	r4, r14
4464:  0e12           push	r14
4466:  0f12           push	r15
4468:  3012 7d00      push	#0x7d
446c:  b012 4245      call	#0x4542 &lt;INT&gt;
4470:  5f44 fcff      mov.b	-0x4(r4), r15
4474:  8f11           sxt	r15
4476:  3152           add	#0x8, sp
4478:  3441           pop	r4
447a:  3041           ret
</code></pre></div></div>
<p>After shifting values inside of various registers/memory, the instruction <code class="language-plaintext highlighter-rouge">mov.b  -0x4(r4), r15</code>
eventually sets a <code class="language-plaintext highlighter-rouge">0</code> value into <code class="language-plaintext highlighter-rouge">r15</code>. The instruction <code class="language-plaintext highlighter-rouge">sxt r15</code> (sign extend) 
is executed on <code class="language-plaintext highlighter-rouge">r15</code> (effectively doing nothing since the value is <code class="language-plaintext highlighter-rouge">0x0</code>),
and soon returns back into <code class="language-plaintext highlighter-rouge">login()</code>, where <code class="language-plaintext highlighter-rouge">r15</code> is tested against <code class="language-plaintext highlighter-rouge">0</code>. It does not
appear that we have <em>any</em> influence over the memory address that’s moved into <code class="language-plaintext highlighter-rouge">r15</code> :anguished:.</p>

<p>After racking my brain for a while, and continuously stepping through various parts of program,
I noticed something interesting…</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_cusco_sp_pc_distance.png" alt="Cusco SP PC distance" /></p>

<p>This version of the code isn’t storing our input at <code class="language-plaintext highlighter-rouge">0x2400</code> as it was originally, and
instead is <em>much</em> closer to the program counter!
Notice how close our user input (<code class="language-plaintext highlighter-rouge">AAAAAAAAAA</code>) is to <code class="language-plaintext highlighter-rouge">pc</code>.
I wonder if we can overwrite parts of the program code!
Let’s try a bunch of <code class="language-plaintext highlighter-rouge">A's</code> and see what happens…</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_cusco_pc_code_overwritten.png" alt="Cusco PC code overwritten" /></p>

<p>Looks like we can! Another interesting thing to note, I tried to input about 200 or so <code class="language-plaintext highlighter-rouge">A's</code>,
but only 48 were copied onto the stack. I suspect maybe during the copy onto the stack,
<code class="language-plaintext highlighter-rouge">__do_copy_data()</code> is being invoked and we’re overwriting instructions as we’re in the
middle of executing them? I wasn’t able to step the code to this level of precision so I’m not sure.
However, this is sort of a moot point because of what happens as a result of inputting
so many bytes…</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_cusco_pc_overwritten.png" alt="Cusco PC overwritten" /></p>

<p>We can control the <code class="language-plaintext highlighter-rouge">pc</code> register. Sweet! Now all we need to do is to figure out the byte offset
to reach <code class="language-plaintext highlighter-rouge">pc</code> and figure out a suitable location to jump the 
execution to. After some experimenting with input strings of various lengths 
and keeping an eye on the <code class="language-plaintext highlighter-rouge">pc</code> register, we can see that the 17th and 18th byte
of our input will overflow into the <code class="language-plaintext highlighter-rouge">pc</code> register. Let’s try overwriting <code class="language-plaintext highlighter-rouge">pc</code> with <code class="language-plaintext highlighter-rouge">0x4528</code>, the 
<code class="language-plaintext highlighter-rouge">call #0x4446 &lt;unlock_door&gt;</code> instruction inside <code class="language-plaintext highlighter-rouge">login()</code> which comes right 
after the <code class="language-plaintext highlighter-rouge">jz</code> instruction we were trying so hard to bypass…</p>

<p class="img"><img src="/assets/images/writeups/microcorruption_cusco_solve.png" alt="Cusco Solved" /></p>

<p>:+1: :beers:</p>

<h3 id="flag-mouse-over-to-reveal">Flag (mouse over to reveal)</h3>
<div class="spoiler"><p>414141414141414141414141414141412845</p></div>]]></content><author><name>jiva</name></author><category term="blog" /><category term="microcorruption" /><category term="CTF" /><category term="writeup" /><category term="reverse engineering" /><category term="assembly" /><category term="hacking" /><summary type="html"><![CDATA[Microcorruption CTF Cusco Write-up]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jiva.io/assets/images/writeups/microcorruption.png" /><media:content medium="image" url="https://jiva.io/assets/images/writeups/microcorruption.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Microcorruption CTF Hanoi Write-up</title><link href="https://jiva.io/blog/microcorruption-ctf-writeup-hanoi" rel="alternate" type="text/html" title="Microcorruption CTF Hanoi Write-up" /><published>2017-08-30T23:17:00+00:00</published><updated>2017-08-30T23:17:00+00:00</updated><id>https://jiva.io/blog/microcorruption-ctf-writeup-hanoi</id><content type="html" xml:base="https://jiva.io/blog/microcorruption-ctf-writeup-hanoi"><![CDATA[<h2 id="summary">Summary:</h2>

<p>This is a write-up of my solution to the <a href="https://microcorruption.com/">Microcorruption CTF</a> challenge “Hanoi” (<code class="language-plaintext highlighter-rouge">LOCKIT PRO r b.01</code>).</p>

<p>Let’s jump right in…</p>

<figure class="highlight"><pre><code class="language-raw" data-lang="raw">4438 &lt;main&gt;
4438:  b012 2045      call	#0x4520 &lt;login&gt;
443c:  0f43           clr	r15</code></pre></figure>

<p><code class="language-plaintext highlighter-rouge">main()</code> this time only makes a call to a function called <code class="language-plaintext highlighter-rouge">login()</code>. Let’s dissect <code class="language-plaintext highlighter-rouge">login()</code>:</p>
<noscript><pre>4520 &lt;login&gt;
4520:  c243 1024      mov.b	#0x0, &amp;0x2410
4524:  3f40 7e44      mov	#0x447e &quot;Enter the password to continue.&quot;, r15
4528:  b012 de45      call	#0x45de &lt;puts&gt;
452c:  3f40 9e44      mov	#0x449e &quot;Remember: passwords are between 8 and 16 characters.&quot;, r15
4530:  b012 de45      call	#0x45de &lt;puts&gt;
4534:  3e40 1c00      mov	#0x1c, r14
4538:  3f40 0024      mov	#0x2400, r15
453c:  b012 ce45      call	#0x45ce &lt;getsn&gt;
4540:  3f40 0024      mov	#0x2400, r15
4544:  b012 5444      call	#0x4454 &lt;test_password_valid&gt;
4548:  0f93           tst	r15
454a:  0324           jz	$+0x8
454c:  f240 ea00 1024 mov.b	#0xea, &amp;0x2410
4552:  3f40 d344      mov	#0x44d3 &quot;Testing if password is valid.&quot;, r15
4556:  b012 de45      call	#0x45de &lt;puts&gt;
455a:  f290 c700 1024 cmp.b	#0xc7, &amp;0x2410
4560:  0720           jne	#0x4570 &lt;login+0x50&gt;
4562:  3f40 f144      mov	#0x44f1 &quot;Access granted.&quot;, r15
4566:  b012 de45      call	#0x45de &lt;puts&gt;
456a:  b012 4844      call	#0x4448 &lt;unlock_door&gt;
456e:  3041           ret
4570:  3f40 0145      mov	#0x4501 &quot;That password is not correct.&quot;, r15
4574:  b012 de45      call	#0x45de &lt;puts&gt;
4578:  3041           ret</pre></noscript>
<script src="https://gist.github.com/jiva/8171ac7eec5c3b5560b15d55fcfe3bcc.js"> </script>

<p>Straight away, the instruction at <code class="language-plaintext highlighter-rouge">0x455a</code> catches my eye, <code class="language-plaintext highlighter-rouge">cmp.b #0xc7, &amp;0x2410</code>.
Ultimately, this instruction will compare the byte located at memory address <code class="language-plaintext highlighter-rouge">0x2410</code>,
with the value <code class="language-plaintext highlighter-rouge">0xc7</code>, and if they are equal, the door will unlock. Let’s set a breakpoint
on the instruction and inspect the memory region around <code class="language-plaintext highlighter-rouge">0x2410</code> when execution pauses.</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_hanoi_break_login_cmp.png" alt="Hanoi CMP Breakpoint" /></p>

<p>When being prompted for the password, I used <code class="language-plaintext highlighter-rouge">AAAAAAAAAA</code>.
Check out the memory dump and notice where our input is (hint <code class="language-plaintext highlighter-rouge">0x2400</code>).
Notice that right after the 16th byte, the 17th byte will land in <code class="language-plaintext highlighter-rouge">0x2410</code>. Great!
Although the password prompt says to use a password of length 8 to 16 characters,
let’s try using a 17-byte password and attempt a one-byte overflow into <code class="language-plaintext highlighter-rouge">0x2410</code> with
<code class="language-plaintext highlighter-rouge">0xc7</code> and see if we can unlock the door…</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_hanoi_solve.png" alt="Hanoi Solve" /></p>

<h3 id="flag-mouse-over-to-reveal">Flag (mouse over to reveal)</h3>
<div class="spoiler"><p>41414141414141414141414141414141c7</p></div>]]></content><author><name>jiva</name></author><category term="blog" /><category term="microcorruption" /><category term="CTF" /><category term="writeup" /><category term="reverse engineering" /><category term="assembly" /><category term="hacking" /><summary type="html"><![CDATA[Microcorruption CTF Hanoi Write-up]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jiva.io/assets/images/writeups/microcorruption.png" /><media:content medium="image" url="https://jiva.io/assets/images/writeups/microcorruption.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Microcorruption CTF Reykjavik Write-up</title><link href="https://jiva.io/blog/microcorruption-ctf-writeup-reykjavik" rel="alternate" type="text/html" title="Microcorruption CTF Reykjavik Write-up" /><published>2017-08-29T23:53:00+00:00</published><updated>2017-08-29T23:53:00+00:00</updated><id>https://jiva.io/blog/microcorruption-ctf-writeup-reykjavik</id><content type="html" xml:base="https://jiva.io/blog/microcorruption-ctf-writeup-reykjavik"><![CDATA[<h2 id="summary">Summary:</h2>

<p>This is a write-up of my solution to the <a href="https://microcorruption.com/">Microcorruption CTF</a> challenge “Reykjavik” (<code class="language-plaintext highlighter-rouge">LOCKIT PRO r a.03</code>).</p>

<p>The last two challenges were relatively straightforward and pretty easy to solve. This version promises “military-grade encryption”:</p>

<figure class="highlight"><pre><code class="language-raw" data-lang="raw">This is Software Revision 02. This release contains military-grade
encryption so users can be confident that the passwords they enter
can not be read from memory.   We apologize for making it too easy
for the password to be recovered on prior versions.  The engineers
responsible have been sacked.</code></pre></figure>

<p>Let’s see what they have up their sleeves. As always, let’s check out what’s going on in <code class="language-plaintext highlighter-rouge">main()</code>:</p>
<noscript><pre>4438 &lt;main&gt;
4438:  3e40 2045      mov	#0x4520, r14
443c:  0f4e           mov	r14, r15
443e:  3e40 f800      mov	#0xf8, r14
4442:  3f40 0024      mov	#0x2400, r15
4446:  b012 8644      call	#0x4486 &lt;enc&gt;
444a:  b012 0024      call	#0x2400
444e:  0f43           clr	r15</pre></noscript>
<script src="https://gist.github.com/jiva/b1b612713215d626e353534f3a9447c7.js"> </script>

<p>As you can see, this version does not have a call to <code class="language-plaintext highlighter-rouge">check_password()</code>. Instead, the program makes a 
call to <code class="language-plaintext highlighter-rouge">enc()</code> and then makes another call to a mysterious portion of memory located at <code class="language-plaintext highlighter-rouge">0x2400</code>. Interesting.</p>

<p>Another thing to note is that the memory located at <code class="language-plaintext highlighter-rouge">0x2400</code> doesn’t actually appear to contain anything interesting
before the program is run (i.e. contains a bunch of zeros):</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_reykjavik_initial_memory.png" alt="Reykjavik Initial Memory Dump" /></p>

<p>Let’s set a breakpoint on the <code class="language-plaintext highlighter-rouge">main()</code> function and see if we can figure out what’s going on:</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_reykjavik_break_main.png" alt="Reykjavik Break Main" /></p>

<p>Did you catch that? It looks like the portion of memory located at <code class="language-plaintext highlighter-rouge">0x2400</code> is being allocated <em>before</em> <code class="language-plaintext highlighter-rouge">main()</code> is called.
Let’s step through the program as soon as it’s executed and keep an eye on <code class="language-plaintext highlighter-rouge">0x2400</code>. Let’s also keep an eye on what
instructions are being executed:</p>
<p class="video"><iframe width="640" height="360" src="https://player.vimeo.com/video/231327185?color=6abd45&amp;title=0&amp;byline=0&amp;portrait=0" frameborder="0" allowfullscreen=""></iframe></p>

<p>We can see that before we enter into <code class="language-plaintext highlighter-rouge">main()</code>, a call is made to <code class="language-plaintext highlighter-rouge">__do_copy_data()</code>. 
In this function, <code class="language-plaintext highlighter-rouge">0x7c</code> bytes are being copied from <code class="language-plaintext highlighter-rouge">0x4538</code> into <code class="language-plaintext highlighter-rouge">0x2400</code>.
Interesting. Let’s continue on to <code class="language-plaintext highlighter-rouge">enc()</code> and observe what it does:</p>
<noscript><pre>4486 &lt;enc&gt;
4486:  0b12           push	r11
4488:  0a12           push	r10
448a:  0912           push	r9
448c:  0812           push	r8
448e:  0d43           clr	r13
4490:  cd4d 7c24      mov.b	r13, 0x247c(r13)
4494:  1d53           inc	r13
4496:  3d90 0001      cmp	#0x100, r13
449a:  fa23           jne	#0x4490 &lt;enc+0xa&gt;
449c:  3c40 7c24      mov	#0x247c, r12
44a0:  0d43           clr	r13
44a2:  0b4d           mov	r13, r11
44a4:  684c           mov.b	@r12, r8
44a6:  4a48           mov.b	r8, r10
44a8:  0d5a           add	r10, r13
44aa:  0a4b           mov	r11, r10
44ac:  3af0 0f00      and	#0xf, r10
44b0:  5a4a 7244      mov.b	0x4472(r10), r10
44b4:  8a11           sxt	r10
44b6:  0d5a           add	r10, r13
44b8:  3df0 ff00      and	#0xff, r13
44bc:  0a4d           mov	r13, r10
44be:  3a50 7c24      add	#0x247c, r10
44c2:  694a           mov.b	@r10, r9
44c4:  ca48 0000      mov.b	r8, 0x0(r10)
44c8:  cc49 0000      mov.b	r9, 0x0(r12)
44cc:  1b53           inc	r11
44ce:  1c53           inc	r12
44d0:  3b90 0001      cmp	#0x100, r11
44d4:  e723           jne	#0x44a4 &lt;enc+0x1e&gt;
44d6:  0b43           clr	r11
44d8:  0c4b           mov	r11, r12
44da:  183c           jmp	#0x450c &lt;enc+0x86&gt;
44dc:  1c53           inc	r12
44de:  3cf0 ff00      and	#0xff, r12
44e2:  0a4c           mov	r12, r10
44e4:  3a50 7c24      add	#0x247c, r10
44e8:  684a           mov.b	@r10, r8
44ea:  4b58           add.b	r8, r11
44ec:  4b4b           mov.b	r11, r11
44ee:  0d4b           mov	r11, r13
44f0:  3d50 7c24      add	#0x247c, r13
44f4:  694d           mov.b	@r13, r9
44f6:  cd48 0000      mov.b	r8, 0x0(r13)
44fa:  ca49 0000      mov.b	r9, 0x0(r10)
44fe:  695d           add.b	@r13, r9
4500:  4d49           mov.b	r9, r13
4502:  dfed 7c24 0000 xor.b	0x247c(r13), 0x0(r15)
4508:  1f53           inc	r15
450a:  3e53           add	#-0x1, r14
450c:  0e93           tst	r14
450e:  e623           jnz	#0x44dc &lt;enc+0x56&gt;
4510:  3841           pop	r8
4512:  3941           pop	r9
4514:  3a41           pop	r10
4516:  3b41           pop	r11
4518:  3041           ret</pre></noscript>
<script src="https://gist.github.com/jiva/5d087fc7a6de3abc5f7621289739875f.js"> </script>

<p>So… we can see that this subroutine is doing a number of things.
Let’s attempt to break down these instructions down slightly to get a sense of what’s going on:</p>

<ol>
  <li>
    <p>Instructions <code class="language-plaintext highlighter-rouge">0x4490</code> to <code class="language-plaintext highlighter-rouge">0x449a</code> are going to loop while loading bytes 
<code class="language-plaintext highlighter-rouge">0x00</code> to <code class="language-plaintext highlighter-rouge">0xff</code> into the memory address starting at <code class="language-plaintext highlighter-rouge">0x0x247c</code>.</p>
  </li>
  <li>
    <p>Instructions <code class="language-plaintext highlighter-rouge">0x449c</code> to <code class="language-plaintext highlighter-rouge">0x44d6</code> appears to be obfuscating the previously created 256 bytes 
using the string located at <code class="language-plaintext highlighter-rouge">0x4472</code>, <code class="language-plaintext highlighter-rouge">ThisIsSecureRight?</code></p>
  </li>
  <li>
    <p>Instructions <code class="language-plaintext highlighter-rouge">0x44d8</code> to <code class="language-plaintext highlighter-rouge">0x4510</code> appear to be using the previously obfuscated byte string
as an XOR key to the original data written at memory location <code class="language-plaintext highlighter-rouge">0x2400</code>.</p>
  </li>
</ol>

<p>After returning back into <code class="language-plaintext highlighter-rouge">main()</code>, <code class="language-plaintext highlighter-rouge">call #0x2400</code> is immediately executed. Stepping through
this code reveals sensible instructions are being executed.
It appears as though the bytes at memory location <code class="language-plaintext highlighter-rouge">0x2400</code> were originally obfuscated/encrypted,
and the call to <code class="language-plaintext highlighter-rouge">enc()</code> ultimately deobfuscated/decrypted this memory for us. Sweet! Let’s dissect these
bytes and disassemble them to see if we can see what instructions are going to be executed:</p>
<noscript><pre>2400:    0b12           push	r11
2402:    0412           push	r4
2404:    0441           mov	sp, r4
2406:    2452           add	#0x4, r4
2408:    3150 e0ff      add	#0xffe0, sp
240c:    3b40 2045      mov	#0x4520, r11
2410:    073c           jmp	$+0x10
2412:    1b53           inc	r11
2414:    8f11           sxt	r15
2416:    0f12           push	r15
2418:    0312           push	#0x0
241a:    b012 6424      call	#0x2464
241e:    2152           add	#0x4, sp
2420:    6f4b           mov.b	@r11, r15
2422:    4f93           tst.b	r15
2424:    f623           jnz	$-0x12
2426:    3012 0a00      push	#0xa
242a:    0312           push	#0x0
242c:    b012 6424      call	#0x2464
2430:    2152           add	#0x4, sp
2432:    3012 1f00      push	#0x1f
2436:    3f40 dcff      mov	#0xffdc, r15
243a:    0f54           add	r4, r15
243c:    0f12           push	r15
243e:    2312           push	#0x2
2440:    b012 6424      call	#0x2464
2444:    3150 0600      add	#0x6, sp
2448:    b490 11ab dcff cmp	#0xab11, -0x24(r4)
244e:    0520           jnz	$+0xc
2450:    3012 7f00      push	#0x7f
2454:    b012 6424      call	#0x2464
2458:    2153           incd	sp
245a:    3150 2000      add	#0x20, sp
245e:    3441           pop	r4
2460:    3b41           pop	r11
2462:    3041           ret
2464:    1e41 0200      mov	0x2(sp), r14
2468:    0212           push	sr
246a:    0f4e           mov	r14, r15
246c:    8f10           swpb	r15
246e:    024f           mov	r15, sr
2470:    32d0 0080      bis	#0x8000, sr
2474:    b012 1000      call	#0x10
2478:    3241           pop	sr
247a:    3041           ret
</pre></noscript>
<script src="https://gist.github.com/jiva/3bfee3b5ba8332515d1080ca3a051527.js"> </script>

<p>After stepping through this deobfuscated code, we can see that it is printing out the password input prompt.
After entering in the password and stepping forward a few instructions, we see that the program will exit or 
continue based on the result of <code class="language-plaintext highlighter-rouge">cmp #0xab11, -0x24(r4)</code>. In other words, the door should open if the password is
<code class="language-plaintext highlighter-rouge">0xab11</code>. Wow… so much for that “military-grade encryption”! Let’s try it out (don’t forget the byte order):</p>
<p class="img"><img src="/assets/images/writeups/microcorruption_reykjavik_solve.png" alt="Reykjavik Solve" /></p>

<h3 id="flag-mouse-over-to-reveal">Flag (mouse over to reveal)</h3>
<div class="spoiler"><p>11ab</p></div>]]></content><author><name>jiva</name></author><category term="blog" /><category term="microcorruption" /><category term="CTF" /><category term="writeup" /><category term="reverse engineering" /><category term="assembly" /><category term="hacking" /><summary type="html"><![CDATA[Microcorruption CTF Reykjavik Write-up]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://jiva.io/assets/images/writeups/microcorruption.png" /><media:content medium="image" url="https://jiva.io/assets/images/writeups/microcorruption.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>