internal static byte[] GetSessionKey(SecHandle context)
 {
     using (var buffer = new SafeStructureInOutBuffer <SecPkgContext_SessionKey>())
     {
         var result = SecurityNativeMethods.QueryContextAttributesEx(context, SECPKG_ATTR.SESSION_KEY, buffer, buffer.Length);
         if (result == SecStatusCode.Success)
         {
             byte[] ret = new byte[buffer.Result.SessionKeyLength];
             Marshal.Copy(buffer.Result.SessionKey, ret, 0, ret.Length);
             return(ret);
         }
     }
     return(new byte[0]);
 }
        /// <summary>
        /// Get security descriptor for the printer.
        /// </summary>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The printer's security descriptor.</returns>
        public NtResult <SecurityDescriptor> GetSecurityDescriptor(bool throw_on_error)
        {
            PrintingNativeMethods.GetPrinter(_handle, 3, SafeHGlobalBuffer.Null, 0, out int length);
            using (var buffer = new SafeStructureInOutBuffer <PRINTER_INFO_3>(length, false))
            {
                var error = PrintingNativeMethods.GetPrinter(_handle, 3, buffer, length, out length).GetLastWin32Error();
                if (error != Win32Error.SUCCESS)
                {
                    return(error.CreateResultFromDosError <SecurityDescriptor>(throw_on_error));
                }

                return(SecurityDescriptor.Parse(buffer.Result.pSecurityDescriptor, _type, throw_on_error));
            }
        }
Esempio n. 3
0
        public RPC_IF_ID[] GetIfIds()
        {
            if (IsClosed)
            {
                throw new ObjectDisposedException("vector");
            }

            var vector_buffer = new SafeStructureInOutBuffer <RPC_IF_ID_VECTOR>(handle, int.MaxValue, false);
            var vector        = vector_buffer.Result;

            IntPtr[] ptrs = new IntPtr[vector.Count];
            vector_buffer.Data.ReadArray(0, ptrs, 0, vector.Count);
            return(ptrs.Select(p => (RPC_IF_ID)Marshal.PtrToStructure(p, typeof(RPC_IF_ID))).ToArray());
        }
Esempio n. 4
0
 private static X509Certificate2 GetCertificate(SecHandle context, SECPKG_ATTR attr)
 {
     using (var buffer = new SafeStructureInOutBuffer <IntPtr>())
     {
         SecurityNativeMethods.QueryContextAttributesEx(context, attr, buffer, buffer.Length).CheckResult();
         try
         {
             return(new X509Certificate2(buffer.Result));
         }
         finally
         {
             SecurityNativeMethods.CertFreeCertificateContext(buffer.Result);
         }
     }
 }
