• projectsIDA Sploiter

    Size 25.4 KB
    DateSeptember 14th, 2014

    IDA Sploiter is a plugin for Hex-Ray's IDA Pro disassembler designed to enhance IDA's capabilities as an exploit development and vulnerability research tool. Some of the plugin's features include a powerful ROP gadgets search engine, semantic gadget analysis and filtering, interactive ROP chain builder, stack pivot analysis, writable function pointer search, cyclic memory pattern generation and offset analysis, detection of bad characters and memory holes, and many others.

    The motivation for the development of IDA Sploiter was to make IDA Pro a comfortable, powerful and integrated environment for vulnerability research and exploit development. The plugin is designed to make many repetitive and time consuming tasks as effortless and natural as possible, so you can concentrate on other more challenging aspects of exploit development.

    To make the work with the plugin convenient, IDA Sploiter closely integrates with the IDA UI and exposes its functionality and various configurations through various views and forms. The plugin's logic uses IDA's powerful disassembly engine and various debugger plugins. As a result, IDA Sploiter can take advantage of many of IDA's unique features (e.g. building ROP chains remotely on a lab machine while effortlessly switching between debugger plugins).

    In the user guide below, you will find a comprehensive discussion of various plugin features and their sample use. Most of the sections are independent of each other, so you are welcome to jump ahead or read through the entire guide.

    Feel free to contact me if you have any questions, feature requests, bugs or just to say hello :)


    Simply copy into the IDA's plugins folder. The plugin will be automatically loaded the next time you start IDA Pro.


    IDA Sploiter uses pure IDA Python API, so it should be compatible with most recent versions. However, it was only extensively tested on IDA Pro 6.5 and 6.6 for Windows and OS X (32 and 64 bit versions).

    The first release of the plugin targets x86 and x86-64 architectures. Module analysis is implemented for Windows PE32 and PE32+ executables only.

    A limited set of the plugin's functionality was tested to work correctly for Linux ELF and OS X Mach-O binaries as well; however, their full support along with non-Intel architectures is in development for the next release.

    User guide

    This guide will walk you through various features of IDA Sploiter using plenty of examples and exploit development tips and tricks. I hope you will enjoy using this plugin as much as I had writing it.


    One of the key steps of exploit development is identifying vulnerable modules in a running process which could be leveraged to produce ROP chains, stack pivots, reliable function pointers, etc. IDA Sploiter includes a comprehensive module analysis view which can be opened from View -> Open Subview -> Modules submenu:

    NOTE: The view is only usable when the target application is started and suspended in the debugger, so all of the necessary modules are loaded in the application's memory space.

    Below is a sample modules view of a 32-bit application on a Windows 7 64bit system:

    You can immediately notice that the main application module does not support neither DEP nor ASLR. This makes it a suitable target for ROP gadgets and pivots. However, because it supports SafeSEH, a different target needs to be chosen for exploit vectors using SEH overwrites.

    Let's look at another modules view, this time for a sample 64-bit application also running on a Windows 7 system:

    Notice that the main application was once more compiled without DEP or ASLR support. However, some of the fields like SafeSEH are no longer applicable on 64bit applications due to the use of a different table-based exception handling mechanism. Furthermore, the plugin was not able to determine whether or not the security cookies (canary) were used in the application.

    NOTE: PE32+ file format no longer provides a definitive pointer to security cookies.

    Filtering Modules

    As an exercise, let's connect to a remote IDA debugger server and view modules loaded by a vulnerable Firefox browser to determine "interesting" modules:

    Looks like a wide assortment of ASLR and non-ASLR enabled modules. In order to concentrate on just non-dynamic base and non-nxcompat modules let's open a filter dialog by selecting Modify filters... in the context menu as follows:

    We can now apply several exclusion filters to make sure that only "interesting" modules are displayed:

    After sorting by path, we can now see that the vulnerability we found in Firefox can be exploited using the outdated Java modules and the good old MSVCR71.dll:

    Searching module selection

    At this point you can select one or more modules and select an action to perform from the context menu (e.g. Search ROP gadgets):

    You can find an in depth discussion of searching for ROP gadgets and writable function pointers below.

    ROP gadgets

    One of the most powerful features of IDA Sploiter is the ROP gadgets search engine. As mentioned in the introduction, the plugin fuses syntactic and semantic gadget analysis and searching to make one of the most laborious tasks in exploit development, ROP chain building, as comfortable and powerful as possible.

    NOTE: Just like the modules view, the ROP gadgets search is only functional when the target application is started and suspended in the debugger.

    Searching ROP gadgets

    You have already seen how to open the ROP gadgets search form in the modules view. Another way is to select ROP gadgets menu item in the Search menu:

    You will be presented with the Search ROP gadgets configuration dialog like the one below

    While the number of options and settings may seem overwhelming at first, you can leave the majority of them as is. The key selection you must make is a set of modules to search. Because we have started this particular dialog from the Search menu, all of the non-ASLR modules will be automatically selected for you. If you would have opened this form from the Modules View, all of the selected modules would have also been selected in this search dialog.

    Below is a complete listing of ROP gadgets search engine settings:

    • Pointer Charset - allows you to apply filters to the bytes constituting the address of the gadget pointer. For example, in cases where the application filters any non-alphanumeric bytes, you can apply the alphanum pointer charset filter to only locate gadgets with alphanumeric addresses.

    • Bad Chars - additional pointer address character set filter. For example, 0x0a and 0x0d bytes often result in the injected payload being terminated too early.

    • Unicode Table - single byte to Unicode conversion table used to determine address pointer Unicode compatibility.

    • Bad Instructions - forbidden instructions in the ROP gadget. For example, instructions like CALL or JMP may result in you losing control over the execution flow.

    • Max ROP size - maximum number of instructions in a ROP gadget including the last RETN instruction. Increase or decrease this number to find larger or smaller gadgets respectively.

    • Max ROP offset - maximum number of bytes used prior to the RETN instruction to locate valid gadgets. Increase or decrease this number to find more or less gadgets respectively.

    • Max RETN imm16 - maximum decimal value of imm16 that is permitted in the RETN instruction. Increasing this value will require you to also increase the padding in the ROP chain. For example, RETN 0x10 instruction will require a 4 DWORD padding following the next gadget in the chain.

    • Max ROP gadgets - maximum number of ROP gadgets to locate in all selected modules.

    • Allow conditional jumps - includes ROP gadgets containing conditional jumps. These gadgets may still be valid if you can control the respective EFLAGS to prevent conditional jumps from hijacking the desired execution flow.

    • Do not allow bad bytes - do not include gadgets containing invalid instructions. Checking this box will reduce the number of gadgets which are likely to work despite bad bytes which cannot be decoded to valid instructions.

    After you have selected the modules to use for the search and configured the search engine, hit the Search button to begin the search. A search progress popup will appear which allows you to stop the search at any time and review all of the discovered gadgets:

    Viewing ROP gadgets

    Once the search completes, you will be presented with a ROP gadgets table containing a collection of discovered gadgets and their characteristics:

    Let's examine various parts of the view and how they can be used to build a ROP chain. The first few columns contain gadget addresses, gadgets themselves as well as some basic information like gadget size and the module used to locate them:

    The default view presents gadgets sorted by the order they were discovered relative to a particular RETN address. For example, the first discovered gadget pop esi # retn at 0x0040105E was discovered just one byte behind the RETN address at 0x0040105F. The next gadget at 0x0040105F was discovered by looking 2 bytes behind that same RETN and so on. You may find this ordering useful when trying to minimize gadget size and the changes it makes to program's state. I also like sorting by size and looking at a few simple gadgets to get a feel for the type of ROP gadgets available in a particular module.

    The other half of the ROP gadgets table contains more descriptive information about gadgets' semantics such as what type of operations they perform (e.g. register to memory copy, arithmetic, stack operation, etc.), registers changed, registers used, and the character sets of the gadgets' addresses:

    Looking at the above screenshot, you can quickly tell that a gadget at 0x0040105D adjusts the stack by 8 bytes (two POPs), performs a stack operation on single registers, modifies the values of registers EDI and ESI, and has an address pointer character set compatible with ASCII filters. Another example, the gadget at 0x0040105C has no effect on the stack pointer, but performs an arithmetic operation (ADD) and uses the register BL to affect a memory address. Powerful stuff!

    Below is a complete list of all of the gadget operations that the plugin can detect:

    • one-reg - Operation involving a single register operand

    • one-mem - Operation involving a single memory operand

    • one-imm - Operation involving a single immediate operand

    • stack - Stack opeartion

    • math - Arithmetic operation

    • bit - Bit-wise operation

    • reg-to-reg - Register to register operation

    • reg-to-mem - Register to memory operation

    • mem-to-reg - Memory to register operation

    • imm-to-reg - Immediate to register operation

    Syntactic and semantic gadget filters

    Using IDA's powerful regular expression table filtering engine you can quickly locate gadgets based on not only their syntactic, but also much more descriptive semantic characteristics. For example, let's try to locate all gadgets which modify the eax register with any other register using syntactic and semantic approaches.

    The syntactic approach involves a simple regular expression to locate all mov instructions:

    The result is the expected collection of gadgets with the mov eax, e?? instructions:

    Now let's try the semantic approach by describing what we want the gadget to accomplish as opposed to searching for the exact instruction pattern:

    The result contains the same mov eax, e?? instructions as well as a few more interesting results which can also accomplish the same task (e.g. xchg, sbb, movzx, etc.):

    Now imagine introducing additional limitations like ensuring that esi register is not modified and the stack pointer is not changed. Such queries can be made easily using semantic search without resorting to long and complex regular expression queries.

    ROP chain builder

    As you find interesting gadgets, IDA sploiter offers an easy way to record them using the Add to chain context menu entry. For example, let's add several sequential reg-to-mem gadgets which are great for filling in memory placeholders (e.g. dynamically calculated values necessary to make a function call like VirtualProtect):

    Once you have selected a collection of interesting gadgets, you can click on the Build chain context menu entry to bring up a new ROP chain builder dialog:

    All of the previously added gadgets will be present in this view where you can build the final ROP chain payload. For example, let's duplicate the pop eax # retn and move each duplicate above each register-to-memory gadget:

    NOTE: To speed up the chain building process you can perform all of the operations in the context menu on multiple gadgets at the same time.

    At this point let's add constant values that we will be POP-ed from the stack into the EAX register and stored at some offset relative to the ECX pointer. Notice the 0x41414141 constant value, a comment field and the Insert button just below the ROP gadgets view. You can use this form to quickly insert constants and padding into the chain:

    We now have a sample ROP chain primitive that will get values from the stack and place them to several memory offsets. The final step in the ROP chain building process is generating a payload that you can paste into the exploit. Let's select Python format in the selector on the bottom and click on the Generate button:

    Using the combination of ROP gadget filtering and the ROP builder, you will be able to quickly build complex ROP chains to bypass DEP and more.

    Stack Pivoting

    Once of the first steps in the exploit development process after you have gained control over the instruction pointer is to pivot the execution flow to your ROP chain. Traditionally this can be accomplished by adjusting the stack pointer to the beginning of your ROP chain and returning to it.

    IDA Sploiter can help you to find a suitable pivot by recording stack pointer change distances in the Pivot column:

    In cases where the location of the ROP chain is located in one of the registers, you can quickly search for a suitable reg-to-reg operation that modifies the ESP register using the semantic search method:


    IDA Sploiter supports exporting of all of the discovered gadgets and their characteristics to a CSV file. Select Export as csv.. context menu item and select a CSV file to save all of the gadgets:

    Writable function pointers

    Exploitation of the write-what-where vulnerabilities often relies on locating and overwriting writable function pointers (e.g. vtable entries). IDA Sploiter includes a powerful writable function pointer and pointer-to-pointer search engine to aid in exploitation of this vulnerability class.

    Searching writable function pointers

    You have already seen how to open the function pointer search form in the modules view. Another way is to select the function pointers... menu item in the Search menu:

    You will be presented with the configuration dialog like the one below:

    NOTE: Modules selected in the Modules view or any non-ASLR modules will be pre-selected automatically.

    Many of the search engine settings are similar to the ones in the ROP gadgets search form:

    • Pointer Charset - allows you to apply filters to the bytes constituting the pointer address. For example, in cases where the application filters any non-alphanumeric bytes, you can apply the alphanum pointer charset filter to only writable function pointers with alphanumeric addresses.

    • Bad Chars - additional pointer address character set filter. For example, 0x0a and 0x0d bytes often result in the injected payload being terminated too early.

    • Unicode Table - single byte to Unicode conversion table used to determine address pointer Unicode compatibility.

    • PTR Offset - writable function pointer offset (see below).

    • P2P Offset - pointer to pointer offset (see below).

    • Max Pointers - maximum number of pointers to find to locate in all selected modules.

    • Filter - apply pointer character set filter on the actual function pointers or pointers to pointers. This depends on whether you are writing directly to the function pointers or using an indirect pointer to pointer.

    • Do not search for pointers-to-pointers - select this box if you do not need to find pointer to pointers (faster).

    After you have selected the modules to use for the search and configured the search engine, hit the Search button to begin the search. A search progress popup will appear which allows you to stop the search at any time and review all of the discovered pointers:

    Viewing writable function pointers

    Once the search completes, you will be presented with a table containing a collection of discovered pointers and their characteristics:

    The view contains a wealth of information including addresses of function pointers, the calls using them, and any discovered pointers to those writable pointers.

    You can quickly jump to the memory location references by either of these addresses for further analysis. For example, let's look at the contents of the first pointer and verify it is indeed writable:

    In the above screenshot we can see that the pointer 0x004760C0 currently contains 4 null bytes and belongs to the writable .data segment. This makes it a perfect target if we can trigger the call dword_4760C0 instruction.

    Pointer offsets

    One of the useful features in searching for writable function pointers is the ability to specify pointer offsets. Imagine a scenario where you control both the fptr and value in the following instruction

    mov [fptr + offset], value
    call [fptr]

    If we want to gain code execution, then we need to subtract the offset from all of the located function pointers before overwriting their values. You can specify a positive or negative offset in the PTR Offset field (located in the search engine configuration form) and it will be automatically applied to all of the discovered writable function pointers. Consider the following entry which illustrates a sample offset 0x10:

    In the screenshot above the discovered pointer 0x004760B0 was automatically applied the offset 0x10. Once the MOV with the offset occurs, the original calling instruction call dword_4760C0 will execute the desired value.

    This feature gets particularly useful once we get to pointers to pointers. Consider the following example pseudo-assembly snippet where we control p2p and value:

    mov fptr, [p2p]
    mov [fptr + offset], value
    call [fptr]

    The pointer to pointer 0x00443783 was calculated using the offset to the pointer 0x004760B0 required for the copy operation, not the actual called function pointer 0x004760C0:

    The final frequently occurring scenario that we must consider is an additional offset in the pointer to pointer itself:

    mov fptr, [p2p + p2p_offset]
    mov [fptr + offset], value
    call [fptr]

    You can specify this new offset in the P2P Offset field of the Search writable function pointers dialog. Below is an example of using offset 0x20 applied to the pointer to pointer values:

    Just as expected the pointer to the actual desired 0x004760B0 address is located at the 0x20 byte offset relative to the specified pointer-to-pointer value of 0x00443763.

    Setting breakpoints

    Once you determine a set of interesting writable pointers, it is often convenient to set breakpoints on the calling instructions to see which one triggers first. You can set one or more breakpoints by selecting desired caller addresses and selecting the Add breakpoint in the context menu:


    IDA Sploiter supports exporting of all of the discovered pointers and their characteristics to a CSV file. Select Export as csv... context menu item and select a CSV file to save all of the pointers:

    Memory patterns

    Cyclic patterns (aka Metasploit patterns) are very useful constructs in the exploit development process used to quickly determine interesting offsets in injected payloads. IDA Sploiter supports both generation and detection of such patterns using default alphanumeric or custom character sets.

    Creating a pattern

    In order to generate a new pattern, open the Create pattern dialog from the Edit submenu:

    The Create pattern form will allow you to specify pattern size, define custom character sets, and select various output formats. For example, let's generate the classic Metasploit pattern of size 1000:

    All of the patterns have a limited size where they remain unique. For example, the classic Aa0Aa1... alphanumeric pattern can only produce up to 20280 unique bytes without repeating itself. Let's create a larger 100,000 byte unique pattern by introducing special characters and use the JavaScript format for the output:

    Feel free to play around with various pattern character sets to produce the desired pattern size compatible with whatever filters implemented by the application (e.g. lowercase only). All of the changes that you make to each character set field will be preserved so you can easily reuse them when to need to detect a pattern offset.

    Detecting a pattern

    To detect a pattern, open the Detect pattern dialog from the Edit submenu:

    The Detect pattern form has two formats depending on whether or not your are currently debugging an application. Below is the debugger version which detects patterns in all of the registers or a custom pattern:

    The static version is virtually identical with the exception of all of the register values:

    Comparing file to memory

    As you approach the end of the exploit development process, you decide to plugin your favorite shellcode. Unfortunately instead of a nice calculator popup or a welcoming port 4444 opening up on the compromised host all you see is a nasty memory error message. It is likely that you are dealing with a bad character or a memory hole issue which somehow corrupts your shellcode. To help you debug this issue, IDA Sploiter implements a file to memory comparison dialog which can help you identify the root of the problem.

    To open the dialog, select Compare file to memory... from the Edit submenu:

    A Compare file to memory form will pop up with the Memory field already filled in using the currently selected address in IDA:

    Let's inject a simple bind shell exploit generated by Metasploit and attempt to inject into the stack area. After the injection we will compare the injected memory with the raw binary on disk:

    In the view above, each memory offset has two rows: top row, identified by F corresponds to the bytes in the file, bottom row, identified by M corresponds to the bytes in memory. Identical bytes in both file and memory are identified using ... Any discrepancies can be observed by different byte values in the file and memory rows. In this example, you can quickly see that the null terminating byte prevented the rest of the shellcode from being injected into memory.

    Notice that even though there were null bytes still in memory (e.g. offset 0x04), they were correctly identified as discrepancies and bundled in the massive 337 byte memory hole starting at the offset 0x03 at the first instance of the bad character.

    Just for completeness let's view a case where both file and memory contents match:

    Great! With no null bytes, we are ready to continue execution of the exploit and pop a calc.

    Special Note

    The plugin would not be possible without the excellent work done by the Hex-Rays development team, especially their lightning quick support. Both the inspiration and the know-how to start using and developing for the IDA Pro came from Chris Eagle and his IDA Pro book.

    The IDA Sploiter itself was built on the backs of the giants including the excellent mona Immunity Debugger / WinDbg plugin by Peter Van Eeckhoutte, Byakugan WinDbg plugin by the Metasploit folks, narly WinDbg plugin by James Johnson, ROPGadget by Jonathan Salwan, and many others.

    Last but not least, greets to all of my teachers who helped me love and appreciate exploitation as an art form: Stephen Sims, Matteo Memelli, Jim O'Gorman, Aaron Portnoy, Zef Cekaj, Peter Van Eeckhoutte, Xeno Kovah, Corey Kallenberg, Steven Seeley, and Jason Kratzer.

    Happy 'sploiting folks!




    corelan - integer overflows - exercise solution

    A solution to the exercise in the Corelan article Root Cause Analysis - Integer Overflows on exploiting integer and heap overflows. The solution illustrates massaging the heap into a vulnerable state by corrupting the Windows front-end allocator and finally exploiting it to gain arbitrary code execution. Read more.

    heap overflows for humans - 102 - exercise solution

    Heap Overflows For Humans is a series of articles by Steven Seeley that explore heap exploitation on Windows. In this article I will go over the exact reasoning and exploitation steps for an exercise created by Steven in the second article of the series. Read more.

    01 oct
    exodus - vuln-dev - master class

    A few weeks ago I had a great pleasure of studying at a week-long training taught by Exodus Intelligence. The Vulnerability Development - Master Class was taught by Aaron Portnoy, Zef Cekaj, and Peter Vreugdenhil. The class had an excellent presentation of two complementary yet unique subjects of vulnerability discovery and exploit development primarily under Windows environment. The instructors are truly masters of their field which was reflected in the great quality and depth of the material.

    While it is still fresh in my mind, I would like to share with you some of the notes on the covered subjects, the recommended prerequisites, and tips on how to get the most out of this very intensive training. Read more.

    exploit exercises - protostar - final levels

    Exploit Exercises' Protostar wargame includes a number of carefully prepared exercises to help hone your basic exploitation skills. The final portion of the wargame combines Stack, Format String, Heap, and Network exploitation techniques into three excellent challenges to help solidify knowledge gained from previous exercises. Read more.


    All original content on this site is copyright protected and licensed under Creative Commons - Attribution, NonCommercial, ShareAlike 4.0 International.