/// <summary> /// Overridden process record method. /// </summary> protected override void ProcessRecord() { using (NtToken token = GetToken()) { NtType type = GetNtType(); if (type == null) { throw new ArgumentException("Must specify a type."); } var result = NtSecurity.AccessCheck(GetSecurityDescriptor(), token, AccessMask, Principal, type.GenericMapping, ObjectType).ToSpecificAccess(type.AccessRightsType); if (PassResult) { WriteObject(result); return; } var mask = result.SpecificGrantedAccess; if (MapToGeneric) { mask = result.SpecificGenericGrantedAccess; } if (ConvertToString) { string access_string = NtObjectUtils.GrantedAccessAsString(mask, type.GenericMapping, type.AccessRightsType, false); WriteObject(access_string); } else { WriteObject(mask); } } }
static string AccessMaskToString(NtType type, uint granted_access) { if (type.HasFullPermission(granted_access)) { return "Full Permission"; } return NtObject.AccessRightsToString(GetTypeAccessRights(type), type.MapGenericRights(granted_access)); }
/// <summary> /// Do an access check between a security descriptor and a token to determine the allowed access. /// </summary> /// <param name="sd">The security descriptor</param> /// <param name="token">The access token.</param> /// <param name="access_rights">The set of access rights to check against</param> /// <param name="type">The type used to determine generic access mapping..</param> /// <returns>The allowed access mask as a unsigned integer.</returns> /// <exception cref="NtException">Thrown if an error occurred in the access check.</exception> public static AccessMask GetAllowedAccess(NtToken token, NtType type, AccessMask access_rights, byte[] sd) { if (sd == null || sd.Length == 0) { return(AccessMask.Empty); } return(GetAllowedAccess(new SecurityDescriptor(sd), token, access_rights, type.GenericMapping)); }
internal NtHandle(int process_id, ProcessHandleTableEntryInfo entry, bool allow_query) { ProcessId = process_id; NtType = NtType.GetTypeByIndex(entry.ObjectTypeIndex); Attributes = entry.HandleAttributes; Handle = entry.HandleValue.ToInt32(); GrantedAccess = entry.GrantedAccess; _allow_query = allow_query; }
/// <summary> /// Open an NT object with a specified type. /// </summary> /// <param name="typename">The name of the type to open (e.g. Event). If null the method will try and lookup the appropriate type.</param> /// <param name="path">The path to the object to open.</param> /// <param name="root">A root directory to open from.</param> /// <param name="access">Generic access rights to the object.</param> /// <param name="attributes">Attributes to open the object.</param> /// <param name="security_quality_of_service">Security quality of service.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The opened object.</returns> /// <exception cref="NtException">Thrown if an error occurred opening the object.</exception> public static NtResult <NtObject> OpenWithType(string typename, string path, NtObject root, AttributeFlags attributes, AccessMask access, SecurityQualityOfService security_quality_of_service, bool throw_on_error) { using (var obj_attr = new ObjectAttributes(path, attributes, root, security_quality_of_service, null)) { NtType type = NtType.GetTypeByName(typename ?? NtDirectory.GetDirectoryEntryType(path, root), false); return(OpenWithType(type, obj_attr, access, throw_on_error)); } }
/// <summary> /// Do an access check between a security descriptor and a token to determine the allowed access. /// </summary> /// <param name="sd">The security descriptor</param> /// <param name="token">The access token.</param> /// <param name="access_rights">The set of access rights to check against</param> /// <param name="type">The type used to determine generic access mapping..</param> /// <returns>The allowed access mask as a unsigned integer.</returns> /// <exception cref="NtException">Thrown if an error occurred in the access check.</exception> public static uint GetAllowedAccess(NtToken token, NtType type, uint access_rights, byte[] sd) { if (sd == null || sd.Length == 0) { return(0); } return(GetAllowedAccess(new SecurityDescriptor(sd), token, (GenericAccessRights)access_rights, type.GenericMapping)); }
/// <summary> /// Overridden ProcessRecord /// </summary> protected override void ProcessRecord() { AccessMask mask = 0; switch (ParameterSetName) { case "FromAce": mask = AccessControlEntry.Mask; break; default: mask = AccessMask; mask |= MapGeneric(SpecificAccessType.File, FileAccess); mask |= MapGeneric(SpecificAccessType.File, FileDirectoryAccess); mask |= MapGeneric(SpecificAccessType.IoCompletion, IoCompletionAccess); mask |= MapGeneric(SpecificAccessType.Mutant, MutantAccess); mask |= MapGeneric(SpecificAccessType.Semaphore, SemaphoreAccess); mask |= MapGeneric(SpecificAccessType.RegistryTransaction, RegistryTransactionAccess); mask |= MapGeneric(SpecificAccessType.ALPCPort, AlpcPortAccess); mask |= MapGeneric(SpecificAccessType.Section, SectionAccess); mask |= MapGeneric(SpecificAccessType.Key, KeyAccess); mask |= MapGeneric(SpecificAccessType.Event, EventAccess); mask |= MapGeneric(SpecificAccessType.SymbolicLink, SymbolicLinkAccess); mask |= MapGeneric(SpecificAccessType.Token, TokenAccess); mask |= GenericAccess; mask |= MapGeneric(SpecificAccessType.Directory, DirectoryAccess); mask |= MapGeneric(SpecificAccessType.Thread, ThreadAccess); mask |= MapGeneric(SpecificAccessType.DebugObject, DebugObjectAccess); mask |= MapGeneric(SpecificAccessType.Job, JobAccess); mask |= MapGeneric(SpecificAccessType.Process, ProcessAccess); mask |= MapGeneric(SpecificAccessType.Transaction, TransactionAccess); mask |= MapGeneric(SpecificAccessType.TransactionManager, TransactionManagerAccess); mask |= MapGeneric(SpecificAccessType.ResourceManager, ResourceManagerAccess); mask |= MapGeneric(SpecificAccessType.Enlistment, EnlistmentAccess); mask |= (uint)ManadatoryLabelPolicy; break; } if (ToGenericAccess) { WriteObject(mask.ToGenericAccess()); } else if (ToMandatoryLabelPolicy) { WriteObject(mask.ToMandatoryLabelPolicy()); } else if (ToSpecificAccess == SpecificAccessType.None && ToTypeAccess == null) { WriteObject(mask); } else { NtType type = ToTypeAccess ?? GetTypeObject(ToSpecificAccess); WriteObject(mask.ToSpecificAccess(type.AccessRightsType)); } }
/// <summary> /// Indicates whether a specific type of kernel object can be opened. /// </summary> /// <param name="typename">The kernel typename to check.</param> /// <returns>True if this type of object can be opened.</returns> public static bool CanOpenType(string typename) { NtType type = NtType.GetTypeByName(typename, false); if (type == null) { return(false); } return(type.CanOpen); }
/// <summary> /// Convert this NtFile to a FileStream for reading/writing. /// </summary> /// <remarks>The stream must be closed separately from the NtFile.</remarks> /// <returns>The file stream.</returns> /// <exception cref="NtException">Thrown on error.</exception> public FileStream ToStream() { FileAccess access = FileAccess.Read; if (NtType.HasWritePermission(GrantedAccessRaw)) { access = FileAccess.ReadWrite; } return(new FileStream(DuplicateAsFile(Handle), access)); }
private AccessMask MapGeneric(SpecificAccessType specific_type, AccessMask access_mask) { if (!MapGenericRights) { return access_mask; } NtType type = GetTypeObject(specific_type); System.Diagnostics.Debug.Assert(type != null); return type.MapGenericRights(access_mask); }
/// <summary> /// Constructor /// </summary> /// <param name="base_object">Base object for security descriptor</param> /// <param name="token">Token for determining user rights</param> /// <param name="is_directory">True if a directory security descriptor</param> public SecurityDescriptor(NtObject base_object, NtToken token, bool is_directory) : this() { if ((base_object == null) && (token == null)) { throw new ArgumentNullException(); } SecurityDescriptor parent_sd = null; if (base_object != null) { parent_sd = base_object.SecurityDescriptor; } SecurityDescriptor creator_sd = null; if (token != null) { creator_sd = new SecurityDescriptor { Owner = new SecurityDescriptorSid(token.Owner, false), Group = new SecurityDescriptorSid(token.PrimaryGroup, false), Dacl = token.DefaultDacl }; } NtType type = base_object.NtType; SafeBuffer parent_sd_buffer = SafeHGlobalBuffer.Null; SafeBuffer creator_sd_buffer = SafeHGlobalBuffer.Null; SafeSecurityObjectBuffer security_obj = null; try { if (parent_sd != null) { parent_sd_buffer = parent_sd.ToSafeBuffer(); } if (creator_sd != null) { creator_sd_buffer = creator_sd.ToSafeBuffer(); } GenericMapping mapping = type.GenericMapping; NtRtl.RtlNewSecurityObject(parent_sd_buffer, creator_sd_buffer, out security_obj, is_directory, token != null ? token.Handle : SafeKernelObjectHandle.Null, ref mapping).ToNtException(); ParseSecurityDescriptor(security_obj); } finally { parent_sd_buffer?.Close(); creator_sd_buffer?.Close(); security_obj?.Close(); } }
private AccessMask MapGeneric(string typename, AccessMask access_mask) { if (!MapGenericRights) { return(access_mask); } NtType type = NtType.GetTypeByName(typename, false); System.Diagnostics.Debug.Assert(type != null); return(type.MapGenericRights(access_mask)); }
internal NtHandle(int process_id, ProcessHandleTableEntryInfo entry, bool allow_query, bool force_file_query, string process_image_path) { ProcessId = process_id; NtType = NtType.GetTypeByIndex(entry.ObjectTypeIndex); Attributes = entry.HandleAttributes; Handle = entry.HandleValue.ToInt32(); GrantedAccess = entry.GrantedAccess; _allow_query = allow_query; _force_file_query = force_file_query; ProcessImagePath = process_image_path; }
/// <summary> /// Convert an enumerable access rights to a string /// </summary> /// <typeparam name="T">The enum type for the access rights</typeparam> /// <param name="access">The access rights</param> /// <param name="typeinfo">NtType to map generic access masks to specific access masks</param> /// <returns>The string format of the access rights</returns> public static string AccessRightsToString <T>(T access, NtType typeinfo) where T : struct, IConvertible { CheckEnumType(typeof(T)); uint mapped_access = typeinfo.MapGenericRights(access.ToUInt32(null)); if ((mapped_access & typeinfo.GenericMapping.GenericAll) == typeinfo.GenericMapping.GenericAll) { return("Full Access"); } return(AccessRightsToString(typeof(T), mapped_access)); }
private static NtType GetTypeObject(SpecificAccessType type) { if (type == SpecificAccessType.ALPCPort) { return(NtType.GetTypeByType <NtAlpc>()); } else { return(NtType.GetTypeByName(type.ToString(), false)); } }
/// <summary> /// Reopen object with different access rights. /// </summary> /// <param name="desired_access">The desired access.</param> /// <param name="attributes">Additional attributes for open.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The reopened object.</returns> public virtual NtResult <O> ReOpen(A desired_access, AttributeFlags attributes, bool throw_on_error) { if (!NtType.CanOpen) { return(NtStatus.STATUS_OBJECT_PATH_NOT_FOUND.CreateResultFromError <O>(throw_on_error)); } using (var obj_attr = new ObjectAttributes(string.Empty, attributes, this)) { return(NtType.Open(obj_attr, ToGenericAccess(desired_access), throw_on_error).Cast <O>()); } }
/// <summary> /// Reopen object with different access rights. /// </summary> /// <param name="desired_access">The desired access.</param> /// <param name="attributes">Additional attributes for open.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns></returns> public virtual NtResult <O> ReOpen(A desired_access, AttributeFlags attributes, bool throw_on_error) { if (!NtType.CanOpen) { throw new ArgumentException("Can't re-open this type"); } using (var obj_attr = new ObjectAttributes(string.Empty, attributes, this)) { return(NtType.Open(obj_attr, ToGenericAccess(desired_access), throw_on_error).Cast <O>()); } }
private static Dictionary <string, NtType> LoadTypes() { var type_factories = NtTypeFactory.GetAssemblyNtTypeFactories(Assembly.GetExecutingAssembly()); Dictionary <string, NtType> ret = new Dictionary <string, NtType>(StringComparer.OrdinalIgnoreCase); int size = 0x8000; NtStatus status = NtStatus.STATUS_INFO_LENGTH_MISMATCH; // repeatly try to fill out ObjectTypes buffer by increasing it's size between each attempt while (size < 0x1000000) { using (var type_info = new SafeStructureInOutBuffer <ObjectAllTypesInformation>(size, true)) { status = NtSystemCalls.NtQueryObject(SafeKernelObjectHandle.Null, ObjectInformationClass.ObjectTypesInformation, type_info, type_info.Length, out int return_length); switch (status) { // if the input buffer is too small, double it's size and retry case NtStatus.STATUS_INFO_LENGTH_MISMATCH: size *= 2; break; // From this point, the return values of NtSystemCalls.NtQueryObject are considered correct case NtStatus.STATUS_SUCCESS: int alignment = IntPtr.Size - 1; ObjectAllTypesInformation result = type_info.Result; IntPtr curr_typeinfo = type_info.DangerousGetHandle() + IntPtr.Size; for (int count = 0; count < result.NumberOfTypes; ++count) { ObjectTypeInformation info = (ObjectTypeInformation)Marshal.PtrToStructure(curr_typeinfo, typeof(ObjectTypeInformation)); string name = info.Name.ToString(); NtTypeFactory factory = type_factories.ContainsKey(name) ? type_factories[name] : _generic_factory; NtType ti = new NtType(count + 2, info, factory); ret[ti.Name] = ti; int offset = (info.Name.MaximumLength + alignment) & ~alignment; curr_typeinfo = info.Name.Buffer + offset; } return(ret); default: throw new NtException(status); } } } // raise exception if the candidate buffer is over a MB. throw new NtException(NtStatus.STATUS_INSUFFICIENT_RESOURCES); }
static void CheckAccess(string path, byte[] sd, NtType type) { try { if (_type_filter.Count > 0) { if (!_type_filter.Contains(type.Name.ToLower())) { return; } } if (sd.Length > 0) { uint granted_access = 0; if (_dir_rights != 0) { granted_access = NtSecurity.GetAllowedAccess(_token, type, (uint)_dir_rights, sd); } else { granted_access = NtSecurity.GetMaximumAccess(_token, type, sd); } if (granted_access != 0) { // As we can get all the rights for the directory get maximum if (_dir_rights != 0) { granted_access = NtSecurity.GetMaximumAccess(_token, type, sd); } if (!_show_write_only || type.HasWritePermission(granted_access)) { Console.WriteLine("<{0}> {1} : {2:X08} {3}", type.Name, path, granted_access, AccessMaskToString(type, granted_access)); if (_print_sddl) { Console.WriteLine("{0}", NtSecurity.SecurityDescriptorToSddl(sd, SecurityInformation.AllBasic)); } } } } } catch (Exception) { } }
internal NtHandle(SystemHandleTableInfoEntry entry, bool allow_query) { ProcessId = entry.UniqueProcessId; NtType info = NtType.GetTypeByIndex(entry.ObjectTypeIndex); if (info != null) { NtType = info; } Attributes = (AttributeFlags)entry.HandleAttributes; Handle = entry.HandleValue; Object = entry.Object.ToUInt64(); GrantedAccess = (GenericAccessRights)entry.GrantedAccess; _allow_query = allow_query; }
private static Dictionary <string, NtType> LoadTypes() { var type_factories = NtTypeFactory.GetAssemblyNtTypeFactories(Assembly.GetExecutingAssembly()); SafeStructureInOutBuffer <ObjectAllTypesInformation> type_info = new SafeStructureInOutBuffer <ObjectAllTypesInformation>(); try { Dictionary <string, NtType> ret = new Dictionary <string, NtType>(StringComparer.OrdinalIgnoreCase); int return_length; NtStatus status = NtSystemCalls.NtQueryObject(SafeKernelObjectHandle.Null, ObjectInformationClass.ObjectAllInformation, type_info.DangerousGetHandle(), type_info.Length, out return_length); if (status != NtStatus.STATUS_INFO_LENGTH_MISMATCH) { status.ToNtException(); } type_info.Close(); type_info = null; type_info = new SafeStructureInOutBuffer <ObjectAllTypesInformation>(return_length, false); int alignment = IntPtr.Size - 1; NtSystemCalls.NtQueryObject(SafeKernelObjectHandle.Null, ObjectInformationClass.ObjectAllInformation, type_info.DangerousGetHandle(), type_info.Length, out return_length).ToNtException(); ObjectAllTypesInformation result = type_info.Result; IntPtr curr_typeinfo = type_info.DangerousGetHandle() + IntPtr.Size; for (int count = 0; count < result.NumberOfTypes; ++count) { ObjectTypeInformation info = (ObjectTypeInformation)Marshal.PtrToStructure(curr_typeinfo, typeof(ObjectTypeInformation)); string name = info.Name.ToString(); NtTypeFactory factory = type_factories.ContainsKey(name) ? type_factories[name] : _generic_factory; NtType ti = new NtType(count + 2, info, factory); ret[ti.Name] = ti; int offset = (info.Name.MaximumLength + alignment) & ~alignment; curr_typeinfo = info.Name.Buffer + offset; } return(ret); } finally { if (type_info != null) { type_info.Close(); } } }
/// <summary> /// Overridden ProcessRecord /// </summary> protected override void ProcessRecord() { AccessMask mask = AccessMask; mask |= MapGeneric("File", FileAccess); mask |= MapGeneric("File", FileDirectoryAccess); mask |= MapGeneric("IoCompletion", IoCompletionAccess); mask |= MapGeneric("Mutant", MutantAccess); mask |= MapGeneric("Semaphore", SemaphoreAccess); mask |= MapGeneric("RegistryTransaction", RegistryTransactionAccess); mask |= MapGeneric("ALPC Port", AlpcPortAccess); mask |= MapGeneric("Section", SectionAccess); mask |= MapGeneric("Key", KeyAccess); mask |= MapGeneric("Event", EventAccess); mask |= MapGeneric("SymbolicLink", SymbolicLinkAccess); mask |= MapGeneric("Token", TokenAccess); mask |= GenericAccess; mask |= MapGeneric("Directory", DirectoryAccess); mask |= MapGeneric("Thread", ThreadAccess); mask |= MapGeneric("DebugObject", DebugObjectAccess); mask |= MapGeneric("Job", JobAccess); mask |= MapGeneric("Process", ProcessAccess); mask |= (uint)ManadatoryLabelPolicy; if (ToGenericAccess) { WriteObject(mask.ToGenericAccess()); } else if (ToMandatoryLabelPolicy) { WriteObject(mask.ToMandatoryLabelPolicy()); } else if (String.IsNullOrEmpty(ToSpecificAccess)) { WriteObject(mask); } else { NtType type = NtType.GetTypeByName(ToSpecificAccess, false); if (type == null) { throw new ArgumentException(String.Format("'{0}' is not a valid NT type name", ToSpecificAccess)); } WriteObject(mask.ToSpecificAccess(type.AccessRightsType)); } }
internal NtHandle(SystemHandleTableInfoEntryEx entry, bool allow_query, bool force_file_query) { ProcessId = entry.UniqueProcessId.ToInt32(); NtType info = NtType.GetTypeByIndex(entry.ObjectTypeIndex); if (info != null) { NtType = info; } Attributes = (AttributeFlags)entry.HandleAttributes; Handle = entry.HandleValue.ToInt32(); Object = entry.Object.ToUInt64(); GrantedAccess = entry.GrantedAccess; _allow_query = allow_query; _force_file_query = force_file_query; }
private static NtType GetTypeObject(SpecificAccessType type) { switch (type) { case SpecificAccessType.Transaction: return NtType.GetTypeByType<NtTransaction>(); case SpecificAccessType.TransactionManager: return NtType.GetTypeByType<NtTransactionManager>(); case SpecificAccessType.ResourceManager: return NtType.GetTypeByType<NtResourceManager>(); case SpecificAccessType.Enlistment: return NtType.GetTypeByType<NtEnlistment>(); case SpecificAccessType.ALPCPort: return NtType.GetTypeByType<NtAlpc>(); } return NtType.GetTypeByName(type.ToString(), false); }
internal NtHandle(SystemHandleTableInfoEntry entry, bool allow_query) { ProcessId = entry.UniqueProcessId; NtType info = NtType.GetTypeByIndex(entry.ObjectTypeIndex); if (info != null) { ObjectType = info.Name; } else { ObjectType = String.Format("Unknown {0}", entry.ObjectTypeIndex); } Attributes = (AttributeFlags)entry.HandleAttributes; Handle = entry.HandleValue; Object = (ulong)entry.Object.ToInt64(); GrantedAccess = entry.GrantedAccess; _allow_query = allow_query; }
/// <summary> /// Open an NT object with a specified type. /// </summary> /// <param name="typename">The name of the type to open (e.g. Event). If null the method will try and lookup the appropriate type.</param> /// <param name="path">The path to the object to open.</param> /// <param name="root">A root directory to open from.</param> /// <param name="access">Generic access rights to the object.</param> /// <returns>The opened object.</returns> /// <exception cref="NtException">Thrown if an error occurred opening the object.</exception> /// <exception cref="ArgumentException">Thrown if type of resource couldn't be found.</exception> public static NtObject OpenWithType(string typename, string path, NtObject root, AccessMask access) { if (typename == null) { typename = NtDirectory.GetDirectoryEntryType(path, root); if (typename == null) { throw new ArgumentException(String.Format("Can't find type for path {0}", path)); } } NtType type = NtType.GetTypeByName(typename, false); if (type != null && type.CanOpen) { return(type.Open(path, root, access)); } else { throw new ArgumentException(String.Format("Can't open type {0}", typename)); } }
static Type GetTypeAccessRights(NtType type) { switch (type.Name.ToLower()) { case "directory": return typeof(DirectoryAccessRights); case "event": return typeof(EventAccessRights); case "section": return typeof(SectionAccessRights); case "mutant": return typeof(MutantAccessRights); case "semaphore": return typeof(SemaphoreAccessRights); case "job": return typeof(JobAccessRights); case "symboliclink": return typeof(SymbolicLinkAccessRights); default: throw new ArgumentException("Can't get type for access rights"); } }
/// <summary> /// Get the NT type from a path. /// </summary> /// <param name="path">The object manager path.</param> /// <param name="root">Optional root object.</param> /// <returns>The NT type. Returns null if not available or unknown.</returns> public static NtType GetTypeFromPath(string path, NtObject root) { NtType type = root?.NtType; // If a file or a key root then that's what the target must end up being. switch (type?.Name) { case "File": case "Key": return(type); } string type_name = NtDirectory.GetDirectoryEntryType(path, root); if (type_name != null) { return(GetTypeByName(type_name, true)); } string full_path = path; if (root != null) { string root_path = root.FullPath; full_path = $@"{(root_path == @"\" ? string.Empty : root_path)}\{full_path}"; } if (full_path.Equals(@"\REGISTRY", StringComparison.OrdinalIgnoreCase) || full_path.StartsWith(@"\REGISTRY\", StringComparison.OrdinalIgnoreCase)) { return(GetTypeByType <NtKey>()); } if (full_path.StartsWith(@"\??\") || full_path.StartsWith(@"\GLOBAL??\", StringComparison.OrdinalIgnoreCase) || full_path.StartsWith(@"\Device\", StringComparison.OrdinalIgnoreCase)) { return(GetTypeByType <NtFile>()); } return(null); }
internal NtType(string name, NtType existing_type) { if (existing_type == null) { throw new ArgumentException($"Invalid NT Type {name}", "name"); } Index = existing_type.Index; Name = existing_type.Name; InvalidAttributes = existing_type.InvalidAttributes; GenericMapping = existing_type.GenericMapping; ValidAccess = existing_type.ValidAccess; SecurityRequired = existing_type.SecurityRequired; TotalNumberOfObjects = existing_type.TotalNumberOfObjects; TotalNumberOfHandles = existing_type.TotalNumberOfHandles; TotalPagedPoolUsage = existing_type.TotalPagedPoolUsage; TotalNonPagedPoolUsage = existing_type.TotalNonPagedPoolUsage; TotalNamePoolUsage = existing_type.TotalNamePoolUsage; TotalHandleTableUsage = existing_type.TotalHandleTableUsage; HighWaterNumberOfObjects = existing_type.HighWaterNumberOfObjects; HighWaterNumberOfHandles = existing_type.HighWaterNumberOfHandles; HighWaterPagedPoolUsage = existing_type.HighWaterPagedPoolUsage; HighWaterNonPagedPoolUsage = existing_type.HighWaterNonPagedPoolUsage; HighWaterNamePoolUsage = existing_type.HighWaterNamePoolUsage; HighWaterHandleTableUsage = existing_type.HighWaterHandleTableUsage; MaintainHandleCount = existing_type.MaintainHandleCount; MaintainTypeList = existing_type.MaintainTypeList; PoolType = existing_type.PoolType; PagedPoolUsage = existing_type.PagedPoolUsage; NonPagedPoolUsage = existing_type.NonPagedPoolUsage; _type_factory = existing_type._type_factory; GenericRead = existing_type.GenericRead; GenericWrite = existing_type.GenericWrite; GenericExecute = existing_type.GenericExecute; GenericAll = existing_type.GenericAll; }
/// <summary> /// Open an NT object with a specified type. /// </summary> /// <param name="typename">The name of the type to open (e.g. Event). If null the method will try and lookup the appropriate type.</param> /// <param name="path">The path to the object to open.</param> /// <param name="root">A root directory to open from.</param> /// <param name="access">Generic access rights to the object.</param> /// <param name="attributes">Attributes to open the object.</param> /// <param name="security_quality_of_service">Security quality of service.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The opened object.</returns> /// <exception cref="NtException">Thrown if an error occurred opening the object.</exception> public static NtResult <NtObject> OpenWithType(string typename, string path, NtObject root, AttributeFlags attributes, AccessMask access, SecurityQualityOfService security_quality_of_service, bool throw_on_error) { using (var obj_attr = new ObjectAttributes(path, attributes, root, security_quality_of_service, null)) { if (typename == null) { typename = NtDirectory.GetDirectoryEntryType(path, root); } // Brute force the open. if (typename == null) { foreach (var nttype in NtType.GetTypes().Where(t => t.CanOpen)) { var result = nttype.Open(obj_attr, access, false); if (result.IsSuccess) { return(result); } } return(NtStatus.STATUS_OBJECT_TYPE_MISMATCH.CreateResultFromError <NtObject>(true)); } NtType type = NtType.GetTypeByName(typename, false); if (type != null && type.CanOpen) { return(type.Open(obj_attr, access, throw_on_error)); } else { return(NtStatus.STATUS_OBJECT_TYPE_MISMATCH.CreateResultFromError <NtObject>(true)); } } }
/// <summary> /// Overridden process record method. /// </summary> protected override void ProcessRecord() { using (NtToken token = GetToken()) { NtType type = GetNtType(); AccessMask mask = NtSecurity.GetAllowedAccess(GetSecurityDescriptor(), token, AccessMask, Principal, type.GenericMapping); if (MapToGeneric) { mask = type.GenericMapping.UnmapMask(mask); } if (ConvertToString) { string access_string = NtObjectUtils.GrantedAccessAsString(mask, type.GenericMapping, type.AccessRightsType, false); WriteObject(access_string); } else { WriteObject(mask.ToSpecificAccess(type.AccessRightsType)); } } }
/// <summary> /// Convert an enumerable access rights to a string /// </summary> /// <param name="map_to_generic">True to try and convert to generic rights where possible.</param> /// <returns>The string format of the access rights</returns> public string GrantedAccessAsString(bool map_to_generic) { return(NtType.AccessMaskToString(GrantedAccessMask, map_to_generic)); }
static void Main(string[] args) { bool show_help = false; int pid = Process.GetCurrentProcess().Id; try { OptionSet opts = new OptionSet() { { "r", "Recursive tree directory listing", v => _recursive = v != null }, { "sddl", "Print full SDDL security descriptors", v => _print_sddl = v != null }, { "p|pid=", "Specify a PID of a process to impersonate when checking", v => pid = int.Parse(v.Trim()) }, { "w", "Show only write permissions granted", v => _show_write_only = v != null }, { "k=", String.Format("Filter on a specific right [{0}]", String.Join(",", Enum.GetNames(typeof(KeyAccessRights)))), v => _key_rights |= ParseRight(v, typeof(KeyAccessRights)) }, { "x=", "Specify a base path to exclude from recursive search", v => _walked.Add(v.ToLower()) }, { "h|help", "show this message and exit", v => show_help = v != null }, }; List<string> paths = opts.Parse(args); if (show_help || (paths.Count == 0)) { ShowHelp(opts); } else { _type = NtType.GetTypeByName("key"); _token = NtToken.OpenProcessToken(pid); foreach (string path in paths) { try { using (NtKey key = OpenKey(path)) { DumpKey(key); } } catch (NtException ex) { Console.WriteLine("Error opening key: {0} - {1}", path, ex.Message); } } } } catch (Exception e) { Console.WriteLine(e.Message); } }
/// <summary> /// Convert a handle to a known object type. /// </summary> /// <param name="handle">The handle.</param> /// <returns>The object type.</returns> public static NtObject FromHandle(SafeKernelObjectHandle handle) { return(NtType.GetTypeByName(handle.NtTypeName, true).FromHandle(handle)); }
private static void LoadTypes() { if (_types == null) { SafeStructureInOutBuffer<ObjectAllTypesInformation> type_info = new SafeStructureInOutBuffer<ObjectAllTypesInformation>(); try { Dictionary<string, NtType> ret = new Dictionary<string, NtType>(StringComparer.OrdinalIgnoreCase); int return_length; NtStatus status = NtSystemCalls.NtQueryObject(SafeKernelObjectHandle.Null, ObjectInformationClass.ObjectAllInformation, type_info.DangerousGetHandle(), type_info.Length, out return_length); if (status != NtStatus.STATUS_INFO_LENGTH_MISMATCH) status.ToNtException(); type_info.Close(); type_info = null; type_info = new SafeStructureInOutBuffer<ObjectAllTypesInformation>(return_length, false); int alignment = IntPtr.Size - 1; NtSystemCalls.NtQueryObject(SafeKernelObjectHandle.Null, ObjectInformationClass.ObjectAllInformation, type_info.DangerousGetHandle(), type_info.Length, out return_length).ToNtException(); ObjectAllTypesInformation result = type_info.Result; IntPtr curr_typeinfo = type_info.DangerousGetHandle() + IntPtr.Size; for (int count = 0; count < result.NumberOfTypes; ++count) { ObjectTypeInformation info = (ObjectTypeInformation)Marshal.PtrToStructure(curr_typeinfo, typeof(ObjectTypeInformation)); NtType ti = new NtType(count + 2, info); ret[ti.Name] = ti; int offset = (info.Name.MaximumLength + alignment) & ~alignment; curr_typeinfo = info.Name.Buffer + offset; } _types = ret; } finally { if (type_info != null) { type_info.Close(); } } } }
static void Main(string[] args) { bool show_help = false; int pid = Process.GetCurrentProcess().Id; try { OptionSet opts = new OptionSet() { { "r", "Recursive tree directory listing", v => _recursive = v != null }, { "sddl", "Print full SDDL security descriptors", v => _print_sddl = v != null }, { "p|pid=", "Specify a PID of a process to impersonate when checking", v => pid = int.Parse(v.Trim()) }, { "w", "Show only write permissions granted", v => _show_write_only = v != null }, { "f=", String.Format("Filter on a file right [{0}]", String.Join(",", Enum.GetNames(typeof(FileAccessRights)))), v => _file_filter |= ParseRight(v, typeof(FileAccessRights)) }, { "d=", String.Format("Filter on a directory right [{0}]", String.Join(",", Enum.GetNames(typeof(FileDirectoryAccessRights)))), v => _dir_filter |= ParseRight(v, typeof(FileDirectoryAccessRights)) }, { "x=", "Specify a base path to exclude from recursive search", v => _walked.Add(v) }, { "q", "Don't print errors", v => _quiet = v != null }, { "onlydirs", "Only check the permissions of directories", v => _only_dirs = v != null }, { "h|help", "show this message and exit", v => show_help = v != null }, }; List<string> paths = opts.Parse(args); if (show_help || (paths.Count == 0)) { ShowHelp(opts); } else { _type = NtType.GetTypeByName("file"); _token = NtToken.OpenProcessToken(pid); foreach (string path in paths) { if ((File.GetAttributes(path) & System.IO.FileAttributes.Directory) == System.IO.FileAttributes.Directory) { DumpDirectory(new DirectoryInfo(path)); } else { DumpFile(new FileInfo(path)); } } } } catch(Exception e) { Console.WriteLine(e.Message); } }