4 #define ANONYMOUSUNIONS
12 #define INCLUDE_THE_DDK_HEADERS
13 #ifdef INCLUDE_THE_DDK_HEADERS
14 #include <ddk/ntddk.h>
15 #define ROS_ACE_HEADER ACE_HEADER
19 typedef LONG NTSTATUS
, *PNTSTATUS
;
21 typedef struct _UNICODE_STRING
26 } UNICODE_STRING
, *PUNICODE_STRING
;
28 typedef struct _OBJECT_ATTRIBUTES
{
31 PUNICODE_STRING ObjectName
;
33 PVOID SecurityDescriptor
; // Points to type SECURITY_DESCRIPTOR
34 PVOID SecurityQualityOfService
; // Points to type SECURITY_QUALITY_OF_SERVICE
36 typedef OBJECT_ATTRIBUTES
*POBJECT_ATTRIBUTES
;
38 typedef struct _ROS_ACE_HEADER
43 } ROS_ACE_HEADER
, *PROS_ACE_HEADER
;
48 ACCESS_MASK AccessMask
;
54 RtlConvertSidToUnicodeString (
55 IN OUT PUNICODE_STRING String
,
57 IN BOOLEAN AllocateString
71 RtlAddAccessAllowedAce (
74 ACCESS_MASK AccessMask
,
90 ZwAllocateLocallyUniqueId(
98 OUT PHANDLE TokenHandle
,
99 IN ACCESS_MASK DesiredAccess
,
100 IN POBJECT_ATTRIBUTES ObjectAttributes
,
101 IN TOKEN_TYPE TokenType
,
102 IN PLUID AuthenticationId
,
103 IN PLARGE_INTEGER ExpirationTime
,
104 IN PTOKEN_USER TokenUser
,
105 IN PTOKEN_GROUPS TokenGroups
,
106 IN PTOKEN_PRIVILEGES TokenPrivileges
,
107 IN PTOKEN_OWNER TokenOwner
,
108 IN PTOKEN_PRIMARY_GROUP TokenPrimaryGroup
,
109 IN PTOKEN_DEFAULT_DACL TokenDefaultDacl
,
110 IN PTOKEN_SOURCE TokenSource
112 #define NT_SUCCESS(StatCode) ((NTSTATUS)(StatCode) >= 0)
117 #define INITIAL_PRIV_ENABLED SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED
118 #define INITIAL_PRIV_DISABLED 0
119 LUID_AND_ATTRIBUTES InitialPrivilegeSet
[] =
121 { { 0x00000007, 0x00000000 }, INITIAL_PRIV_ENABLED
}, // SeTcbPrivilege
122 { { 0x00000002, 0x00000000 }, INITIAL_PRIV_DISABLED
}, // SeCreateTokenPrivilege
123 { { 0x00000009, 0x00000000 }, INITIAL_PRIV_DISABLED
}, // SeTakeOwnershipPrivilege
124 { { 0x0000000f, 0x00000000 }, INITIAL_PRIV_ENABLED
}, // SeCreatePagefilePrivilege
125 { { 0x00000004, 0x00000000 }, INITIAL_PRIV_ENABLED
}, // SeLockMemoryPrivilege
126 { { 0x00000003, 0x00000000 }, INITIAL_PRIV_DISABLED
}, // SeAssignPrimaryTokenPrivilege
127 { { 0x00000005, 0x00000000 }, INITIAL_PRIV_DISABLED
}, // SeIncreaseQuotaPrivilege
128 { { 0x0000000e, 0x00000000 }, INITIAL_PRIV_ENABLED
}, // SeIncreaseBasePriorityPrivilege
129 { { 0x00000010, 0x00000000 }, INITIAL_PRIV_ENABLED
}, // SeCreatePermanentPrivilege
130 { { 0x00000014, 0x00000000 }, INITIAL_PRIV_ENABLED
}, // SeDebugPrivilege
131 { { 0x00000015, 0x00000000 }, INITIAL_PRIV_ENABLED
}, // SeAuditPrivilege
132 { { 0x00000008, 0x00000000 }, INITIAL_PRIV_DISABLED
}, // SeSecurityPrivilege
133 { { 0x00000016, 0x00000000 }, INITIAL_PRIV_DISABLED
}, // SeSystemEnvironmentPrivilege
134 { { 0x00000017, 0x00000000 }, INITIAL_PRIV_ENABLED
}, // SeChangeNotifyPrivilege
135 { { 0x00000011, 0x00000000 }, INITIAL_PRIV_DISABLED
}, // SeBackupPrivilege
136 { { 0x00000012, 0x00000000 }, INITIAL_PRIV_DISABLED
}, // SeRestorePrivilege
137 { { 0x00000013, 0x00000000 }, INITIAL_PRIV_DISABLED
}, // SeShutdownPrivilege
138 { { 0x0000000a, 0x00000000 }, INITIAL_PRIV_DISABLED
}, // SeLoadDriverPrivilege
139 { { 0x0000000d, 0x00000000 }, INITIAL_PRIV_ENABLED
}, // SeProfileSingleProcessPrivilege
140 { { 0x0000000c, 0x00000000 }, INITIAL_PRIV_DISABLED
}, // SeSystemtimePrivilege
141 { { 0x00000019, 0x00000000 }, INITIAL_PRIV_DISABLED
}, // SeUndockPrivilege
142 { { 0x0000001c, 0x00000000 }, INITIAL_PRIV_DISABLED
}, // SeManageVolumePrivilege
145 typedef struct _SID_2
148 UCHAR SubAuthorityCount
;
149 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
150 ULONG SubAuthority
[2];
153 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
155 PrintSid(SID_AND_ATTRIBUTES
* pSid
, TOKEN_OWNER
* pOwner
, TOKEN_PRIMARY_GROUP
* pPrimary
)
157 UNICODE_STRING scSid
;
159 RtlConvertSidToUnicodeString(&scSid
, pSid
->Sid
, TRUE
);
160 printf("%wZ [", &scSid
);
161 LocalFree(scSid
.Buffer
);
163 if ( EqualSid(pSid
->Sid
, pOwner
->Owner
) )
166 if ( EqualSid(pSid
->Sid
, pPrimary
->PrimaryGroup
) )
169 if ( pSid
->Attributes
& SE_GROUP_ENABLED
)
171 if ( pSid
->Attributes
& SE_GROUP_ENABLED_BY_DEFAULT
)
172 printf("enabled-default,");
177 if ( pSid
->Attributes
& SE_GROUP_LOGON_ID
)
181 if ( pSid
->Attributes
& SE_GROUP_MANDATORY
)
182 printf("mandatory,");
187 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
189 DisplayTokenSids(TOKEN_USER
* pUser
,
190 TOKEN_GROUPS
* pGroups
,
192 TOKEN_PRIMARY_GROUP
* pPrimary
)
197 PrintSid(&pUser
->User
, pOwner
, pPrimary
);
198 printf("\nGroups:\n");
199 for (i
= 0; i
< pGroups
->GroupCount
; i
++)
200 PrintSid(&pGroups
->Groups
[i
], pOwner
, pPrimary
);
203 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
205 DisplayTokenPrivileges(TOKEN_PRIVILEGES
* pPriv
)
210 printf("\nprivileges:\n");
211 for (i
= 0; i
< pPriv
->PrivilegeCount
; i
++)
213 DWORD cbName
= sizeof(buffer
) / sizeof(buffer
[0]);
214 LookupPrivilegeName(0, &pPriv
->Privileges
[i
].Luid
, buffer
, &cbName
);
216 printf("%S{0x%08x, 0x%08x} [", buffer
, pPriv
->Privileges
[i
].Luid
.HighPart
, pPriv
->Privileges
[i
].Luid
.LowPart
);
218 if ( pPriv
->Privileges
[i
].Attributes
& SE_PRIVILEGE_ENABLED
)
220 if ( pPriv
->Privileges
[i
].Attributes
& SE_PRIVILEGE_ENABLED_BY_DEFAULT
)
222 if ( pPriv
->Privileges
[i
].Attributes
& SE_PRIVILEGE_USED_FOR_ACCESS
)
229 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
231 DisplayDacl(PACL pAcl
)
238 printf("\nNo Default Dacl.\n");
243 for (i
= 0; i
< pAcl
->AceCount
; i
++)
245 UNICODE_STRING scSid
;
250 status
= RtlGetAce(pAcl
, i
, (ROS_ACE
**) &pAce
);
251 if ( ! NT_SUCCESS(status
) )
253 printf("RtlGetAce(): status = 0x%08x\n", status
);
257 pSid
= (PSID
) (pAce
+ 1);
258 if ( pAce
->Header
.AceType
== ACCESS_ALLOWED_ACE_TYPE
)
260 if ( pAce
->Header
.AceType
== ACCESS_DENIED_ACE_TYPE
)
263 status
= RtlConvertSidToUnicodeString(&scSid
, pSid
, TRUE
);
264 if ( ! NT_SUCCESS(status
) )
266 printf("RtlConvertSidToUnicodeString(): status = 0x%08x\n", status
);
270 printf("%d.) %S %wZ 0x%08x\n", i
, wszType
, &scSid
, pAce
->AccessMask
);
271 LocalFree(scSid
.Buffer
);
275 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
277 GetFromToken(HANDLE hToken
, TOKEN_INFORMATION_CLASS tic
)
283 bResult
= GetTokenInformation(hToken
, tic
, 0, 0, &n
);
284 if ( ! bResult
&& GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
287 p
= (PBYTE
) malloc(n
);
288 if ( ! GetTokenInformation(hToken
, tic
, p
, n
, &n
) )
290 printf("GetFromToken() failed for TOKEN_INFORMATION_CLASS(%d): %d\n", tic
, GetLastError());
298 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
300 DisplayToken(HANDLE hTokenSource
)
302 TOKEN_USER
* pTokenUser
= (PTOKEN_USER
) GetFromToken(hTokenSource
, TokenUser
);
303 TOKEN_GROUPS
* pTokenGroups
= (PTOKEN_GROUPS
) GetFromToken(hTokenSource
, TokenGroups
);
304 TOKEN_OWNER
* pTokenOwner
= (PTOKEN_OWNER
) GetFromToken(hTokenSource
, TokenOwner
);
305 TOKEN_PRIMARY_GROUP
* pTokenPrimaryGroup
= (PTOKEN_PRIMARY_GROUP
) GetFromToken(hTokenSource
, TokenPrimaryGroup
);
306 TOKEN_PRIVILEGES
* pTokenPrivileges
= (PTOKEN_PRIVILEGES
) GetFromToken(hTokenSource
, TokenPrivileges
);
307 TOKEN_DEFAULT_DACL
* pTokenDefaultDacl
= (PTOKEN_DEFAULT_DACL
) GetFromToken(hTokenSource
, TokenDefaultDacl
);
309 DisplayTokenSids(pTokenUser
, pTokenGroups
, pTokenOwner
, pTokenPrimaryGroup
);
310 // DisplayTokenPrivileges(pTokenPrivileges);
311 DisplayDacl(pTokenDefaultDacl
->DefaultDacl
);
316 free(pTokenPrimaryGroup
);
317 free(pTokenPrivileges
);
318 free(pTokenDefaultDacl
);
321 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
323 EnablePrivilege(LPWSTR wszName
)
326 TOKEN_PRIVILEGES priv
= {1, {{{0, 0}, SE_PRIVILEGE_ENABLED
}}};
329 LookupPrivilegeValue(0, wszName
, &priv
.Privileges
[0].Luid
);
331 OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
, &hToken
);
333 AdjustTokenPrivileges(hToken
, FALSE
, &priv
, sizeof priv
, 0, 0);
334 bResult
= GetLastError() == ERROR_SUCCESS
;
340 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
342 CreateInitialSystemToken(HANDLE
* phSystemToken
)
344 static SID sidSystem
= { 1, 1, {SECURITY_NT_AUTHORITY
}, {SECURITY_LOCAL_SYSTEM_RID
} };
345 static SID sidEveryone
= { 1, 1, {SECURITY_WORLD_SID_AUTHORITY
}, {SECURITY_WORLD_RID
} };
346 static SID sidAuthenticatedUser
= { 1, 1, {SECURITY_NT_AUTHORITY
}, {SECURITY_AUTHENTICATED_USER_RID
} };
347 static SID_2 sidAdministrators
= { 1, 2, {SECURITY_NT_AUTHORITY
}, {SECURITY_BUILTIN_DOMAIN_RID
, DOMAIN_ALIAS_RID_ADMINS
} };
348 static const int nGroupCount
= 3;
355 TOKEN_OWNER tkDefaultOwner
;
356 TOKEN_PRIMARY_GROUP tkPrimaryGroup
;
358 TOKEN_GROUPS
* ptkGroups
= 0;
359 TOKEN_PRIVILEGES
* ptkPrivileges
= 0;
360 TOKEN_DEFAULT_DACL tkDefaultDacl
= { 0 };
362 LARGE_INTEGER tkExpiration
;
364 LUID authId
= SYSTEM_LUID
;
366 TOKEN_SOURCE source
=
368 { '*', '*', 'A', 'N', 'O', 'N', '*', '*' },
372 SECURITY_QUALITY_OF_SERVICE sqos
=
376 SECURITY_STATIC_TRACKING
,
380 OBJECT_ATTRIBUTES oa
=
390 tkExpiration
.QuadPart
= -1;
391 status
= ZwAllocateLocallyUniqueId(&source
.SourceIdentifier
);
395 tkUser
.User
.Sid
= &sidSystem
;
396 tkUser
.User
.Attributes
= 0;
398 // Under WinXP (the only MS OS I've tested) ZwCreateToken()
399 // squawks if we use sidAdministrators here -- though running
400 // a progrem under AT and using the DisplayToken() function
401 // shows that the system token does default ownership to
404 // For now, default ownership to system, since that works
405 tkDefaultOwner
.Owner
= &sidSystem
;
406 tkPrimaryGroup
.PrimaryGroup
= &sidSystem
;
408 uSize
= sizeof(TOKEN_GROUPS
) - sizeof(ptkGroups
->Groups
);
409 uSize
+= sizeof(SID_AND_ATTRIBUTES
) * nGroupCount
;
411 ptkGroups
= (TOKEN_GROUPS
*) malloc(uSize
);
412 ptkGroups
->GroupCount
= nGroupCount
;
414 ptkGroups
->Groups
[0].Sid
= (SID
*) &sidAdministrators
;
415 ptkGroups
->Groups
[0].Attributes
= SE_GROUP_ENABLED
;
417 ptkGroups
->Groups
[1].Sid
= &sidEveryone
;
418 ptkGroups
->Groups
[1].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
;
420 ptkGroups
->Groups
[2].Sid
= &sidAuthenticatedUser
;
421 ptkGroups
->Groups
[2].Attributes
= SE_GROUP_ENABLED
|SE_GROUP_ENABLED_BY_DEFAULT
|SE_GROUP_MANDATORY
;
423 uSize
= sizeof(TOKEN_PRIVILEGES
) - sizeof(ptkPrivileges
->Privileges
);
424 uSize
+= sizeof(LUID_AND_ATTRIBUTES
) * sizeof(InitialPrivilegeSet
) / sizeof(InitialPrivilegeSet
[0]);
425 ptkPrivileges
= (TOKEN_PRIVILEGES
*) malloc(uSize
);
426 ptkPrivileges
->PrivilegeCount
= sizeof(InitialPrivilegeSet
) / sizeof(InitialPrivilegeSet
[0]);
427 for (i
= 0; i
< ptkPrivileges
->PrivilegeCount
; i
++)
429 ptkPrivileges
->Privileges
[i
].Luid
.HighPart
= InitialPrivilegeSet
[i
].Luid
.HighPart
;
430 ptkPrivileges
->Privileges
[i
].Luid
.LowPart
= InitialPrivilegeSet
[i
].Luid
.LowPart
;
431 ptkPrivileges
->Privileges
[i
].Attributes
= InitialPrivilegeSet
[i
].Attributes
;
434 // Calculate the length needed for the ACL
436 uSize
+= sizeof(ACE
) + sizeof(sidSystem
);
437 uSize
+= sizeof(ACE
) + sizeof(sidAdministrators
);
438 uSize
= (uSize
& (~3)) + 8;
439 tkDefaultDacl
.DefaultDacl
= (PACL
) malloc(uSize
);
441 status
= RtlCreateAcl(tkDefaultDacl
.DefaultDacl
, uSize
, ACL_REVISION
);
442 if ( ! NT_SUCCESS(status
) )
443 printf("RtlCreateAcl() failed: 0x%08x\n", status
);
445 status
= RtlAddAccessAllowedAce(tkDefaultDacl
.DefaultDacl
, ACL_REVISION
, GENERIC_ALL
, &sidSystem
);
446 if ( ! NT_SUCCESS(status
) )
447 printf("RtlAddAccessAllowedAce() failed: 0x%08x\n", status
);
449 status
= RtlAddAccessAllowedAce(tkDefaultDacl
.DefaultDacl
, ACL_REVISION
, GENERIC_READ
|GENERIC_EXECUTE
|READ_CONTROL
, (PSID
) &sidAdministrators
);
450 if ( ! NT_SUCCESS(status
) )
451 printf("RtlAddAccessAllowedAce() failed: 0x%08x\n", status
);
453 printf("Parameters being passed into ZwCreateToken:\n\n");
454 DisplayTokenSids(&tkUser
, ptkGroups
, &tkDefaultOwner
, &tkPrimaryGroup
);
455 DisplayDacl(tkDefaultDacl
.DefaultDacl
);
457 printf("Calling ZwCreateToken()...\n");
458 status
= ZwCreateToken(phSystemToken
,
475 free(tkDefaultDacl
.DefaultDacl
);
480 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
482 main(int argc
, char* argv
[])
489 printf("Current process Token:\n");
491 Status
=ZwOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
|TOKEN_QUERY_SOURCE
, &hOurToken
);
492 if ( NT_SUCCESS(Status
) )
494 DisplayToken(hOurToken
);
495 CloseHandle(hOurToken
);
499 printf("ZwOpenProcessToken() failed: 0x%08x\n", Status
);
502 //#define ENABLE_PRIVILEGE
503 #ifdef ENABLE_PRIVILEGE
504 EnablePrivilege(SE_CREATE_TOKEN_NAME
);
507 // Now do the other one
508 Status
= CreateInitialSystemToken(&hSystemToken
);
509 if ( NT_SUCCESS(Status
) )
511 printf("System Token: 0x%08x\n", hSystemToken
);
512 DisplayToken(hSystemToken
);
513 CloseHandle(hSystemToken
);
517 printf("CreateInitialSystemToken() return: 0x%08x\n", Status
);
520 printf("press return");