Esempio n. 1
0
        private static IEnumerable <string> GetServiceRequiredPrivileges(SafeServiceHandle service)
        {
            using (var buf = new SafeHGlobalBuffer(8192))
            {
                if (!Win32NativeMethods.QueryServiceConfig2(service, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO,
                                                            buf, buf.Length, out int needed))
                {
                    return(new string[0]);
                }

                IntPtr str_pointer = buf.Read <IntPtr>(0);
                if (str_pointer == IntPtr.Zero)
                {
                    return(new string[0]);
                }

                SafeHGlobalBuffer str_buffer = new SafeHGlobalBuffer(str_pointer, 8192 - 8, false);
                ulong             offset     = 0;
                List <string>     privs      = new List <string>();
                while (offset < str_buffer.ByteLength)
                {
                    string s = str_buffer.ReadNulTerminatedUnicodeString(offset);
                    if (s.Length == 0)
                    {
                        break;
                    }
                    privs.Add(s);
                    offset += (ulong)(s.Length + 1) * 2;
                }
                return(privs.AsReadOnly());
            }
        }
Esempio n. 2
0
 static void ReadArray <T>(IntPtr ptr, int count, out T[] ret) where T : struct
 {
     ret = new T[count];
     using (SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(ptr, count * Marshal.SizeOf(typeof(T)), false)) {
         buffer.ReadArray(0, ret, 0, count);
     }
 }
Esempio n. 3
0
        private static NtResult <string[]> GetAppIds(string full_name)
        {
            var result = Win32NativeMethods.OpenPackageInfoByFullName(full_name, 0, out IntPtr package_info);

            if (result != Win32Error.SUCCESS)
            {
                return(result.CreateResultFromDosError <string[]>(false));
            }
            try {
                int length = 0;
                result = Win32NativeMethods.GetPackageApplicationIds(package_info, ref length, SafeHGlobalBuffer.Null, out int count);
                if (result != Win32Error.ERROR_INSUFFICIENT_BUFFER)
                {
                    return(result.CreateResultFromDosError <string[]>(false));
                }
                using (var buffer = new SafeHGlobalBuffer(length)) {
                    return(Win32NativeMethods.GetPackageApplicationIds(package_info, ref length, buffer, out count)
                           .CreateWin32Result(false, () => ReadStrings(buffer, count)));
                }
            } finally {
                if (package_info != IntPtr.Zero)
                {
                    Win32NativeMethods.ClosePackageInfo(package_info);
                }
            }
        }
Esempio n. 4
0
        private void ParseDebugData()
        {
            try
            {
                _debug_data = new DllDebugData();

                IntPtr debug_data = Win32NativeMethods.ImageDirectoryEntryToData(handle, MappedAsImage,
                                                                                 IMAGE_DIRECTORY_ENTRY_DEBUG, out int size);
                if (debug_data == IntPtr.Zero)
                {
                    return;
                }

                SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(debug_data, size, false);
                int count = size / Marshal.SizeOf(typeof(ImageDebugDirectory));

                ImageDebugDirectory[] entries = new ImageDebugDirectory[count];
                buffer.ReadArray(0, entries, 0, count);
                foreach (var debug_dir in entries)
                {
                    if (debug_dir.Type == IMAGE_DEBUG_TYPE_CODEVIEW && debug_dir.AddressOfRawData != 0)
                    {
                        var codeview = new SafeHGlobalBuffer(RvaToVA(debug_dir.AddressOfRawData), debug_dir.SizeOfData, false);
                        _debug_data = new DllDebugData(codeview);
                        break;
                    }
                }
            }
            catch
            {
            }
        }
Esempio n. 5
0
        internal Credential(CREDENTIAL cred)
        {
            Flags       = cred.Flags;
            Type        = cred.Type;
            TargetName  = cred.TargetName ?? string.Empty;
            Comment     = cred.Comment ?? string.Empty;
            LastWritten = cred.LastWritten.ToDateTime();
            Persist     = cred.Persist;
            TargetAlias = cred.TargetAlias ?? string.Empty;
            UserName    = cred.UserName ?? string.Empty;
            if (cred.CredentialBlob == IntPtr.Zero || cred.CredentialBlobSize <= 0)
            {
                _credblob = new byte[0];
            }
            else
            {
                _credblob = new byte[cred.CredentialBlobSize];
                Marshal.Copy(cred.CredentialBlob, _credblob, 0, _credblob.Length);
            }

            var attrs = new List <CredentialAttribute>();

            if (cred.AttributeCount > 0 && cred.Attributes != IntPtr.Zero)
            {
                var buffer = new SafeHGlobalBuffer(cred.Attributes, 1, false);
                attrs.AddRange(buffer.DangerousReadArray <CREDENTIAL_ATTRIBUTE>(0,
                                                                                cred.AttributeCount).Select(a => new CredentialAttribute(a)));
            }
            Attributes = attrs.AsReadOnly();
        }
