Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is AccessCheck NOT applying GenericMapping to the DACL?

The AccessCheck function gets a GenericMapping parameter. What is this parameter used for? It is NOT used for the DesiredAccess parameter since MapGenericMask must be applied to DesiredAccess before.

It is also not applied to the DACL contained in the SecurityDescriptor as I found out using a C program doing this:

  • open the current thread token
  • create a security descriptor with owner and default group from the token and an DACL granting GENERIC_ALL to the owner "D:(A;;GA;;;ownerSID)"
  • setup GENERIC_MAPPING, which maps (among others) GenericAll to my OWN_READ | OWN_WRITE (defined as 0x0001 and 0x0002)
  • call AccessCheck with security descriptor created above, the thread token, OWN_READ as DesiredAccess, the described GENERIC_MAPPING

However, this fails with an access denied error. When I change the security descriptor to "D:(A;;0x0001;;;ownerSID)" access is granted. This shows that AccessCheck is NOT using the GenericMapping parameter to convert generic access flags (GA/GW/GR/GX) in the DACL to the specific access rights. Why? Am I doing something wrong?

https://msdn.microsoft.com/de-de/library/windows/desktop/aa374815(v=vs.85).aspx does not give any hints on how the security descriptor should be set.

like image 980
dannyM Avatar asked Nov 09 '22 05:11

dannyM


1 Answers

you do almost all correct, but you not take in account that when you try assign security descriptor(SD) to kernel object - system not exactly "as is" assigned your SD but apply GenericMapping to ACEs first.

every object - have assosiated _OBJECT_TYPE which containing _OBJECT_TYPE_INITIALIZER and here exist GENERIC_MAPPING GenericMapping; and this GenericMapping (unique for each type of object) used for convert you generic flags in ACCESS_MASK to non-generic.

for test i create file with next SD - "D:P(A;;GA;;;WD)" (10000000 - GenericAll for S-1-1-0 EveryOne). and then i query DACL from created file - and see really 001F01FF for S-1-1-0 but not 10000000.

when i use "D:P(A;;GX;;;WD)" (GenericExecute - 20000000 for S-1-1-0) - in final file i view 001200A0 for S-1-1-0

so real kernel object have no generic bits in ACCESS_MASK and your DACL in exactly form you cannot assign to any object.

Why is AccessCheck NOT applying GenericMapping to the DACL?

AccessCheck assume that ACCESS_MASK in DACL already converted (no generic bits)

i think this is performance optimization - better convert generic bits once (on object creating or assigning SD to it - than every time do this convertation when somebody try open object)

about how GenericMapping parameter used ?

really very weak - only in case when object have no DACL (or if PreviousMode == KernelMode) and you request MAXIMUM_ALLOWED as DesiredAccess - system grant you GenericMapping->GenericAll. this is based on looking source code from WRK (accessck.c)

no DACL and MAXIMUM_ALLOWED this is rare case, but in this case how system can calculate what concrete access need grant to caller ? he not ask concrete access (like read/write/delete) - but "ALL". so system and give him GenericMapping->GenericAll

like image 191
RbMm Avatar answered Nov 15 '22 12:11

RbMm