private MaximumAccess GetMaxAccess(TokenEntry token, NtObject obj, ulong obj_address, Dictionary <ulong, MaximumAccess> max_access) { if (max_access.ContainsKey(obj_address)) { return(max_access[obj_address]); } NtType type = obj.NtType; if (!type.SecurityRequired && String.IsNullOrEmpty(GetObjectName(obj))) { max_access[obj_address] = new MaximumAccess(type.GenericMapping.GenericAll, String.Empty); return(max_access[obj_address]); } var result = obj.GetSecurityDescriptor(SecurityInformation.AllBasic, false); if (!result.IsSuccess && !obj.IsAccessMaskGranted(GenericAccessRights.ReadControl)) { // Try and duplicate handle to see if we can just ask for ReadControl. using (var dup_obj = obj.DuplicateObject(GenericAccessRights.ReadControl, AttributeFlags.None, DuplicateObjectOptions.None, false)) { if (dup_obj.IsSuccess) { result = dup_obj.Result.GetSecurityDescriptor(SecurityInformation.AllBasic, false); } } } MaximumAccess access = null; if (result.IsSuccess) { access = new MaximumAccess(NtSecurity.GetMaximumAccess(result.Result, token.Token, type.GenericMapping), result.Result.ToSddl()); } else if (type.CanOpen) { using (var new_obj = ReopenUnderImpersonation(token, type, obj)) { if (new_obj.IsSuccess) { access = new MaximumAccess(new_obj.Result.GrantedAccessMask, String.Empty); } } } max_access[obj_address] = access; return(access); }
private void DumpObject(IEnumerable <TokenEntry> tokens, HashSet <string> type_filter, AccessMask access_rights, NtObject obj, bool is_directory) { NtType type = obj.NtType; if (!IsTypeFiltered(type.Name, type_filter)) { return; } if (!IncludePath(obj.Name)) { return; } AccessMask desired_access = type.MapGenericRights(access_rights); var result = GetSecurityDescriptor(obj); if (!result.IsSuccess && !obj.IsAccessMaskGranted(GenericAccessRights.ReadControl)) { // Try and duplicate handle to see if we can just ask for ReadControl. using (var dup_obj = obj.DuplicateObject(GenericAccessRights.ReadControl, AttributeFlags.None, DuplicateObjectOptions.None, false)) { if (dup_obj.IsSuccess) { result = GetSecurityDescriptor(dup_obj.Result); } } } if (result.IsSuccess) { foreach (var token in tokens) { CheckAccess(token, obj, type, is_directory, desired_access, result.Result); } } else if (type.CanOpen) { // If we can't read security descriptor then try opening the object. foreach (var token in tokens) { CheckAccessUnderImpersonation(token, type, is_directory, desired_access, obj); } } // TODO: Do we need a warning here? }
private object GetObject(NtObject obj) { return(obj.DuplicateObject(GetDesiredAccess(), ObjectAttributes ?? 0, GetOptions())); }