{"id":3341,"date":"2021-07-30T13:17:43","date_gmt":"2021-07-30T11:17:43","guid":{"rendered":"https:\/\/andreas-klingler.de\/infosec\/?p=3341"},"modified":"2021-08-11T11:23:32","modified_gmt":"2021-08-11T09:23:32","slug":"rop-return-oriented-programming","status":"publish","type":"post","link":"https:\/\/infosec.andreas-klingler.de\/?p=3341","title":{"rendered":"<span class=\"caps\">ROP<\/span> Return-oriented programming"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">O<a href=\"https:\/\/andreas-klingler.de\/infosec\/?p=3324\">n the return-to-libc post<\/a>, we described the process of inject\u00ading a sys\u00adtem call with para\u00adme\u00adters via envi\u00adron\u00adment vari\u00adables to start a new process. But this requires to exe\u00adcute anoth\u00ader pro\u00adgram (which maybe no avail\u00adable on the target).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of call\u00ading sys\u00adtem we can call oth\u00ader instruc\u00adtions from some\u00adwhere in the mem\u00ado\u00adry. But it would be dif\u00adfi\u00adcult to find instruc\u00adtions in the mem\u00ado\u00adry which does exact\u00adly what we want. The idea of <span class=\"caps\">ROP<\/span> is to use only instruc\u00adtions at the end of func\u00adtions before a return (=Gad\u00adgets) and com\u00adbine them via manip\u00adu\u00adla\u00adtion of the return address\u00ades to exe\u00adcute arbi\u00adtrary&nbsp;code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Helper functions for&nbsp;<span class=\"caps\">ROP<\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The fol\u00adlow\u00ading Win\u00addows sys\u00adtem calls can be used to con\u00adstruct a <span class=\"caps\">ROP<\/span>&nbsp;chain.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">VirtualProtect()<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">We want to use Vir\u00adtu\u00adal\u00adPro\u00adtect() before our shell\u00adcode to dis\u00adable <span class=\"caps\">DEP<\/span> for the mem\u00ado\u00adry where we have inject\u00aded it. To do this, we start our exe\u00adcu\u00adtion at the over\u00adwrit\u00adten <span class=\"caps\">EIP<\/span> by call\u00ading a series of gad\u00adgets which cal\u00adcu\u00adlate the cur\u00adrent mem\u00ado\u00adry address\u00ades and argu\u00adments for the Vir\u00adtu\u00adal\u00adPro\u00adtect() syscall, call it and return to our shellcode.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/andreas-klingler.de\/infosec\/wp-content\/uploads\/2021\/08\/rop_virtualprotect.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"685\" src=\"https:\/\/andreas-klingler.de\/infosec\/wp-content\/uploads\/2021\/08\/rop_virtualprotect-1024x685.png\" alt class=\"wp-image-3429\" srcset=\"https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/rop_virtualprotect-1024x685.png 1024w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/rop_virtualprotect-300x201.png 300w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/rop_virtualprotect-768x514.png 768w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/rop_virtualprotect.png 1270w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\"><\/a><figcaption>Sim\u00adple <span class=\"caps\">ROP<\/span> chain for exe\u00adcut\u00ading Vir\u00adtu\u00adal\u00adPro\u00adtect() before our inject\u00aded shellcode.<\/figcaption><\/figure><\/div>\n\n\n\n<ol class=\"wp-block-list\"><li>We over\u00adwrite the buffer with an overflow<\/li><li>We over\u00adwrite the RIP\u2019s address with an address where we have a gad\u00adget which saves the cur\u00adrent stack point\u00ader. We will use it as our ref\u00ader\u00adence point for all oth\u00ader instructions.<\/li><li>Then we call a gad\u00adget which jumps to our next gad\u00adget after the fol\u00adlow\u00ading block of reserved spaces for the Vir\u00adtu\u00adal\u00adPro\u00adtect() call and argu\u00adments. Note that these mem\u00ado\u00adry space is ini\u00adtialy only over\u00adwrit\u00adten, but not with the final val\u00adues (we don\u2019t know&nbsp;yet).<\/li><li>The next gad\u00adget cal\u00adcu\u00adlates the start address of our shell\u00adcode (which comes lat\u00ader in the stack) and stores it in a register.<\/li><li>The next gad\u00adget stored this cal\u00adcu\u00adlat\u00aded val\u00adue to the mem\u00ado\u00adry place\u00adhold\u00ader posi\u00adtion for&nbsp;it.<\/li><li>Now, three \/ six oth\u00ader gad\u00adgets fol\u00adlow which cal\u00adcu\u00adlate and store the oth\u00ader argu\u00adments. After all these gad\u00adget ran, all argu\u00adments from our place\u00adhold\u00ader mem\u00ado\u00adry are set with the valid values.<\/li><li>Now we set with a last gad\u00adget the return address for Vir\u00adtu\u00adal\u00adPro\u00adtect() and then jump to&nbsp;it.<\/li><li>Vir\u00adtu\u00adal\u00adPro\u00adtect() is exe\u00adcut\u00aded and returns to our pro\u00advid\u00aded return address, where\u2026<\/li><li>our shell\u00adcode&nbsp;is.<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">General notes<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Some\u00adtimes you can\u00adnot find a per\u00adfect gad\u00adget which does one instruc\u00adtion and has a ret direct\u00adly after it. Then, try to find gad\u00adgets which have instruc\u00adtions before the ret which don\u2019t harm you. For exam\u00adple, if there is a pop instruc\u00adtion before the ret instruc\u00adtion, you could add a dum\u00admy val\u00adue to the stack before so that an addi\u00adtion\u00adal pop would not destroy the stack order you overwrote.<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>On the return-to-libc post, we described the process of inject\u00ading a sys\u00adtem call with para\u00adme\u00adters via envi\u00adron\u00adment vari\u00adables to start a new process. But this requires to exe\u00adcute anoth\u00ader pro\u00adgram (which maybe no avail\u00adable on the tar\u00adget). Instead of call\u00ading sys\u00adtem we can call oth\u00ader instruc\u00adtions from some\u00adwhere in the mem\u00ado\u00adry. But it would&nbsp;be&nbsp;[\u2026]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"wp_typography_post_enhancements_disabled":false,"footnotes":""},"categories":[355],"tags":[428],"class_list":["post-3341","post","type-post","status-publish","format-standard","hentry","category-reverse-engineering","tag-rop"],"_links":{"self":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/3341","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3341"}],"version-history":[{"count":10,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/3341\/revisions"}],"predecessor-version":[{"id":3433,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/3341\/revisions\/3433"}],"wp:attachment":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3341"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3341"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3341"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}