chml and regil: Utilities To Manage Windows Integrity Levels
NEW: CHML 1.53 released 16 July 2009, fixes a subtle bug.
NEW: REGIL 1.0 released 26 Feb, the first tool to let you work with Registry integrity levels!
Integrity Levels? What are They?
Vista and later versions of Windows include a new notion of what were originally called "Mandatory Integrity Controls" but eventually became "Windows Integrity Levels," (WILs) often shortened further to "integrity levels" or ILs. Under WIL, every object that can have permissions can also have a label, stored in roughly the same place as it stores permissions, that identifies its "integrity level." Another way to think of an integrity level is a measure of how trustworthy it's considered by the system. There are six integrity levels, from highest trustworthiness to lowest:
Files, folders and Registry keys have integrity levels, as do processes (including user sessions -- if you're logged on as administrator, your session has higher integrity ("high") than it would normally ("medium"). What good are these "trustworthiness levels?" Well, they act as a kind of second, overriding 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: think of it as "ILs trump ACLs." (It sounds better when you say it out loud.)
Sounds neat? I thought so, and when I found that Microsoft had installed this new plumbing in Vista, 2008, Windows 7 and 2008 R2 Server but weren't doing anything with it, I set out to learn a bit of C++ and write a couple of apps:
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. Furthermore, Chml's design goals were simple. I wanted a tool that would:
If You're Using Windows 7...
Between Vista and Windows 7, Microsoft changed something -- I haven't figured out what, yet -- that broke the -fs ("force system") switch on chml. That means you can't force an integrity level to or from System directly from chml under Windows 7. You can work around this by running chml under Sysinternals' psexec tool. Just use the -s switch on psexec and start a command prompt like so:
psexec -s cmd
The command prompt window now runs as System (you can verify that by running the "whoami" command) and now chml will let you work with items that have the "System" integrity level. Sorry for the inconvenience, I'll get around to figuring it out eventually.
Downloading Chml and Regil
Here they are:
Installing them is trivial. Just right-click the hyperlinks above and save the EXE somewhere on your Windows path. (I usually store it in the \windows\system32 folder.) There's no setup, just open a command prompt and type "chml" or "regil" followed by whatever options you need. (There's lots of help if you don't include any options.)
What Rights/Permissions Do I Need to Use Chml/Regil?
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
But if you want to modify an object's integrity level, then there are several rules. To modify a file/folder's IL, you
You don't need the "Modify," privilege despite what I said in my book; I was working from pre-release materials and apologize for the error. Just being a member of the Administrators group should be all you need to do anything that you want with chml, particularly with the -fs option.
I was quite surprised to find that the rules for changing Registry entries are quite different: you've got to be either an admin with the ability to take ownership or be the owner, but -- here was the strange part -- as an owner you can actually modify a Registry key's integrity level from a non-elevated command prompt, which you can not do with files or folders. With Regil, I can (while sitting at a non-elevated command prompt with an integrity level of Medium) assign a Medium IL to a Registry folder. Odd!
There's online help for other stuff (or feel free to email me), but here are few quickstarts.
Modifying an Integrity Level
To see chml's basic powers in action, open an elevated command prompt and 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.50 -- View and change Windows file/folder integrity levels by Mark Minasi (c) 2006-2009 www.minasi.com email:xxx Successfully changed c:\test's integrity level. Folder c:\test's integrity level: Low Inheritance flags: Containers in this container should inherit IL (CI) Objects in this container should inherit IL (OI) Integrity policies: No read up: disabled No execute up: disabled No write up: enabled
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, i, m, h, or s, which signify Untrusted, Low, Medium, High, or System. (By the way, if you want to skip the copyright 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 C:\>chml c:\test\testfile.txt Chml v1.50 -- View and change Windows file/folder integrity levels by Mark Minasi (c) 2006-2009 www.minasi.com email:xxx File c:\test\testfile.txt's integrity level: Low Inheritance flags: This object inherited this IL (ID) Integrity policies: No read up: disabled No execute up: disabled No write up: enabled
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 Successfully changed c:\test's integrity level. Folder c:\test's integrity level: High Inheritance flags: Containers in this container should inherit IL (CI) Objects in this container should inherit IL (OI) Integrity policies: No read up: disabled No execute up: disabled No write up: enabled
(Notice that I added the "-b" option, which stops Chml from printing the copyright banner.) 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 -b Successfully changed c:\test's integrity level. Folder c:\test's integrity level: High Inheritance flags: Containers in this container should inherit IL (CI) Objects in this container should inherit IL (OI) Integrity policies: No read up: disabled No execute up: disabled No write up: enabled 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/from "System:" the -fs and -nfs Options
In the "trustworthiness" hierarchy, non-admin users are Medium admin users are High and some operating system things are System. The problem with System are a couple of basic rules about Windows integrity-wise:
Thus, the problem with System, it seemed to me early on, was "what would happen if a bad guy installed some malware and gave it an IL of System somehow?" We admins, who are merely High, couldn't delete a System file or folder! The answer would be to run Chml as System somehow... but how? When I first wrote Chml, I figured out how to run it as System three ways:
Those are all still possible, but they're clumsy, which was one of the main reasons that I built Chml 1.5. It can now lower files from System or raise them to System. How'd I do it? Simple: I just construct a scheduled task that executes Chml, tell the system to run it immediately, and then delete the task. Chml doesn't go the task scheduler route -- it's called "forcesystem" mode inside Chml -- by default unless it sees an explicit "-i:s" command, so if you ever need that extra juice, add "-fs" to your Chml command. Again, this is easiest to grasp with an example or two.
First, let's raise test's integrity to System, like so:
C:\>chml test -i:s Chml v1.50 -- View and change Windows file/folder integrity levels by Mark Minasi (c) 2006-2009 www.minasi.com email:xxx Successfully changed C:\test's integrity level. Folder C:\test's integrity level: System Inheritance flags: Containers in this container should inherit IL (CI) Objects in this container should inherit IL (OI) Integrity policies: No read up: disabled No execute up: disabled No write up: enabled
As I said above, whenever Chml sees "-i:s" then it automatically activates "forcesystem," creating the scheduled tasks. But now try to lower test's integrity to Medium:
C:\>chml test -i:m Chml v1.50 -- View and change Windows file/folder integrity levels by Mark Minasi (c) 2006-2009 www.minasi.com email:xxx UPDATEIL: Access denied when trying to write new integrity label. Chml was unable to update test's integrity label, no change occurred. Check that you are running at sufficient integrity and the right permissions -- you need to either own the folder or have the Take Ownership right and the ability to change permissions on it. Also, Chml must run at an integrity level greater than or equal to both the object's current IL, and the IL that you want to raise it to. (Thus, it takes System integrity to raise a file to System integrity, and it takes System integrity to drop a System integrity file down to something below it.) Folder test's integrity level: System Inheritance flags: Containers in this container should inherit IL (CI) Objects in this container should inherit IL (OI) Integrity policies: No read up: disabled No execute up: disabled No write up: enabled
That's because you were running as a mere administrator with High integrity, so that System file merely laughed when you tried to change its integrity. You canna do tha' job on impulse, laddie... add "-fs" to engage warp drive!
C:\>chml test -i:m -fs Chml v1.50 -- View and change Windows file/folder integrity levels by Mark Minasi (c) 2006-2009 www.minasi.com email:xx Successfully changed C:\test's integrity level. Folder C:\test's integrity level: Medium Inheritance flags: Containers in this container should inherit IL (CI) Objects in this container should inherit IL (OI) Integrity policies: No read up: disabled No execute up: disabled No write up: enabled
-fs has one problem, though: what about WinPE? It's a great, basic, simple and free operating system for troubleshooting and repairing Windows systems (look at Newsletter #59 for the skinny on it) but it doesn't have a task scheduler and wouldn't need it in this case anyway because, again, it lets you run as System anyway. Sometimes, then, you want to keep Chml from trying to use the Task Scheduler altogether and you can do that with the "-nfs" option. The only time you'd need it would be if you ever ran a command with the "-i:s" option, recall.
That's not all that's new in Chml 1.5, though... take a look at the revision
history below. Download the latest Chml and please drop me a line to let
me know how you like it.
I Want To Change Entire Folders!
I know, I know, you want chml to be able to do stuff like "chml *.txt" to work on all text files in the current folder, or "chml *.txt /s" to work on all text files in the current folder and all subfolders. One of these days I'll figure it out, but I've not had the time... but here's a great workaround: the "for" command. It looks like
for [/r]%f in (filepattern) do [whatever you want chml to do, putting "%f" where the filename would go]
For example, to lower the integrity level of all text files in the current folder, type
for %f in (*.txt) do chml %f -i:l
To recurse folders, change "for" to "for /r." I hope this fills a gap until I can get the time to figure out wildcards. Thanks!
Regil's designed to work very similarly to chml, but for Registry entries. It's got a lot more help built-in than chml does:
Some examples (from regil -st):
Viewing Current ILs
Just invoke regil with the Registry key's name, as in
(That's one of the few Registry keys with a built-in IL; most are unlabeled.)
Modifying a Registry Key's IL
Use the -i: option to raise/lower the IL:
regil HKEY_CURRENT_USER\Iltest -i:l
That changes HKCU\Iltest's IL to be low and to set the 'inherit' flag, so
any subkeys created under that key will also be low.
Removing Existing Integrity Labels
To remove an explicit IL, use -rl:
regil hklm\software -rl
Viewing an Existing SDDL String
Simplify understanding ILs under the hood; use -ss
regil HKCU\Software\AppDataLow -ss
Directly Modify an IL Via an SDDL String
regil hkcu\iltest -ws:S:(ML;OICI;NWNR;;;ME)
Sets the iltest subkey in the HKCU key (which doesn't exist by default) to integrity, any subkeys inherit, and both a no-write-up and a no-read-up policy.
What about System? Unfortunately I've not had the time to add warp drive to Regil, but I will when I can. Until then, try one of the three routes that I outlined above.
If experimenting with ILs interests you, give Regil a try and let me know what you think.
16 July 2009:
26 April 2009:
April 2009: chml 1.5 adds
Feb 2009: chml and regil are now code-signed. chml 1.5 adds
Jan 2009: fixed a bug that caused chml to sometimes think that a folder was a file. Thanks to Peter Strelecki for pointing out the bug. Added "-rl" option that will remove any existing mandatory labels, returning a file to "unlabeled" status, like
C:\>chml test.txt -rl -b
Integrity level reset to "unlabeled", object treated as medium.
Why Not Use icacls?
Well, again, I didn't use icacls in my experimentation because it didn't work throughout almost all of the Vista beta process, so it was of no value to me then. But Chml can do several things that icacls cannot:
Windows integrity controls aren't well-understood by many because there's so little information on them. That's why I wrote chml and, now, regil. 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 and/or Regil useful, and thanks for visiting!