What’s Exploitable?


As I alluded to previously, this has gotten to be a more and more interesting question lately. One of the things I’ve been kicking around is a sort of flowchart so that people who don’t study this stuff will come to the correct conclusion more often. It’s also a question of what counter-measures are in place, and which version. For example, David Litchfield made it clear that with the Visual C++ 7.0 version of /GS, all it takes is to whack an exception handler and cause an exception to take control of an application. But then in the 7.1 compiler, there’s SafeSEH, which does a decent job of thwarting this attack, and in the 8.0 compiler, the exception record is even more well guarded. So here’s some notes about what things will and won’t do –

ASLR – as I said last post, this is a speed bump. It makes it harder to write worms, but it won’t help much (sometimes at all) against local attacks. It’s also true that if the exploit depends on a relative offset instead of an absolute offset, this may not be much help at all. If you abuse exception handlers, you can undo any good this might have gotten you.

SafeSEH – keeps exception handlers from getting whacked, but if you load a DLL that doesn’t have this, it’s exception handlers could get whacked, and just about anything in the DLL could be fair game for being called. It’s a good countermeasure, but know the limits. Note – if it is a 64-bit binary, then the exception handlers are hard-coded in the binary, are read-only, and this attack is foiled.

NX – probably one of the most potent of the countermeasures, when it can be turned on. Theoretically, you could VirtualProtect something into being executable, but as had been pointed out, this is practically difficult. Can be thwarted by return into libc, or even a return into your code that happens to do just what the attacker wants. This plus ASLR can make life really difficult for the exploit writers.

64-bit – this changes the game quite a bit. The default calling convention is fastcall – with a twist – in fastcall, the first parameter is passed in a register on 32-bit, but on 64-bit, the first _4_ parameters are passed in registers. A whole lot of stuff is different, and harder to attack. Unbreakable? I don’t think so. Harder? I think it will be, especially until everyone gets the hang of it.

What’s still out there? There’s certainly data-driven attacks – if you can munge up the argument to LoadLIbrary, that’s the same as running completely arbitrary code.

Interesting stuff – Low rights (protected mode IE) is a really cool feature. Limitations – it can still read your data, but can’t trash your system or even your personal settings. Something else really cool I’ve written articles on in the past are restricted tokens. I’ve learned more about these in the last couple of years (and some more in the last month or so). You can use these to create a process running as essentially nobody, which is a neat thing to be able to do. Yeah, yeah, UNIX has had it for ages, and I still can’t chroot, but I can still do some cool stuff with it, and I’m personally more concerned about what can be done with Windows security. I’ll spend more time on this later.


Comments (3)

  1. Andrew Royal says:

    Exploiting NX with VirtualProtect could be a bit complicated. Perhaps an easier way would be a memcpy to writable and executable memory. There are many writable areas used for trampolines. In fact that was the biggest obstacle for PAX like implementations on Windows due to too many false positives.

    If that worked well we would had NX implementations long before SP2. NX became possible once Microsoft cleaned up its code by replacing PAGE_READWRITE with PAGE_EXECUTE_READWRITE. However, writable and executable trampolines are still there.

    ASLR certainly makes it harder, but have a look at this article: http://www.determina.com/security.research/presentations/bh-eu07/bh-eu07-sotirov-paper.html

  2. Andrew Royal says:

    By the way, Joanna Rutkowska has pointed on a hole in integrity levels (IE “protected mode”), particularly WM_KEYDOWN message that can be sent to a higher integrity process. I still didn’t see a reply on this, will it be fixed and when?

    http://theinvisiblethings.blogspot.com/2007/02/running-vista-every-day.html

    Also I guess there are others breaches in integrity levels implementation. What other messages are bypassed? There is very little info on UIPI implementation.

  3. It’s true – if there are still RWX pages in the process (though this could be complicated by ASLR), it represents a much easier attack point.

    I think you may have given me the wrong link – it doesn’t mention ASLR. ASLR would tend to complicate what is starting to look like a more and more unreliable approach, since the address that you’d need to jump into gets less deterministic. Before going too far out on this limb, I’d like to be able to take a poke at a real app, find the RWX pages (if any), then see if they show up in predictable places from one instance to the next. This is based on the assumption that you’ve managed to cause an attacker-controlled write into RWX memory, and are now seeking to jump into that memory by heap spraying. If the RWX memory is moving around, and the heap has gotten harder to play with, that’s a difficult one.

    Joanna’s article is interesting. I can’t comment here about open issues, and certainly not my job to say when things might get fixed. There’s an API to set which window messages can be sent from lower IL processes to higher – it can either open them up, or it can reduce them.

    My take on it is that trying to put privilege levels where they did not previously exist is hard, and I don’t expect such things to initially be perfect. I expect us all to find them over time, and we’d be fixing them.

    You’re right that there is very little info, even internally – on some things at least. I know the guy who designed this, so I have better access than most, but even I’m not completely sure what messages are allowed by default and which ones are not. I’ll hopefully have it sorted out soon, and I’d expect it to get published to MSDN.

    Thanks for the links – I hadn’t seen those previously.