On July 6, April 22, a small program for modifying the DACL of the Registry

Source: Internet
Author: User

That's just a little thing. It took two and a half days !! Of course, I also learned about objects and DACL in the middle. Although I have read it before, I can only forget it once I read it. It must be applied, you must have the desire to learn. boring books will become very easy to read ,,,,

Do not give up or be careful. If you forget it when you fail to change the DACL through the hkey obtained by regopenkey at the beginning, it will actually be done ,,,, although it is not a big deal, I am reminded that I can try again no matter how big or small it is, and I am careful with ret = lookupaccountname (null, user_groupname, & SID, & sidlen, siddomain, & siddomainlen,
& Sidtype); in this sentence, I wrote user_groupname as "everyone", and spent a whole night looking for this error, so I practiced my debugging capability, but I still don't think it's worth it. Besides, this is a problem.

Every key in the registry is an object. In windows, all keys are objects. Take the example in phrack 59 0x10.

Typedef struct _ object_header {
/* 000 */DWORD pointercount; // number of references
/* 004 */DWORD handlecount; // number of open handles
/* 008 */pobject_type objecttype; // pointer to object type struct
/* 00c */byte nameoffset; // object_name offset
/* 00D */byte handledboffset; // object_handle_db offset
/* 00e */byte quotachargesoffset; // object_quota_charges offset
/* 00f */byte objectflags; // ob_flag _*
/* 010 */Union
{// Ob_flag_create_info? Objectcreateinfo: quotablock
/* 010 */pquota_block quotablock;
/* 010 */pobject_create_info objectcreateinfo;
};
/* 014 */psecurity_descriptor securitydescriptor;
/* 018 */} object_header, * pobject_header;

Different objects have different objecttypes, and all the same object_headers are in front of the Object Body. I still don't know what is in the object body. The nameoffset IN THE object_header, the location in the memory of the object_type structure is in front of the object_header, that is, if you want to find the corresponding content of nameoffset, you need object_header-nameoffset.

Kd>! Object/device/physicalmemory
Object: e1001250 type: (81899040) Section
Objectheader: e1001238
Handlecount: 0 pointercount: 3
Directory object: 8189a180 name: physicalmemory
Kd> dd e1001238 L 6
E1001238 00000003 00000000 81899040 16300020
E1001248 00000001 e1008bd8
Kd>! SD e1008bd8 // view securitydescriptor
-> Revision: 0x1
-> Sbz1: 0x0
-> Control: 0x8004
Se_dacl_present
Se_self_relative
-> Owner: S-1-5-32-544
-> Group: S-1-5-18
-> DACL:
-> DACL:-> aclrevision: 0x2
-> DACL:-> sbz1: 0x0
-> DACL:-> aclsize: 0x44
-> DACL:-> acecount: 0x2
-> DACL:-> sbz2: 0x0
-> DACL:-> ace [0]:-> acetype: access_allowed_ace_type
-> DACL:-> ace [0]:-> aceflags: 0x0
-> DACL:-> ace [0]:-> acesize: 0x14
-> DACL:-> ace [0]:-> mask: 0x000f001f
-> DACL:-> ace [0]:-> Sid: S-1-5-18

-> DACL:-> ace [1]:-> acetype: access_allowed_ace_type
-> DACL:-> ace [1]:-> aceflags: 0x0
-> DACL:-> ace [1]:-> acesize: 0x18
-> DACL:-> ace [1]:-> mask: 0x0002000d
-> DACL:-> ace [1]:-> Sid: S-1-5-32-544

-> SACL: Is null

The DACL contains an ace, and each ace represents an access rule. There is a user or group Sid in it, and an accessmask represents the corresponding permission bit, if deny_ace is used, the accessmask permission is forbidden, and allow_ace is used. deny_ace always takes effect before allow_ace, that is, there are two same accessmask and the same SID ace at the same time, if one is deny and the other is allow, the result is deny.

SACL does not indicate permissions, but records are required,System access-control list (SACL)Specifies which operations by which users shoshould be logged in the security audit log. This may be the review in the system. SACL has never been used,

The program is just a few lines, it is very simple. After knowing how to do it, just a few APIs will be finished, but before that, I will be depressed ,, I went to the dormitory next door to play CS and added 20 expert robots. In the snow, it was full of snow.

