Saturday, January 5, 2008

SetWindowsHookEx and Restricted Token

One easy way on Windows to inject a DLL is to use SetWindowsHookEx.

From MSDN:

The SetWindowsHookEx function installs an application-defined hook procedure
into a hook chain. You would install a hook procedure to monitor the system for
certain types of events. These events are associated either with a specific
thread or with all threads in the same desktop as the calling thread.




When the event you are interested in is triggered for the first time in a process, your DLL is going to get loaded and your hook procedure will be called. For example, if you set a mouse hook, the DLL is going to get loaded in the process as soon as you move the mouse over a window owned by this process.

But the desktop is not a perfect security boundary. You can have applications on the desktop running as a different users, with different rights. You can also have some applications running as a restricted version of yourself. How can we ensure that an application can't use SetWindowsHookEx to elevate it's privilege?

There are multiple answers.

First of all you can put this application on a job object and set the UILIMIT_HANDLES restriction. With this restriction a process in the job object can set hooks only on processes that are also in the job. But setting this flag also means that you can't access any user handles (HWND, etc) created by processes not associated with the job. If your application has some UI, then you have a lot of work to do if you want to fix everything that is going to break! (No icons, no cursors, can't access the desktop window). UserHandleGrantAccess can help you here...

On vista it's a little bit easier, you can run the application with a low integrity level token and User Interface Privilege Isolation (UIPI) will do the work for you. Internet Explorer 7 is using it to be more secure. It will prevent your application from setting hooks on other applications running with a higher integrity level.

What if you can't use any of them? Well, if your application is running with a restricted token, you may not have to worry about this at all. A restricted token is a stripped down version of your token created with the CreateRestrictedToken api. The SidsToRestrict array passed to the function must be non-null. In other words, IsTokenRestricted must return true. If this is the case, Windows will do the right thing and will not trust your application if you try to set a hook.

I haven't found any documentation on this... but during my tests I have seen two different behaviors:

  1. For some hooks (WH_MOUSE for example), when the event is received in another process, instead of loading the DLL, it sends a message to the thread that registered the hook. The message is handled internally and will cause the hook procedure to be called. Your application is now receiving and parsing all the events from all processes by itself in its own process. That does not sounds very efficient to me, but at least it's not a security flaw. (Don't quote me on this)
  2. For some other hooks (WH_CALLWNDPROC for example), the event seems to be ignored and the hook procedure is never called.

I haven't done a lot of testing so far on this, but it seems like a thread running with a restricted token can't inject a DLL using SetWindowsHookEx, which is good.

One warning: If you try to do this, there is a nasty side effect. Since the events are now sent to the calling thread using window messages, you must have a message loop, otherwise your system is going hang! I don't think there was any requirement before that the caller of SetWindowsHookEx have to peek messages.

Saturday, September 22, 2007

Old Old New Thing

Today I was trying to catch up with all the new entries on Raymond's blog and I found some interesting posts that are worth taking a look.


What do I do with per-user data when I uninstall?

Microsoft says... oh wait... I mean.. Raymond Chen says that we should not touch it! Quick and Easy! I like that :)

Why isn't QuickEdit on by default in console windows?

Because it breaks console mode applications using the mouse.

Does creating a thread from DllMain deadlock or doesn't it?

It does not. Except if you create the lock yourself by waiting for the thread to do something, because it's not going to run until you exit DllMain.

Sunday, September 2, 2007

Handle Format

A couple of posts ago I talked about how to get the list of all open handles. When I started playing with that it did not work at the first try, so I had to use the brute force method to get all the handles in the current process. The code was doing a loop like this:


for (LONG_PTR h = 0; h < 0xFFFF; ++h) {
HANDLE handle = (HANDLE)(h);
DoSomething(handle);
}


The result was unexpected to me. All handles in the process were duplicated 4 times. It looks like the lowest 2 bits in the handle value are ignored.

If the handle to a file is 0x7C then you can use 0x7C, 0x7D, 0x7E or 0x7F to access the file.

Is this documented somewhere?

Updated on 9/3/2007:
I was talking with Ivanlef0u about this and my assumption that the last 2 bits are ignored is right. He showed me the disassembly of the function to lookup the object in the handle table and it looks like this:


ExpLookupHandleTableEntry
mov edi, edi
push ebp
mov ebp, esp
and [ebp+Handle], 0FFFFFFFCh ; Unset the last 2 bits
mov eax, [ebp+Handle]
mov ecx, [ebp+HandleTable]
mov edx, [ebp+Handle]
shr eax, 2 ; Shift right the last 2 bits
cmp edx, [ecx+38h] ; HandleTable->NextHandleNeedingPool
jnb loc_49DDF8


Thanks Ivanlef0u.

Using Visual Studio to debug your token.

For as long as I remember I have been using TokenMaster to be able to see and dump the information contained in my access tokens.
Recently greggm blogged about another way to get this information. This is now integrated in the visual studio debugger. Just type "$user" in the watch window and you will get a complete view of the current token.

Updated on 9/4/2007
Thanks to Marc-Antoine Ruel for the information, Windbg also does that! Just type this command to get the same information:

!token -n

How to list all the open handles?


