What is this thing called, SID?


One of the core data structures in the NT security infrastructure is the security identifier, or SID.

NT uses two data types to represent the SID, a PSID, which is just an alias for VOID *, and a SID, which is a more complicated structure (declared in winnt.h).

The contents of a SID can actually be rather fascinating.  Here’s the basic SID structure:

typedef struct _SID {
   BYTE  Revision;
   BYTE  SubAuthorityCount;
   SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
   DWORD SubAuthority[ANYSIZE_ARRAY];
} SID, *PISID;

Not a lot there, but some fascinating stuff none the less.  First let’s consider the Revision.  That’s always set to 1, for existing versions of NT.  There may be a future version of NT that defines other values, but not yet.

The next interesting field in a version 1 SID is the IdentifierAuthority.  The IdentifierAuthority is an array of 6 bytes, which describes which system “owns” the SID.  Essentially the IdentifierAuthority defines the meaning of the fields in the SubAuthority array, which is an array of DWORDs that is SubAuthorityCount in length (SubAuthorityCount can be any number between 1 and SID_MAX_SUB_AUTHORITIES (15 currently).  NT’s access check logic and SID validation logic treats the sub authority array as an opaque data structure, which can allow a resource manager to define their own semantics for the contents of the SubAuthority (this is strongly NOT recommended btw).

The “good stuff” in the SID (the stuff that makes a SID unique) lives in the SubAuthority array in the SID.  Each entry in the SubAuthority array is known as a RID (for Relative ID), more on this later. 

NT defines a string representation of the SID by constructing a string S-<Revision>-<IdentifierAuthority>-<SubAuthority0>-<SubAuthority1>-…-<SubAuthority<SubAuthorityCount>>.  For the purposes of constructing a string sid, the IdentifierAuthority is treated as a 48bit number.  You can convert between a binary SID and back by using the ConvertSidToStringSid and ConvertStringSidToSid APIs.

NT defines 6 IdentifierAuthorities, they are:

#define SECURITY_NULL_SID_AUTHORITY         {0,0,0,0,0,0}
#define SECURITY_WORLD_SID_AUTHORITY        {0,0,0,0,0,1}
#define SECURITY_LOCAL_SID_AUTHORITY        {0,0,0,0,0,2}
#define SECURITY_CREATOR_SID_AUTHORITY      {0,0,0,0,0,3}
#define SECURITY_NON_UNIQUE_AUTHORITY       {0,0,0,0,0,4}
#define SECURITY_NT_AUTHORITY               {0,0,0,0,0,5}
#define SECURITY_RESOURCE_MANAGER_AUTHORITY {0,0,0,0,0,9}

Taken in turn, they are:

·         SECURITY_NULL_SID_AUTHORITY: The “NULL” Sid authority is used to hold the “null” account SID, or S-1-0-0. 

·         SECURITY_WORLD_SID_AUTHORITY: The “World” Sid authority is used for the “Everyone” group, there’s only one SID in that group, S-1-1-0.

·         SECURITY_LOCAL_SID_AUTHORITY: The “Local” Sid authority is used for the “Local” group, again, there’s only one SID in that group, S-1-2-0.

·         SECURITY_CREATOR_SID_AUTHORITY: This Sid authority is responsible for the CREATOR_OWNER, CREATOR_GROUP, CREATOR_OWNER_SERVER and CREATOR_GROUP_SERVER well known SIDs, S-1-3-0, S-1-3-1, S-1-3-2 and S-1-3-3.
The SIDs under the CREATOR_SID_AUTHORITY are sort-of “meta-SIDs”.  Basically, when ACL inheritance is run, any ACEs that are owned by the SECURITY_CREATOR_SID_AUTHORITY are replaced (duplicated if the ACEs are inheritable) by ACEs that reflect the relevant principal that is performing the inheritance.  So a CREATOR_OWNER ACE will be replaced by the owner SID from the token of the user that’s performing the inheritance.

·         SECURITY_NON_UNIQUE_AUTHORITY:  Not used by NT

·         SECURITY_RESOURCE_MANAGER_AUTHORITY:  The “resource manager” authority is a catch-all that’s used for 3rd party resource managers. 

·         SECURITY_NT_AUTHORITY: The big kahuna.  This describes accounts that are managed by the NT security subsystem.

There are literally dozens of well known SIDs under the SECURITY_NT_AUTHORITY sub authority.  They range from NETWORK (S-1-5-2), a group added to the token of all users connected to the machine via a network, to S-1-5-5-X-Y, which is the SID for all authenticated NT users (X and Y will be replaced by values specific to your per-machine logon instance).

Each domain controller allocates RIDs for that domain, each principal created gets its own RID.  In general, for NT principals, the SID for each user in a domain will be identical, except for the last RID (that’s why it’s a “relative” ID – the value in SubAuthority[n] is relative to SubAuthority[n-1]).  In Windows NT (before Win2000), RID allocation was trivial – user accounts could only be created at the primary domain controller (there was only one  PDC, with multiple backup domain controllers) so the PDC could manage the list of RIDs that was allocated easily.  For Windows 2000 and later, user accounts can be created on any domain controller, so the RID allocation algorithm is somewhat more complicated.

Clearly a great deal of effort is made to ensure uniqueness of SIDs, if SIDs did not uniquely identify a user, then “bad things” would happen.

If you look in WINNT.H, you can find definitions for many of the RIDs for the builtin NT accounts, to form a SID for one of those accounts, you’d initialize a SID with the SECURITY_NT_AUTHORITY, and set the first SubAuthority to the RID of the desired account.  The good news is that because this is an extremely tedious process, the NT security guys defined an API (in Windows XP and later) named CreateWellKnownSid which can be used to create any of the “standard” SIDs.

Tomorrow: Some fun things you can do with a SID.

 

Comments (22)

  1. David Candy says:

    What about some, any, documentation on the restricted account. There is one MS article that mentions it, in relation to the RunAs dialog, that says it prevents registry writing. In a MS list of well known SIDS it is listed but that is all.

    One cannot get effective permissions on files or registry keys for this Restricted user/group. XP’s dialogs has not heard of Restricted so …

    Also Restricted in not recognised by User Rights either.

  2. Do you mean the RestrictedCode user? Well, if you search MSDN for SECURITY_RESTRICTED_CODE_RID, you’ll find:

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/sid_strings.asp

    Which has a pointer to:

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/createrestrictedtoken.asp

    To me, this implies that the restricted code group (S-1-5-C) is added to the token that is created by the CreateRestrictedToken API.

    This allows you to put an ACE in an ACL that would deny access to all restricted tokens.

  3. David Candy says:

    Lovely gobblygook that. It still seems that noone actually knows what this new prominent feature does exactly.

    I ran a program with restricted and it errored. I can’t think of a way to debug it while restricted (I’m not going to even attempt to start the VB IDE while restricted).

    But this raises another point. How many types of error dialogs are there in XP. Because I’ve just seen a new one – it’s very polite but has no details at all and Alt + D doesn’t work (and I’m sure I’ve seen Alt + D style dialogs). It’s an XP two tone dialog. Error Reporting for programs is enabled. And when one closes it one gets a second error message, similar to the first, but one I’ve seen often before, also without error reporting or details. It looks like a conventional message box.

    There seems to be a lot of different types of error dialogs.

  4. andy says:

    talk about gobbledygook, David. I actually understood Larry’s, but yours are truly special.

    How do XP dialog control characters relate to the drilldown on security identifiers? If there’s a connection, please enlighten us, because I think this is bound to be a good topic.

  5. David Candy says:

    In the RunAs graphical command in XP a feature was added called "Protect My Computer …".

    There is one reference to this in the MSDN library and one reference in the web. MSDN says, in an article in passing, that it prevents registry writes. The web reference says it uses the Restricted SID, which is mentioned in the PSDK but that all.

    However it prevents more than registry writes. I just wrote a program with file writes only in it and got Path/File Access Error (RunTime Error 75).

    However I tried to avooid writing anything so earlier used an old program that I had written, this written in same language/same version. This generated an error, but not from the Runtime library but from XP. Surprisingly it is a type of error dialog I’ve not seen before.

    There are many types of dialogs in XP. EG in Add Fonts it is a Win 3.1 dialog. I use classic scheme so what I see others mightn’t. But there are two tone error dialogs (similar in style, but smaller to the Help – About dialogs) without error reporting or details. There are Win2000/ME error dialogs (have to press Alt + D to see details), there are standard XP error dialogs with error reporting, there are explorer.exe error dialogs that look like a message box but don’t log as an error in event viewer (plus sometimes a second dialog saying the shell stopped or started), not to mention app error dialogs. PS MS Word still includes all the Win 2 or 1 dialogs – the ugly white ones without titlebars.

    I hate XP as it’s not tested or designed. If you look at something like Win CE or Palm you find an integrated design philosophy. This is totally missing from XP and has been since 95 to a lesser extent and IE4 to a greater extent.

    So. I want to know what ticking "Protect My Computer ..", a in your face new undocumented feature, does. It’s SID is S-1–5–12 and it’s only description is Restricted (which I had sort of worked out from it’s mnomic SECURITY_RESTRICTED_CODE_RID). The only MS reference to the feature states that it prevents registry writes – this it may do but it also appears to prevent file system writes as well. I can’t use something if I don’t know exactly what it does.

    So

    1. What exactly does the protect my computer protect against. The docs larry gave are aimed at people wanting to create their own restricted users not what Windows does.

    2. It brings up the second point why is there so many different types of error dialogs. There should be 1. Why do they have different features and appearance.

    3 Why aren’t both of the above documented. In the MS language I knew best many things were illegal because someone added code to make it not work because they thought it was illogical for it to work at the conceptual level – none of this was ever documented so I’ve spent years of my life writing programs to run experiments so I can write the program I’m trying to write. An pseudo example would be not allowed to enter a page number if the view was outline because someone thought it’s illogical to do that and so we’ll write code to error if it is tried and keep silent about it in the docs.

  6. Mike Dimmick says:

    The VB6 IDE doesn’t work at all unless you’re an administrator, I’ve found, or at least for ActiveX components since it’s continually monkeying with HKEY_CLASSES_ROOT.

    Aaron Margosis’ PrivBar can show you what’s in a restricted token. When you create one, basically every SID in your token – apart from your own – gets added again as a restricting SID. A restricting SID in a token tells AccessCheck and its kernel brethren to only consider this SID for Deny entries in ACLs; Allow entries (which might override inherited Deny entries) are not considered. If a restricting SID isn’t explicitly Denied, you might end up being Allowed.

    This feature allows a user who would normally have high privileges to drop them temporarily. It’s probably safer to work the other way around, though.

    You can’t allow access specifically to restricted tokens, because the Restricted SID is added to the token as a restricting (deny-only) SID.

    S-1-5-5-X-Y is your logon SID. Each logon session gets its own logon SID. When you log on, WinLogon replaces the ACL on Winsta0, the interactive window station (a window station handles human-interface input and contains desktops, which contain windows) so that only the logon SID which it’s just created can manipulate this window station. When you log in through Terminal Services, the window station created for your login also has an ACL applied so that that session is the only one which can manipulate the window station.

    This is a slight simplification: the Administrators group also has some read-only access, LocalSystem has unlimited access, and the logged-in user’s principal has very limited additional rights.

    More on SIDs, logons, tokens, window stations and desktops in Keith Brown’s excellent book "Programming Windows Security".

  7. In general, for NT principals, the SID for each user in a domain will be identical, except for the last RID (that&#8217;s why it&#8217;s a &#8220;relative&#8221; ID &#8211; the value in SubAuthority[n] is relative to SubAuthority[n-1]). In Windows NT (before Win2000), RID allocation was trivial &#8211; user accounts could only be created at the primary domain controller (there was only one PDC, with multiple backup domain controllers) so the PDC could manage the list of RIDs that was allocated easily.

  8. David Candy says:

    I have PrivBar installed (don’t know why – I’m always admin). It doesn’t seem to work if IE is started as Restricted. One can tick or untick the menu but no bar appears.

    Of course one needs explorer running to select restricted and I can’t see a way to do it – maybe as a bat file – nope.

    Perhaps you saw on the privbar article my post on how the rules are not as simple as stated in that article re explorer seperate processes.

    I read the disallow part in the msdn. Presumbably I have no deny (and a check confirms) on the file that I tried to write (c:test.txt).

  9. timchen says:

    Why does HKEY_LOCAL_MACHINE in w2k has an Allow Read ACE for the RESTRICTED SID, if this SID is meant only for denying purpose?

  10. M Knight says:

    PrivBar works under a restricted setting. Its just mostlike the privbar is hanging off the screen. Since PrevBar cant keep its position.

    As for what "Protect My Computer .." does:

    Restricted SIDs:

    <Computer name>None | mandatory enabled default

    Everyone | mandatory enabled default

    BUILTINRemote Desktop Users | mandatory enabled default

    BUILTINUsers | mandatory enabled default

    NT AUTHORITYINTERACTIVE | mandatory enabled default

    NT AUTHORITYAuthenticated Users | mandatory enabled default

    <login ID> | mandatory enabled default

    LOCAL | mandatory enabled default

    NT AUTHORITYRESTRICTED | mandatory enabled default

    As for what the hell this is denying is another question.

  11. David Candy says:

    I have to say that when checking permissions I go straight to the effective permissions tab. There is no Restricted there. But there is on all the dialogs on the way to effective permissions. Caught by not reading dialogs again.

    XP is the same as 2000 in it’s Allow Permissions.

    I’m fairly certain it disallows all file and registry writes. But what else? Particulary for non file/registry objects and Priveledges (like Shutdown System).

  12. Mike Dimmick says:

    You need to use regsvr32 on PrivBar as an administrator so that the registration information ends up in the "all users" part of HKEY_CLASSES_ROOT, I think. Also, you need to ensure that Everyone has read access to PrivBar.dll. Otherwise, IE simply gets an error from CoCreateInstance.

    ACLs can have two basic types of Access Control Entries (ACEs) – Allowed and Denied. An Allowed ACE matching a non-restricted SID in the token causes the matching bits to be permitted in the resulting access mask; once all bits are set, the request succeeds.

    A Denied ACE matching any SID in the token with any bits matching the requested access causes the access check to abort at that point. A restricting SID (one marked SE_GROUP_USE_FOR_DENY_ONLY) can never permit access, only deny.

    Your own SID is never restricted. This means that a restricted token created from your logon token can do whatever you can, unless a group you belong to is explicitly denied in the ACL. Windows XP’s default for new objects created by an administrator is to set the object’s owner to the creating account, unlike older versions and Server 2003, which set BUILTINAdministrators. Since the default DACL includes CREATOR OWNER with Full Control, it actually means that you still have access to a lot of things you might not have if you’d installed software using a different account. This explains why I get errors from some programs at work that I don’t get at home – most of my software at work was installed before we set up our domain, and the files and registry keys are therefore owned by a different principal from the one I now use to log on.

    Windows security is very flexible – far more so than Unix’s standard owner/group/all read/write/execute bitmasks – but can also be very confusing.

    I should probably lock down %ProgramFiles% so it’s owned by BUILTINAdministrators and my principal isn’t listed in the ACLs at all.

  13. Pavel Lebedinsky says:

    > A restricting SID (one marked

    > SE_GROUP_USE_FOR_DENY_ONLY) can never

    > permit access, only deny

    Actually, restricting SIDs and deny-only SIDs are two separate things. CreateRestrictedToken allows you to specify both.

    The best way to see what exactly "protect my computer" option does is to try it. Run cmd.exe with protection turned on, then run pview.exe from Platform SDK and look at the process token for cmd.exe. You will see both deny-only (disabled) SIDs and restricted SIDs (under Other…).

    > This allows you to put an ACE in an ACL

    > that would deny access to all restricted

    > tokens.

    Note that SECURITY_RESTRICTED_CODE_RID is added only to the list of restricting SIDs. So if you grant access to RESTRICTED, it doesn’t mean arbitrary restricted code will be allowed access (access is only granted if both lists allow it – read the docs for CreateRestrictedToken for details).

    Essentially, RESTRICTED is used to give you back some of the rights that you lost by running a program as restricted code. For example, if you turn on "protect my computer" then you can’t access your profile folder, but you can read from HCKU. This is because HCKU grants read access to RESTRICTED and %USERPROFILE% does not.

  14. David Candy says:

    Only the NT4 version of Pview has a button for token and that is greyed out. All the other pview/pviewer (Pview now was pviewer in NT4)are of a different style (XP support tools/MSDN 7.1(whatever that is)/VS6) and only show memory stats.

    I’ll have to find a CD with the sdk on it (I only have filed CDs I got 5 years ago – I gave up filing then – so I know exactly where 1998 sdk cd is but not any more recent). But that makes some sense what you are saying.

    This page will end up as the definitive documentation on this feature. But I can’t believe MS built in a prominent GUI feature without any reference mention of it anywhere and a wrong article about how good it is.

    Larry will end up being known as the "Protect My Computer" king.

  15. Pavel Lebedinsky says:

    I’m using pview from Platform SDK (Program FilesMicrosoft SDKBinwinnt). It is definitely more recent than NT4 – in fact, the version number is 5.2.3790.0 which is Win2K3.

    NT4 version probably doesn’t show restricting SIDs anyway as I believe this feature was introduced in Win2K.

    I believe that the reason why "protect my computer" feature doesn’t get more coverage is because it’s not really secure. For example, I don’t think it can prevent malicious code from sending window messages to other programs running as the user (a "shatter"-style attack).

    I still occasionally run IE in restricted mode but I definitely don’t count on it as my only protection.

  16. David Candy says:

    Apparantly http://blogs.msdn.com/aaron_margosis as been promising to talk about this for a while.

    I sent him a message to remind him.

  17. The best published description of restricted tokens that I’ve read is in Keith Brown’s "Programming Windows Security". He doesn’t cover the "protect my computer" option, though, because his book predated Windows XP, which is where that option was introduced. Solomon and Russinovich’s upcoming "Windows Internals" book will have great info on it.

    I am planning a post on the "protect my computer" option, focusing more on the effects perceived by the end user than about how the underlying access checks actually work. Real Soon Now.

    It takes more than a couple of paragraphs to accurately describe how an access check is performed against a non-restricted SID, when you take into account deny-only and disabled SIDs. The important part is that an access check compares the union of the user’s identity and the list of groups the user is a member of against the ACL of interest. With a restricted token, the access check performs two passes. The first compares the union of the user’s identity and the groups against the ACL; the second test compares only the SIDs in the token’s "restricting SIDs" list against the ACL. The result of the access check is essentially the intersection of the results. If the first pass grants you "full control" and the second pass grants you "read only", then you get "read only". If either test fails to grant you any access, you get no access. Although it is legal for the restricting SIDs list to include the user account’s SID, the restricted token created by "protect my computer" does not. Therefore, if you’re running with a "protect my computer" restricted token, you do not get access to anything that is ACLed for you only. The object needs to grant access to something else that allows the second pass to succeed. The reason that most of HKCU gives you read-only access is because "RESTRICTED" is granted read-only. (Like the example above: first pass gives you "full", second pass gives you "read", you get "read".) The NTFS permissions on your profile folder hierarchy does not grant RESTRICTED anything, so you can’t access your profile folder when running with a "protect my computer" restricted token. (The reason you CAN access HKCU, which lives in a file in your profile, is because you’re not accessing it directly through NTFS – if I’m not mistaken your HKCU hive is loaded by code running as System.)

    As Pavel indicated, "restricting SIDs" and "deny-only SIDs" are completely different. "Restricting SIDs" are really misnamed, since the more SIDs you add to the list in a restricted token, the more you’re granting access, not denying access.

    I’ll try to get that thing posted – sorry for the delay!

  18. Security Developer Center: Columns: Browsing the Web and Reading E-mail Safely as an Administrator Part 1 ">Part 2 I got the heads up to this pair of MSDN articles by Microsoft Security Engineering Michael Howard off the activedir list and…

  19. It’s a complicated mix.

  20. Inherited permissions are established at creation.