chml: A Utility To Manage Windows Integrity Levels

Vista includes a new notion of what were originally called "Mandatory Integrity Controls" but eventually became "Windows Integrity Controls." Under WIC, every object that have permission can also have a label that identifies its "integrity level." There are six integrity levels, from highest trustworthiness to lowest:

  • Trusted Installer
  • System (operating system processes)
  • High (administrators)
  • Medium (non-administrators)
  • Low (temporary Internet files)
  • Untrusted

Files and folders have integrity levels, as do users and processes.   What good are these "trustworthiness levels?"  Well, they act as a kind of second level of Windows permissions.  When a lower-integrity user tries to modify a higher-integrity object, then Windows integrity controls blocks the modification attempt, and blocks it even if the object's permissions list contains a "full control" permission for that user.  It is, thus, a sort of set of uber-permissions, albeit a simple one.

What chml Does

When I set out to write my book Administering Windows Vista Security:  The Big Surprises, I knew that the book would be incomplete without an in-depth look at Windows integrity controls.  But no tools existed that could let me modify an integrity level.  Microsoft eventually came out with a tool "icacls" that allows some basic manipulation of integrity levels, but it didn't work properly until just a few weeks before Vista shipped, and I needed a tool much earlier than that, hence chml.  Nor was my time wasted because, as you'll see, it turned out that icacls is too rudimentary to really showcase Windows integrity controls' capabilities.

chml's design goals were simple.  I wanted a tool that would:

  • Install simply and with a minimum of trouble.  chml is, therefore, a command-line tool that is just a simple EXE file, with no setup program required.
  • Allow me to view a file or folder's integrity level.
  • Allow me to change a file or folder's integrity level.
  • Allow me to experiment with extensions of the basic Windows integrity control, and go beyond the standard "no write up" policy (no low-integrity process can modify a higher-integrity object) to the implemented but unused "no read up" policy, which blocks any attempts by a lower-integrity process or user to read the object.  This seemed like a potentially nice feature in a world beset by Web-borne spyware!

Downloading chml

It's right here at www.minasi.com/vista/chml.exe.  Just right-click it and save it somewhere on your Windows path.  I usually store it in the \windows\system32 folder.  Then you can open up a command prompt and run chml.

Getting Ready to Use chml

You can use chml "right out of the box" to view a file or folder's integrity level just by typing chml fileorfolder, as in

C:\>chml \windows\notepad.exe

But if you want to modify an object's integrity level, then you'll need to give your user account a new-to-Vista permission, "Modify an object label."  You can find that in the "User Rights" part of Group Policy on a Vista machine.  Or, in a few more words:

  1. Open gpedit.msc
  2. Navigate to Computer Configuration / Windows Settings / Local Policies / User Rights Assignment
  3. In the right-hand pane, you'll see an entry "Modify an object label;" open it
  4. By default, there are no user accounts listing with this privilege.  Add your user account.
  5. Close the Group Policy Editor
  6. Log off, then back on to finish getting the new privilege on your logon token.

Now just open an elevated command prompt -- one that you get by right-clicking the "Command Prompt" icon in Accessories, then choosing "Run as administrator" -- and you're ready to roll.  There's online help, but here are few quickstarts.

Modifying an Integrity Level

To see chml's basic powers in action, create a folder.  In my example, I'll create one named c:\test.  Then set it to low integrity by typing

chml c:\test -i:l

Your run will look something like this:

C:\>chml c:\test -i:l

chml v1.010 -- Change Windows Integrity Level
by Mark Minasi (c) 2006 www.minasi.com
"chml -?" for syntax, examples and notes.

Integrity level of c:\test successfully set to low.

C:\>

The syntax is simple:  just follow chml with the name of the folder, followed by a lowercase "i," a colon, and then one of the letters u, l, m, h, or s, which signify Untrusted, Low, Medium, High, or System.  (By the way, if you want to skip the copyright and help banner, just add the "-b" option.)  Now create a file inside c:\test named "testfile.txt" -- it doesn't matter what text is in it, or if there is any text there at all.  Then ask chml what integrity label the file has, like so:

