/// <summary>
        /// Get a safer token.
        /// </summary>
        /// <param name="token">The base token.</param>
        /// <param name="level">The safer level to use.</param>
        /// <param name="make_inert">True to make the token inert.</param>
        /// <returns>The safer token.</returns>
        public static NtToken GetTokenFromSaferLevel(NtToken token, SaferLevel level, bool make_inert)
        {
            IntPtr level_handle;

            if (!Win32NativeMethods.SaferCreateLevel(SaferScope.User, level, Win32NativeMethods.SAFER_LEVEL_OPEN, out level_handle, IntPtr.Zero))
            {
                throw new SafeWin32Exception();
            }

            try
            {
                using (NtToken duptoken = token.Duplicate(TokenAccessRights.GenericRead | TokenAccessRights.GenericExecute))
                {
                    SafeKernelObjectHandle handle;
                    if (Win32NativeMethods.SaferComputeTokenFromLevel(level_handle,
                                                                      duptoken.Handle, out handle, make_inert ? SaferFlags.MakeInert : 0, IntPtr.Zero))
                    {
                        return(NtToken.FromHandle(handle));
                    }
                    else
                    {
                        throw new SafeWin32Exception();
                    }
                }
            }
            finally
            {
                Win32NativeMethods.SaferCloseLevel(level_handle);
            }
        }
        /// <summary>
        /// Get tokens for all logged on sessions.
        /// </summary>
        /// <remarks>Needs SeTcbPrivilege to work.</remarks>
        /// <returns>The list of session tokens.</returns>
        public static IEnumerable <NtToken> GetSessionTokens()
        {
            List <NtToken> tokens         = new List <NtToken>();
            IntPtr         pSessions      = IntPtr.Zero;
            int            dwSessionCount = 0;

            try
            {
                if (Win32NativeMethods.WTSEnumerateSessions(IntPtr.Zero, 0, 1, out pSessions, out dwSessionCount))
                {
                    IntPtr current = pSessions;
                    for (int i = 0; i < dwSessionCount; ++i)
                    {
                        WTS_SESSION_INFO session_info = (WTS_SESSION_INFO)Marshal.PtrToStructure(current, typeof(WTS_SESSION_INFO));

                        if (session_info.State == WTS_CONNECTSTATE_CLASS.WTSActive && Win32NativeMethods.WTSQueryUserToken(session_info.SessionId, out SafeKernelObjectHandle handle))
                        {
                            tokens.Add(NtToken.FromHandle(handle));
                        }
                        current += Marshal.SizeOf(typeof(WTS_SESSION_INFO));
                    }
                }
            }
            finally
            {
                if (pSessions != IntPtr.Zero)
                {
                    Win32NativeMethods.WTSFreeMemory(pSessions);
                }
            }

            return(tokens);
        }
