Friday, November 21, 2008

Fun with SSDT Hooks and DEP

My favorite part of work here at the VRT is how much you can learn from a project that, in the end, doesn’t achieve what you set out to do. This past week, I was looking at the possibility of watching, in the Windows kernel, for attempts to bypass DEP protection. Briefly, DEP is Microsoft’s term for a combination of hardware and software techniques to prevent code execution on memory pages that contain data. You can get a more through description here and here. In this case, I’m looking just at the hardware protection (NX) parts of DEP.


I started by looking at the bypass address used in Metasploit’s English XPsp2 attack over the MS08-067 attack in acgeneral.dll. The code looks like this:

[acgeneral.dll]
.text:6F8916E2 push 4
.text:6F8916E4 lea eax, [ebp+arg_0]
.text:6F8916E7 push eax
.text:6F8916E8 push 22h
.text:6F8916EA push 0FFFFFFFFh
.text:6F8916EC mov [ebp+arg_0], 2
.text:6F8916F3 call ds:__imp__NtSetInformationProcess@16 ;NtSetInformationProcess(x,x,x,x)
The function is setting up the arguments to NTSeteInformationProcess, which are:
[ntdll.dll]
0x4 (Length of the arguments field)
*ptr args (Pointer to the arguments for the ProcessInformationClass, in this case “ExecuteFlags”)
0x22h (ProcessInformationClass, with 0x22 meaning “ProcessExecuteFlags”)
0xFFFFFFFF (Handle, with FFFFFFFF meaning “This Thread”)
Here is the code for the SetInformationProcess call:
[ntdll.dll]
.text:7C90E62D mov eax, 0E4h ; NtSetInformationProcess
.text:7C90E632 mov edx, 7FFE0300h
.text:7C90E637 call dword ptr [edx]
.text:7C90E639 retn 10h
7FFE0300 is a pointer to a data structure that contains the address of the KiFastSystemCall (syscall) function. 0E4 is the offset in the System Service Dispatch Table (SSDT) which contains the address for the system call handler for NtSetInformationProcess calls. The SSDT is in kernel land, which means you need to feed the call to Ring0. For completeness, here is the code that ntdll.dll uses to call SSDT entries:
[ntdll.dll]
.text:7C90EB8B mov edx, esp
.text:7C90EB8D sysenter
By definition, EDX holds a pointer to the arguments to syscalls, in this case ESP, but it doesn’t have to be, the address just needs to be in EDX when the sysenter call is made.

So at this point, I know that from userland, one major way to turn off DEP ends up with a call to the SSDT at offset 0xe4h, with the “ProcessExecuteFlags” opnum. Now I needed to find a description of these flags; which I found in, of all places, the source code for Chrome. Here is their enumeration for ExecuteFlags:
const int MEM_EXECUTE_OPTION_ENABLE = 1;
const int MEM_EXECUTE_OPTION_DISABLE = 2;
const int MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION = 4;
const int MEM_EXECUTE_OPTION_PERMANENT = 8;
So my idea was this…if I can trap the SSDT call to NtSetInformationProcess, then I should be able to watch for calls to ProcessExecuteFlags, check the ExecuteFlags field and then call them out in an attached debugger (or a userland app that grabs DbgPrint calls). My end hope was that we could use this at some of our test points to try and catch exploits that used the syscall method (either through DLL or through custom stack creation and passing control to NtSetInformation process in ntdll, or if they are mighty clever directly calling the KiFastSystemCall function directly, you’d need control of EDX, or have it point to a place you can control) to bypass DEP.

So I wrote a hook into the SSDT that would call a function of my choosing when the NtSetInformationProcess call was made. For the moment, all the hook does is check to see if the call is a ProcessExecuteFlags call (0x22) and then if the flags field attempts to turn off DEP. If it matches these parameters, a DbgPrint call is made, and I check on the client side to see what process is called. Note: In kernel land it is possible, but not straightforward to get the process name, so it was just quicker this way.

The test box is a VMWare install of Windows XP at SP2. The processor I’m on doesn’t support NX, so for the moment, I just have to trust what I’m seeing and not monkey with the calls to prevent DEP from changing. While more testing is required, here is a list of things I’ve seen turn off the DEP bit:
  • VMWareService.exe
  • wscntfy.exe
  • msmsgs.exe
  • msimn.exe
  • IEXPLORE.EXE
  • VMwareTray.exe
  • VMwareUser.exe
  • UpdNotifier.exe
  • firefox.exe
  • Impact.exe
So…pending some more investigation (Vista, should be interesting trying to get the hooks in..., XPsp3, checking output on a NX capable processor…) it looks like what you would think is a bad idea (enabling code execution on data pages) happens a fair amount. I was initially suspicious that this might be because I was “Opt In”, so I changed the XP system to “Opt Out”, so that only programs I specify don’t have NX on. But that didn’t change the results. I’m going to update the system, and try to track down an NX capable box, and then see if that changes anything. Either way, I’ve got the framework for hooking SSDT and I’m sure I can come up with some interesting things to do with that :).

Hit us up with some comments, information, testing thoughts etc...

No comments:

Post a Comment