Monday, February 23, 2009

nsearch - A New ImmunityDbg Searching Script

Hola, hope all in the world finds you well!

Well, some of my new research has not really been new at all, in fact, it's been catching up with all the different protections for memory corruption issues and how to get around them. This was really a necessity for me, as I was sitting on some stack-based buffer overflows that were not, what I would call, straightforward to exploit. Several protections were in play at the same time, including /GS, /SafeSEH n all modules, and DEP. To help me out with this, I wrote up an Immunity Debugger plugin that would help me search memory for potential pop/pop/ret r32 and call/jmp dword ptr[ebp/esp +/- X] and equivalent commands. I needed to find these either in some module that did not have /SafeSEH, or in a mapped, executable memory segment.

Due to the great support for Python in ImmDbg and the API it exposes to work with the debugger, this was pretty straightforward and easy to write. The examples provided by Immunity really helped out, as well. Thanks to Nico for all the help!

You can download it from the Immunity Forums, here. Which is also where I will maintain any revisions.

It has a couple of modes, which I'll describe below:

1.) Search instructions: !nsearch /a pop r32\\npop r32\\nret
This can be used to search all memory regions for a given set of commands.

This is intended to perform similar to the !search script included with Immunity Debugger, but it works a little different. It has an advantage, in that it can and will search all of memory; however, it uses imm.Assemble(), which does not currently support assembly of instructions with offsets (and possibly with numeric values). For example, call dword ptr[ebp+30] will not assemble correctly, and therefore will not be found using this mode. For this, you will need to use the /x mode and supply the opcodes for the command, or use the /f mode and code into the script the opcodes you want to look for.

2.) Search opcodes: !nsearch /x ff 55 30
This can be used to search all memory regions for a given set of opcodes.

The search is done using the imm.Search() method, but in this case, it will not first use imm.Assemble() method to assemble supplied instructions into opcodes.

This is going to be the most reliable, but also least flexible, method of using this script to search memory, as it will find exact opcodes you want, not try to get the assembly of an instruction right.

3.) Feelin Lucky: !nsearch /f
This can be used to search many opcodes at the same time.

The reasoning for using this search method is to search many opcodes at the same time that might bring you back to your shell code. There's only a couple examples right now, but this section could be easily added to. Essentially what I've done so far is use the pop pop ret combos, jmp/call dword ptr[ebp/esp+x] instructions from Litchfield's paper on exploiting win2k3, and a couple of examples from Pablo Sole's paper on DEPLib. If someone has a good list of obvious ones, I'll throw that in, otherwise, feel free to add your own favorites or required per your exploit into the code. This mode was really what the script was designed for, but I figured I'd put in the other modes to make it useful there as well. The code for this is all located within the doSearch method on approx line 96 in the first conditional, feelinlucky. It has a number of examples to show how you could add your own commands to search for.

4.) Less Mode: !nsearch /f /less
The /less mode allows for less verbose output, in this case only those modules marked "No" for /SafeSEH, those modules marked "Yes [No Handler]" for /SafeSEH (think ATL.dll), and memory pages that are not loaded modules will be displayed. This cleans it up a bit for those sploiting something with tons of modules. While I'm on the subject, ATL.dll shows up as Yes [No Handler], and it's quite often used in SEH overwrite exploits.

I've heard mention that it's usable because it was built with an "old version" of /SafeSEH checks, and I'm trying to confirm what causes that. So, I make no claims as to if every module that shows up as "Yes [No Handler]" will be usable for an SEH overwrite, but it's worth a look. I will also be trying to figure out exactly what's going on with this behavior, I just haven't gotten to it yet.

5.) Single Module Mode: !nsearch /f /singlemod modname
The /singlemod modname mode allows you to search only for usable opcodes from a single module. This is nice for cases where you know exactly which module you want to use (say a module that always starts at the same base addy in vista).


1 comment:

Russ McRee said...

Welcome back, Nate. Good to see you're well.