1 #define UNICODE 2 #define _UNICODE 3 4 #define ANONYMOUSUNIONS 5 #include <windows.h> 6 #include <stdlib.h> 7 8 #define NTOS_MODE_USER 9 #include <ndk/ntndk.h> 10 11 12 #define INCLUDE_THE_DDK_HEADERS 13 #ifdef INCLUDE_THE_DDK_HEADERS 14 #include <ddk/ntddk.h> 15 #define ROS_ACE_HEADER ACE_HEADER 16 #define ROS_ACE ACE 17 18 #else 19 typedef LONG NTSTATUS, *PNTSTATUS; 20 21 typedef struct _UNICODE_STRING 22 { 23 USHORT Length; 24 USHORT MaximumLength; 25 PWSTR Buffer; 26 } UNICODE_STRING, *PUNICODE_STRING; 27 28 typedef struct _OBJECT_ATTRIBUTES { 29 ULONG Length; 30 HANDLE RootDirectory; 31 PUNICODE_STRING ObjectName; 32 ULONG Attributes; 33 PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR 34 PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE 35 } OBJECT_ATTRIBUTES; 36 typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; 37 38 typedef struct _ROS_ACE_HEADER 39 { 40 CHAR AceType; 41 CHAR AceFlags; 42 USHORT AceSize; 43 } ROS_ACE_HEADER, *PROS_ACE_HEADER; 44 45 typedef struct 46 { 47 ACE_HEADER Header; 48 ACCESS_MASK AccessMask; 49 } ROS_ACE, *PROS_ACE; 50 51 NTSYSAPI 52 NTSTATUS 53 NTAPI 54 RtlConvertSidToUnicodeString ( 55 IN OUT PUNICODE_STRING String, 56 IN PSID Sid, 57 IN BOOLEAN AllocateString 58 ); 59 60 NTSYSAPI 61 NTSTATUS 62 NTAPI 63 RtlCreateAcl( 64 PACL Acl, 65 ULONG AclSize, 66 ULONG AclRevision); 67 68 NTSYSAPI 69 NTSTATUS 70 NTAPI 71 RtlAddAccessAllowedAce ( 72 PACL Acl, 73 ULONG Revision, 74 ACCESS_MASK AccessMask, 75 PSID Sid 76 ); 77 78 NTSYSAPI 79 NTSTATUS 80 NTAPI 81 RtlGetAce ( 82 PACL Acl, 83 ULONG AceIndex, 84 PROS_ACE *Ace 85 ); 86 87 NTSYSAPI 88 NTSTATUS 89 NTAPI 90 ZwAllocateLocallyUniqueId( 91 OUT PLUID Luid 92 ); 93 94 NTSYSAPI 95 NTSTATUS 96 NTAPI 97 ZwCreateToken( 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 111 ); 112 #define NT_SUCCESS(StatCode) ((NTSTATUS)(StatCode) >= 0) 113 #endif 114 115 #include <stdio.h> 116 117 #define INITIAL_PRIV_ENABLED SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED 118 #define INITIAL_PRIV_DISABLED 0 119 LUID_AND_ATTRIBUTES InitialPrivilegeSet[] = 120 { 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 143 }; 144 145 typedef struct _SID_2 146 { 147 UCHAR Revision; 148 UCHAR SubAuthorityCount; 149 SID_IDENTIFIER_AUTHORITY IdentifierAuthority; 150 ULONG SubAuthority[2]; 151 } SID_2; 152 153 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 154 void 155 PrintSid(SID_AND_ATTRIBUTES* pSid, TOKEN_OWNER* pOwner, TOKEN_PRIMARY_GROUP* pPrimary) 156 { 157 UNICODE_STRING scSid; 158 159 RtlConvertSidToUnicodeString(&scSid, pSid->Sid, TRUE); 160 printf("%wZ [", &scSid); 161 LocalFree(scSid.Buffer); 162 163 if ( EqualSid(pSid->Sid, pOwner->Owner) ) 164 printf("owner,"); 165 166 if ( EqualSid(pSid->Sid, pPrimary->PrimaryGroup) ) 167 printf("primary,"); 168 169 if ( pSid->Attributes & SE_GROUP_ENABLED ) 170 { 171 if ( pSid->Attributes & SE_GROUP_ENABLED_BY_DEFAULT ) 172 printf("enabled-default,"); 173 else 174 printf("enabled,"); 175 } 176 177 if ( pSid->Attributes & SE_GROUP_LOGON_ID ) 178 printf("logon,"); 179 180 181 if ( pSid->Attributes & SE_GROUP_MANDATORY ) 182 printf("mandatory,"); 183 184 printf("]\n"); 185 } 186 187 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 188 void 189 DisplayTokenSids(TOKEN_USER* pUser, 190 TOKEN_GROUPS* pGroups, 191 TOKEN_OWNER* pOwner, 192 TOKEN_PRIMARY_GROUP* pPrimary) 193 { 194 DWORD i; 195 196 printf("\nSids:\n"); 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); 201 } 202 203 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 204 void 205 DisplayTokenPrivileges(TOKEN_PRIVILEGES* pPriv) 206 { 207 WCHAR buffer[256]; 208 DWORD i; 209 210 printf("\nprivileges:\n"); 211 for (i = 0; i < pPriv->PrivilegeCount; i++) 212 { 213 DWORD cbName = sizeof(buffer) / sizeof(buffer[0]); 214 LookupPrivilegeName(0, &pPriv->Privileges[i].Luid, buffer, &cbName); 215 216 printf("%S{0x%08x, 0x%08x} [", buffer, pPriv->Privileges[i].Luid.HighPart, pPriv->Privileges[i].Luid.LowPart); 217 218 if ( pPriv->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED ) 219 printf("enabled,"); 220 if ( pPriv->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT ) 221 printf("default,"); 222 if ( pPriv->Privileges[i].Attributes & SE_PRIVILEGE_USED_FOR_ACCESS ) 223 printf("used"); 224 225 printf("]\n"); 226 } 227 } 228 229 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 230 void 231 DisplayDacl(PACL pAcl) 232 { 233 DWORD i; 234 NTSTATUS status; 235 236 if ( ! pAcl ) 237 { 238 printf("\nNo Default Dacl.\n"); 239 return; 240 } 241 242 printf("\nDacl:\n"); 243 for (i = 0; i < pAcl->AceCount; i++) 244 { 245 UNICODE_STRING scSid; 246 ROS_ACE* pAce; 247 LPWSTR wszType = 0; 248 PSID pSid; 249 250 status = RtlGetAce(pAcl, i, (ROS_ACE**) &pAce); 251 if ( ! NT_SUCCESS(status) ) 252 { 253 printf("RtlGetAce(): status = 0x%08x\n", status); 254 break; 255 } 256 257 pSid = (PSID) (pAce + 1); 258 if ( pAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE ) 259 wszType = L"allow"; 260 if ( pAce->Header.AceType == ACCESS_DENIED_ACE_TYPE ) 261 wszType = L"deny "; 262 263 status = RtlConvertSidToUnicodeString(&scSid, pSid, TRUE); 264 if ( ! NT_SUCCESS(status) ) 265 { 266 printf("RtlConvertSidToUnicodeString(): status = 0x%08x\n", status); 267 break; 268 } 269 270 printf("%d.) %S %wZ 0x%08x\n", i, wszType, &scSid, pAce->AccessMask); 271 LocalFree(scSid.Buffer); 272 } 273 } 274 275 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 276 PVOID 277 GetFromToken(HANDLE hToken, TOKEN_INFORMATION_CLASS tic) 278 { 279 BOOL bResult; 280 DWORD n; 281 PBYTE p = 0; 282 283 bResult = GetTokenInformation(hToken, tic, 0, 0, &n); 284 if ( ! bResult && GetLastError() != ERROR_INSUFFICIENT_BUFFER) 285 return 0; 286 287 p = (PBYTE) malloc(n); 288 if ( ! GetTokenInformation(hToken, tic, p, n, &n) ) 289 { 290 printf("GetFromToken() failed for TOKEN_INFORMATION_CLASS(%d): %d\n", tic, GetLastError()); 291 free(p); 292 return 0; 293 } 294 295 return p; 296 } 297 298 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 299 void 300 DisplayToken(HANDLE hTokenSource) 301 { 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); 308 309 DisplayTokenSids(pTokenUser, pTokenGroups, pTokenOwner, pTokenPrimaryGroup); 310 // DisplayTokenPrivileges(pTokenPrivileges); 311 DisplayDacl(pTokenDefaultDacl->DefaultDacl); 312 313 free(pTokenUser); 314 free(pTokenGroups); 315 free(pTokenOwner); 316 free(pTokenPrimaryGroup); 317 free(pTokenPrivileges); 318 free(pTokenDefaultDacl); 319 } 320 321 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 322 BOOL 323 EnablePrivilege(LPWSTR wszName) 324 { 325 HANDLE hToken; 326 TOKEN_PRIVILEGES priv = {1, {{{0, 0}, SE_PRIVILEGE_ENABLED}}}; 327 BOOL bResult; 328 329 LookupPrivilegeValue(0, wszName, &priv.Privileges[0].Luid); 330 331 OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken); 332 333 AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof priv, 0, 0); 334 bResult = GetLastError() == ERROR_SUCCESS; 335 336 CloseHandle(hToken); 337 return bResult; 338 } 339 340 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 341 NTSTATUS 342 CreateInitialSystemToken(HANDLE* phSystemToken) 343 { 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; 349 350 NTSTATUS status; 351 ULONG uSize; 352 DWORD i; 353 354 TOKEN_USER tkUser; 355 TOKEN_OWNER tkDefaultOwner; 356 TOKEN_PRIMARY_GROUP tkPrimaryGroup; 357 358 TOKEN_GROUPS* ptkGroups = 0; 359 TOKEN_PRIVILEGES* ptkPrivileges = 0; 360 TOKEN_DEFAULT_DACL tkDefaultDacl = { 0 }; 361 362 LARGE_INTEGER tkExpiration; 363 364 LUID authId = SYSTEM_LUID; 365 366 TOKEN_SOURCE source = 367 { 368 { '*', '*', 'A', 'N', 'O', 'N', '*', '*' }, 369 {0, 0} 370 }; 371 372 SECURITY_QUALITY_OF_SERVICE sqos = 373 { 374 sizeof(sqos), 375 SecurityAnonymous, 376 SECURITY_STATIC_TRACKING, 377 FALSE 378 }; 379 380 OBJECT_ATTRIBUTES oa = 381 { 382 sizeof(oa), 383 0, 384 0, 385 0, 386 0, 387 &sqos 388 }; 389 390 tkExpiration.QuadPart = -1; 391 status = ZwAllocateLocallyUniqueId(&source.SourceIdentifier); 392 if ( status != 0 ) 393 return status; 394 395 tkUser.User.Sid = &sidSystem; 396 tkUser.User.Attributes = 0; 397 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 402 // Administrator. 403 404 // For now, default ownership to system, since that works 405 tkDefaultOwner.Owner = &sidSystem; 406 tkPrimaryGroup.PrimaryGroup = &sidSystem; 407 408 uSize = sizeof(TOKEN_GROUPS) - sizeof(ptkGroups->Groups); 409 uSize += sizeof(SID_AND_ATTRIBUTES) * nGroupCount; 410 411 ptkGroups = (TOKEN_GROUPS*) malloc(uSize); 412 ptkGroups->GroupCount = nGroupCount; 413 414 ptkGroups->Groups[0].Sid = (SID*) &sidAdministrators; 415 ptkGroups->Groups[0].Attributes = SE_GROUP_ENABLED; 416 417 ptkGroups->Groups[1].Sid = &sidEveryone; 418 ptkGroups->Groups[1].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY; 419 420 ptkGroups->Groups[2].Sid = &sidAuthenticatedUser; 421 ptkGroups->Groups[2].Attributes = SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY; 422 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++) 428 { 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; 432 } 433 434 // Calculate the length needed for the ACL 435 uSize = sizeof(ACL); 436 uSize += sizeof(ACE) + sizeof(sidSystem); 437 uSize += sizeof(ACE) + sizeof(sidAdministrators); 438 uSize = (uSize & (~3)) + 8; 439 tkDefaultDacl.DefaultDacl = (PACL) malloc(uSize); 440 441 status = RtlCreateAcl(tkDefaultDacl.DefaultDacl, uSize, ACL_REVISION); 442 if ( ! NT_SUCCESS(status) ) 443 printf("RtlCreateAcl() failed: 0x%08x\n", status); 444 445 status = RtlAddAccessAllowedAce(tkDefaultDacl.DefaultDacl, ACL_REVISION, GENERIC_ALL, &sidSystem); 446 if ( ! NT_SUCCESS(status) ) 447 printf("RtlAddAccessAllowedAce() failed: 0x%08x\n", status); 448 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); 452 453 printf("Parameters being passed into ZwCreateToken:\n\n"); 454 DisplayTokenSids(&tkUser, ptkGroups, &tkDefaultOwner, &tkPrimaryGroup); 455 DisplayDacl(tkDefaultDacl.DefaultDacl); 456 457 printf("Calling ZwCreateToken()...\n"); 458 status = ZwCreateToken(phSystemToken, 459 TOKEN_ALL_ACCESS, 460 &oa, 461 TokenPrimary, 462 &authId, 463 &tkExpiration, 464 &tkUser, 465 ptkGroups, 466 ptkPrivileges, 467 &tkDefaultOwner, 468 &tkPrimaryGroup, 469 &tkDefaultDacl, 470 &source); 471 472 // Cleanup 473 free(ptkGroups); 474 free(ptkPrivileges); 475 free(tkDefaultDacl.DefaultDacl); 476 477 return status; 478 } 479 480 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 481 int 482 main(int argc, char* argv[]) 483 { 484 NTSTATUS Status; 485 HANDLE hSystemToken; 486 CHAR buffer[512]; 487 HANDLE hOurToken; 488 489 printf("Current process Token:\n"); 490 491 Status=ZwOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_QUERY_SOURCE, &hOurToken); 492 if ( NT_SUCCESS(Status) ) 493 { 494 DisplayToken(hOurToken); 495 CloseHandle(hOurToken); 496 } 497 else 498 { 499 printf("ZwOpenProcessToken() failed: 0x%08x\n", Status); 500 } 501 502 //#define ENABLE_PRIVILEGE 503 #ifdef ENABLE_PRIVILEGE 504 EnablePrivilege(SE_CREATE_TOKEN_NAME); 505 #endif 506 507 // Now do the other one 508 Status = CreateInitialSystemToken(&hSystemToken); 509 if ( NT_SUCCESS(Status) ) 510 { 511 printf("System Token: 0x%08x\n", hSystemToken); 512 DisplayToken(hSystemToken); 513 CloseHandle(hSystemToken); 514 } 515 else 516 { 517 printf("CreateInitialSystemToken() return: 0x%08x\n", Status); 518 } 519 520 printf("press return"); 521 gets(buffer); 522 523 return 0; 524 } 525