Using regopenkey to get the handle of the registry key may not be feasible, and it was not successful at first, because, for example, reading machine/SAM has no read permission, when opening a handle, it is fixed to fail. Well, alas, such a program is nothing more than a combination of several APIs. It is not qualified to laugh at people's Java as a building block ,,,, if you do not know much about the operating system, you can only do this ,,,,,,

When the program changes its permissions, it must have the permission to write DACL in the modified key. Because the default Sam has the permission to write DACL in the Administrators group ,, this saves time. If not, the administrator can refer to setakeownership for the token permission of the program process.

Setakeownership Required to take ownership of an object without being granted Discretionary Access

If the caller has the Take-ownership privilege, the security system grants write-owner access and then examines the DACL. however, if write-owner access was the only access requested by a caller with take-ownership privilege, the security system grants that access and never examines the DACL. that is to say, with setakeownership, you can have the write-owner permission, and then use the functions that write the owner to improve the owner,Setsecuritydescriptorowner

If the caller is the owner of the object, the read-control and write-DACL access rights are granted. if these rights were the only access rights that caller requested, access is granted without examining the DACL. then you have the write-DACL permission ,,

However, the program does not have that many functions. Generally, you only need to move the original write-DACL.

/*************************************** ******************************
* This registry permission is granted with the DACL write permission on the registry.
* Writen by uty @ uaty
**************************************** *****************************/
# Include <stdio. h>
# Include <windows. h>
# Include <winnt. h>
# Include <aclapi. h>
# Include <accctrl. h>

// # Define specific_rights_all 0x0000ffff
// # Define standard_rights_required 0x000f0000
// # Define standard_rights_all 0x001f0000

Int getprivilege (lpctstr privilege );