Esempio n. 6
0
        /// <summary>
        /// Sets UI restrictions.
        /// </summary>
        /// <param name="uiRestrictionsClass">The restriction class for the UI.</param>
        public void SetUiRestrictions(JOB_OBJECT_UILIMIT_FLAGS uiRestrictionsClass = JOB_OBJECT_UILIMIT_FLAGS.ALL)
        {
            this.tracer.Trace(nameof(JobObject), "Setting UI restrictions");

            var uiRestrictions = new JOBOBJECT_BASIC_UI_RESTRICTIONS
            {
                UIRestrictionsClass = uiRestrictionsClass,
            };

            using (var nativeUiRestrictions = new SafeHGlobalBuffer(Marshal.SizeOf(typeof(JOBOBJECT_BASIC_UI_RESTRICTIONS))))
            {
                Marshal.StructureToPtr(
                    uiRestrictions,
                    nativeUiRestrictions.DangerousGetHandle(),
                    false /* fDeleteOld */);

                if (!Methods.SetInformationJobObject(
                    this.handle,
                    JOB_OBJECT_INFO_CLASS.JobObjectBasicUIRestrictions,
                    nativeUiRestrictions.DangerousGetHandle(),
                    nativeUiRestrictions.Size))
                {
                    throw
                        new SandboxException(
                            "Unable to set job object basic ui restrictions",
                            new Win32Exception());
                }
            }
        }
Esempio n. 7
0
        static IEnumerable <ServiceTriggerInformation> GetTriggersForService(SafeServiceHandle service)
        {
            List <ServiceTriggerInformation> triggers = new List <ServiceTriggerInformation>();

            using (var buf = new SafeStructureInOutBuffer <SERVICE_TRIGGER_INFO>(8192, false))
            {
                int required = 0;
                if (!QueryServiceConfig2(service, SERVICE_CONFIG_TRIGGER_INFO, buf, 8192, out required))
                {
                    return(triggers.AsReadOnly());
                }

                SERVICE_TRIGGER_INFO trigger_info = buf.Result;
                if (trigger_info.cTriggers == 0)
                {
                    return(triggers.AsReadOnly());
                }

                SERVICE_TRIGGER[] trigger_arr;
                using (SafeHGlobalBuffer trigger_buffer = new SafeHGlobalBuffer(trigger_info.pTriggers, trigger_info.cTriggers * Marshal.SizeOf(typeof(SERVICE_TRIGGER)), false))
                {
                    trigger_arr = new SERVICE_TRIGGER[trigger_info.cTriggers];
                    trigger_buffer.ReadArray(0, trigger_arr, 0, trigger_arr.Length);
                }

                for (int i = 0; i < trigger_arr.Length; ++i)
                {
                    triggers.Add(new ServiceTriggerInformation(trigger_arr[i]));
                }

                return(triggers.AsReadOnly());
            }
        }
Esempio n. 8
0
        public SecurityInformationImpl(string obj_name, NtObject handle,
                                       Dictionary <uint, string> names, GenericMapping generic_mapping,
                                       bool read_only)
        {
            _mapping    = generic_mapping;
            _handle     = handle;
            _obj_name   = new SafeStringBuffer(obj_name);
            _access_map = new SafeHGlobalBuffer(Marshal.SizeOf(typeof(SiAccess)) * names.Count);
            SiAccess[] sis         = new SiAccess[names.Count];
            IntPtr     current_ptr = _access_map.DangerousGetHandle();

            _names = new DisposableList <SafeStringBuffer>();
            int i = 0;

            foreach (KeyValuePair <uint, string> pair in names)
            {
                _names.Add(new SafeStringBuffer(pair.Value));
                SiAccess si = new SiAccess();
                si.dwFlags = SiAccessFlags.SI_ACCESS_SPECIFIC | SiAccessFlags.SI_ACCESS_GENERAL;
                si.mask    = pair.Key;
                si.pszName = _names[i].DangerousGetHandle();
                sis[i]     = si;
                i++;
            }
            _access_map.WriteArray(0, sis, 0, names.Count);
            _read_only = read_only;
        }
        /// <summary>
        /// Get the list of registered trace GUIDs.
        /// </summary>
        /// <returns>The list of trace GUIDs.</returns>
        public static IEnumerable <Guid> GetTraceGuids()
        {
            int curr_length = 1024;

            while (true)
            {
                using (var buffer = new SafeHGlobalBuffer(curr_length))
                {
                    Win32Error error = Win32NativeMethods.EnumerateTraceGuidsEx(TRACE_QUERY_INFO_CLASS.TraceGuidQueryList,
                                                                                SafeHGlobalBuffer.Null, 0, buffer, buffer.Length, out int return_length);
                    if (error == Win32Error.ERROR_INSUFFICIENT_BUFFER)
                    {
                        curr_length = return_length;
                        continue;
                    }

                    error.ToNtException();
                    int count = return_length / 16;

                    Guid[] ret = new Guid[count];
                    buffer.ReadArray(0, ret, 0, count);
                    return(ret);
                }
            }
        }
