I'm interested in both defensive and offensive aspects of computer/information security, and have the good fortune to be able to provide services such as penetration testing and security assessments along with typical defensive security operations and practices and malware analysis/research, which gives me a well-rounded perspective with the trade-off that it takes longer to gather deep knowledge due to this same diversity.
I've been interested in memory corruption attacks for some years, starting back when the Morris worm was unleashed. I've written some stack overflows, and other simpler memory corruption exploits, but have never taken the time to learn heap attacks with any significant depth. This changed a few weeks back when I had the good fortune to attend a Windows Heap Overflow course presented by Immunity Inc. and taught mostly by the international expert Nicolas Waisman in sunny Miami Beach Florida (Nicolas Pouvesle, a new Immunity employee also taught a section of the course). This was an excellent opportunity to spend a few days focusing on heap exploitation techniques that I've never quite completely understood *in practice*, having only encountered them in phrack and other security research papers and conference presentations that helped give me some theory.
The class was small - 4 students - which allowed for a good deal of dedicated attention from Nico, who exhibited patience and the willingness to explain things in multiple ways - verbally, visually and with other examples (such as using paper pads as heap chunks and pens as forward and backward link pointers).
Nicolas Waisman giving the foo on the Vista Low Fragmentation Heap
As I'm writing this a few weeks after the course, the exact order of events may be a bit fuzzy, and posted images may not correspond with surrounding text. This write-up won't be too useful for people who are already skilled with heap techniques; such people won't likely learn anything new but for people like myself who have interest but little hands-on exposure may gain something new.
We started off on day one with basic heap theory which helped give us the necessary foundations to move forward. This included concepts such as the heap layout, the freelist, the lookaside list, unlinking and coalescence. Next, we moved to hands-on analysis with Windows 2000 virtual machines and analyzed the now-obsolete unlink technique with a crafted service that was specifically designed to respond to Immunity's VisualSploit tool. We studied the concept and practice of a Write4, writing 4 bytes of our choice to a location of our choice and analyzed the whole process step-by-step with Immunity Debugger, which is my debugger of choice for fumbling around inside Windows. We also analyzed the more rare case of a Write8 from the contrived heap scenario. In the process we also talked about various ways to trigger the crash including the use of the page heap, which I found useful, except when I forgot to disable it and was getting odd results later in the analysis process. Next, we moved onto other useful imdb commands such as !heap and !hippie to set hooks and view heap info. At the time of the class, to make !hippie work we had to select NTDLL.DLL from the executable modules list and analyze it in order for hippie to gather it's prerequisite information on allocation/free hooks. I think Nico said this would be fixed in the future, but I haven't checked for an update since it only takes a few seconds to analyze NTDLL.
Crashing function in Windows 2003 exercise
VisualSploit layout to trigger an early crash in the Freelist exercise
Next up, we practiced massaging the heap and using hard and soft memleaks to get the heap into a state favorable to a more reliable expoit. This was an interesting process to observe through imdb. At some point, we moved into a hands-on exercise taking a look at the spooler service heap corruption vulnerability (MS05-043). I only got part of the way into this particular exercise, as we ran out of time and plus I needed to spend additional time on the previous exercise in order to generate a more solid practical understanding.
Additional information on where to use our Write4 was delivered, such as the use of the PEB Lock, the RtlCommitRoutine, the .data section, RPC dispatch functions, function pointers and lastly the stack. Most of these suggestions were new to me, having never worked with them before (except the stack).
We also had further discussions about the challenges of the techniques of repairing the heap after corruption, and the differing approach taken by Immunity's CANVAS exploitation engine/framework which injects the payload into another process, bypassing the need to deal with the broken heap. The target needs to have SEDebug privs or fork-load, and LSASS was mentioned as fitting the bill. The CANVAS function is apparently self.createHeapSafeInjectionIntoProcess(self.badstring, host, port, smallcode=1) I thought this was a nice approach and shows innovation over the 'repairing the heap' mentality. I have not analyzed how this situation is handled in other exploits such as those written for Metasploit or Core Impact or the occasional stand-alone heap exploit published to Milw0rm by skilled people such as SkyLined.
We then spent time on some Lookaside methodology discovered/publicized by Oded Horovitz. I thought it was pretty cool that one of the techniques can end up transforming two Write4's into a write of up to 1024 bytes. The second technique on the Lookaside only needs one Write4, but points the Lookaside index into a function pointer. By this stage, it was nice to see the theory falling into place and I could feel several "aha!" moments taking place.
Next a section on RPC heap issues was discussed. Immunity has other course material that covers this in more depth, and I believe they are discontinuing the dedicated RPC course and rolling the contents into the "unethical hacking" class, if I recall correctly. IDA pro analysis screenshots were used here, then it was mentioned that we could use imdb's !getrpc to fetch the location of the function pointer array located in the writeable .data segment. Taking a look at the UUID of some RPC functions reminded me of using Nessus to enumerate the MSRPC DCE endpoints some years ago when I was a consultant in Chicago (and in times since). At that time in Chicago, I only had a vague notion of what the UUID represented, but it was nice to have things tie together in this section of the class. I don't think I'll be auditing any RPC services any time soon, but it was very interesting and practical.
Next we moved into covering methodology to bypass XP SP2+ and 2003 heap protections, starting with the use of the Lookaside and it's use of a vulnerable single-linked list pointer to perform a Write4 through the overwrite of a free lookaside chunks pointer with a fake pointer. Exploitation can then take place through various allocations until the crafted pointer is returned. The next technique was the FreeList insert, which I thought was pretty interesting. Somewhere in here, Nico used several pads of paper to represent heap chunks on Freelist and pens as the link pointers, which helped me to visually process the methodology.
This image shows an overflow into the freelist prior to alignment.
Next up was a DEP bypass, via a ret2libc technique. Nico showed a nice trick to switch the heap into the stack and then call ntdll.ZwSetInformationProcess, bypassing null bytes by jumping to just the right mem location. As I was falling behind at this stage of the course, Nico walked me through the process and I was impressed with the elegance of this hack and watching each step of the way with the very useful imdb scripts. I think that Skape & company covered a similar technique in one of the issues of the Uninformed journal. In hindsight, it would be have been nice to turn on the VMware video feature to save the example of this taking place for later review. It's not every day (for me at least) that I have the time and the means to step through such a technique with an international heap expert. JMP ESP ftw!
Heap to ESP location found via imdb search
VisualSploit setup for the DEP bypass technique
The last day was dedicated to covering the Vista heap, which has been redesigned to be much more secure. I found there was a great deal of information here and I found my brain starting to gum up with pointers and chunks and other heap related matters and had a harder time concentrating. But Nico did a good job handling this material, I only wish I had more time to sit with it and him. We covered the low-fragmentation heap (LFH), I_Buckets (replacing the FreeList) and more. The walkthrough on the LFH was when I began to notice my eyes seriously glazing over as I began to reach saturation threshold. Still, I appreciated some of the expressive wording in the training material such as "We need to be able to predict and control a heap universe..." as well as the focus-inducing "Whats important so far" heading, which helped my eyes unglaze a bit. We didn't have time to cover all the Vista exercises, but soon moved on into the PHEAP technique.
The PHEAP technique, presented by Ben Hawkes at RuxCon 2008, was enjoyable. The overwrite of a heap pointer with a crafted chunk (including crafted encrypted values where appropriate) was a nice way to bypass some of the Vista checks that would be very difficult to bypass otherwise and just goes to show how hard it is to truly secure memory allocation processes. The imdb script !benhawkes (as discussed on Nico's blog) is a big time saver with regards to picking addresses that meet the several criteria for use with the technique. Seeing Ben's techniques demonstrated and discussed made me wonder what other Vista heap techniques might exist in the wild, or in private research circles.
By the end of the course, I had learned a great deal about the windows heap, and the idea that heap overflows are much more difficult than stack overflows became an in-the-face reality. There was a lot of material covered, and I found that the ideal scenario would have me spending a full week on this course instead of four days. People with more exposure to debuggers and windows internals would of course need less time. The "drinking from a firehose" concept comes to mind. I could have used more "What's important so far" sections to help re-focus my mind, especially on the 3rd and 4th days when the material got more dense.
Some suggestions that would have made the class more enjoyable for me include the following:
1) A more detailed list of prerequisite knowledge, including specifics. Nico was kind enough to tweet me before the course and give me some pointers, but given my lack of exposure to some of this, I wished I had spent more time preparing. I understand that anyone offering a course wants people to attend and doesn't want to scare people away, but a published list of suggested prerequisites that went into some detail would have been very useful.
2) The 257 page book, printed single sided in landscape. The binding was quality and not likely to break, but it kept wanting to close by itself. I liked to use the book to take notes but since it didn't like to stay open, this required continuous mashing to the desk. This was a distraction, but I knew that if I didn't take notes on some of this, I'd lose it. In hindsight, I should have taken along a larger notebook but taking notes directly on the course materials is one of the best ways for me to focus on the important points.
3) A more consistent and in-sync lab environment. We were plagued by various problems caused by versions being out of sync, causing various problems that slowed me down even further than my already molasses-slow process had me going in the first place. It was easy to fall behind while having to deal with some of these issues. Nico was helpful in passing around the new code, but it would have been nice to have all of this handled ahead of time, allowing the students to focus in on the material as much as possible. In addition, Vmware liked to crash every so often, which would stunt progress. Sometimes, these things are just unavoidable and simply represent the types of real-world challenges that we all have to face, but in a four day from-the-firehose course, minimal issues of this nature would have been favorable.
4) Video walkthroughs of some of the lab exercises. It would be as simple as turning on the Vmware video recorder while stepping through an exercise. The student could then pause the exercise and rewind as needed to follow the methodology as it's put into practice. Such walkthroughs would be very helpful for people who had trouble remembering everything after the fact. Perhaps others with younger brains would have an easier time of this than I, a 40 year old greying computer nerd who started out in the 80's with a Commodore VIC=20.
6) Some area, perhaps on the Immunity forum, for class members to discuss the course after the course ends, perhaps up to 3 months worth of access (or longer). Sure, this could be done with a google group or private e-mails but a forum might be useful for others taking the course(s) in the future, to build some history and community.
Overall, I enjoyed the course a great deal, with my favorite part being when Nico walked me through one of the Windows 2003 DEP bypass techniques in Immunity Debugger that I only previously knew from theory. It was great to get *practical* information that's real-world and usable now. Other courses sometimes focus only on the ancient, long-dead techniques, raking in a few thousand dollars to have you exploit Windows 2000 and RedHat 9, which will be of limited value in practical application such as doing security research, writing PoC's and doing pentests on custom binaries.
A very nice personal touch took place each day at lunch, when other Immunity employees visited. Justine Aitel brought them by and it was great to meet quite a few of the Miami-Beach based Immunity staff. We also got to see a basic demo of a slick SILICA device, although the "click here to pwn the network" button never got pressed :)
After the last day of the course, we all went to the Immunity HQ on Alton Road and had drinks, food and conversation. This was a great way to cap things off. In addition to social time, much good discussion was had, including some excellent brainstorming on a webapp assessment I'm doing, discussed with an Immunity staffer. My thanks to Justine for her facilitation of this! Afterwards I walked over to Whole Foods for a super-expensive-but-tasty healthy dinner.
I would highly recommend the Immunity Heap exploitation course to anyone who is looking to gain a deeper and practical understanding of heap exploitation methodology and technique. Simply taking a few days to focus on the material at hand has given me a large boost of understanding into this classic exploitation technique and hands-on skills to use this information in practice.
Evading CSP with DOM-based dangling markup
4 days ago