{"id":8783,"date":"2012-02-29T20:09:57","date_gmt":"2012-02-29T19:09:57","guid":{"rendered":"https:\/\/www.corelan.be\/?p=8783"},"modified":"2026-03-22T10:14:00","modified_gmt":"2026-03-22T09:14:00","slug":"debugging-fun-putting-a-process-to-sleep","status":"publish","type":"post","link":"https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/","title":{"rendered":"Debugging Fun - Putting a process to sleep()"},"content":{"rendered":"<h3>Introduction \/ Problem description<\/h3>\n<p>Recently I played with an older CVE (CVE-2008-0532, <a title=\"http:\/\/www.securityfocus.com\/archive\/1\/489463\" href=\"http:\/\/www.securityfocus.com\/archive\/1\/489463\">http:\/\/www.securityfocus.com\/archive\/1\/489463<\/a>, by <a href=\"https:\/\/twitter.com\/41414141\">FX<\/a>) and I was having trouble debugging the CGI executable where the vulnerable function was located.<\/p>\n<p>Here's the problem : The CGI Executable CSUserCGI.exe is a child process of IIS, and only spawns when called by a user. The executable script then quickly closes after serving its purpose... and before we can attach our debugger. So how do we essentially debug this? Would configuring the debugger for JIT (Just In Time) work ?<\/p>\n<p>Let's see<\/p>\n<p>When we call the CGI script over HTTP we can see it open and close real quick.<\/p>\n<p>Try #1<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic15.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=\"pic1\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic1_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic21.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=\"pic2\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic2_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p>No luck! So How am I going to debug this? There has to be a way.<\/p>\n<h3>Putting the process to sleep()<\/h3>\n<p>At the time one of my Corelan team mates sinn3r had completed a few HP NNM modules which he encountered similar circumstances. The idea was to put the child process to sleep until I attach a debugger, by inserting some code that would do this:<\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #191919; 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\">\/\/ (pseudo code):<\/span>\n\n<span style=\"color: #0000ff\">while<\/span> (IsDebuggerPresent == <span style=\"color: #0000ff\">false<\/span>) {\n   sleep(1);\n}\n\n<span style=\"color: #008000\">\/\/ Repair the prologue of the entry point you hijacked,<\/span>\n<span style=\"color: #008000\">\/\/ and then jmp back to the entry point.<\/span><\/pre>\n<p>Okay made sense, so time to get my hands dirty. I opened the executable in immunity and picked a good function to hook (0x00401010). I wanted to skip some of the initial kernel calls and environment and jump right into main().<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic31.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=\"pic3\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic3_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p>The next thing I needed to was find a place in .text that wasn\u2019t being used by the executable and would not corrupt any other functions, or prevent the executable from working as intended. The goal would be to use the existing call instruction (call 0x00401010 in this case), and change the offset value of that call to make a jump to the location where my custom routine will be placed.<\/p>\n<p>I found a nice spot at 0x00415362 so I would edit the call at 0x00414CD6 to point to that location.<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic41.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\/2012\/02\/pic4_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p>Now I need to find the location of&#160; kernel32.Sleep &amp; kernel32.IsDebuggerPresent. Since this is just a patch I am doing locally on my system there is no need to look for a generic calls to these function, I can just look up the locations in Immunity under executable then names. On my Windows 2003 SP2 system the locations are 0x77e424de &amp; 0x77e5da00. More than likely they will be different on your machine!<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic51.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\/2012\/02\/pic5_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p>&#160;<\/p>\n<p>Time to insert my function hook. Note that for this particular exploit there was not a need to jump back to the next instruction after our original (now updated) call&#160; but I did it anyways.<\/p>\n<p>First, I patched the call offset (to make it jump to the custom routine, which I'm going to place at 0x00415362)<\/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\">00414CD6   E8 87060000      CALL CSUserCG.00415362 ; jmp to custom routine<\/pre>\n<p>and I placed the custom routine at 0x00415362<\/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\">00415362   6A 01            PUSH 1\n00415364   E8 75D1A277      CALL kernel32.Sleep\n00415369   E8 9286A477      CALL kernel32.IsDebuggerPresent\n0041536E   83F8 01          CMP EAX,1\n00415371  ^75 EF            JNZ SHORT CSuserCG.00415362\n00415373   CC               INT3\n00415374   83C4 04          ADD ESP,4\n00415377   E8 94BCFEFF      CALL CSuserCG.00401010  ;go back\n0041537C  ^E9 5AF9FFFF      JMP CSuserCG.00414CDB<\/pre>\n<p>&#160;<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic61.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\/2012\/02\/pic6_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p>With immunity we can now right click and save the changes to a new name. I decided to name the file NEWCSUserCGI.exe and place it in our CGI script directory (C:\\Inetpub\\wwwroot\\securecgi-bin).<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic71.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\/2012\/02\/pic7_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic81.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\/2012\/02\/pic8_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p>I then renamed the original executable to OLDCSUserCGI.exe and then changed NEWCSUserCGI.exe to CSUserCGI.exe (which is the original name of the file)<\/p>\n<p>This time I launched with the proof of concept in our URL and viola the script is still running!<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic91.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=\"pic9\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic9_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p>Now time to see our buffer overflow and to verify our public proof of concept code is working. If we take a look at (<a title=\"http:\/\/www.securityfocus.com\/archive\/1\/489463\" href=\"http:\/\/www.securityfocus.com\/archive\/1\/489463\">http:\/\/www.securityfocus.com\/archive\/1\/489463<\/a> by FX) we can see that when we supply a long string after \u201cLogout+\u201d we will reach our buffer overflow giving us control of EIP<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic101.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\/2012\/02\/pic10_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p>The vulnerable function is a subroutine in the function we hooked (0x00401010). First we can see a fixed buffer of 0x60 being setup for our Logout argument.<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic111.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=\"pic11\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic11_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic121.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=\"pic12\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic12_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p>msvcrt.strtok is called and is looking for the first string that ends in \u201c.\u201d<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic131.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=\"pic13\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic13_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p>The string is then copied on the stack and we eventually reach our buffer overflow.<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic141.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=\"pic14\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic14_thumb1.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p>Woot! This was an easy stack buffer overflow and the final code can be seen here: (<a href=\"https:\/\/github.com\/rapid7\/metasploit-framework\/blob\/unstable\/unstable-modules\/exploits\/untested\/cisco_acs_ucp.rb\">https:\/\/github.com\/rapid7\/metasploit-framework\/blob\/unstable\/unstable-modules\/exploits\/untested\/cisco_acs_ucp.rb<\/a>)<\/p>\n<h3>What about automating this?<\/h3>\n<p>I thought that this might be a good opportunity to create a script that would automate this process or come up with an alternative. I presented the idea to my teammates before leaving from work and drove home eager to give this a shot over the weekend. Low and behold I must have had a memory lapse and forgot that corelanc0d3r has over 5000 lines of python-fu with immunity (mona.py anyone?) and finished this before I even got home from work! All the credit goes to him for this one.<\/p>\n<p>Here is his automated script that will essentially sleep the application until you attach the debugger and it does it all without calling any kernel32 API calls. <\/p>\n<pre style=\"border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #191919; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px\"># binary patcher\n# will inject routine to make the binary hang\n# so you can attach to it with a debugger\n#\n# corelanc0d3r\n# (c) 2012 - www.corelan.be\n\n<span style=\"color: #0000ff\">import<\/span> <span style=\"color: #0000ff\">sys<\/span>,pefile,<span style=\"color: #0000ff\">os<\/span>,binascii\n\n<span style=\"color: #0000ff\">def<\/span> patch_file(binaryfile):\n\n\troutine = &quot;<span style=\"color: #8b0000\">\\x33\\xc0<\/span>&quot;\t\t# <span style=\"color: #0000ff\">xor<\/span> eax,eax\n\troutine += &quot;<span style=\"color: #8b0000\">\\x83\\xF8\\x00<\/span>&quot;\t# cmp eax,0\n\troutine += &quot;<span style=\"color: #8b0000\">\\x74\\xFB<\/span>&quot;\t\t# JE back to cmp\n\n\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\">[+] Opening file %s<\/span>&quot; % binaryfile\n\tpe = pefile.PE(binaryfile)\n\n\tentrypoint = pe.OPTIONAL_HEADER.AddressOfEntryPoint\n\tbase = pe.OPTIONAL_HEADER.ImageBase\n\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\"> - Original Entrypoint : 0x%x<\/span>&quot; % (base + entrypoint)\n\n\tsearchend = 0\n\tstartrva = 0\n\tfor section in pe.sections:\n\t\t<span style=\"color: #0000ff\">if<\/span> section.Name.<span style=\"color: #0000ff\">replace<\/span>('\\x00','') == '.text':\n\t\t\t# <span style=\"color: #0000ff\">code<\/span> segment\n\t\t\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\"> - Finding a good spot in code segment at 0x%x<\/span>&quot; % (base + section.VirtualAddress)\n\t\t\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\"> Size : 0x%x<\/span>&quot; % section.SizeOfRawData\n\t\t\tsearchend = section.SizeOfRawData\n\t\t\tstartrva = section.VirtualAddress\n\t\t\t#<span style=\"color: #0000ff\">print<\/span> (section.Name, hex(section.VirtualAddress), hex(section.Misc_VirtualSize), section.SizeOfRawData )\n\t<span style=\"color: #0000ff\">if<\/span> searchend &gt; 0:\n\t\tcnt = 0\n\t\tconsecutive = 0\n\t\tstopnow = False\n\t\toffsethere = 0\n\t\twhile cnt &lt; searchend and not stopnow:\n\t\t\tthisbyte = pe.get_dword_at_rva(startrva+cnt)\n\t\t\t<span style=\"color: #0000ff\">if<\/span> thisbyte == 0:\n\t\t\t\t<span style=\"color: #0000ff\">if<\/span> offsethere == 0:\n\t\t\t\t\toffsethere = startrva+cnt\n\t\t\t\tconsecutive += 1\n\t\t\t<span style=\"color: #0000ff\">else<\/span>:\n\t\t\t\toffsethere = 0\n\t\t\t\tconsecutive = 0\n\t\t\t<span style=\"color: #0000ff\">if<\/span> consecutive &gt;= len(routine)+5:\n\t\t\t\tstopnow=True\n\t\t\tcnt = cnt + 1\n\t\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\"> - Found %d consecutive null bytes at offset 0x%x<\/span>&quot; % (consecutive,offsethere)\n\t\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\"> Distance from original entrypoint : %x bytes<\/span>&quot; % (offsethere - entrypoint)\n\t\tjmpback = &quot;<span style=\"color: #8b0000\">%x<\/span>&quot; % (4294967295 - (offsethere - entrypoint + 4 + len(routine)))\n\t\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\"> Jmpback : 0x%s<\/span>&quot; % jmpback\n\t\troutine += &quot;<span style=\"color: #8b0000\">\\xe8<\/span>&quot;\n\t\troutine += binascii.a2b_hex(jmpback[6:8])\n\t\troutine += binascii.a2b_hex(jmpback[4:6])\n\t\troutine += binascii.a2b_hex(jmpback[2:4])\n\t\troutine += binascii.a2b_hex(jmpback[0:2])\n\t\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\"> - Injecting hang + redirect (%d bytes) at 0x%x<\/span>&quot; % (len(routine),(base+offsethere))\n\t\tpe.set_bytes_at_rva(offsethere,routine)\n\t\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\"> - Setting new EntryPoint to 0x%x<\/span>&quot; % (base+offsethere)\n\t\tpe.OPTIONAL_HEADER.AddressOfEntryPoint = offsethere\n\t\tentrypoint = pe.OPTIONAL_HEADER.AddressOfEntryPoint\n\t\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\"> - Entrypoint now set to : 0x%x<\/span>&quot; % (base + entrypoint)\n\n\t\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\">[+] Saving file<\/span>&quot;\n\t\tpe.<span style=\"color: #0000ff\">write<\/span>(filename=binaryfile.<span style=\"color: #0000ff\">replace<\/span>(&quot;<span style=\"color: #8b0000\">.exe<\/span>&quot;,&quot;&quot;)+&quot;<span style=\"color: #8b0000\">_patched.exe<\/span>&quot;)\n\t\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\">[+] Patched.<\/span>&quot;\n\t<span style=\"color: #0000ff\">else<\/span>:\n\t\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\">[-] No code segment found ?<\/span>&quot;\n\n<span style=\"color: #0000ff\">if<\/span> len(<span style=\"color: #0000ff\">sys<\/span>.argv) == 2:\n\ttarget = <span style=\"color: #0000ff\">sys<\/span>.argv[1]\n\t<span style=\"color: #0000ff\">if<\/span> <span style=\"color: #0000ff\">os<\/span>.<span style=\"color: #0000ff\">path<\/span>.exists(target):\n\t\tpatch_file(target)\n\t<span style=\"color: #0000ff\">else<\/span>:\n\t\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\"> ** Unable to find file '%s' **<\/span>&quot; % target\n<span style=\"color: #0000ff\">else<\/span>:\n\t<span style=\"color: #0000ff\">print<\/span> &quot;<span style=\"color: #8b0000\">\\nUsage : patchbinary.py filename\\r\\n<\/span>&quot;<\/pre>\n<p>&#160;<\/p>\n<p>What corelanc0d3r did was take advantage of <a href=\"http:\/\/code.google.com\/p\/pefile\/\">pefile<\/a>, a python module that allows us to read and work with PE (Portable Executable) files.&#160;&#160; (This module is installed by default on BackTrack and Immunity Debugger, just for your information)<\/p>\n<p>His script will load the executable file and get the original entrypoint of the module.<\/p>\n<p>Next, the script will look for a location in the file that has 12 consecutive null bytes (you could replace this with for example NOPS if needed).<\/p>\n<p>At that location, an custom routine will be placed. This routine will clear out EAX, compare it with 0, and then jump back to the compare statement if the condition is true. Essentially this will be a loop until we attach our debugger.&#160;&#160; After the conditional jump (which ensures the loop), a call to the original location of the entrypoint is placed.&#160; Finally, the entrypoint RVA in the PE file is updated to point at the custom routine.<\/p>\n<p>In other words, when you would run this executable, it would just hang (infinite loop). When attaching a debugger the process will pause.&#160; You then only need to find the location where the custom asm routine was inserted (the address is, in fact, right after the updated entrypoint), and either replace the cmp instruction with nops, or just change the cmp eax,0 into cmp eax,1.&#160; If you would continue to run the process, the executable would simply start doing what it's supposed to do.&#160; Alternatively, you can just let the application run and then pause (break)... it would halt on the cmp or the jump instruction inside the custom routine.<\/p>\n<p>Lets go ahead now and run this from cmd.exe and see everything work automatically.<\/p>\n<p>After the script finds and writes to a safe place for the loop, it will save a new file with the filename and \u201c_patched.exe\u201d.<\/p>\n<p>If we go ahead and run we can see that it works and does the same thing as my manual patch.<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic151.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=\"pic15\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic15_thumb.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p>Now if we rename our patched file and run our proof of concept again we can then attach the debugger and press \u201cpause\u201d to stop the loop. We then break out of the loop and the call back to the original entrypoint will be executed.<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic16.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=\"pic16\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic16_thumb.png\" width=\"620\" height=\"331\" \/><\/a><\/p>\n<p>Woot! Looks like everything is working properly. So that\u2019s pretty much it, this is just a short article on a problem I encountered and how it was solved.&#160; Note that this technique most likely won't worked with packed\/encoded binaries...<\/p>\n<h3>Windbg ?<\/h3>\n<p>You can, of course, do the same thing with other debuggers as well.&#160; The basic procedure will be exactly the same, you only need to know how to edit the instruction in memory to break out of the loop.<\/p>\n<p>Let's say you want to change the CMP instruction into CMP EAX,1.&#160; This requires us to change one byte in memory (the byte at 0x00415337 in this case).<\/p>\n<p>With the debugger attached (and the process interrupted), simply run the following command:<\/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\">eb 0x00415337 0x01<\/pre>\n<p>eb = edit byte.&#160; Other windbg 'edit' commands are ew (edit word) and ed (edit dword).<\/p>\n<p>Afer making the change, press F5 (or type 'g') to let the process break out of the loop and return to the original entrypoint.<\/p>\n<p>&#160;<\/p>\n<h3>Update (march 1st 2012)<\/h3>\n<p>As various people on twitter suggested, you can obviously also use \\xeb\\xfe as patch routine (which will just jump to itself).&#160; Tx <a href=\"https:\/\/twitter.com\/#!\/fdfalcon\">@fdfalcon<\/a> and <a href=\"https:\/\/twitter.com\/#!\/pa_kt\">@pa_kt<\/a> for the good feedback !<\/p>\n<p>&#160;<\/p>\n<p>&#160;<\/p>\n<hr \/>\n","protected":false},"excerpt":{"rendered":"<p>Recently I played with an older CVE (CVE-2008-0532, http:\/\/www.securityfocus.com\/archive\/1\/489463, by FX) and I was having trouble debugging the CGI executable where the vulnerable function was located.<\/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":[3708,244,2561,127,1],"tags":[2576,2128,2124,1978,262,261],"class_list":["post-8783","post","type-post","status-publish","format-standard","hentry","category-debugging","category-exploit-writing-tutorials","category-malware-and-reversing","category-security","category-uncategorized","tag-debugging","tag-immunity-debugger","tag-debugger","tag-python","tag-corelan-team","tag-corelan"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Debugging Fun - Putting a process to sleep() - 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\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Debugging Fun - Putting a process to sleep() - Corelan | Exploit Development &amp; Vulnerability Research\" \/>\n<meta property=\"og:description\" content=\"Recently I played with an older CVE (CVE-2008-0532, http:\/\/www.securityfocus.com\/archive\/1\/489463, by FX) and I was having trouble debugging the CGI executable where the vulnerable function was located.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/\" \/>\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=\"2012-02-29T19:09:57+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-22T09:14:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic1_thumb1.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\\\/2012\\\/02\\\/29\\\/debugging-fun-putting-a-process-to-sleep\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2012\\\/02\\\/29\\\/debugging-fun-putting-a-process-to-sleep\\\/\"},\"author\":{\"name\":\"Corelan Team (Lincoln)\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#\\\/schema\\\/person\\\/9605d0b07558c7917f492a508df12932\"},\"headline\":\"Debugging Fun - Putting a process to sleep()\",\"datePublished\":\"2012-02-29T19:09:57+00:00\",\"dateModified\":\"2026-03-22T09:14:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2012\\\/02\\\/29\\\/debugging-fun-putting-a-process-to-sleep\\\/\"},\"wordCount\":1371,\"publisher\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2012\\\/02\\\/29\\\/debugging-fun-putting-a-process-to-sleep\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2012\\\/02\\\/pic1_thumb1.png\",\"keywords\":[\"debugging\",\"immunity debugger\",\"debugger\",\"python\",\"corelan team\",\"corelan\"],\"articleSection\":[\"Debugging\",\"Exploit Writing Tutorials\",\"Malware and Reversing\",\"Security\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2012\\\/02\\\/29\\\/debugging-fun-putting-a-process-to-sleep\\\/\",\"url\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2012\\\/02\\\/29\\\/debugging-fun-putting-a-process-to-sleep\\\/\",\"name\":\"Debugging Fun - Putting a process to sleep() - Corelan | Exploit Development &amp; Vulnerability Research\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2012\\\/02\\\/29\\\/debugging-fun-putting-a-process-to-sleep\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2012\\\/02\\\/29\\\/debugging-fun-putting-a-process-to-sleep\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2012\\\/02\\\/pic1_thumb1.png\",\"datePublished\":\"2012-02-29T19:09:57+00:00\",\"dateModified\":\"2026-03-22T09:14:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2012\\\/02\\\/29\\\/debugging-fun-putting-a-process-to-sleep\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2012\\\/02\\\/29\\\/debugging-fun-putting-a-process-to-sleep\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2012\\\/02\\\/29\\\/debugging-fun-putting-a-process-to-sleep\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2012\\\/02\\\/pic1_thumb1.png\",\"contentUrl\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2012\\\/02\\\/pic1_thumb1.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2012\\\/02\\\/29\\\/debugging-fun-putting-a-process-to-sleep\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.corelan.be\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Debugging Fun - Putting a process to sleep()\"}]},{\"@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":"Debugging Fun - Putting a process to sleep() - 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\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/","og_locale":"en_US","og_type":"article","og_title":"Debugging Fun - Putting a process to sleep() - Corelan | Exploit Development &amp; Vulnerability Research","og_description":"Recently I played with an older CVE (CVE-2008-0532, http:\/\/www.securityfocus.com\/archive\/1\/489463, by FX) and I was having trouble debugging the CGI executable where the vulnerable function was located.","og_url":"https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/","og_site_name":"Corelan | Exploit Development &amp; Vulnerability Research","article_publisher":"https:\/\/www.facebook.com\/corelanconsulting","article_published_time":"2012-02-29T19:09:57+00:00","article_modified_time":"2026-03-22T09:14:00+00:00","og_image":[{"url":"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic1_thumb1.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\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/#article","isPartOf":{"@id":"https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/"},"author":{"name":"Corelan Team (Lincoln)","@id":"https:\/\/www.corelan.be\/#\/schema\/person\/9605d0b07558c7917f492a508df12932"},"headline":"Debugging Fun - Putting a process to sleep()","datePublished":"2012-02-29T19:09:57+00:00","dateModified":"2026-03-22T09:14:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/"},"wordCount":1371,"publisher":{"@id":"https:\/\/www.corelan.be\/#organization"},"image":{"@id":"https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/#primaryimage"},"thumbnailUrl":"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic1_thumb1.png","keywords":["debugging","immunity debugger","debugger","python","corelan team","corelan"],"articleSection":["Debugging","Exploit Writing Tutorials","Malware and Reversing","Security"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/","url":"https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/","name":"Debugging Fun - Putting a process to sleep() - Corelan | Exploit Development &amp; Vulnerability Research","isPartOf":{"@id":"https:\/\/www.corelan.be\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/#primaryimage"},"image":{"@id":"https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/#primaryimage"},"thumbnailUrl":"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic1_thumb1.png","datePublished":"2012-02-29T19:09:57+00:00","dateModified":"2026-03-22T09:14:00+00:00","breadcrumb":{"@id":"https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/#primaryimage","url":"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic1_thumb1.png","contentUrl":"https:\/\/www.corelan.be\/wp-content\/uploads\/2012\/02\/pic1_thumb1.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.corelan.be\/index.php\/2012\/02\/29\/debugging-fun-putting-a-process-to-sleep\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.corelan.be\/"},{"@type":"ListItem","position":2,"name":"Debugging Fun - Putting a process to sleep()"}]},{"@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":14526,"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\/8783","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=8783"}],"version-history":[{"count":1,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/posts\/8783\/revisions"}],"predecessor-version":[{"id":17187,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/posts\/8783\/revisions\/17187"}],"wp:attachment":[{"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/media?parent=8783"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/categories?post=8783"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/tags?post=8783"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}