I'm trying to tighten the security on a Windows process, by overriding the process owners ability to further alter the DACL on the process.
Having created the process with CreateProcessAsUser()
I then proceed to get the existing DACL from it like so:
CDacl procDacl;
if (AtlGetDacl(hProcess, SE_KERNEL_OBJECT, &procDacl))
{
//..
}
After this, I construct an OWNER RIGHTS ACE and add it to the DACL so that the owner only has read access to the permissions (this removes the default WRITE_DAC access):
PSID OwnerRightsSid;
if (ConvertStringSidToSid(OWNER_RIGHTS_SID_STRING, &OwnerRightsSid))
{
CSid sidOwnerRights(*static_cast<SID*>(OwnerRightsSid));
LocalFree(OwnerRightsSid);
procDacl.AddAllowedAce(sidOwnerRights, READ_CONTROL);
}
Before setting the DACL back on the process.
AtlSetDacl(hProcess, SE_KERNEL_OBJECT, procDacl, PROTECTED_DACL_SECURITY_INFORMATION);
If I use AtlGetDacl()
at this point I can enumerate the ACEs and see that all of them have 0 flags. However, looking at the process in WinDBG I see the owner rights SID has gained flag 0x8 (INHERIT_ONLY_ACE) which means it doesn't actually apply to the process its self. What's weird is that:
Here's my ACEs in WinDBG:
0: kd> !sd (0xffff8903`70d9d5e7 & 0xffffffff`fffffff0)
->Revision: 0x1
->Sbz1 : 0x0
->Control : 0x8014
SE_DACL_PRESENT
SE_SACL_PRESENT
SE_SELF_RELATIVE
->Owner : S-1-5-21-2264418099-4034413657-3176887289-1001
->Group : S-1-5-21-2264418099-4034413657-3176887289-513
->Dacl :
->Dacl : ->AclRevision: 0x2
->Dacl : ->Sbz1 : 0x0
->Dacl : ->AclSize : 0x64
->Dacl : ->AceCount : 0x4
->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 : 0x001fffff
->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 : 0x001fffff
->Dacl : ->Ace[1]: ->SID: S-1-5-32-544
->Dacl : ->Ace[2]: ->AceType: ACCESS_ALLOWED_ACE_TYPE
->Dacl : ->Ace[2]: ->AceFlags: 0x0
->Dacl : ->Ace[2]: ->AceSize: 0x1c
->Dacl : ->Ace[2]: ->Mask : 0x00120410
->Dacl : ->Ace[2]: ->SID: S-1-5-5-0-165627
->Dacl : ->Ace[3]: ->AceType: ACCESS_ALLOWED_ACE_TYPE
->Dacl : ->Ace[3]: ->AceFlags: 0x8
->Dacl : ->Ace[3]: INHERIT_ONLY_ACE
->Dacl : ->Ace[3]: ->AceSize: 0x14
->Dacl : ->Ace[3]: ->Mask : 0x00020000
->Dacl : ->Ace[3]: ->SID: S-1-3-4
->Sacl :
->Sacl : ->AclRevision: 0x2
->Sacl : ->Sbz1 : 0x0
->Sacl : ->AclSize : 0x1c
->Sacl : ->AceCount : 0x1
->Sacl : ->Sbz2 : 0x0
->Sacl : ->Ace[0]: ->AceType: SYSTEM_MANDATORY_LABEL_ACE_TYPE
->Sacl : ->Ace[0]: ->AceFlags: 0x0
->Sacl : ->Ace[0]: ->AceSize: 0x14
->Sacl : ->Ace[0]: ->Mask : 0x00000003
->Sacl : ->Ace[0]: ->SID: S-1-16-8192
I've already tried looking at the process hacker source code, and I can't see that they're doing anything differently (Except that they seem to be using SetObjectInfo() rather than the ATL wrapper functions). Does anyone have a good understanding how how these inheritance flags work? And why my ACE seems to have been altered from the flags I set?
User contributions licensed under CC BY-SA 3.0