Wednesday 20 February 2008

CASToggle and The Polymorphic Podcast

Craig Shoemaker, a good friend, Microsoft MVP and host of The Polymorphic Podcast, sweetened my little CASToggle quiz by trowing in a license for a Microsoft .NET development tool. Check out hist post. Thanks Craig!

The reason is that the setting for disabled CAS enforcement is implemented with a mutex owned by the BUILTIN\Administrators group. As a non-admin user, you can also create this mutex, but it will be owned by your account, not by the administrator group. And the CLR checks the ownership of the mutex and will only acknowledge it when it is owned by BUILTIN\Administrators.

But my CASToggle tool does not use a mutex. CASToggle allows you to directly manipulate the variable in the CLR where the status of the mutex is stored. This variable can have 3 values:

0: uninitialized, this means that the CLR has not yet looked for the presence of the mutex. This is the case when your .NET program starts to run.

1: CAS enforcement disabled, this means that the CLR has found the mutex.

2: CAS enforcement enabled, this means that the CLR has not found the mutex.

The CLR will only perform a single check for the presence of the mutex. That’s why changing the CAS enforcement policy with caspol has no effect on running .NET programs.

Did you know that the CLR runs in your own process memory? And did you know that in Windows, you have full control over your own processes, even as a limited user? To manipulate the process of another user (e.g. reading and writing to the virtual memory owned by the target process), you need the debug privilege (local admins have this privilege by default). But you don’t need this privilege for your own processes.

That’s what differentiates CASToggle from caspol. If you’re a local admin (or you have the debug privilege, to be more precise), you can use CASToggle on any process. But as a limited user, you can still use it to disable CAS enforcement for your own processes.

I’ve been doing some research on security mechanisms implemented in the user’s own process space. The design of these security mechanisms is fundamentally flawed, because a limited user has full control over his own processes and can thus bypass the security mechanism. He just needs internal knowledge about the mechanisms (or a tool), and then he can bypass it because he has the rights to do so.

Robust security mechanisms are implemented in process space that is off-limit to normal users. This can be inside the kernel (like the reference monitor) or inside user-land space of a protected account (like services that run under the local system account).