00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
#include "cmp.h"
00043
#include <stdio.h>
00044
#include <stdlib.h>
00045
#include <string.h>
00046
00047 #define WORK_SIZE 1024
00048
00049
00050
00051
00052
00053 #define FirstAce(Acl) ((PVOID)((PUCHAR)(Acl) + sizeof(ACL)))
00054
00055
00056
00057
00058
00059 #define NextAce(Ace) ((PVOID)((PUCHAR)(Ace) + ((PACE_HEADER)(Ace))->AceSize))
00060
00061
00062
00063
00064
00065 typedef struct _KNOWN_ACE {
00066 ACE_HEADER
Header;
00067 ACCESS_MASK
Mask;
00068 ULONG
SidStart;
00069 }
KNOWN_ACE, *
PKNOWN_ACE;
00070
00071
00072
00073
VOID
00074
InitVars();
00075
00076
VOID
00077
PrintAcl (
00078 IN PACL Acl
00079 );
00080
00081
VOID
00082
PrintAccessMask(
00083 IN ACCESS_MASK AccessMask
00084 );
00085
00086
void __cdecl
main(
int,
char *);
00087
void processargs();
00088
00089
void print(PUNICODE_STRING);
00090
00091
void
00092
DumpSecurity(
00093 HANDLE Handle
00094 );
00095
00096
void
00097
Dump(
00098 HANDLE Handle
00099 );
00100
00101 UNICODE_STRING
WorkName;
00102 WCHAR
workbuffer[
WORK_SIZE];
00103
00104
00105
00106
00107
00108 PSID
NullSid;
00109 PSID
WorldSid;
00110 PSID
LocalSid;
00111 PSID
CreatorOwnerSid;
00112
00113
00114
00115
00116
00117 PSID
NtAuthoritySid;
00118
00119 PSID
DialupSid;
00120 PSID
NetworkSid;
00121 PSID
BatchSid;
00122 PSID
InteractiveSid;
00123 PSID
LocalSystemSid;
00124
00125
void
00126 __cdecl
main(
00127
int argc,
00128
char *argv[]
00129 )
00130 {
00131
NTSTATUS status;
00132 OBJECT_ATTRIBUTES
ObjectAttributes;
00133 HANDLE BaseHandle;
00134
00135
InitVars();
00136
00137
00138
00139
00140
00141
WorkName.MaximumLength =
WORK_SIZE;
00142
WorkName.Length = 0
L;
00143
WorkName.Buffer = &(
workbuffer[0]);
00144
00145
processargs(argc, argv);
00146
00147
00148
00149
00150
00151
00152 printf(
"rtdmpsec: starting\n");
00153
00154 InitializeObjectAttributes(
00155 &
ObjectAttributes,
00156 &
WorkName,
00157 0,
00158 (HANDLE)
NULL,
00159
NULL
00160 );
00161
ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
00162
00163 status =
NtOpenKey(
00164 &BaseHandle,
00165 MAXIMUM_ALLOWED,
00166 &
ObjectAttributes
00167 );
00168
if (!
NT_SUCCESS(status)) {
00169 printf(
"rtdmpsec: t0: %08lx\n", status);
00170
exit(1);
00171 }
00172
00173
Dump(BaseHandle);
00174 }
00175
00176
00177
void
00178
Dump(
00179 HANDLE Handle
00180 )
00181 {
00182
NTSTATUS status;
00183 PKEY_BASIC_INFORMATION KeyInformation;
00184 OBJECT_ATTRIBUTES
ObjectAttributes;
00185 ULONG NamePos;
00186 ULONG index;
00187 STRING enumname;
00188 HANDLE WorkHandle;
00189 ULONG ResultLength;
00190
static char buffer[
WORK_SIZE];
00191 PUCHAR p;
00192
00193 KeyInformation = (PKEY_BASIC_INFORMATION)buffer;
00194 NamePos =
WorkName.Length;
00195
00196
00197
00198
00199 printf(
"\n");
00200
print(&WorkName);
00201 printf(
"::\n");
00202
00203
00204
00205
00206
DumpSecurity(Handle);
00207
00208
00209
00210
00211
00212
for (index = 0;
TRUE; index++) {
00213
00214 RtlZeroMemory(KeyInformation, WORK_SIZE);
00215 status =
NtEnumerateKey(
00216 Handle,
00217 index,
00218 KeyBasicInformation,
00219 KeyInformation,
00220 WORK_SIZE,
00221 &ResultLength
00222 );
00223
00224
if (status == STATUS_NO_MORE_ENTRIES) {
00225
00226
WorkName.Length = NamePos;
00227
return;
00228
00229 }
else if (!
NT_SUCCESS(status)) {
00230
00231 printf(
"rtdmpsec: dump1: status = %08lx\n", status);
00232
exit(1);
00233
00234 }
00235
00236 enumname.Buffer = &(KeyInformation->Name[0]);
00237 enumname.Length = KeyInformation->NameLength;
00238 enumname.MaximumLength = KeyInformation->NameLength;
00239
00240 p =
WorkName.Buffer;
00241 p +=
WorkName.Length;
00242 *p =
'\\';
00243 p++;
00244 *p =
'\0';
00245
WorkName.Length += 2;
00246
00247
RtlAppendStringToString((PSTRING)&WorkName, (PSTRING)&enumname);
00248
00249 InitializeObjectAttributes(
00250 &ObjectAttributes,
00251 &enumname,
00252 0,
00253 Handle,
00254 NULL
00255 );
00256
ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
00257
00258 status =
NtOpenKey(
00259 &WorkHandle,
00260 MAXIMUM_ALLOWED,
00261 &ObjectAttributes
00262 );
00263
if (!
NT_SUCCESS(status)) {
00264
if (status == STATUS_ACCESS_DENIED) {
00265 printf(
"\n");
00266
print(&WorkName);
00267 printf(
"::\n\tAccess denied!\n");
00268 }
else {
00269 printf(
"rtdmpsec: dump2: %08lx\n", status);
00270
exit(1);
00271 }
00272 }
else {
00273
Dump(WorkHandle);
00274
NtClose(WorkHandle);
00275 }
00276
00277
WorkName.Length = NamePos;
00278 }
00279 }
00280
00281
00282
void
00283 DumpSecurity(
00284 HANDLE Handle
00285 )
00286 {
00287 PSECURITY_DESCRIPTOR SecurityDescriptor;
00288
NTSTATUS Status;
00289 ULONG Length;
00290 PACL
Dacl;
00291 BOOLEAN DaclPresent;
00292 BOOLEAN DaclDefaulted;
00293
00294
Status =
NtQuerySecurityObject(
Handle,
00295 DACL_SECURITY_INFORMATION,
00296
NULL,
00297 0,
00298 &Length );
00299
00300
if (
Status != STATUS_BUFFER_TOO_SMALL) {
00301 printf(
"DumpSecurity t0: NtQuerySecurityObject failed %lx\n",
Status);
00302
exit(1);
00303 }
00304
00305 SecurityDescriptor = malloc(Length);
00306
if (SecurityDescriptor ==
NULL) {
00307 printf(
"DumpSecurity: couldn't malloc buffer\n");
00308
exit(1);
00309 }
00310
00311
Status =
NtQuerySecurityObject(
Handle,
00312 DACL_SECURITY_INFORMATION,
00313 SecurityDescriptor,
00314 Length,
00315 &Length );
00316
00317
if (!
NT_SUCCESS(
Status)) {
00318 printf(
"DumpSecurity t1: NtQuerySecurityObject failed %lx\n",
Status);
00319
exit(1);
00320 }
00321
00322
Dacl =
NULL;
00323
00324
Status =
RtlGetDaclSecurityDescriptor( SecurityDescriptor,
00325 &DaclPresent,
00326 &
Dacl,
00327 &DaclDefaulted );
00328
if (!
NT_SUCCESS(
Status)) {
00329 printf(
"DumpSecurity t2: RtlGetDaclSecurityDescriptor failed %lx\n",
Status);
00330 }
00331
00332
if (DaclPresent) {
00333
PrintAcl(
Dacl);
00334 }
else {
00335 printf(
"\tAcl not present\n");
00336 }
00337
00338 }
00339
00340
00341
void
00342
print(
00343 PUNICODE_STRING String
00344 )
00345 {
00346
static ANSI_STRING temp;
00347
static char tempbuffer[
WORK_SIZE];
00348
00349 temp.MaximumLength =
WORK_SIZE;
00350 temp.Length = 0
L;
00351 temp.Buffer = tempbuffer;
00352
00353
RtlUnicodeStringToAnsiString(&temp, String, FALSE);
00354 printf(
"%s", temp.Buffer);
00355
return;
00356 }
00357
00358
00359
void
00360 processargs(
00361
int argc,
00362
char *argv[]
00363 )
00364 {
00365 ANSI_STRING temp;
00366
00367
if ( (argc != 2) )
00368 {
00369 printf(
"Usage: %s <KeyPath>\n",
00370 argv[0]);
00371
exit(1);
00372 }
00373
00374
RtlInitAnsiString(
00375 &temp,
00376 argv[1]
00377 );
00378
00379
RtlAnsiStringToUnicodeString(
00380 &
WorkName,
00381 &temp,
00382
FALSE
00383 );
00384
00385
return;
00386 }
00387
00388
00389 BOOLEAN
00390 SidTranslation(
00391 PSID Sid,
00392 PSTRING AccountName
00393 )
00394
00395
00396 {
00397
if (
RtlEqualSid(Sid,
WorldSid)) {
00398
RtlInitString( AccountName,
"WORLD");
00399
return(
TRUE);
00400 }
00401
00402
if (
RtlEqualSid(Sid,
LocalSid)) {
00403
RtlInitString( AccountName,
"LOCAL");
00404
00405
return(
TRUE);
00406 }
00407
00408
if (
RtlEqualSid(Sid,
NetworkSid)) {
00409
RtlInitString( AccountName,
"NETWORK");
00410
00411
return(
TRUE);
00412 }
00413
00414
if (
RtlEqualSid(Sid,
BatchSid)) {
00415
RtlInitString( AccountName,
"BATCH");
00416
00417
return(
TRUE);
00418 }
00419
00420
if (
RtlEqualSid(Sid,
InteractiveSid)) {
00421
RtlInitString( AccountName,
"INTERACTIVE");
00422
return(
TRUE);
00423 }
00424
00425
if (
RtlEqualSid(Sid,
LocalSystemSid)) {
00426
RtlInitString( AccountName,
"SYSTEM");
00427
return(
TRUE);
00428 }
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
return(
FALSE);
00442
00443 }
00444
00445
00446
VOID
00447 DisplayAccountSid(
00448 PSID Sid
00449 )
00450 {
00451 UCHAR
Buffer[128];
00452 STRING AccountName;
00453 UCHAR i;
00454 ULONG Tmp;
00455 PSID_IDENTIFIER_AUTHORITY IdentifierAuthority;
00456 UCHAR SubAuthorityCount;
00457
00458
Buffer[0] = 0;
00459
00460 AccountName.MaximumLength = 127;
00461 AccountName.Length = 0;
00462 AccountName.Buffer = (PVOID)&
Buffer[0];
00463
00464
00465
00466
if (
SidTranslation( (PSID)Sid, &AccountName) ) {
00467
00468 printf(
"%s\n", AccountName.Buffer );
00469
00470 }
else {
00471 IdentifierAuthority =
RtlIdentifierAuthoritySid(Sid);
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 printf(
"S-%u-", (
USHORT) *((PUCHAR) Sid) );
00482
00483
if ( (IdentifierAuthority->Value[0] != 0) ||
00484 (IdentifierAuthority->Value[1] != 0) ){
00485 printf(
"0x%02hx%02hx%02hx%02hx%02hx%02hx",
00486 IdentifierAuthority->Value[0],
00487 IdentifierAuthority->Value[1],
00488 IdentifierAuthority->Value[2],
00489 IdentifierAuthority->Value[3],
00490 IdentifierAuthority->Value[4],
00491 IdentifierAuthority->Value[5] );
00492 }
else {
00493 Tmp = IdentifierAuthority->Value[5] +
00494 (IdentifierAuthority->Value[4] << 8) +
00495 (IdentifierAuthority->Value[3] << 16) +
00496 (IdentifierAuthority->Value[2] << 24);
00497 printf(
"%lu", Tmp);
00498 }
00499
00500 SubAuthorityCount = *
RtlSubAuthorityCountSid(Sid);
00501
for (i=0;i<SubAuthorityCount ;i++ ) {
00502 printf(
"-%lu", (*
RtlSubAuthoritySid(Sid, i)));
00503 }
00504 printf(
"\n");
00505
00506 }
00507
00508 }
00509
00510
VOID
00511 InitVars()
00512 {
00513 ULONG SidWithZeroSubAuthorities;
00514 ULONG SidWithOneSubAuthority;
00515 ULONG SidWithThreeSubAuthorities;
00516 ULONG SidWithFourSubAuthorities;
00517
00518 SID_IDENTIFIER_AUTHORITY NullSidAuthority = SECURITY_NULL_SID_AUTHORITY;
00519 SID_IDENTIFIER_AUTHORITY WorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
00520 SID_IDENTIFIER_AUTHORITY LocalSidAuthority = SECURITY_LOCAL_SID_AUTHORITY;
00521 SID_IDENTIFIER_AUTHORITY CreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
00522
00523 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
00524
00525
00526
00527
00528
00529
00530 SidWithZeroSubAuthorities =
RtlLengthRequiredSid( 0 );
00531 SidWithOneSubAuthority =
RtlLengthRequiredSid( 1 );
00532 SidWithThreeSubAuthorities =
RtlLengthRequiredSid( 3 );
00533 SidWithFourSubAuthorities =
RtlLengthRequiredSid( 4 );
00534
00535
00536
00537
00538
00539
NullSid = (PSID)malloc(SidWithOneSubAuthority);
00540
WorldSid = (PSID)malloc(SidWithOneSubAuthority);
00541
LocalSid = (PSID)malloc(SidWithOneSubAuthority);
00542
CreatorOwnerSid = (PSID)malloc(SidWithOneSubAuthority);
00543
00544
RtlInitializeSid(
NullSid, &NullSidAuthority, 1 );
00545
RtlInitializeSid(
WorldSid, &WorldSidAuthority, 1 );
00546
RtlInitializeSid(
LocalSid, &LocalSidAuthority, 1 );
00547
RtlInitializeSid(
CreatorOwnerSid, &CreatorSidAuthority, 1 );
00548
00549 *(
RtlSubAuthoritySid(
NullSid, 0 )) = SECURITY_NULL_RID;
00550 *(
RtlSubAuthoritySid(
WorldSid, 0 )) = SECURITY_WORLD_RID;
00551 *(
RtlSubAuthoritySid(
LocalSid, 0 )) = SECURITY_LOCAL_RID;
00552 *(
RtlSubAuthoritySid(
CreatorOwnerSid, 0 )) = SECURITY_CREATOR_OWNER_RID;
00553
00554
00555
00556
00557
00558
NtAuthoritySid = (PSID)malloc(SidWithZeroSubAuthorities);
00559
DialupSid = (PSID)malloc(SidWithOneSubAuthority);
00560
NetworkSid = (PSID)malloc(SidWithOneSubAuthority);
00561
BatchSid = (PSID)malloc(SidWithOneSubAuthority);
00562
InteractiveSid = (PSID)malloc(SidWithOneSubAuthority);
00563
LocalSystemSid = (PSID)malloc(SidWithOneSubAuthority);
00564
00565
RtlInitializeSid(
NtAuthoritySid, &NtAuthority, 0 );
00566
RtlInitializeSid(
DialupSid, &NtAuthority, 1 );
00567
RtlInitializeSid(
NetworkSid, &NtAuthority, 1 );
00568
RtlInitializeSid(
BatchSid, &NtAuthority, 1 );
00569
RtlInitializeSid(
InteractiveSid, &NtAuthority, 1 );
00570
RtlInitializeSid(
LocalSystemSid, &NtAuthority, 1 );
00571
00572 *(
RtlSubAuthoritySid(
DialupSid, 0 )) = SECURITY_DIALUP_RID;
00573 *(
RtlSubAuthoritySid(
NetworkSid, 0 )) = SECURITY_NETWORK_RID;
00574 *(
RtlSubAuthoritySid(
BatchSid, 0 )) = SECURITY_BATCH_RID;
00575 *(
RtlSubAuthoritySid(
InteractiveSid, 0 )) = SECURITY_INTERACTIVE_RID;
00576 *(
RtlSubAuthoritySid(
LocalSystemSid, 0 )) = SECURITY_LOCAL_SYSTEM_RID;
00577
00578
return;
00579
00580 }
00581
00582
00583
00584
VOID
00585 PrintAcl (
00586 IN PACL Acl
00587 )
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607 {
00608 ULONG i;
00609
PKNOWN_ACE Ace;
00610 BOOLEAN KnownType;
00611 PCHAR AceTypes[] = {
"Access Allowed",
00612
"Access Denied ",
00613
"System Audit ",
00614
"System Alarm "
00615 };
00616
00617
if (Acl ==
NULL) {
00618
00619 printf(
"\tAcl == ALL ACCESS GRANTED!\n");
00620
return;
00621
00622 }
00623
00624
00625
00626
00627
00628 printf(
"\tRevision: %02x", Acl->AclRevision);
00629 printf(
" Size: %04x", Acl->AclSize);
00630 printf(
" AceCount: %04x\n", Acl->AceCount);
00631
00632
00633
00634
00635
00636
for (i = 0, Ace =
FirstAce(Acl);
00637 i < Acl->AceCount;
00638 i++, Ace =
NextAce(Ace) ) {
00639
00640
00641
00642
00643
00644 printf(
"\n\tAceHeader: %08lx ", *(PULONG)Ace);
00645
00646
00647
00648
00649
00650
if ((Ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) ||
00651 (Ace->Header.AceType == ACCESS_DENIED_ACE_TYPE) ||
00652 (Ace->Header.AceType == SYSTEM_AUDIT_ACE_TYPE) ||
00653 (Ace->Header.AceType == SYSTEM_ALARM_ACE_TYPE)) {
00654
00655
00656
00657
00658
00659
00660 PCHAR AceTypes[] = {
"Access Allowed",
00661
"Access Denied ",
00662
"System Audit ",
00663
"System Alarm "
00664 };
00665
00666 printf(AceTypes[Ace->Header.AceType]);
00667
PrintAccessMask(Ace->Mask);
00668 KnownType =
TRUE;
00669
00670 }
else {
00671
00672 KnownType =
FALSE;
00673 printf(
" Unknown Ace Type\n");
00674
00675 }
00676
00677 printf(
"\n");
00678
00679 printf(
"\tAceSize = %d\n",Ace->Header.AceSize);
00680
00681 printf(
"\tAce Flags = ");
00682
if (Ace->Header.AceFlags & OBJECT_INHERIT_ACE) {
00683 printf(
"OBJECT_INHERIT_ACE\n");
00684 printf(
" ");
00685 }
00686
00687
if (Ace->Header.AceFlags & CONTAINER_INHERIT_ACE) {
00688 printf(
"CONTAINER_INHERIT_ACE\n");
00689 printf(
" ");
00690 }
00691
00692
if (Ace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE) {
00693 printf(
"NO_PROPAGATE_INHERIT_ACE\n");
00694 printf(
" ");
00695 }
00696
00697
if (Ace->Header.AceFlags & INHERIT_ONLY_ACE) {
00698 printf(
"INHERIT_ONLY_ACE\n");
00699 printf(
" ");
00700 }
00701
00702
if (Ace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) {
00703 printf(
"SUCCESSFUL_ACCESS_ACE_FLAG\n");
00704 printf(
" ");
00705 }
00706
00707
if (Ace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG) {
00708 printf(
"FAILED_ACCESS_ACE_FLAG\n");
00709 printf(
" ");
00710 }
00711
00712 printf(
"\n");
00713
00714 printf(
"\tSid = ");
00715
DisplayAccountSid(&Ace->SidStart);
00716 }
00717
00718 }
00719
00720
00721
VOID
00722 PrintAccessMask(
00723 IN ACCESS_MASK AccessMask
00724 )
00725 {
00726 printf(
"\n\tAccess Mask: ");
00727
00728
if (AccessMask == KEY_ALL_ACCESS) {
00729 printf(
"KEY_ALL_ACCESS\n\t ");
00730
return;
00731 }
00732
if (AccessMask == KEY_READ) {
00733 printf(
"KEY_READ\n\t ");
00734
return;
00735 }
00736
if (AccessMask == KEY_WRITE) {
00737 printf(
"KEY_WRITE\n\t ");
00738
return;
00739 }
00740
00741
if (AccessMask & KEY_QUERY_VALUE) {
00742 printf(
"KEY_QUERY_VALUE\n\t ");
00743 }
00744
if (AccessMask & KEY_SET_VALUE) {
00745 printf(
"KEY_SET_VALUE\n\t ");
00746 }
00747
if (AccessMask & KEY_CREATE_SUB_KEY) {
00748 printf(
"KEY_CREATE_SUB_KEY\n\t ");
00749 }
00750
if (AccessMask & KEY_ENUMERATE_SUB_KEYS) {
00751 printf(
"KEY_ENUMERATE_SUB_KEYS\n\t ");
00752 }
00753
if (AccessMask & KEY_NOTIFY) {
00754 printf(
"KEY_NOTIFY\n\t ");
00755 }
00756
if (AccessMask & KEY_CREATE_LINK) {
00757 printf(
"KEY_CREATE_LINK\n\t ");
00758 }
00759
if (AccessMask & GENERIC_ALL) {
00760 printf(
"GENERIC_ALL\n\t ");
00761 }
00762
if (AccessMask & GENERIC_EXECUTE) {
00763 printf(
"GENERIC_EXECUTE\n\t ");
00764 }
00765
if (AccessMask & GENERIC_WRITE) {
00766 printf(
"GENERIC_WRITE\n\t ");
00767 }
00768
if (AccessMask & GENERIC_READ) {
00769 printf(
"GENERIC_READ\n\t ");
00770 }
00771
if (AccessMask & GENERIC_READ) {
00772 printf(
"GENERIC_READ\n\t ");
00773 }
00774
if (AccessMask & MAXIMUM_ALLOWED) {
00775 printf(
"MAXIMUM_ALLOWED\n\t ");
00776 }
00777
if (AccessMask & ACCESS_SYSTEM_SECURITY) {
00778 printf(
"ACCESS_SYSTEM_SECURITY\n\t ");
00779 }
00780
if (AccessMask & WRITE_OWNER) {
00781 printf(
"WRITE_OWNER\n\t ");
00782 }
00783
if (AccessMask & WRITE_DAC) {
00784 printf(
"WRITE_DAC\n\t ");
00785 }
00786
if (AccessMask & READ_CONTROL) {
00787 printf(
"READ_CONTROL\n\t ");
00788 }
00789
if (AccessMask & DELETE) {
00790 printf(
"DELETE\n\t ");
00791 }
00792 }