Esempio n. 10
0
 public void AddAttribute(IntPtr attribute, SafeHGlobalBuffer value)
 {
     if (!UpdateProcThreadAttribute(handle, 0, attribute, value.DangerousGetHandle(), new IntPtr(value.Length), IntPtr.Zero, IntPtr.Zero))
     {
         throw new SafeWin32Exception();
     }
 }
        /// <summary>
        /// Query security of an event.
        /// </summary>
        /// <param name="guid">The event GUID to query.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The event security descriptor.</returns>
        public static NtResult <SecurityDescriptor> QueryTraceSecurity(Guid guid, bool throw_on_error)
        {
            int        length = 0;
            Win32Error error  = Win32NativeMethods.EventAccessQuery(ref guid, SafeHGlobalBuffer.Null, ref length);

            if (error == Win32Error.ERROR_FILE_NOT_FOUND && guid != TraceKnownGuids.DefaultTraceSecurity)
            {
                return(QueryTraceSecurity(TraceKnownGuids.DefaultTraceSecurity, throw_on_error));
            }

            if (error != Win32Error.ERROR_MORE_DATA)
            {
                return(error.CreateResultFromDosError <SecurityDescriptor>(throw_on_error));
            }

            using (var buffer = new SafeHGlobalBuffer(length))
            {
                error = Win32NativeMethods.EventAccessQuery(ref guid, buffer, ref length);
                if (error != Win32Error.SUCCESS)
                {
                    return(error.CreateResultFromDosError <SecurityDescriptor>(throw_on_error));
                }
                return(SecurityDescriptor.Parse(buffer, NtType.GetTypeByType <NtEtwRegistration>(), throw_on_error));
            }
        }
Esempio n. 12
0
        internal IkeSecurityAssociation(IKEEXT_SA_DETAILS1 sa_details)
        {
            Id                 = sa_details.saId;
            KeyModuleType      = sa_details.keyModuleType;
            LocalAddress       = FirewallUtils.GetAddress(sa_details.ikeTraffic.ipVersion, sa_details.ikeTraffic.localAddress);
            RemoteAddress      = FirewallUtils.GetAddress(sa_details.ikeTraffic.ipVersion, sa_details.ikeTraffic.remoteAddress);
            InitiatorCookie    = sa_details.cookiePair.initiator;
            ResponderCookie    = sa_details.cookiePair.responder;
            IkePolicyKey       = sa_details.ikePolicyKey;
            VirtualIfTunnelId  = sa_details.virtualIfTunnelId;
            CorrelationKey     = sa_details.correlationKey.ToArray();
            CipherAlgorithm    = sa_details.ikeProposal.cipherAlgorithm.algoIdentifier;
            KeyLength          = sa_details.ikeProposal.cipherAlgorithm.keyLen;
            Rounds             = sa_details.ikeProposal.cipherAlgorithm.rounds;
            IntegrityAlgorithm = sa_details.ikeProposal.integrityAlgorithm.algoIdentifier;
            MaxLifetime        = sa_details.ikeProposal.maxLifetimeSeconds;
            DiffieHellmanGroup = sa_details.ikeProposal.dhGroup;
            QuickModeLimit     = sa_details.ikeProposal.quickModeLimit;

            List <IkeCredentialPair> credentials = new List <IkeCredentialPair>();

            if (sa_details.ikeCredentials.numCredentials > 0)
            {
                SafeHGlobalBuffer buf = new SafeHGlobalBuffer(sa_details.ikeCredentials.credentials, 1, false);
                buf.Initialize <IKEEXT_CREDENTIAL_PAIR1>((uint)sa_details.ikeCredentials.numCredentials);
                var arr = buf.ReadArray <IKEEXT_CREDENTIAL_PAIR1>(0, sa_details.ikeCredentials.numCredentials);
                credentials.AddRange(arr.Select(c => new IkeCredentialPair(c)));
            }
            Credentials = credentials.AsReadOnly();
        }