Esempio n. 5
0
        private SafeStructureInOutBuffer <SYMBOL_INFO> GetSymbolFromIndex(int type_index, long module_base)
        {
            SYMBOL_INFO symbol_info = new SYMBOL_INFO(SYMBOL_INFO.MAX_SYM_NAME);

            symbol_info.Index = type_index;
            int total_size = (symbol_info.MaxNameLen * 2) + symbol_info.SizeOfStruct - 2;

            using (var ret = new SafeStructureInOutBuffer <SYMBOL_INFO>(symbol_info, total_size, false)) {
                if (_sym_from_index(Handle, module_base, type_index, ret))
                {
                    return(ret.Detach());
                }
            }
            return(null);
        }
 private RpcFaultException(SafeStructureInOutBuffer <LRPC_FAULT_MESSAGE> buffer, LRPC_FAULT_MESSAGE message)
     : this(message.RpcStatus)
 {
     if (message.Flags.HasFlag(LRPC_FAULT_MESSAGE_FLAGS.ExtendedErrorInfo))
     {
         try
         {
             byte[] data = buffer.GetStructAtOffset <LRPC_FAULT_MESSAGE_EXTENDED>(0).Data.ToArray();
             ExtendedErrorInfo = RpcExtendedErrorInfo.ReadErrorInfo(data);
         }
         catch
         {
         }
     }
 }
 private RpcFaultException(SafeStructureInOutBuffer <LRPC_FAULT_MESSAGE> buffer, LRPC_FAULT_MESSAGE message)
     : this(message.RpcStatus)
 {
     ExtendedErrorInfo = new RpcExtendedErrorInfo[0];
     if (message.Flags.HasFlag(LRPC_FAULT_MESSAGE_FLAGS.ExtendedErrorInfo))
     {
         try
         {
             byte[] data = buffer.Data.ReadBytes(16, buffer.Data.Length - 16);
             ExtendedErrorInfo = RpcExtendedErrorInfo.ReadErrorInfo(data);
         }
         catch
         {
         }
     }
 }
        /// <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>
        /// <returns>The logged on token.</returns>
        public static NtToken LogonS4U(string user, string realm, SecurityLogonType type)
        {
            LsaString pkgName = new LsaString("Negotiate");

            Win32NativeMethods.LsaConnectUntrusted(out SafeLsaHandle hlsa).ToNtException();
            using (hlsa)
            {
                uint authnPkg;
                Win32NativeMethods.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
                    {
                        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");
                    Win32NativeMethods.AllocateLocallyUniqueId(out tokenSource.SourceIdentifier);

                    LsaString    originName   = new LsaString("S4U");
                    QUOTA_LIMITS quota_limits = new QUOTA_LIMITS();

                    Win32NativeMethods.LsaLogonUser(hlsa, originName, type, authnPkg,
                                                    buffer, buffer.Length, IntPtr.Zero,
                                                    tokenSource, out IntPtr profile, out int cbProfile, out Luid logon_id, out SafeKernelObjectHandle token_handle,
                                                    quota_limits, out NtStatus subStatus).ToNtException();
                    Win32NativeMethods.LsaFreeReturnBuffer(profile);
                    return(NtToken.FromHandle(token_handle));
                }
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Get the list of registered trace providers.
        /// </summary>
        /// <returns>The list of trace providers.</returns>
        public static IEnumerable <EventTraceProvider> GetProviders()
        {
            int retry_count   = 10;
            int buffer_length = 1024;
            Dictionary <Guid, EventTraceProvider> providers = new Dictionary <Guid, EventTraceProvider>();

            while (retry_count-- > 0)
            {
                using (var buffer = new SafeStructureInOutBuffer <PROVIDER_ENUMERATION_INFO>(buffer_length, false))
                {
                    Win32Error error = Win32NativeMethods.TdhEnumerateProviders(buffer, ref buffer_length);
                    if (error == Win32Error.ERROR_INSUFFICIENT_BUFFER)
                    {
                        continue;
                    }
                    if (error != Win32Error.SUCCESS)
                    {
                        error.ToNtException();
                    }
                    var result = buffer.Result;
                    var data   = buffer.Data;
                    TRACE_PROVIDER_INFO[] infos = new TRACE_PROVIDER_INFO[result.NumberOfProviders];
                    buffer.Data.ReadArray(0, infos, 0, infos.Length);
                    foreach (var info in infos)
                    {
                        if (!providers.ContainsKey(info.ProviderGuid))
                        {
                            providers.Add(info.ProviderGuid,
                                          new EventTraceProvider(info.ProviderGuid,
                                                                 buffer.ReadNulTerminatedUnicodeString(info.ProviderNameOffset),
                                                                 info.SchemaSource == 0));
                        }
                    }
                    break;
                }
            }
            foreach (var guid in GetTraceGuids())
            {
                if (!providers.ContainsKey(guid))
                {
                    providers.Add(guid, new EventTraceProvider(guid));
                }
            }
            return(providers.Values);
        }
Esempio n. 10
0
        private static string GetServiceDisplayName(SafeServiceHandle service)
        {
            using (var buf = new SafeStructureInOutBuffer <QUERY_SERVICE_CONFIG>(8192, false))
            {
                if (!Win32NativeMethods.QueryServiceConfig(service, buf, buf.Length, out int required))
                {
                    return(string.Empty);
                }

                var result = buf.Result;
                if (result.lpDisplayName == IntPtr.Zero)
                {
                    return(string.Empty);
                }

                return(Marshal.PtrToStringUni(result.lpDisplayName));
            }
        }
Esempio n. 11
0
 internal static string GetOwnerModule <T>(GetOwnerModuleDelegate <T> func, T entry, int process_id)
 {
     using (var buffer = new SafeStructureInOutBuffer <TCPIP_OWNER_MODULE_BASIC_INFO>(64 * 1024, true))
     {
         int        size  = buffer.Length;
         Win32Error error = func(entry, TCPIP_OWNER_MODULE_INFO_CLASS.TCPIP_OWNER_MODULE_INFO_BASIC, buffer, ref size);
         string     ret;
         if (error == Win32Error.SUCCESS)
         {
             ret = Marshal.PtrToStringUni(buffer.Result.pModulePath);
         }
         else
         {
             ret = NtSystemInfo.GetProcessIdImagePath(process_id, false).GetResultOrDefault(string.Empty);
         }
         return(ret);
     }
 }
Esempio n. 12
0
        private static IEnumerable <T> EnumFilter <T, U>(FindFirst find_first, FindNext find_next,
                                                         FindClose find_close, GetNextOffset <U> get_next, CreateObject <T, U> create) where U : struct
        {
            using (var buffer = new SafeStructureInOutBuffer <U>(128 * 1024, true))
            {
                NtStatus          no_more_hresult = Win32Error.ERROR_NO_MORE_ITEMS.ToHresult();
                NtResult <IntPtr> handle          = new NtResult <IntPtr>(no_more_hresult, IntPtr.Zero);
                var list = new List <T>();
                try
                {
                    handle = find_first(buffer);
                    var status = handle.Status;
                    while (status != no_more_hresult)
                    {
                        if (status != NtStatus.STATUS_SUCCESS)
                        {
                            throw new NtException(status);
                        }

                        var next_buffer = buffer;
                        do
                        {
                            list.Add(create(next_buffer));
                            int offset = get_next(next_buffer);
                            if (offset == 0)
                            {
                                break;
                            }
                            next_buffer = next_buffer.GetStructAtOffset <U>(offset);
                        }while (true);

                        status = find_next(handle.Result, buffer);
                    }
                }
                finally
                {
                    if (handle.IsSuccess)
                    {
                        find_close(handle.Result);
                    }
                }
                return(list.AsReadOnly());
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Create from a package full name.
        /// </summary>
        /// <param name="package_full_name">The package full name.</param>
        /// <param name="full_information">Query for full information (needs to be installed for the current user).</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The package identity.</returns>
        public static NtResult <PackageIdentity> CreateFromFullName(string package_full_name, bool full_information, bool throw_on_error)
        {
            PackageFlags flags  = full_information ? PackageFlags.Full : PackageFlags.Basic;
            int          length = 0;

            var result = Win32NativeMethods.GetStagedPackagePathByFullName(package_full_name, ref length, null);

            if (result != Win32Error.ERROR_INSUFFICIENT_BUFFER)
            {
                return(result.CreateResultFromDosError <PackageIdentity>(throw_on_error));
            }

            var builder = new StringBuilder(length);

            result = Win32NativeMethods.GetStagedPackagePathByFullName(package_full_name, ref length, builder);
            if (result != Win32Error.SUCCESS)
            {
                return(result.CreateResultFromDosError <PackageIdentity>(throw_on_error));
            }

            result = _get_staged_package_origin(package_full_name, out PackageOrigin origin);
            if (result != Win32Error.SUCCESS)
            {
                return(result.CreateResultFromDosError <PackageIdentity>(throw_on_error));
            }

            length = 0;
            result = Win32NativeMethods.PackageIdFromFullName(package_full_name, flags, ref length, SafeHGlobalBuffer.Null);
            if (result != Win32Error.ERROR_INSUFFICIENT_BUFFER)
            {
                return(result.CreateResultFromDosError <PackageIdentity>(throw_on_error));
            }

            using (var buffer = new SafeStructureInOutBuffer <PACKAGE_ID>(length, false))
            {
                result = Win32NativeMethods.PackageIdFromFullName(package_full_name, flags, ref length, buffer);
                if (result != Win32Error.SUCCESS)
                {
                    return(result.CreateResultFromDosError <PackageIdentity>(throw_on_error));
                }

                return(new PackageIdentity(package_full_name, buffer.Result, origin, builder.ToString()).CreateResult());
            }
        }
Esempio n. 14
0
        private NtResult <SafeStructureInOutBuffer <T> > QueryBuffer <T>(AUTHZ_CONTEXT_INFORMATION_CLASS info_class, bool throw_on_error) where T : new()
        {
            if (SecurityNativeMethods.AuthzGetInformationFromContext(_handle, info_class, 0, out int required_size, SafeHGlobalBuffer.Null))
            {
                return(NtStatus.STATUS_INVALID_PARAMETER.CreateResultFromError <SafeStructureInOutBuffer <T> >(throw_on_error));
            }

            var err = Win32Utils.GetLastWin32Error();

            if (err != Win32Error.ERROR_INSUFFICIENT_BUFFER)
            {
                return(err.CreateResultFromDosError <SafeStructureInOutBuffer <T> >(throw_on_error));
            }

            using (var buffer = new SafeStructureInOutBuffer <T>(required_size, false)) {
                return(SecurityNativeMethods.AuthzGetInformationFromContext(_handle, info_class,
                                                                            buffer.Length, out required_size, buffer).CreateWin32Result(throw_on_error, () => buffer.Detach()));
            }
        }
        internal SocketSecurityInformation(SafeStructureInOutBuffer <SOCKET_SECURITY_QUERY_INFO> buffer)
        {
            var query_info = buffer.Result;

            Flags = query_info.Flags;
            PeerApplicationToken = CreateToken(query_info.PeerApplicationAccessTokenHandle);
            PeerMachineToken     = CreateToken(query_info.PeerMachineAccessTokenHandle);
            if (buffer.Length < Marshal.SizeOf(typeof(SOCKET_SECURITY_QUERY_INFO_IPSEC2)) ||
                query_info.SecurityProtocol != SOCKET_SECURITY_PROTOCOL.IPsec2)
            {
                return;
            }
            var query_info_2 = buffer.Read <SOCKET_SECURITY_QUERY_INFO_IPSEC2>(0);

            MmSaId            = query_info_2.MmSaId;
            QmSaId            = query_info_2.QmSaId;
            NegotiationWinerr = query_info_2.NegotiationWinerr;
            SaLookupContext   = query_info_2.SaLookupContext;
        }
Esempio n. 16
0
        internal FilterDriver(SafeStructureInOutBuffer <FILTER_AGGREGATE_STANDARD_INFORMATION> buffer)
        {
            var result = buffer.Result;

            if (result.Flags.HasFlagSet(FILTER_AGGREGATE_STANDARD_INFORMATION_FLAGS.FLTFL_ASI_IS_LEGACYFILTER))
            {
                Flags    = result.LegacyFilter.Flags;
                Name     = buffer.ReadUnicodeString(result.LegacyFilter.FilterNameBufferOffset, result.LegacyFilter.FilterNameLength / 2);
                Altitude = FilterManagerUtils.ParseAltitude(buffer.ReadUnicodeString(result.LegacyFilter.FilterAltitudeBufferOffset, result.LegacyFilter.FilterAltitudeLength / 2));
            }
            else
            {
                MiniFilter        = true;
                Flags             = result.MiniFilter.Flags;
                FrameID           = result.MiniFilter.FrameID;
                NumberOfInstances = result.MiniFilter.NumberOfInstances;
                Name     = buffer.ReadUnicodeString(result.MiniFilter.FilterNameBufferOffset, result.MiniFilter.FilterNameLength / 2);
                Altitude = FilterManagerUtils.ParseAltitude(buffer.ReadUnicodeString(result.MiniFilter.FilterAltitudeBufferOffset, result.MiniFilter.FilterAltitudeLength / 2));
            }
        }
Esempio n. 17
0
        private static ApiSetNamespace FromCurrentProcess()
        {
            if (NtObjectUtils.SupportedVersion < SupportedVersion.Windows10)
            {
                return(new ApiSetNamespace(ApiSetFlags.None, new List <ApiSetEntry>()));
            }

            IntPtr base_ptr = NtProcess.Current.GetPeb().GetApiSetMap();
            var    header   = (API_SET_NAMESPACE_WIN10)Marshal.PtrToStructure(base_ptr, typeof(API_SET_NAMESPACE_WIN10));

            if (header.Version < 5)
            {
                return(new ApiSetNamespace(ApiSetFlags.None, new List <ApiSetEntry>()));
            }

            var map     = new SafeStructureInOutBuffer <API_SET_NAMESPACE_WIN10>(base_ptr, header.Size, false);
            var entries = map.ReadArray <API_SET_NAMESPACE_ENTRY_WIN10>(header.NamespaceOffset, header.Count).Select(e => CreateEntry(e, map));

            return(new ApiSetNamespace(header.Flags, entries.ToList()));
        }
Esempio n. 18
0
        private static KerberosPrincipalName ParseName(IntPtr ptr)
        {
            if (ptr == IntPtr.Zero)
            {
                return(new KerberosPrincipalName());
            }
            KerberosNameType name_type = (KerberosNameType)Marshal.ReadInt16(ptr, 0);
            int count = Marshal.ReadInt16(ptr, 2);

            if (count == 0)
            {
                return(new KerberosPrincipalName(name_type, new string[0]));
            }

            var name = new SafeStructureInOutBuffer <KERB_EXTERNAL_NAME>(ptr, Marshal.SizeOf(typeof(KERB_EXTERNAL_NAME))
                                                                         + Marshal.SizeOf(typeof(UnicodeStringOut)) * count, false);

            UnicodeStringOut[] names = new UnicodeStringOut[count];
            name.Data.ReadArray(0, names, 0, count);
            return(new KerberosPrincipalName(name_type, names.Select(u => u.ToString())));
        }
Esempio n. 19
0
 public override int Read(byte[] buffer, int offset, int count)
 {
     if (offset == 0)
     {
         using (var len = new SafeStructureInOutBuffer <int>())
         {
             _stm.Read(buffer, count, len.DangerousGetHandle());
             return(len.Result);
         }
     }
     else
     {
         using (var len = new SafeStructureInOutBuffer <int>())
         {
             byte[] temp_buffer = new byte[count];
             _stm.Read(temp_buffer, count, len.DangerousGetHandle());
             int read_len = len.Result;
             Buffer.BlockCopy(temp_buffer, 0, buffer, offset, count);
             return(read_len);
         }
     }
 }
        /// <summary>
        /// Get certificates from a PE file.
        /// </summary>
        /// <param name="file">The PE file.</param>
        /// <param name="throw_on_error">True the throw on error.</param>
        /// <returns>The list of authenticode certificate entries.</returns>
        public static NtResult <IReadOnlyList <AuthenticodeCertificate> > GetCertificates(NtFile file, bool throw_on_error)
        {
            List <AuthenticodeCertificate> certs = new List <AuthenticodeCertificate>();
            Win32Error error = Win32NativeMethods.ImageEnumerateCertificates(file.Handle, WinCertType.WIN_CERT_TYPE_ANY, out int count, null, 0).GetLastWin32Error();

            if (error != Win32Error.SUCCESS)
            {
                return(error.CreateResultFromDosError <IReadOnlyList <AuthenticodeCertificate> >(throw_on_error));
            }
            for (int i = 0; i < count; ++i)
            {
                int size = 0;
                error = Win32NativeMethods.ImageGetCertificateData(file.Handle, i, SafeHGlobalBuffer.Null, ref size).GetLastWin32Error();
                if (error != Win32Error.ERROR_INSUFFICIENT_BUFFER)
                {
                    return(error.CreateResultFromDosError <IReadOnlyList <AuthenticodeCertificate> >(throw_on_error));
                }
                using (var buffer = new SafeStructureInOutBuffer <WIN_CERTIFICATE>(size, true))
                {
                    error = Win32NativeMethods.ImageGetCertificateData(file.Handle, i, buffer, ref size).GetLastWin32Error();
                    if (error != Win32Error.SUCCESS)
                    {
                        return(error.CreateResultFromDosError <IReadOnlyList <AuthenticodeCertificate> >(throw_on_error));
                    }
                    var result = buffer.Result;
                    if (result.wCertificateType != WinCertType.WIN_CERT_TYPE_PKCS_SIGNED_DATA)
                    {
                        continue;
                    }
                    var cert = AuthenticodeCertificate.Parse(buffer.Data.ReadBytes(result.dwLength), throw_on_error);
                    if (!cert.IsSuccess)
                    {
                        return(cert.Cast <IReadOnlyList <AuthenticodeCertificate> >());
                    }
                    certs.Add(cert.Result);
                }
            }
            return(certs.AsReadOnly().CreateResult().Cast <IReadOnlyList <AuthenticodeCertificate> >());
        }
        private static NtResult <SafeLsaReturnBufferHandle> QueryCachedTicket(SafeLsaLogonHandle handle, uint auth_package, string target_name, KERB_RETRIEVE_TICKET_FLAGS flags,
                                                                              Luid logon_id, SecHandle sec_handle, bool throw_on_error)
        {
            int string_length     = (target_name.Length) * 2;
            int max_string_length = string_length + 2;

            using (var request = new SafeStructureInOutBuffer <KERB_RETRIEVE_TKT_REQUEST>(max_string_length, true))
            {
                request.Data.WriteUnicodeString(target_name + '\0');
                var request_str = new KERB_RETRIEVE_TKT_REQUEST()
                {
                    CacheOptions      = flags,
                    CredentialsHandle = sec_handle,
                    LogonId           = logon_id,
                    MessageType       = KERB_PROTOCOL_MESSAGE_TYPE.KerbRetrieveEncodedTicketMessage,
                    TargetName        = new UnicodeStringOut()
                    {
                        Length        = (ushort)string_length,
                        MaximumLength = (ushort)max_string_length,
                        Buffer        = request.Data.DangerousGetHandle()
                    }
                };
                request.Result = request_str;
                using (var result = handle.CallPackage(auth_package, request, throw_on_error))
                {
                    if (!result.IsSuccess)
                    {
                        return(result.Cast <SafeLsaReturnBufferHandle>());
                    }
                    if (!result.Result.Status.IsSuccess())
                    {
                        return(result.Result.Status.CreateResultFromError <SafeLsaReturnBufferHandle>(throw_on_error));
                    }
                    return(result.Result.Buffer.Detach().CreateResult());
                }
            }
        }
        internal ServiceInformation(string name, SecurityDescriptor sd,
                                    IEnumerable <ServiceTriggerInformation> triggers, ServiceSidType sid_type,
                                    ServiceLaunchProtectedType launch_protected, IEnumerable <string> required_privileges,
                                    SafeStructureInOutBuffer <QUERY_SERVICE_CONFIG> config, bool delayed_auto_start)
        {
            using (config)
            {
                Name = name;
                SecurityDescriptor = sd;
                Triggers           = triggers;
                SidType            = sid_type;
                LaunchProtected    = launch_protected;
                RequiredPrivileges = required_privileges;

                if (config == null)
                {
                    BinaryPathName   = string.Empty;
                    LoadOrderGroup   = string.Empty;
                    Dependencies     = new string[0];
                    DisplayName      = string.Empty;
                    ServiceStartName = string.Empty;
                    return;
                }

                var result = config.Result;
                ServiceType      = result.dwServiceType;
                StartType        = result.dwStartType;
                ErrorControl     = result.dwErrorControl;
                BinaryPathName   = result.lpBinaryPathName.GetString();
                LoadOrderGroup   = result.lpLoadOrderGroup.GetString();
                TagId            = result.dwTagId;
                Dependencies     = result.lpLoadOrderGroup.GetMultiString();
                DisplayName      = result.lpDisplayName.GetString();
                ServiceStartName = result.lpServiceStartName.GetString();
                DelayedAutoStart = delayed_auto_start;
            }
        }
        /// <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));
            }
        }
        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);
                }
            }
        }
 /// <summary>
 /// Enumerate all atoms.
 /// </summary>
 /// <returns>An enumeration of all atoms on the system.</returns>
 public static IEnumerable<NtAtom> GetAtoms()
 {
     int size = 1024;
     while (size < 5 * 1024 * 1024)
     {
         using (SafeStructureInOutBuffer<AtomTableInformation> buffer = new SafeStructureInOutBuffer<AtomTableInformation>(size, true))
         {
             int return_length;
             NtStatus status = NtSystemCalls.NtQueryInformationAtom(0, AtomInformationClass.AtomTableInformation, buffer, buffer.Length, out return_length);
             if (status.IsSuccess())
             {
                 AtomTableInformation table = buffer.Result;
                 IntPtr data = buffer.Data.DangerousGetHandle();
                 for (int i = 0; i < table.NumberOfAtoms; ++i)
                 {
                     ushort atom = (ushort)Marshal.ReadInt16(data);
                     yield return new NtAtom(atom);
                     data += 2;
                 }
                 
             }
             else if (status != NtStatus.STATUS_INFO_LENGTH_MISMATCH)
             {
                 throw new NtException(status);
             }
             size *= 2;
         }
     }
 }