C:\>echo Hi there>\test\testfile.txt

C:\>chml c:\test\testfile.txt -b
c:\test\testfile.txt's mandatory integrity level=low

C:\>

What you're seeing here is that just as objects in folders can inherit permissions from their parent folders, they can also inherit integrity levels.

Seeing the Effect of "No Write Up"

Recall that the main value of Windows integrity controls is to keep lower-integrity processes from modifying higher-integrity objects.  We'll demonstrate that by setting a file's integrity level to High, then we'll open up a non-elevated command prompt (which will run at Medium) and see that we can't erase the file.

From the elevated command prompt, raise c:\test to High integrity like so:

C:\>chml c:\test -i:h -b
Integrity level of c:\test successfully set to high.

C:\>

Now, open a second command prompt, but don't elevate it.  Try to erase c:\test\testfile.txt and you'll get an "Access is denied" error.

Setting Something to "No Read Up"

Now we'll take it a bit further and try out that "no read up" policy.  There are actually three Windows integrity control policies:  no read up, no write up, and no execute up, and you can apply any combination of them to any object using the -nr, -nw and/or -nx switches.  Set c:\testfile's policy to "no read up/no write up" like so, from the elevated command prompt:

C:\>chml c:\test -i:h -nr -nx -b
Integrity level of c:\test successfully set to high.

C:\>

Now try to examine the file or folder at all from the non-elevated command prompt, or even from Explorer for that matter, and you'll again see an "access is denied."  Wondering why I had to once again assign an integrity level of High, rather than just using a -nr?  Integrity labels are simple:  each object only gets one, so to modify one you can't just specify changes, you've got to redefine the whole thing.

Setting an Integrity Level to "System"

In the book, I explained that Windows integrity controls only let you elevate integrity levels to be equal to yours.  Many operating system processes aren't explicitly labeled as System, but when they run, they run at a System level.  As System is of higher trustworthiness than is High, that implies that if someone were to create a file and somehow manage to label it as System, then no administrator could delete it.  That worried me, and in fact when I asked a highly-placed Microsoft employee what would happen if someone managed to create some kind of malware that marked itself as System, he replied, "well, at that point it'd be 'game over' as far as cleaning that system went, short of repartitioning and reformatting the drive."

But with time I've figured out three ways to elevate my account to System.  Armed with that power, I can now be sure that if such malware does appear, then we've got three strategies for lowering its integrity level back down to one that will allow me to delete it.

  • Run a scheduled chml task as System.
  • Use psexec -s to run chml as System.  You can find psexec at the Sysinternals Web site.
  • Boot WinPE -- which logs you on as System -- and run chml

In every case, use the -i:s option, which is available in chml but which I'd forgotten to put in the online Help file. For example, to set c:\test\testfile.txt using psexec, you'd download psexec, put it in your system path and type

C:\>psexec -s chml c:\test\testfile.txt -i:s -b

PsExec v1.73 - Execute processes remotely
Copyright (C) 2001-2006 Mark Russinovich
Sysinternals - www.sysinternals.com


Integrity level of c:\test\testfile.txt successfully set to system.
chml exited on ENT64 with error code 0.

C:\>

Why Not Use icacls?

Well, again, I didn't use icacls in my experimentation because it didn't work throughout almost all of the beta process.  But chml can do several things that icacls cannot:

  • It cannot set integrity levels at Untrusted or System.
  • It cannot assign "no read up" or "no execute up" integrity policies.
  • It will not let you view the "raw" integrity control label, as chml's -sddl option does.
  • It will not let you create and apply a hand-crafted raw integrity control label, as chml's -wsddl option does.

Windows integrity controls aren't well-understood by many because there's so little information on them.  That's why I wrote chml.  I hope you find it useful and if you'd like more detail both on integrity levels and chml, then please consider buying my Administering Windows Vista Security:  The Big Surprises book, which I've seen at Bookpool for as little as $21.

You can send me email at the "minasi.com" domain under the name "help."  Drop me a line and tell me how you're finding chml useful, and thanks for visiting!