(self, ace)
| 383 | # Parses a specified ACE and extract the different values (Flags, Access Mask, Trustee, ObjectType, InheritedObjectType) |
| 384 | # - ace : the ACE to parse |
| 385 | def parse_ace(self, ace): |
| 386 | # For the moment, only the Allowed and Denied Access ACE are supported |
| 387 | if ace["TypeName"] in [ |
| 388 | "ACCESS_ALLOWED_ACE", |
| 389 | "ACCESS_ALLOWED_OBJECT_ACE", |
| 390 | "ACCESS_DENIED_ACE", |
| 391 | "ACCESS_DENIED_OBJECT_ACE", |
| 392 | ]: |
| 393 | _ace_flags = [FLAG.name for FLAG in ACE_FLAGS if ace.hasFlag(FLAG.value)] |
| 394 | parsed_ace = {"ACE Type": ace["TypeName"], "ACE flags": ", ".join(_ace_flags) or "None"} |
| 395 | |
| 396 | # For standard ACE |
| 397 | # Extracts the access mask (by parsing the simple permissions) and the principal's SID |
| 398 | if ace["TypeName"] in ["ACCESS_ALLOWED_ACE", "ACCESS_DENIED_ACE"]: |
| 399 | access_mask = f"{', '.join(self.parse_perms(ace['Ace']['Mask']['Mask']))} (0x{ace['Ace']['Mask']['Mask']:x})" |
| 400 | trustee_sid = f"{self.resolveSID(ace['Ace']['Sid'].formatCanonical()) or 'UNKNOWN'} ({ace['Ace']['Sid'].formatCanonical()})" |
| 401 | parsed_ace = { |
| 402 | "Access mask": access_mask, |
| 403 | "Trustee (SID)": trustee_sid |
| 404 | } |
| 405 | elif ace["TypeName"] in ["ACCESS_ALLOWED_OBJECT_ACE", "ACCESS_DENIED_OBJECT_ACE"]: # for object-specific ACE |
| 406 | # Extracts the mask values. These values will indicate the ObjectType purpose |
| 407 | access_mask_flags = [FLAG.name for FLAG in ALLOWED_OBJECT_ACE_MASK_FLAGS if ace["Ace"]["Mask"].hasPriv(FLAG.value)] |
| 408 | parsed_ace["Access mask"] = ", ".join(access_mask_flags) |
| 409 | # Extracts the ACE flag values and the trusted SID |
| 410 | object_flags = [FLAG.name for FLAG in OBJECT_ACE_FLAGS if ace["Ace"].hasFlag(FLAG.value)] |
| 411 | parsed_ace["Flags"] = ", ".join(object_flags) or "None" |
| 412 | # Extracts the ObjectType GUID values |
| 413 | if ace["Ace"]["ObjectTypeLen"] != 0: |
| 414 | obj_type = bin_to_string(ace["Ace"]["ObjectType"]).lower() |
| 415 | try: |
| 416 | parsed_ace["Object type (GUID)"] = f"{OBJECT_TYPES_GUID[obj_type]} ({obj_type})" |
| 417 | except KeyError: |
| 418 | parsed_ace["Object type (GUID)"] = f"UNKNOWN ({obj_type})" |
| 419 | # Extracts the InheritedObjectType GUID values |
| 420 | if ace["Ace"]["InheritedObjectTypeLen"] != 0: |
| 421 | inh_obj_type = bin_to_string(ace["Ace"]["InheritedObjectType"]).lower() |
| 422 | try: |
| 423 | parsed_ace["Inherited type (GUID)"] = f"{OBJECT_TYPES_GUID[inh_obj_type]} ({inh_obj_type})" |
| 424 | except KeyError: |
| 425 | parsed_ace["Inherited type (GUID)"] = f"UNKNOWN ({inh_obj_type})" |
| 426 | # Extract the Trustee SID (the object that has the right over the DACL bearer) |
| 427 | parsed_ace["Trustee (SID)"] = f"{self.resolveSID(ace['Ace']['Sid'].formatCanonical()) or 'UNKNOWN'} ({ace['Ace']['Sid'].formatCanonical()})" |
| 428 | else: # if the ACE is not an access allowed |
| 429 | self.context.log.debug(f"ACE Type ({ace['TypeName']}) unsupported for parsing yet, feel free to contribute") |
| 430 | _ace_flags = [FLAG.name for FLAG in ACE_FLAGS if ace.hasFlag(FLAG.value)] |
| 431 | parsed_ace = { |
| 432 | "ACE type": ace["TypeName"], |
| 433 | "ACE flags": ", ".join(_ace_flags) or "None", |
| 434 | "DEBUG": "ACE type not supported for parsing by dacleditor.py, feel free to contribute", |
| 435 | } |
| 436 | return parsed_ace |
| 437 | |
| 438 | def print_parsed_dacl(self, parsed_dacl): |
| 439 | """Prints a full DACL by printing each parsed ACE |
no test coverage detected