Esempio n. 13
0
        /// <summary>
        /// Logon user using S4U
        /// </summary>
        /// <param name="user">The username.</param>
        /// <param name="realm">The user's realm.</param>
        /// <param name="type">The type of logon token.</param>
        /// <param name="auth_package">The name of the auth package to user.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The logged on token.</returns>
        public static NtResult <NtToken> LsaLogonS4U(string user, string realm, SecurityLogonType type, string auth_package, bool throw_on_error)
        {
            if (user is null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            if (realm is null)
            {
                throw new ArgumentNullException(nameof(realm));
            }

            byte[] user_bytes  = Encoding.Unicode.GetBytes(user);
            byte[] realm_bytes = Encoding.Unicode.GetBytes(realm);

            using (var buffer = new SafeStructureInOutBuffer <KERB_S4U_LOGON>(user_bytes.Length + realm_bytes.Length, true)) {
                KERB_S4U_LOGON logon_struct = new KERB_S4U_LOGON {
                    MessageType = KERB_LOGON_SUBMIT_TYPE.KerbS4ULogon
                };
                SafeHGlobalBuffer data_buffer = buffer.Data;

                logon_struct.ClientUpn.Buffer = data_buffer.DangerousGetHandle();
                data_buffer.WriteArray(0, user_bytes, 0, user_bytes.Length);
                logon_struct.ClientUpn.Length        = (ushort)user_bytes.Length;
                logon_struct.ClientUpn.MaximumLength = (ushort)user_bytes.Length;

                logon_struct.ClientRealm.Buffer = data_buffer.DangerousGetHandle() + user_bytes.Length;
                data_buffer.WriteArray((ulong)user_bytes.Length, realm_bytes, 0, realm_bytes.Length);
                logon_struct.ClientRealm.Length        = (ushort)realm_bytes.Length;
                logon_struct.ClientRealm.MaximumLength = (ushort)realm_bytes.Length;
                buffer.Result = logon_struct;

                return(LsaLogonUser(type, auth_package, "S4U", buffer, null, throw_on_error));
            }
        }
Esempio n. 14
0
        private void ParseDelayImports(bool is_64bit)
        {
            try
            {
                IntPtr imports = Win32NativeMethods.ImageDirectoryEntryToData(handle, MappedAsImage,
                                                                              IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, out int size);
                if (imports == IntPtr.Zero)
                {
                    return;
                }

                SafeHGlobalBuffer          buffer      = new SafeHGlobalBuffer(imports, size, false);
                ulong                      ofs         = 0;
                ImageDelayImportDescriptor import_desc = buffer.Read <ImageDelayImportDescriptor>(ofs);
                while (import_desc.szName != 0)
                {
                    _imports.Add(ParseSingleImport(import_desc.szName, import_desc.pINT, import_desc.pIAT, is_64bit, true));
                    ofs        += (ulong)Marshal.SizeOf(typeof(ImageDelayImportDescriptor));
                    import_desc = buffer.Read <ImageDelayImportDescriptor>(ofs);
                }
            }
            catch
            {
            }
        }
Esempio n. 15
0
 internal EventTraceLog(long handle, Guid session_guid, string session_name, SafeHGlobalBuffer properties)
 {
     _handle     = handle;
     SessionGuid = session_guid;
     SessionName = session_name;
     _properties = properties.Detach();
     _providers  = new List <EnabledProvider>();
 }
Esempio n. 16
0
 /// <summary>
 /// Send a message to the filter.
 /// </summary>
 /// <param name="input">The input buffer.</param>
 /// <param name="max_output_length">The maximum size of the output buffer.</param>
 /// <param name="throw_on_error">true to throw on error.</param>
 /// <returns>The output buffer.</returns>
 public NtResult <byte[]> SendMessage(byte[] input, int max_output_length, bool throw_on_error)
 {
     using (var input_buffer = input?.ToBuffer()) {
         using (var output_buffer = new SafeHGlobalBuffer(max_output_length)) {
             return(SendMessage(input_buffer, output_buffer, throw_on_error).Map(i => output_buffer.ReadBytes(i)));
         }
     }
 }
Esempio n. 17
0
        internal ImageSection(ImageSectionHeader header, bool mapped_as_image, IntPtr base_ptr)
        {
            Name = header.GetName();
            int data_offset = mapped_as_image ? header.VirtualAddress : header.PointerToRawData;
            int data_size   = mapped_as_image ? header.VirtualSize : header.SizeOfRawData;

            Data = new SafeHGlobalBuffer(base_ptr + data_offset, data_size, false);
            RelativeVirtualAddress = header.VirtualAddress;
        }
Esempio n. 18
0
 internal DllDebugData(SafeHGlobalBuffer buffer) : this()
 {
     Magic = buffer.Read <uint>(0);
     if (Magic == CV_RSDS_MAGIC)
     {
         Id            = new Guid(buffer.ReadBytes(4, 16));
         Age           = buffer.Read <int>(20);
         PdbPath       = buffer.ReadNulTerminatedAnsiString(24, Encoding.UTF8);
         IdentiferPath = $"{Id:N}{Age:X}".ToUpper();
     }
 }
        private static IReadOnlyList <UserGroup> ReadSids(IntPtr ptr, int count)
        {
            if (ptr == IntPtr.Zero || count == 0)
            {
                return(new List <UserGroup>().AsReadOnly());
            }
            SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(ptr, 1, false);

            buffer.Initialize <SidAndAttributes>((uint)count);
            return(buffer.ReadArray <SidAndAttributes>(0, count).Select(s => s.ToUserGroup()).ToList().AsReadOnly());
        }
Esempio n. 20
0
 public static extern int NtDeviceIoControlFile(
     SafeFileHandle FileHandle,
     IntPtr Event,
     IntPtr ApcRoutine,
     IntPtr ApcContext,
     [In][Out] IoStatusBlock IoStatusBlock,
     uint IoControlCode,
     SafeHGlobalBuffer InputBuffer,
     int InputBufferLength,
     SafeHGlobalBuffer OutputBuffer,
     int OutputBufferLength
     );
Esempio n. 21
0
        private static IEnumerable <string> GetServiceRequiredPrivileges(SafeServiceHandle service)
        {
            using (var buf = new SafeHGlobalBuffer(8192)) {
                if (!Win32NativeMethods.QueryServiceConfig2(service, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO,
                                                            buf, buf.Length, out int needed))
                {
                    return(new string[0]);
                }

                return(buf.Read <IntPtr>(0).GetMultiString());
            }
        }
        internal ImageSection(ImageSectionHeader header, bool mapped_as_image, IntPtr base_ptr)
        {
            Name = header.GetName();
            int data_offset = mapped_as_image ? header.VirtualAddress : header.PointerToRawData;
            int data_size   = mapped_as_image ? header.VirtualSize : header.SizeOfRawData;

            Data = new SafeHGlobalBuffer(base_ptr + data_offset, data_size, false);
            RelativeVirtualAddress = header.VirtualAddress;
            Characteristics        = (ImageSectionCharacteristics)(uint)header.Characteristics;
            Characteristics       &= ImageSectionCharacteristics.Code | ImageSectionCharacteristics.Execute | ImageSectionCharacteristics.InitiailizedData
                                     | ImageSectionCharacteristics.Read | ImageSectionCharacteristics.Shared | ImageSectionCharacteristics.UninitializedData | ImageSectionCharacteristics.Write;
        }
Esempio n. 23
0
 internal static extern bool EnumServicesStatusEx(
     SafeServiceHandle hSCManager,
     SC_ENUM_TYPE InfoLevel,
     ServiceType dwServiceType,
     SERVICE_STATE dwServiceState,
     SafeHGlobalBuffer lpServices,
     int cbBufSize,
     out int pcbBytesNeeded,
     out int lpServicesReturned,
     ref int lpResumeHandle,
     string pszGroupName
     );
Esempio n. 24
0
        /// <summary>
        /// Sets limits.
        /// </summary>
        /// <param name="activeProcessLimit">The number of processes that can be added to the job object.</param>
        /// <param name="jobMemoryLimitInBytes">The total amount of memory that can be consumed by all processes in the job object.</param>
        /// <param name="limitFlags">The limits that are in effect.</param>
        /// <param name="processMemoryLimitInBytes">The maximum number of bytes a process can consume.</param>
        public void SetLimits(
            uint? activeProcessLimit = null,
            ulong? jobMemoryLimitInBytes = null,
            JOB_OBJECT_LIMIT_FLAGS limitFlags = JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,
            ulong? processMemoryLimitInBytes = null)
        {
            this.tracer.Trace(nameof(JobObject), "Setting limits");

            var extendedLimitInformation = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
            {
                BasicLimitInformation =
                {
                    LimitFlags = limitFlags,
                },
            };

            if (activeProcessLimit.HasValue)
            {
                extendedLimitInformation.BasicLimitInformation.ActiveProcessLimit = activeProcessLimit.GetValueOrDefault();
                extendedLimitInformation.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_ACTIVE_PROCESS;
            }

            if (jobMemoryLimitInBytes.HasValue)
            {
                extendedLimitInformation.JobMemoryLimit = new UIntPtr(jobMemoryLimitInBytes.GetValueOrDefault());
                extendedLimitInformation.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_JOB_MEMORY;
            }

            if (processMemoryLimitInBytes.HasValue)
            {
                extendedLimitInformation.ProcessMemoryLimit = new UIntPtr(processMemoryLimitInBytes.GetValueOrDefault());
                extendedLimitInformation.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_PROCESS_MEMORY;
            }

            // Apply the limits to the job object.
            using (var nativeExtendedLimitInformation = new SafeHGlobalBuffer(Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION))))
            {
                Marshal.StructureToPtr(extendedLimitInformation, nativeExtendedLimitInformation.DangerousGetHandle(), fDeleteOld: false);

                if (!Methods.SetInformationJobObject(
                        this.handle,
                        JOB_OBJECT_INFO_CLASS.JobObjectExtendedLimitInformation,
                        nativeExtendedLimitInformation.DangerousGetHandle(),
                        nativeExtendedLimitInformation.Size))
                {
                    throw
                        new SandboxException(
                            "Unable to set job object limit information",
                            new Win32Exception());
                }
            }
        }
