04 Mar
Posted by: Christian Wimmer in: JEDI Windows Security Code Lib
Windows Vista contains a new feature that allows an administrator to work with less privileges. Every time a user who belongs to the administrator group logs on, the LogonUser API creates two tokens. One tokens contains the real power of the user and the second contains only restricted access. We call such a token restricted token. This feature was implemented way back in Windows 2000 . The changes on the restricted token starts with removed privileges and ends with setting the administrator group in the token groups to use for deny only. A deny only Sid is only used for access control entries that deny access. So in our case the access to a file which allows Administrators full access may be disallowed if there is not any other positive element that grants us the access.
Back to the topic. The token groups contains a special Sid that is called an integrity Sid. The token that has the administrator group enabled receives a high integrity Sid. Tthe medium integrity Sid goes to the groups of the restricted token.
The token returned bei LogonUser is always the restricted one. Although you can retrieve the the twin token, you cannot do anything with it if you are not a SYSTEM process or an administrator. However a SYSTEM process may return the powerful token to create a process with full administrator rights. UAC does not do anything else. It gets the user’s credentials, logs on and uses the twin token (if any, otherwise it prompts for an administrator account credentials) to create the process.
Both tokens are linked together. Thus the following conditions are true.
Token.LinkedToken = TwinToken
TwinToken.LinkedToken = Token
You can use the twin token in any way you treat a token if you are powerful enough. Use it in CreateProcess or impersonate the user to do things as the user.
At the end I post a quite useful piece of code that displays primary information about a token.
Tell me how you liked this blog entry by adding a comment.
2 Responses
GunSmoker
15|Jul|2008 1How can I detect if the given Token : TJwSecurityToken is a restricted token or a full token?
Christian Wimmer
15|Jul|2008 2I thought the answer to your question would be easy (for me).
But the real result is very mysterious
There are two usual ways how to get the restricted SIDs (1.) or determine the token restriction status (2.).
1. Use TJwSecurityToken. TokenRestrictedSids
2. Use TJwSecurityToken.IsRestricted property.
However, I found out by testing that the underlying API functions, doesn’t work correctly on my Vista SP1 System. I always got FALSE for 1. and zero SID items for 2. So I decided to use TokenGroups that returns a full list of all SIDs that can be searched for the sidaGroupUseForDenyOnly Attribute in the AttributeType property of TJwSecurityID.
function IsRestrictedToken(const T : TJwSecurityToken) : Boolean; var i : Integer; Group : TJwSecurityIdList; begin result := false; Group := T.TokenGroups; try for i := 0 to Group.Count-1 do begin result := sidaGroupUseForDenyOnly in Group.Items[i].AttributesType; if result then break; end; finally Group.Free; end; end;This function does the same as the IsTokenRestricted API equivalent, but for unknown reasons it returns FALSE for a token with a deny SID entry (in my OS).
Be aware that there is no option to detect a token created by CreateRestrictedToken that is missing only some privileges. It is by design!
Find out more about Restricted Tokens on MSDN.
Leave a reply