Recently I had to get the list of all the handles open in a process. I searched on the web to find a good way to do it, and realized that most of the articles I found are wrong.

I guess this is because the documentation in "Windows NT/2000 Native API Reference" by Gary Nebbett is a little bit misleading.

Under the SystemHandleInformation class, the structure defined is:

typedef struct _SYSTEM_HANDLE_INFORMATION {
USHORT ProcessId;
USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;


One could think that the buffer returned is actually a list of structures like this one. But this is not the case, it's actually returning a structure like this one:


typedef struct _SYSTEM_HANDLE_INFORMATION_EX {
ULONG NumberOfHandles;
SYSTEM_HANDLE_INFORMATION Information[1];
} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;


Even though the description in the book is misleading, Gary Nebbett is not wrong. There is a remark saying: "The data returning to the SystemInformation buffer is a ULONG count of he number of handles followed immediately by an array of SYSTEM_HANDLE_INFORMATION".


There is another factor making this task a little bit more complex to achieve: The function is really picky about the buffer size.


Usually you can call the function with a NULL buffer and 0 for the size and then get back the size you need to allocate your buffer. This does not work here. The return value is 0xC0000004 : The specified information record length does not match the length required for the specified information class.


If you try with a SYSTEM_HANDLE_INFORMATION buffer, it won't work either. You need to pass to the function a buffer large enough to hold the number of handles and the first handle if you want to get the size needed back. This is a little bit weird.


Finally, the code:



// Get the number of handles on the system
DWORD buffer_size = 0;
SYSTEM_HANDLE_INFORMATION_EX temp_info;


NTSTATUS status = NtQuerySystemInformation(
SystemHandleInformation, &temp_info,
sizeof(temp_info), &buffer_size);


SYSTEM_HANDLE_INFORMATION_EX *system_handles =
(SYSTEM_HANDLE_INFORMATION_EX*)(new BYTE[buffer_size]);


status = NtQuerySystemInformation(SystemHandleInformation,
system_handles,
buffer_size, &buffer_size);


printf("nb of handles = %d", system_handles->NumberOfHandles);

Thursday, August 9, 2007

sizeof Cheat Sheet

It's hard to justify why this kind of cheat sheet is necessary. We should all know this information by heart. Unfortunately I realize that sometimes I'm not 100% sure and I have to look it up. If it happens again, then I'll come back here!


The size of the different types is in bytes.


win64 win32
-------------------------------
bool 1 1
BYTE 1 1
char 1 1
-------------------------------
SHORT 2 2
wchar_t 2 2
WORD 2 2
-------------------------------
BOOL 4 4
DWORD 4 4
float 4 4
HRESULT 4 4
int 4 4
long 4 4
unsigned int 4 4
unsigned long 4 4
-------------------------------
HANDLE 8 4
INT_PTR 8 4
LONG_PTR 8 4
ULONG_PTR 8 4
void* 8 4
-------------------------------
__int64 8 8
double 8 8
LONGLONG 8 8
ULONGLONG 8 8
-------------------------------
FLOAT128 16 16
-------------------------------

Wednesday, August 8, 2007

ThreadHideFromDebugger! But Why?

At BlackHat last week Mark Vincent Yason talked about the art of unpacking. One of the techniques used by some packers is to hide their threads from the debugger so it can't be easily debugged.

It is really easy to hide a thread from the debugger, you just have to call :

NtSetInformationThread(hThread, ThreadHideFromDebugger, NULL, 0);

At this point the debugger will stop receiving debug information or exceptions from this thread. But be careful! If you are debugging the process and you set a breakpoint and it happens to hit in the hidden thread, the process will crash and windbg won't even realize it.

After the presentation I was not able to stop asking myself why did Microsoft implemented this feature. It seems like the only usage is to make "malicious" code harder to debug. Maybe they implemented it to mute some noisy threads? Or maybe they wanted to protect some system threads? If you know the answer, please let me know!

The next thing to do was to check if Microsoft is in fact using this feature. I put a conditional breakpoint on NtSetInformationThread to hit when the ThreadInformationClass is equal to ThreadHideFromDebugger.
Unfortunately it never hit. (Tested on XPSP2 and Vista). There is also the possibility that they are changing the ETHREAD structure manually, but I doubt so. I'll try to check that later.

On the other hand, something interesting came up during this experiment. On Vista it seems like NtSetInformationThread is called really often with an invalid (or undocumented) ThreadInformationClass. I'll try to investigate that and write my results in another post. In the mean time, I dumped the number of occurrences of each ThreadInformationClass during the boot of windows. I haven't found any use for that yet, but anyway:

Windows XP SP2
   4 ThreadPriority
16 ThreadBasePriority
2 ThreadAffinityMask
2069 ThreadImpersonationToken
16 ThreadQuerySetWin32StartAddress
16 ThreadZeroTlsCell


Windows VISTA
  16 ThreadPriority
490 ThreadBasePriority
4 ThreadAffinityMask
6293 ThreadImpersonationToken
71 ThreadZeroTlsCell
1 ThreadPriorityBoost
460 Unknown - 0x16
481 Unknown - 0x18
10 Unknown - 0x19