Esempio n. 26
0
 internal RpcFaultException(SafeStructureInOutBuffer <LRPC_FAULT_MESSAGE> buffer)
     : this(buffer, buffer.Result)
 {
 }
Esempio n. 27
0
 private RpcFaultException(SafeStructureInOutBuffer <LRPC_FAULT_MESSAGE> buffer, LRPC_FAULT_MESSAGE message)
     : base(NtObjectUtils.MapDosErrorToStatus(message.RpcStatus))
 {
     // Maybe read extended error info.
 }
        /// <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();
                }
            }
        }
Esempio n. 29
0
        static void DumpTriggers(SafeServiceHandle service)
        {
            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;
                }

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

                SERVICE_TRIGGER[] trigger_arr;
                using (SafeHGlobalBuffer triggers = new SafeHGlobalBuffer(trigger_info.pTriggers, trigger_info.cTriggers * Marshal.SizeOf(typeof(SERVICE_TRIGGER)), false))
                {
                    trigger_arr = new SERVICE_TRIGGER[trigger_info.cTriggers];
                    triggers.ReadArray(0, trigger_arr, 0, trigger_arr.Length);
                }
                for (int i = 0; i < trigger_arr.Length; ++i)
                {
                    SERVICE_TRIGGER trigger = trigger_arr[i];
                    Console.WriteLine("Trigger: {0} - Type: {1} - Action: {2}", i, trigger.dwTriggerType, trigger.dwAction);
                    switch (trigger.dwTriggerType)
                    {
                    case ServiceTriggerType.Custom:
                        Console.WriteLine("Subtype: [ETW UUID] {0:B}", trigger.GetSubType());
                        break;

                    case ServiceTriggerType.DeviceInterfaceArrival:
                        Console.WriteLine("Subtype: [Interface Class GUID] {0:B}", trigger.GetSubType());
                        break;

                    case ServiceTriggerType.GroupPolicy:
                    {
                        Guid sub_type = trigger.GetSubType();
                        if (sub_type == MACHINE_POLICY_PRESENT_GUID)
                        {
                            Console.WriteLine("Subtype: [Machine Policy Present]");
                        }
                        else if (sub_type == USER_POLICY_PRESENT_GUID)
                        {
                            Console.WriteLine("Subtype: [User Policy Present]");
                        }
                        else
                        {
                            Console.WriteLine("Subtype: [Unknown Group Policy] {0:B}", sub_type);
                        }
                    }
                    break;

                    case ServiceTriggerType.NetworkEndpoint:
                    {
                        Guid sub_type = trigger.GetSubType();
                        if (sub_type == RPC_INTERFACE_EVENT_GUID)
                        {
                            Console.WriteLine("Subtype: [RPC Interface]");
                        }
                        else if (sub_type == NAMED_PIPE_EVENT_GUID)
                        {
                            Console.WriteLine("Subtype: [Named Pipe]");
                        }
                        else
                        {
                            Console.WriteLine("Subtype: [Unknown Network Endpoint] {0:B}", sub_type);
                        }
                    }
                    break;

                    case ServiceTriggerType.DomainJoin:
                    {
                        Guid sub_type = trigger.GetSubType();
                        if (sub_type == DOMAIN_JOIN_GUID)
                        {
                            Console.WriteLine("Subtype: [Domain Join]");
                        }
                        else if (sub_type == DOMAIN_LEAVE_GUID)
                        {
                            Console.WriteLine("Subtype: [Domain Leave]");
                        }
                        else
                        {
                            Console.WriteLine("Subtype: [Unknown Domain Join] {0:B}", sub_type);
                        }
                    }
                    break;

                    case ServiceTriggerType.IPAddressAvailability:
                    {
                        Guid sub_type = trigger.GetSubType();
                        if (sub_type == NETWORK_MANAGER_FIRST_IP_ADDRESS_ARRIVAL_GUID)
                        {
                            Console.WriteLine("Subtype: [First IP Address Available]");
                        }
                        else if (sub_type == NETWORK_MANAGER_LAST_IP_ADDRESS_REMOVAL_GUID)
                        {
                            Console.WriteLine("Subtype: [Last IP Address Available]");
                        }
                        else
                        {
                            Console.WriteLine("Subtype: [Unknown IP Address Availability] {0:B}", sub_type);
                        }
                    }
                    break;
                    }

                    if (trigger.pDataItems != IntPtr.Zero && trigger.cDataItems > 0)
                    {
                        DumpCustomData(trigger);
                    }
                }
            }
        }
        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();
                    }
                }
            }

        }