Пример #3
0
        private static NtResult <NtToken> LsaLogonUser(SecurityLogonType type, string auth_package, string origin_name,
                                                       SafeBuffer buffer, IEnumerable <UserGroup> local_groups, bool throw_on_error)
        {
            using (var list = new DisposableList()) {
                var hlsa = list.AddResource(SafeLsaLogonHandle.Connect(throw_on_error));
                if (!hlsa.IsSuccess)
                {
                    return(hlsa.Cast <NtToken>());
                }

                var auth_pkg = hlsa.Result.LookupAuthPackage(auth_package, throw_on_error);
                if (!auth_pkg.IsSuccess)
                {
                    return(auth_pkg.Cast <NtToken>());
                }

                var groups = local_groups == null ? SafeTokenGroupsBuffer.Null
            : list.AddResource(SafeTokenGroupsBuffer.Create(local_groups));

                TOKEN_SOURCE tokenSource = new TOKEN_SOURCE("NT.NET");
                SecurityNativeMethods.AllocateLocallyUniqueId(out tokenSource.SourceIdentifier);
                QUOTA_LIMITS quota_limits = new QUOTA_LIMITS();
                return(SecurityNativeMethods.LsaLogonUser(hlsa.Result, new LsaString(origin_name),
                                                          type, auth_pkg.Result, buffer, buffer.GetLength(), groups,
                                                          tokenSource, out SafeLsaReturnBufferHandle profile,
                                                          out int cbProfile, out Luid logon_id, out SafeKernelObjectHandle token_handle,
                                                          quota_limits, out NtStatus subStatus).CreateResult(throw_on_error, () => {
                    using (profile) {
                        return NtToken.FromHandle(token_handle);
                    }
                }));
            }
        }
        /// <summary>
        /// Logon a user.
        /// </summary>
        /// <param name="type">The type of logon.</param>
        /// <param name="auth_package">The authentication package to use.</param>
        /// <param name="origin_name">The name of the origin.</param>
        /// <param name="source_context">The token source context.</param>
        /// <param name="buffer">The authentication credentials buffer.</param>
        /// <param name="local_groups">Additional local groups.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The LSA logon result.</returns>
        public NtResult <LsaLogonResult> LsaLogonUser(SecurityLogonType type, string auth_package, string origin_name,
                                                      TokenSource source_context, SafeBuffer buffer, IEnumerable <UserGroup> local_groups, bool throw_on_error)
        {
            using (var list = new DisposableList())
            {
                var auth_pkg = _handle.LookupAuthPackage(auth_package, throw_on_error);
                if (!auth_pkg.IsSuccess)
                {
                    return(auth_pkg.Cast <LsaLogonResult>());
                }

                var groups = local_groups == null ? SafeTokenGroupsBuffer.Null
                    : list.AddResource(SafeTokenGroupsBuffer.Create(local_groups));

                QUOTA_LIMITS quota_limits = new QUOTA_LIMITS();
                return(SecurityNativeMethods.LsaLogonUser(_handle, new LsaString(origin_name),
                                                          type, auth_pkg.Result, buffer, buffer.GetLength(), groups,
                                                          source_context, out SafeLsaReturnBufferHandle profile,
                                                          out int cbProfile, out Luid logon_id, out SafeKernelObjectHandle token_handle,
                                                          quota_limits, out NtStatus subStatus).CreateResult(throw_on_error, () =>
                {
                    profile.InitializeLength(cbProfile);
                    return new LsaLogonResult(NtToken.FromHandle(token_handle), profile, logon_id, quota_limits);
                }));
            }
        }
 /// <summary>
 /// Logon a user with a username and password.
 /// </summary>
 /// <param name="user">The username.</param>
 /// <param name="domain">The user's domain.</param>
 /// <param name="password">The user's password.</param>
 /// <param name="type">The type of logon token.</param>
 /// <returns>The logged on token.</returns>
 public static NtToken Logon(string user, string domain, string password, SecurityLogonType type)
 {
     if (!Win32NativeMethods.LogonUser(user, domain, password, type, 0, out SafeKernelObjectHandle handle))
     {
         throw new SafeWin32Exception();
     }
     return(NtToken.FromHandle(handle));
 }
 private static NtToken CreateToken(long handle)
 {
     if (handle == 0)
     {
         return(null);
     }
     return(NtToken.FromHandle(new IntPtr(handle), true));
 }
 /// <summary>
 /// Get session token for a session ID.
 /// </summary>
 /// <param name="session_id">The session ID.</param>
 /// <returns>The session token.</returns>
 public static NtToken GetSessionToken(int session_id)
 {
     if (!Win32NativeMethods.WTSQueryUserToken(session_id,
                                               out SafeKernelObjectHandle handle))
     {
         throw new SafeWin32Exception();
     }
     return(NtToken.FromHandle(handle));
 }
        /// <summary>
        /// Open the current clipboard token.
        /// </summary>
        /// <param name="desired_access"></param>
        /// <param name="throw_on_error"></param>
        /// <returns></returns>
        public static NtResult <NtToken> OpenClipboardToken(TokenAccessRights desired_access, bool throw_on_error)
        {
            if (Win32NativeMethods.GetClipboardAccessToken(out SafeKernelObjectHandle handle, desired_access))
            {
                return(NtToken.FromHandle(handle).CreateResult());
            }

            return(NtStatus.STATUS_NO_TOKEN.CreateResultFromError <NtToken>(throw_on_error));
        }
