Jump to navigation

Poupou's Corner of the Web

Looking for perfect security? Try a wireless brick.
Otherwise you may find some unperfect stuff here...

Weblog

More Cecil/Dot graphs

I did more Cecil/Dot hacking this weekend. The previous graphs has given me good ideas of how some user code could exploit some critical methods. It even shows some of the security checks, the declarative security attributes, on the methods (called before entering the method). But this picture is missing a lot of details, like any security checks done inside the methods (i.e. the imperative security checks).

A good example is when access to a file or an environment variable is required. The name of the resource isn't known until runtime (at least from the framework point of view) so declarative security cannot be used. This graphic shows the calls made to Environment.GetEnvironmentVariable(String) from inside mscorlib.dll. We see that, by definition (metadata), anyone can call Environment.GetEnvironmentVariable(String). We also know, or at least expect, that the access to environment variables be protected by CAS. But we can't see it unless we look at the IL code.

Note #1: The graphic shows public types/methods in blue. Bold is used on static methods.

Note #2: Actually the previous graphic also show another problem. The static constructor (.cctor) of the System.Runtime.Serialization.Formatters.Binary.BinaryCommon type ask for an environment variable. The problem is that we can't predict the stack when a static constructor is called - so we can't know if any CAS permissions will succeed or fail. In this case this isn't a big problem as the type (and the .cctor) aren't public and because the environment variable name cannot be influenced by user code. We just have to change the existing call to a security-less version of Environment.GetEnvironmentVariable(String).

Ok, Back to the main issue... we expect to see a CAS permission demand in Environment.GetEnvironmentVariable(String). We could look at the IL itself which would be easy in very small methods, like this one, but can easily gets confusing for large methods (e.g. do all the code paths go thru the security check ?).

System.String System.Environment::GetEnvironmentVariable(System.String) { // code size : 29 .maxstack 8 .locals () IL_0000: call System.Boolean System.Security.SecurityManager::get_SecurityEnabled() IL_0005: brfalse IL_0016 IL_000A: ldc.i4.1 IL_000B: ldarg.0 IL_000C: newobj System.Void System.Security.Permissions.EnvironmentPermission::.ctor (System.Security.Permissions.EnvironmentPermissionAccess,System.String) IL_0011: callvirt System.Void System.Security.CodeAccessPermission::Demand() IL_0016: ldarg.0 IL_0017: call System.String System.Environment::internalGetEnvironmentVariable(System.String) IL_001C: ret }

Note #3: Extracting the IL code with Cecil is very simple. See Jean-Baptiste Evain's sample code.

So this time I wanted to add graphs of the IL code, i.e. generate dot files from the previous IL. This is very similar to what other people have been doing. However my version as some security enhancements (well that's the whole point of it ;-). For example I mark some calls to the security runtime in red and display interal calls with "double lines". It's simple but effective as it makes it easy to see if (and where) some code can bypass a security check inside a method.

Now looking at the same IL code as a colored graph makes it perfectly clear. If the security manager is enabled (first red box) then an EnvironmentPermission instance is created with the variable name and a Demand (second red box) is made prior to returning the value.

My only problem is that dot-ing IL can generate very big bitmaps (this one being small). They compress well on disk but their RAM requirements can be very high to display. I'll need to look at dot's options to see if I can squeeze them a little without loosing readability.

I still have many ideas to visualize code using Cecil and Dot but I think it's about time I put some Gtk# GUI on top of this...


4/18/2005 11:09:30 | Comments

The views expressed on this website/weblog are mine alone and do not necessarily reflect the views of my employer.