Esempio n. 31
0
 private RpcClientResponse HandleImmediateResponse(AlpcMessageRaw message, SafeStructureInOutBuffer <LRPC_IMMEDIATE_RESPONSE_MESSAGE> response, AlpcReceiveMessageAttributes attributes, int data_length)
 {
     return(new RpcClientResponse(response.Data.ToArray(), attributes.Handles));
 }
Esempio n. 32
0
 static void Main(string[] args)
 {
     try
     {
         if (args.Length < 1)
         {
             return;
         }
         EnablePrivileges();
         using (var dir = OpenReparseDirectory(args[0]))
         {
             using (var buffer = new SafeStructureInOutBuffer <FileReparseTagInformation>())
             {
                 using (var io_status = new SafeIoStatusBuffer())
                 {
                     while (true)
                     {
                         NtStatus status = NtSystemCalls.NtQueryDirectoryFile(dir.Handle, SafeKernelObjectHandle.Null, IntPtr.Zero,
                                                                              IntPtr.Zero, io_status, buffer, buffer.Length, FileInformationClass.FileReparsePointInformation,
                                                                              true, null, false);
                         if (status == NtStatus.STATUS_NO_MORE_FILES)
                         {
                             break;
                         }
                         if (status != NtStatus.STATUS_SUCCESS)
                         {
                             throw new NtException(status);
                         }
                         var result   = buffer.Result;
                         var filedata = GetFileData(dir, result.Tag, result.FileReferenceNumber);
                         Console.WriteLine("{0} {1}", filedata.FileName, filedata.Reparse.Tag);
                         if (filedata.Reparse is MountPointReparseBuffer mount_point)
                         {
                             Console.WriteLine("Target: {0}", mount_point.SubstitutionName);
                             Console.WriteLine("Print: {0}", mount_point.PrintName);
                         }
                         else if (filedata.Reparse is SymlinkReparseBuffer symlink)
                         {
                             Console.WriteLine("Target: {0}", symlink.SubstitutionName);
                             Console.WriteLine("Print: {0}", symlink.PrintName);
                             Console.WriteLine("Flags: {0}", symlink.Flags);
                         }
                         else if (filedata.Reparse is ExecutionAliasReparseBuffer alias)
                         {
                             Console.WriteLine("Target: {0}", alias.Target);
                             Console.WriteLine("Package: {0}", alias.PackageName);
                             Console.WriteLine("Entry Point: {0}", alias.EntryPoint);
                             Console.WriteLine("AppType: {0}", alias.AppType);
                         }
                         else if (filedata.Reparse is OpaqueReparseBuffer opaque)
                         {
                             HexDumpBuilder builder = new HexDumpBuilder(true, true, true, false, 0);
                             builder.Append(opaque.Data);
                             Console.WriteLine(builder);
                         }
                     }
                 }
             }
         }
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex);
     }
 }