Int main (INT argc, char * argv [])
{
Long ret = 0;
Psecurity_descriptor psecuritydescriptor;
PACl;
PACl pnewacl;
// Trustee;
// Access_mask accessmask;
Explicit_access EA;
Char * user_groupname;
Char * keypath;
 
Char Sid [64];
DWORD receivedace;
DWORD sidlen;
DWORD sidtype;
Char siddomain [128];
DWORD siddomainlen;
Int aceindex = 0;

// Char username [128]; // debug
// DWORD usernamelen = 128;

If (argc! = 5 ){
Printf ("Usage: % s registrypath user | group username | groupname deny | allow | readonly/n", argv [0]);
Printf ("it's a simple work/N"
"Registerpath like this machine // security.../N"
"Predefined registry keys:/" classes_root/",/" CURRENT_USER/",/" machine/", And/" users/"/n ");
Return 0;
};

Keypath = argv [1];
User_groupname = argv [3];

Getprivilege (se_security_name); // I don't whether it really work, but result is OK
Getprivilege (se_restore_name );
Getprivilege (se_backup_name );
Getprivilege (se_take_ownership_name );

Getprivilege (se_debug_name );

Ret = getnamedsecurityinfo (keypath, se_registry_key, dacl_security_information,
Null, null, & PACl, null, & psecuritydescriptor );
If (Ret! = Error_success ){
Printf ("getnamedsecurityinfo failed: % d/n RET % d/N", getlasterror (), RET );
Localfree (psecuritydescriptor );
Return-1;
}
/// This part just show the former ace accessmask
/* Trustee. pmultipletrustee = NULL;
Trustee. multipletrusteeoperation = no_multiple_trustee;
Trustee. trusteeform = trustee_is_name;
Trustee. trusteetype = trustee_is_user ;////
Trustee. ptstrname = user_groupname ;////

Ret = geteffectiverightsfromacl (PACl, & trustee, & accessmask );
If (Ret! = Error_success ){
Printf ("geteffectiverightsfromacl failed/N ");
Localfree (psecuritydescriptor );
Return-1;
}*/

/// Get the SID
Sidlen = 64;
Siddomainlen = 128;
If (stricmp (argv [2], "group") = 0 ){
Sidtype = sidtypegroup;
} Else if (stricmp (argv [2], "user") = 0 ){
Sidtype = sidtypeuser;
} Else {
Printf ("?? , User or group/N ");
Exit (1 );
}

Ret = lookupaccountname (null, user_groupname, & SID, & sidlen, siddomain, & siddomainlen,
& Sidtype );
If (ret = 0 ){
Printf ("lookupaccountname failed: % d/n Sid size if % d/nsidlen requres % d/n", getlasterror (), sizeof (SID), sidlen );
Localfree (psecuritydescriptor );
Return-1;
}
/* Sleep (200); // Why can not lookup the Sid's username? Still don't know

Ret = lookupaccountsid (null, (psid) (SID), username, & usernamelen,
Siddomain, & siddomainlen, & sidtype );
Printf ("Debug: ret = % d, getlasterror = % d/N", RET, getlasterror ());
Printf ("% s/n", username );
Return 0 ;///////////////
*/
 
//// Delete the previous Ace of the same user or group
While (getace (PACl, aceindex, (pvoid) & receivedace )){
If (inclusid (psid) Sid, (psid) (incluedace + sizeof (ace_header) + sizeof (access_mask) {// if equal, return nonzero
Deleteace (PACl, aceindex );
Continue;
} Else {
Aceindex ++;
}
}

/*
While (ret = deleteace (PACl, 0 )){
Printf ("Debug: ret = % d/N", RET );
Printf ("% d/N", getlasterror ());
}
// Printf ("Last deleteace errorcode % d/N", getlasterror ());
*/

Memset (& EA, 0, sizeof (explicit_access ));
 
If (stricmp (argv [4], "allow") = 0 ){
EA. grfaccessmode = grant_access;
EA. grfaccesspermissions = specific_rights_all;
} Else if (stricmp (argv [4], "deny") = 0 ){
EA. grfaccessmode = deny_access;
EA. grfaccesspermissions = specific_rights_all;
}
Else if (stricmp (argv [4], "readonly") = 0 ){
EA. grfaccessmode = deny_access;
EA. grfaccesspermissions = 0xff06;
// Yun, the first 6 bits are the query value setting value create subitem enumeration subitem notification create connection
// 0 1 2 3 4 5
} Else {
Printf ("?? , Allow or deny or readonly/N ");
Exit (1 );
}

EA. grfinheritance = container_inherit_ace;
EA. Trustee. multipletrusteeoperation = no_multiple_trustee;
EA. Trustee. pmultipletrustee = NULL;
EA. Trustee. trusteeform = trustee_is_name;
If (stricmp (argv [2], "group") = 0 ){
EA. Trustee. trusteetype = trustee_is_group ;////
} Else if (stricmp (argv [2], "user") = 0 ){
EA. Trustee. trusteetype = trustee_is_user ;////
} Else {
Printf ("?? , User or group/N ");
Exit (1 );
}
EA. Trustee. ptstrname = user_groupname ;////

Ret = setentriesinacl (1, & EA, PACl, & pnewacl );
If (Ret! = Error_success ){
Printf ("setentriesinacl failed: % d/N", getlasterror ());
Localfree (psecuritydescriptor );
Return-1;
}
Ret = setnamedsecurityinfo (keypath, se_registry_key, dacl_security_information, null, null, pnewacl, null );
If (Ret! = Error_success ){
Printf ("setnamedsecurityinfo failed: % d/N", getlasterror ());
Localfree (psecuritydescriptor );
Return-1;
}

Return 0;
}
//--------------------------------------------------------------------
Int getprivilege (lpctstr privilege)
{
////////////////////////
Handle hprocesstoken = NULL;
Token_privileges TP;
Luid;
// Open token
If (! Openprocesstoken (getcurrentprocess (), token_all_access, & hprocesstoken )){
Printf ("/nopen current process token failed: % d", getlasterror ());
Return-1;
}

// Find the luid of the required permission
If (! Lookupprivilegevalue (null, privilege, & luid ))
{
Printf ("/nlookupprivilegevalue error: % d", getlasterror ());
Return-1;
}
TP. privilegecount = 1; // indicates that only one privilege to set
TP. Privileges [0]. luid = luid;
TP. Privileges [0]. Attributes = se_privilege_enabled;
// Add permissions to the token
Adjusttokenprivileges (hprocesstoken, false, & TP, sizeof (token_privileges)
, (Ptoken_privileges) null, (pdword) null );

If (getlasterror ()! = Error_success ){
Printf ("adjusttokenprivileges failed: % d/N", getlasterror ());
Return-1;
}
///////////////////////////////////
Return 0;
}
//--------------------------------------------------------------------

What's wrong with this blog? Why can I leave a blank line when I press enter?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.