Esempio n. 25
0
        public static NtToken LogonS4U(string user, string realm, SecurityLogonType type)
        {
            SafeLsaHandle hlsa    = null;
            LsaString     pkgName = new LsaString("Negotiate");

            LsaConnectUntrusted(out hlsa).ToNtException();
            using (hlsa)
            {
                uint authnPkg;
                LsaLookupAuthenticationPackage(hlsa, pkgName, out authnPkg).ToNtException();
                byte[] user_bytes  = Encoding.Unicode.GetBytes(user);
                byte[] realm_bytes = Encoding.Unicode.GetBytes(realm);

                using (var buffer = new SafeStructureInOutBuffer <KERB_S4U_LOGON>(user_bytes.Length + realm_bytes.Length, true))
                {
                    KERB_S4U_LOGON logon_struct = new KERB_S4U_LOGON();
                    logon_struct.MessageType = KERB_LOGON_SUBMIT_TYPE.KerbS4ULogon;
                    SafeHGlobalBuffer data_buffer = buffer.Data;

                    logon_struct.ClientUpn.Buffer = data_buffer.DangerousGetHandle();
                    data_buffer.WriteArray(0, user_bytes, 0, user_bytes.Length);
                    logon_struct.ClientUpn.Length        = (ushort)user_bytes.Length;
                    logon_struct.ClientUpn.MaximumLength = (ushort)user_bytes.Length;

                    logon_struct.ClientRealm.Buffer = data_buffer.DangerousGetHandle() + user_bytes.Length;
                    data_buffer.WriteArray((ulong)user_bytes.Length, realm_bytes, 0, realm_bytes.Length);
                    logon_struct.ClientRealm.Length        = (ushort)realm_bytes.Length;
                    logon_struct.ClientRealm.MaximumLength = (ushort)realm_bytes.Length;

                    Marshal.StructureToPtr(logon_struct, buffer.DangerousGetHandle(), false);

                    TOKEN_SOURCE tokenSource = new TOKEN_SOURCE("NtLmSsp");
                    AllocateLocallyUniqueId(out tokenSource.SourceIdentifier);

                    LsaString              originName = new LsaString("S4U");
                    IntPtr                 profile;
                    int                    cbProfile;
                    Luid                   logon_id;
                    NtStatus               subStatus;
                    QUOTA_LIMITS           quota_limits;
                    SafeKernelObjectHandle token_handle;

                    LsaLogonUser(hlsa, originName, type, authnPkg,
                                 buffer, buffer.Length, IntPtr.Zero,
                                 tokenSource, out profile, out cbProfile, out logon_id, out token_handle,
                                 out quota_limits, out subStatus).ToNtException();
                    LsaFreeReturnBuffer(profile);
                    return(NtToken.FromHandle(token_handle));
                }
            }
        }