Esempio n. 33
0
 private static string GetNameFromSymbolInfo(SafeStructureInOutBuffer <SYMBOL_INFO> buffer)
 {
     return(buffer.Data.ReadNulTerminatedUnicodeString());
 }
Esempio n. 34
0
        internal ServiceInformation(string machine_name, string name, SecurityDescriptor sd,
                                    IEnumerable <ServiceTriggerInformation> triggers, ServiceSidType sid_type,
                                    ServiceLaunchProtectedType launch_protected, IEnumerable <string> required_privileges,
                                    SafeStructureInOutBuffer <QUERY_SERVICE_CONFIG> config, bool delayed_auto_start)
        {
            Name = name;
            SecurityDescriptor = sd;
            Triggers           = triggers;
            SidType            = sid_type;
            LaunchProtected    = launch_protected;
            RequiredPrivileges = required_privileges;

            if (config == null)
            {
                BinaryPathName   = string.Empty;
                LoadOrderGroup   = string.Empty;
                Dependencies     = new string[0];
                DisplayName      = string.Empty;
                ServiceStartName = string.Empty;
                return;
            }

            var result = config.Result;

            ServiceType      = result.dwServiceType;
            StartType        = result.dwStartType;
            ErrorControl     = result.dwErrorControl;
            BinaryPathName   = result.lpBinaryPathName.GetString();
            LoadOrderGroup   = result.lpLoadOrderGroup.GetString();
            TagId            = result.dwTagId;
            Dependencies     = result.lpLoadOrderGroup.GetMultiString();
            DisplayName      = result.lpDisplayName.GetString();
            ServiceStartName = result.lpServiceStartName.GetString();
            DelayedAutoStart = delayed_auto_start;
            MachineName      = machine_name ?? string.Empty;
            ImagePath        = string.Empty;
            ServiceDll       = string.Empty;
            ServiceHostType  = string.Empty;
            ServiceMain      = string.Empty;

            // TODO: Maybe try and query using remote registry service?
            if (!string.IsNullOrEmpty(MachineName))
            {
                return;
            }
            ImagePath = Win32Utils.GetImagePathFromCommandLine(BinaryPathName);
            using (RegistryKey key = OpenKeySafe(Registry.LocalMachine, $@"SYSTEM\CurrentControlSet\Services\{Name}"))
            {
                if (key != null)
                {
                    UserName   = ReadStringFromKey(key, null, "ObjectName");
                    ServiceDll = ReadStringFromKey(key, "Parameters", "ServiceDll");
                    if (string.IsNullOrEmpty(ServiceDll))
                    {
                        ServiceDll = ReadStringFromKey(key, null, "ServiceDll");
                    }

                    if (!string.IsNullOrEmpty(ServiceDll))
                    {
                        string[] args = Win32Utils.ParseCommandLine(BinaryPathName);
                        for (int i = 0; i < args.Length - 1; ++i)
                        {
                            if (args[i] == "-k")
                            {
                                ServiceHostType = args[i + 1];
                                break;
                            }
                        }

                        ServiceMain = ReadStringFromKey(key, "Parameters", "ServiceMain");
                        if (string.IsNullOrEmpty(ServiceMain))
                        {
                            ServiceMain = "ServiceMain";
                        }
                    }
                }
            }
        }