Пример #9
0
 internal static ExportedSecurityContext ExportContext(SecHandle context, SecPkgContextExportFlags export_flags, string package)
 {
     using (SecBuffer buffer = new SecBuffer(SecurityBufferType.Empty, 64 * 1024))
     {
         SecurityNativeMethods.ExportSecurityContext(context, SecPkgContextExportFlags.None,
                                                     buffer, out SafeKernelObjectHandle token).CheckResult();
         return(new ExportedSecurityContext(package, buffer.ToArray(), NtToken.FromHandle(token)));
     }
 }
Пример #10
0
 /// <summary>
 /// Get the token from the clipboard.
 /// </summary>
 /// <param name="desired_access">The access rights for the opened token.</param>
 /// <returns>The clipboard token.</returns>
 public static NtToken GetTokenFromClipboard(TokenAccessRights desired_access)
 {
     try {
         return(NtToken.FromHandle(OpenClipboardToken(desired_access)));
     } catch (NtException) {
         throw;
     } catch {
         throw new InvalidOperationException("GetClipboardAccessToken doesn't exist");
     }
 }
Пример #11
0
        static Form GetFormFromArgs(string[] args)
        {
            try
            {
                int    pid       = -1;
                int    handle    = -1;
                string text      = string.Empty;
                bool   show_help = false;

                OptionSet opts = new OptionSet()
                {
                    { "p|pid=", "Specify a process ID to view the token.",
                      v => pid = int.Parse(v) },
                    { "handle=", "Specify an inherited handle to view.",
                      v => handle = int.Parse(v) },
                    { "text=", "Specify a text string for the token window.",
                      v => text = v },
                    { "h|help", "Show this message and exit",
                      v => show_help = v != null },
                };

                opts.Parse(args);

                if (show_help || (handle <= 0 && pid <= 0))
                {
                    ShowHelp(opts);
                }
                else if (handle > 0)
                {
                    using (NtToken token = NtToken.FromHandle(new SafeKernelObjectHandle(new IntPtr(handle), true)))
                    {
                        if (token.NtType != NtType.GetTypeByType <NtToken>())
                        {
                            throw new ArgumentException("Passed handle is not a token");
                        }

                        return(new TokenForm(token.Duplicate(), text));
                    }
                }
                else if (pid > 0)
                {
                    using (NtProcess process = NtProcess.Open(pid, ProcessAccessRights.QueryLimitedInformation))
                    {
                        return(new TokenForm(process.OpenToken(),
                                             $"{process.Name}:{pid}"));
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return(null);
        }
 public static NtResult <NtToken> CreateAppContainerToken(NtToken token, Sid appcontainer_sid,
                                                          IEnumerable <Sid> capabilities, bool throw_on_error)
 {
     using (var resources = new DisposableList())
     {
         SECURITY_CAPABILITIES caps = Win32Utils.CreateSecuityCapabilities(appcontainer_sid, capabilities ?? new Sid[0], resources);
         if (!Win32NativeMethods.CreateAppContainerToken(token.GetHandle(), ref caps, out SafeKernelObjectHandle new_token))
         {
             return(Win32Utils.GetLastWin32Error().CreateResultFromDosError <NtToken>(throw_on_error));
         }
         return(NtToken.FromHandle(new_token).CreateResult());
     }
 }
Пример #13
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));
                }
            }
        }
 public static NtToken GetTokenFromClipboard()
 {
     try
     {
         return(NtToken.FromHandle(OpenClipboardToken()));
     }
     catch (SafeWin32Exception)
     {
         throw;
     }
     catch
     {
         throw new InvalidOperationException("GetClipboardAccessToken doesn't exist");
     }
 }