Esempio n. 26
0
        private static IEnumerable <UsnJournalRecord> ReadJournal(NtFile volume, ulong start_usn, ulong end_usn, UsnJournalReasonFlags reason_mask, bool unprivileged)
        {
            if (volume is null)
            {
                throw new ArgumentNullException(nameof(volume));
            }

            NtIoControlCode ioctl = unprivileged ? NtWellKnownIoControlCodes.FSCTL_READ_UNPRIVILEGED_USN_JOURNAL : NtWellKnownIoControlCodes.FSCTL_READ_USN_JOURNAL;

            Dictionary <long, Tuple <string, string> > ref_paths = new Dictionary <long, Tuple <string, string> >();
            var data = QueryUsnJournalData(volume);

            end_usn = Math.Min(end_usn, data.NextUsn);
            using (var buffer = new SafeHGlobalBuffer(64 * 1024))
            {
                while (start_usn < end_usn)
                {
                    READ_USN_JOURNAL_DATA_V0 read_journal = new READ_USN_JOURNAL_DATA_V0
                    {
                        ReasonMask   = reason_mask,
                        StartUsn     = start_usn,
                        UsnJournalID = data.UsnJournalID
                    };
                    using (var in_buffer = read_journal.ToBuffer())
                    {
                        int length = volume.FsControl(ioctl, in_buffer, buffer);
                        int offset = 8;
                        if (length < 8)
                        {
                            yield break;
                        }
                        start_usn = buffer.Read <ulong>(0);
                        while (offset < length)
                        {
                            var header = buffer.Read <USN_RECORD_COMMON_HEADER>((ulong)offset);
                            if (header.MajorVersion == 2 && header.MinorVersion == 0)
                            {
                                var entry = new UsnJournalRecord(buffer.GetStructAtOffset <USN_RECORD_V2>(offset), volume, ref_paths);
                                if (entry.Usn >= end_usn)
                                {
                                    break;
                                }
                                yield return(entry);
                            }

                            offset += header.RecordLength;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Get the Win32 services for the SCM.
        /// </summary>
        /// <param name="service_state">The state of the services to return.</param>
        /// <param name="service_types">The types of services to return.</param>
        /// <param name="throw_on_error">True throw on error.</param>
        /// <returns>The list of services.</returns>
        /// <remarks>SCM must have been opened with EnumerateService access.</remarks>
        public NtResult <IEnumerable <Win32Service> > GetServices(ServiceState service_state, ServiceType service_types, bool throw_on_error)
        {
            SERVICE_STATE state;

            switch (service_state)
            {
            case ServiceState.All:
                state = SERVICE_STATE.SERVICE_STATE_ALL;
                break;

            case ServiceState.Active:
                state = SERVICE_STATE.SERVICE_ACTIVE;
                break;

            case ServiceState.InActive:
                state = SERVICE_STATE.SERVICE_INACTIVE;
                break;

            default:
                throw new ArgumentException("Invalid service state", nameof(service_state));
            }

            List <Win32Service> ret_services = new List <Win32Service>();
            const int           Length       = 32 * 1024;

            using (var buffer = new SafeHGlobalBuffer(Length))
            {
                int resume_handle = 0;
                while (true)
                {
                    bool ret = Win32NativeMethods.EnumServicesStatusEx(_handle, SC_ENUM_TYPE.SC_ENUM_PROCESS_INFO,
                                                                       service_types, state, buffer, buffer.Length, out int bytes_needed, out int services_returned,
                                                                       ref resume_handle, null);
                    Win32Error error = Win32Utils.GetLastWin32Error();
                    if (!ret && error != Win32Error.ERROR_MORE_DATA)
                    {
                        return(error.CreateResultFromDosError <IEnumerable <Win32Service> >(throw_on_error));
                    }

                    ENUM_SERVICE_STATUS_PROCESS[] services = new ENUM_SERVICE_STATUS_PROCESS[services_returned];
                    buffer.ReadArray(0, services, 0, services_returned);
                    ret_services.AddRange(services.Select(s => new Win32Service(_machine_name, s)));
                    if (ret)
                    {
                        break;
                    }
                }
            }
            return(ret_services.CreateResult().Cast <IEnumerable <Win32Service> >());
        }
Esempio n. 28
0
        private static void CheckForFault(SafeHGlobalBuffer buffer, LRPC_MESSAGE_TYPE message_type)
        {
            var header = buffer.Read <LRPC_HEADER>(0);

            if (header.MessageType != LRPC_MESSAGE_TYPE.lmtFault && header.MessageType != message_type)
            {
                throw new ArgumentException($"Invalid response message type {header.MessageType}");
            }

            if (header.MessageType == LRPC_MESSAGE_TYPE.lmtFault)
            {
                var fault = buffer.GetStructAtOffset <LRPC_FAULT_MESSAGE>(0);
                throw new RpcFaultException(fault);
            }
        }
Esempio n. 29
0
        private static NtResult <SafeHGlobalBuffer> GetClassProperty(Guid class_guid, CmClassType flags, DEVPROPKEY key, out DEVPROPTYPE type, bool throw_on_error)
        {
            int length = 0;
            var result = DeviceNativeMethods.CM_Get_Class_PropertyW(class_guid, key, out type, SafeHGlobalBuffer.Null, ref length, flags);

            if (result != CrError.BUFFER_SMALL)
            {
                return(result.ToNtStatus().CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
            }

            using (var buffer = new SafeHGlobalBuffer(length)) {
                return(DeviceNativeMethods.CM_Get_Class_PropertyW(class_guid, key, out type, buffer,
                                                                  ref length, flags).ToNtStatus().CreateResult(throw_on_error, () => buffer.Detach()));
            }
        }
Esempio n. 30
0
        private static NtResult <SafeHGlobalBuffer> GetDeviceInterfaceProperty(string device_instance, DEVPROPKEY key, out DEVPROPTYPE type, bool throw_on_error)
        {
            int length = 0;
            var result = DeviceNativeMethods.CM_Get_Device_Interface_PropertyW(device_instance, key, out type, SafeHGlobalBuffer.Null, ref length, 0);

            if (result != CrError.BUFFER_SMALL)
            {
                return(result.ToNtStatus().CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
            }

            using (var buffer = new SafeHGlobalBuffer(length)) {
                return(DeviceNativeMethods.CM_Get_Device_Interface_PropertyW(device_instance, key, out type, buffer,
                                                                             ref length, 0).ToNtStatus().CreateResult(throw_on_error, () => buffer.Detach()));
            }
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="security_descriptor">Binary form of security descriptor</param>
 public SecurityDescriptor(byte[] security_descriptor)
 {
     using (SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(security_descriptor))
     {
         ParseSecurityDescriptor(buffer);
     }
 }
        /// <summary>
        /// Convert security descriptor to a byte array
        /// </summary>
        /// <returns>The binary security descriptor</returns>
        public byte[] ToByteArray()
        {
            SafeStructureInOutBuffer<SecurityDescriptorStructure> sd_buffer = null;
            SafeHGlobalBuffer dacl_buffer = null;
            SafeHGlobalBuffer sacl_buffer = null;
            SafeSidBufferHandle owner_buffer = null;
            SafeSidBufferHandle group_buffer = null;

            try
            {
                sd_buffer = new SafeStructureInOutBuffer<SecurityDescriptorStructure>();
                NtRtl.RtlCreateSecurityDescriptor(sd_buffer, Revision).ToNtException();
                SecurityDescriptorControl control = Control & SecurityDescriptorControl.ValidControlSetMask;
                NtRtl.RtlSetControlSecurityDescriptor(sd_buffer, control, control).ToNtException();
                if (Dacl != null)
                {
                    if (!Dacl.NullAcl)
                    {
                        dacl_buffer = new SafeHGlobalBuffer(Dacl.ToByteArray());
                    }
                    else
                    {
                        dacl_buffer = new SafeHGlobalBuffer(IntPtr.Zero, 0, false);
                    }

                    NtRtl.RtlSetDaclSecurityDescriptor(sd_buffer, true, dacl_buffer.DangerousGetHandle(), Dacl.Defaulted).ToNtException();
                }
                if (Sacl != null)
                {
                    if (!Sacl.NullAcl)
                    {
                        sacl_buffer = new SafeHGlobalBuffer(Sacl.ToByteArray());
                    }
                    else
                    {
                        sacl_buffer = new SafeHGlobalBuffer(IntPtr.Zero, 0, false);
                    }

                    NtRtl.RtlSetSaclSecurityDescriptor(sd_buffer, true, sacl_buffer.DangerousGetHandle(), Sacl.Defaulted).ToNtException();
                }
                if (Owner != null)
                {
                    owner_buffer = Owner.Sid.ToSafeBuffer();
                    NtRtl.RtlSetOwnerSecurityDescriptor(sd_buffer, owner_buffer.DangerousGetHandle(), Owner.Defaulted);
                }
                if (Group != null)
                {
                    group_buffer = Group.Sid.ToSafeBuffer();
                    NtRtl.RtlSetGroupSecurityDescriptor(sd_buffer, group_buffer.DangerousGetHandle(), Group.Defaulted);
                }

                int total_length = 0;
                NtStatus status = NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer, new SafeHGlobalBuffer(IntPtr.Zero, 0, false), ref total_length);
                if (status != NtStatus.STATUS_BUFFER_TOO_SMALL)
                {
                    status.ToNtException();
                }

                using (SafeHGlobalBuffer relative_sd = new SafeHGlobalBuffer(total_length))
                {
                    NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer, relative_sd, ref total_length).ToNtException();
                    return relative_sd.ToArray();
                }
            }
            finally
            {
                if (sd_buffer != null)
                {
                    sd_buffer.Close();
                }
                if (dacl_buffer != null)
                {
                    dacl_buffer.Close();
                }
                if (sacl_buffer != null)
                {
                    sacl_buffer.Close();
                }
                if (owner_buffer != null)
                {
                    owner_buffer.Close();
                }
                if (group_buffer != null)
                {
                    group_buffer.Close();
                }
            }
        }
        /// <summary>
        /// Get a list of handles
        /// </summary>
        /// <param name="pid">A process ID to filter on. If -1 will get all handles</param>
        /// <param name="allow_query">True to allow the handles returned to query for certain properties</param>
        /// <returns>The list of handles</returns>
        public static IEnumerable<NtHandle> GetHandles(int pid, bool allow_query)
        {
            SafeHGlobalBuffer handleInfo = new SafeHGlobalBuffer(0x10000);
            try
            {
                NtStatus status = 0;
                int return_length = 0;
                while ((status = NtSystemCalls.NtQuerySystemInformation(SystemInformationClass.SystemHandleInformation,
                                                         handleInfo.DangerousGetHandle(),
                                                         handleInfo.Length,
                                                         out return_length)) == NtStatus.STATUS_INFO_LENGTH_MISMATCH)
                {
                    int length = handleInfo.Length * 2;
                    handleInfo.Close();
                    handleInfo = new SafeHGlobalBuffer(length);
                }
                status.ToNtException();

                IntPtr handleInfoBuf = handleInfo.DangerousGetHandle();
                int handle_count = Marshal.ReadInt32(handleInfoBuf);
                List<NtHandle> ret = new List<NtHandle>();
                handleInfoBuf += IntPtr.Size;
                for (int i = 0; i < handle_count; ++i)
                {
                    SystemHandleTableInfoEntry entry = (SystemHandleTableInfoEntry)Marshal.PtrToStructure(handleInfoBuf, typeof(SystemHandleTableInfoEntry));

                    if (pid == -1 || entry.UniqueProcessId == pid)
                    {
                        ret.Add(new NtHandle(entry, allow_query));
                    }
                    handleInfoBuf += Marshal.SizeOf(typeof(SystemHandleTableInfoEntry));
                }
                return ret;
            }
            finally
            {
                handleInfo.Close();
            }
        }
 /// <summary>
 /// Constructor from an manged buffer.
 /// </summary>
 /// <param name="sid">A buffer containing a valid SID.</param>
 /// <exception cref="NtException">Thrown if the buffer is not valid.</exception>
 public Sid(byte[] sid)
 {
     using (SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(sid))
     {
         InitializeFromPointer(buffer.DangerousGetHandle());
     }
 }
 public void AddAttribute(IntPtr attribute, SafeHGlobalBuffer value)
 {
     if (!UpdateProcThreadAttribute(handle, 0, attribute, value.DangerousGetHandle(), new IntPtr(value.Length), IntPtr.Zero, IntPtr.Zero))
     {
         throw new SafeWin32Exception();
     }
 }
 public SecurityInformationImpl(string obj_name, NtObject handle,
     Dictionary<uint, string> names, GenericMapping generic_mapping)
 {
     _mapping = generic_mapping;
     _handle = handle;
     _obj_name = new SafeStringBuffer(obj_name);
     _access_map = new SafeHGlobalBuffer(Marshal.SizeOf(typeof(SiAccess)) * names.Count);
     SiAccess[] sis = new SiAccess[names.Count];
     IntPtr current_ptr = _access_map.DangerousGetHandle();
     _names = new DisposableList<SafeStringBuffer>();
     int i = 0;
     foreach (KeyValuePair<uint, string> pair in names)
     {
         _names.Add(new SafeStringBuffer(pair.Value));
         SiAccess si = new SiAccess();
         si.dwFlags = SiAccessFlags.SI_ACCESS_SPECIFIC | SiAccessFlags.SI_ACCESS_GENERAL;
         si.mask = pair.Key;
         si.pszName = _names[i].DangerousGetHandle();
         sis[i] = si;
         i++;
     }
     _access_map.WriteArray(0, sis, 0, names.Count);
 }