Пример #15
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        public static void Main(string[] args)
        {
            string                      database_file            = null;
            string                      save_file                = null;
            bool                        do_enum                  = false;
            bool                        enum_clsid               = false;
            bool                        enum_runtime             = false;
            bool                        show_help                = false;
            bool                        query_interfaces         = false;
            int                         concurrent_queries       = Environment.ProcessorCount;
            bool                        refresh_interfaces       = false;
            bool                        enable_activation_filter = false;
            string                      symbol_dir               = null;
            bool                        delete_database          = false;
            string                      view_access_sd           = null;
            string                      view_launch_sd           = null;
            string                      view_name                = null;
            COMRegistryMode             mode         = COMRegistryMode.Merged;
            IEnumerable <COMServerType> server_types = new COMServerType[] { COMServerType.InProcHandler32, COMServerType.InProcServer32, COMServerType.LocalServer32 };
            NtToken                     token        = null;

            OptionSet opts = new OptionSet()
            {
                { "i|in=", "Open a database file.", v => database_file = v },
                { "o|out=", "Save database and exit.", v => save_file = v },
                { "e|enum", "Enumerate the provided CLSID (GUID).", v => enum_clsid = v != null },
                { "r|rt", "Enumerate the provided Runtime Class.", v => enum_runtime = v != null },
                { "q|query", "Query all interfaces for database", v => query_interfaces = v != null },
                { "c|conn=", "Number of concurrent interface queries", v => concurrent_queries = int.Parse(v) },
                { "s|server=", "Specify server types for query", v => server_types = ParseServerTypes(v) },
                { "refresh", "Refresh interfaces in query", v => refresh_interfaces = v != null },
                { "m", "Loading mode is machine only.", v => mode = COMRegistryMode.MachineOnly },
                { "u", "Loading mode is user only.", v => mode = COMRegistryMode.UserOnly },
                { "a", "Enable activation filter.", v => enable_activation_filter = v != null },
                { "g=", "Generate a symbol file in the specified directory.", v => symbol_dir = v },
                { "d", "Delete the input database once loaded", v => delete_database = v != null },
                { "v=", "View a COM access security descriptor (specify the SDDL)", v => view_access_sd = v },
                { "l=", "View a COM launch security descriptor (specify the SDDL)", v => view_launch_sd = v },
                { "n=", "Name any simple form display such as security descriptor", v => view_name = v },
                { "t=", "Specify a token to use when enumerating interfaces", v => token = NtToken.FromHandle(new IntPtr(int.Parse(v))) },
                { "h|help", "Show this message and exit.", v => show_help = v != null },
            };

            List <string> additional_args = new List <string>();

            try
            {
                additional_args = opts.Parse(args);
            }
            catch
            {
                show_help = true;
            }

            do_enum = enum_clsid || enum_runtime;

            if (show_help || (do_enum && additional_args.Count < 4) || (symbol_dir != null && !Directory.Exists(symbol_dir)))
            {
                StringWriter writer = new StringWriter();
                writer.WriteLine("Usage: OleViewDotNet [options] [enum args]");
                writer.WriteLine();
                writer.WriteLine("Options:");
                opts.WriteOptionDescriptions(writer);
                MessageBox.Show(writer.ToString(), "Help", MessageBoxButtons.OK, MessageBoxIcon.Information);
                Environment.Exit(1);
            }

            if (do_enum)
            {
                try
                {
                    Environment.Exit(EnumInterfaces(new Queue <string>(additional_args), enum_runtime, token));
                }
                catch
                {
                    Environment.Exit(42);
                }
            }
            else if (symbol_dir != null)
            {
                try
                {
                    COMUtilities.GenerateSymbolFile(symbol_dir,
                                                    Environment.Is64BitProcess ? Properties.Settings.Default.DbgHelpPath64 : Properties.Settings.Default.DbgHelpPath32, Properties.Settings.Default.SymbolPath);
                    Environment.Exit(0);
                }
                catch (Exception)
                {
                    Environment.Exit(1);
                }
            }
            else
            {
                AutoSaveLoadConfiguration autoload_config = new AutoSaveLoadConfiguration();
                AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);

                try
                {
                    if (view_access_sd != null || view_launch_sd != null)
                    {
                        bool access           = view_access_sd != null;
                        SecurityDescriptor sd = new SecurityDescriptor(view_access_sd ?? view_launch_sd);
                        bool has_container    = false;
                        if (sd.DaclPresent)
                        {
                            foreach (var ace in sd.Dacl)
                            {
                                if (ace.Mask.IsAccessGranted(COMAccessRights.ActivateContainer | COMAccessRights.ExecuteContainer))
                                {
                                    has_container = true;
                                    break;
                                }
                            }
                        }
                        AccessMask valid_access = access ? 0x7 : 0x1F;
                        if (has_container)
                        {
                            valid_access |= (access ? 0x20 : 0x60);
                        }

                        SecurityDescriptorViewerControl control = new SecurityDescriptorViewerControl();
                        DocumentForm frm   = new DocumentForm(control);
                        string       title = $"{(access ? "Access Security" : "Launch Security")}";
                        if (!string.IsNullOrWhiteSpace(view_name))
                        {
                            title = $"{view_name} {title}";
                        }
                        frm.Text = title;
                        control.SetSecurityDescriptor(sd, typeof(COMAccessRights), new GenericMapping()
                        {
                            GenericExecute = valid_access,
                            GenericRead    = valid_access,
                            GenericWrite   = valid_access,
                            GenericAll     = valid_access
                        }, valid_access);
                        Application.Run(frm);
                        return;
                    }

                    COMRegistry registry = null;

                    if (database_file == null && autoload_config.AutoLoad && File.Exists(autoload_config.DatabasePath))
                    {
                        try
                        {
                            registry = COMUtilities.LoadRegistry(null, autoload_config.DatabasePath);
                        }
                        catch
                        {
                            MessageBox.Show($"Error loading database {autoload_config.DatabasePath}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }

                    if (registry == null)
                    {
                        registry = database_file != null?COMUtilities.LoadRegistry(null, database_file)
                                       : COMUtilities.LoadRegistry(null, mode);
                    }

                    if (delete_database && database_file != null)
                    {
                        File.Delete(database_file);
                    }

                    if (query_interfaces)
                    {
                        if (!COMUtilities.QueryAllInterfaces(null, registry.Clsids.Values, server_types, concurrent_queries, refresh_interfaces))
                        {
                            Environment.Exit(1);
                        }
                    }

                    if (save_file != null)
                    {
                        registry.Save(save_file);
                        Environment.Exit(0);
                    }

                    _appContext = new MultiApplicationContext(new MainForm(registry));
                    if (enable_activation_filter)
                    {
                        COMUtilities.CoRegisterActivationFilter(new ActivationFilter());
                    }
                    Application.Run(_appContext);

                    autoload_config = new AutoSaveLoadConfiguration();
                    if (autoload_config.AutoSave)
                    {
                        registry.Save(autoload_config.DatabasePath);
                    }
                }
                catch (Exception ex)
                {
                    if (!(ex is OperationCanceledException))
                    {
                        ShowError(null, ex);
                    }
                }
            }
        }
 /// <summary>
 /// Get an access token for the authenticated user.
 /// </summary>
 /// <returns>The user's access token.</returns>
 public NtToken GetAccessToken()
 {
     SecurityNativeMethods.QuerySecurityContextToken(_context, out SafeKernelObjectHandle token).CheckResult();
     return(NtToken.FromHandle(token));
 }
        internal static ExportedSecurityContext ExportContext(SecHandle context, SecPkgContextExportFlags export_flags, string package, bool client)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            SecBuffer buffer = new SecBuffer(SecurityBufferType.Empty);

            try
            {
                SecurityNativeMethods.ExportSecurityContext(context, export_flags,
                                                            buffer, out SafeKernelObjectHandle token).CheckResult();
                return(new ExportedSecurityContext(package, buffer.ToArray(), !token.IsInvalid ? NtToken.FromHandle(token) : null, client));
            }
            finally
            {
                if (buffer.pvBuffer != IntPtr.Zero)
                {
                    SecurityNativeMethods.FreeContextBuffer(buffer.pvBuffer);
                }
            }
        }