예제 #1
0
        static void cleanUp(bool terminate)
        {
            if (_thread != null)
            {
                _thread.Close();
                _thread = null;
            }

            if (_process != null)
            {
                if (terminate)
                {
                    _process.Terminate(NtStatus.DBG_CONTROL_C, false);
                }
                else
                {
                    _process.Close();
                }
                _process = null;
            }

            if (_waitHandle != IntPtr.Zero)
            {
                CloseHandle(_waitHandle);
                _waitHandle = IntPtr.Zero;
            }
        }
            public static ThreadDetails FromThread(NtThread thread)
            {
                string description = String.Empty;
                int    thread_id   = -1;

                if (thread.IsAccessGranted(ThreadAccessRights.QueryLimitedInformation))
                {
                    description = thread.Description;
                    thread_id   = thread.ThreadId;
                }
                else
                {
                    using (var dup_thread = thread.Duplicate(ThreadAccessRights.QueryLimitedInformation,
                                                             AttributeFlags.None, DuplicateObjectOptions.None, false))
                    {
                        if (dup_thread.IsSuccess)
                        {
                            description = dup_thread.Result.Description;
                            thread_id   = dup_thread.Result.ThreadId;
                        }
                    }
                }
                return(new ThreadDetails()
                {
                    Description = description,
                    ThreadId = thread_id
                });
            }
 internal Win32Process(PROCESS_INFORMATION proc_info)
 {
     Process = NtProcess.FromHandle(new SafeKernelObjectHandle(proc_info.hProcess, true));
     Thread  = NtThread.FromHandle(new SafeKernelObjectHandle(proc_info.hThread, true));
     Pid     = proc_info.dwProcessId;
     Tid     = proc_info.dwThreadId;
 }
        private void DoAccessCheck(IEnumerable <TokenEntry> tokens,
                                   ProcessDetails proc_details, NtThread thread, AccessMask access_rights)
        {
            var sd = thread.GetSecurityDescriptor(SecurityInformation.AllBasic, false);

            if (sd.IsSuccess)
            {
                foreach (TokenEntry token in tokens)
                {
                    CheckAccess(token, proc_details, ThreadDetails.FromThread(thread), _thread_type, access_rights, sd.Result);
                }
            }
            else
            {
                // Try and open process when under impersonation.
                foreach (TokenEntry token in tokens)
                {
                    using (var new_thread = token.Token.RunUnderImpersonate(() => NtThread.Open(thread.ThreadId, ThreadAccessRights.MaximumAllowed, false)))
                    {
                        if (new_thread.IsSuccess && IsAccessGranted(new_thread.Result.GrantedAccessMask, access_rights))
                        {
                            WriteAccessCheckResult(proc_details, ThreadDetails.FromThread(thread), new_thread.Result.GrantedAccessMask,
                                                   _thread_type.GenericMapping, String.Empty, token.Information);
                        }
                    }
                }
            }
        }
        internal override void RunAccessCheck(IEnumerable <TokenEntry> tokens)
        {
            AccessMask access_rights        = _process_type.MapGenericRights(AccessRights);
            AccessMask thread_access_rights = _thread_type.MapGenericRights(ThreadAccessRights);

            if (!NtToken.EnableDebugPrivilege())
            {
                WriteWarning("Current process doesn't have SeDebugPrivilege, results may be inaccurate");
            }

            if (CheckProcess())
            {
                using (var procs = NtProcess.GetProcesses(ProcessAccessRights.MaximumAllowed, false).ToDisposableList())
                {
                    DoAccessCheck(tokens, procs.Where(p => ShowDeadProcesses || !p.IsDeleting), access_rights, thread_access_rights);
                }
            }
            else
            {
                using (var threads = NtThread.GetThreads(ThreadAccessRights.MaximumAllowed, true).ToDisposableList())
                {
                    foreach (var thread in threads)
                    {
                        DoAccessCheck(tokens, ProcessDetails.FromThread(thread), thread, thread_access_rights);
                    }
                }
            }
        }
        /// <summary>
        /// Method to create an object from a set of object attributes.
        /// </summary>
        /// <param name="obj_attributes">The object attributes to create/open from.</param>
        /// <returns>The newly created object.</returns>
        protected override object CreateObject(ObjectAttributes obj_attributes)
        {
            NtProcess process = Process ?? NtProcess.Current;

            return(NtThread.Create(obj_attributes, Access, process, StartRoutine.ToInt64(), Argument.ToInt64(),
                                   CreateFlags, ZeroBits.ToInt64(), StackSize.ToInt64(), MaximumStackSize.ToInt64(), null));
        }
예제 #7
0
 /// <summary>
 /// Overridden ProcessRecord method.
 /// </summary>
 protected override void ProcessRecord()
 {
     if (ThreadId == -1 && ProcessId == -1)
     {
         IEnumerable <NtThread> threads = NtThread.GetThreads(Access);
         if (FilterScript == null)
         {
             WriteObject(threads);
         }
         else
         {
             using (var ths = new DisposableList <NtThread>(threads))
             {
                 WriteObject(ths.Where(t => ArbitraryFilter(t, FilterScript)).Select(t => t.Duplicate()).ToArray());
             }
         }
     }
     else if (ProcessId != -1)
     {
         using (NtProcess process = NtProcess.Open(ProcessId, ProcessAccessRights.MaximumAllowed))
         {
             WriteObject(process.GetThreads());
         }
     }
     else
     {
         WriteObject(NtThread.Open(ThreadId, Access));
     }
 }
        private NtToken GetEffectiveToken(TokenAccessRights desired_access)
        {
            if (Pseduo)
            {
                return(NtToken.PseudoEffectiveToken);
            }
            NtToken token = GetImpersonationToken(desired_access);

            if (token != null)
            {
                return(token);
            }

            if (Thread == null && !ThreadId.HasValue)
            {
                return(NtToken.OpenProcessToken(NtProcess.Current, false, desired_access));
            }

            int pid;

            if (Thread != null)
            {
                pid = Thread.ProcessId;
            }
            else
            {
                using (NtThread thread = NtThread.Open(ThreadId.Value, ThreadAccessRights.QueryLimitedInformation))
                {
                    pid = thread.ProcessId;
                }
            }

            return(NtToken.OpenProcessToken(pid, false, desired_access));
        }
예제 #9
0
 private NtThread GetThread()
 {
     if (ParameterSetName == "Thread")
     {
         return(Thread.Duplicate(ThreadAccessRights.Impersonate));
     }
     return(NtThread.Open(ThreadId, ThreadAccessRights.Impersonate));
 }
 internal Win32Process(PROCESS_INFORMATION proc_info, bool terminate_on_dispose)
 {
     Process            = NtProcess.FromHandle(new SafeKernelObjectHandle(proc_info.hProcess, true));
     Thread             = NtThread.FromHandle(new SafeKernelObjectHandle(proc_info.hThread, true));
     Pid                = proc_info.dwProcessId;
     Tid                = proc_info.dwThreadId;
     TerminateOnDispose = terminate_on_dispose;
 }
 static void CallMethod(NtProcess proc, IntPtr entry_point, IntPtr arg_ptr)
 {
     using (var load_thread = NtThread.FromHandle(CreateRemoteThread(proc.Handle,
                                                                     IntPtr.Zero, IntPtr.Zero, entry_point, arg_ptr, 0, null)))
     {
         load_thread.Wait();
     }
 }
예제 #12
0
        public static bool StartProcessAsCurrentUser(string appPath, NtJob job)
        {
            var hUserToken = IntPtr.Zero;
            var startInfo  = new STARTUPINFO();
            var procInfo   = new PROCESS_INFORMATION();
            var pEnv       = IntPtr.Zero;
            int iResultOfCreateProcessAsUser;

            startInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO));

            try {
                if (!GetSessionUserToken(out hUserToken))
                {
                    throw new Exception("StartProcessAsCurrentUser: GetSessionUserToken failed.");
                }

                uint dwCreationFlags = CREATE_UNICODE_ENVIRONMENT | CREATE_SUSPENDED | CREATE_NEW_CONSOLE;
                startInfo.wShowWindow = (short)(SW.SW_SHOW);
                startInfo.lpDesktop   = @"winsta0\default";

                if (!CreateEnvironmentBlock(ref pEnv, hUserToken, false))
                {
                    throw new Exception("StartProcessAsCurrentUser: CreateEnvironmentBlock failed.");
                }

                if (!CreateProcessAsUser(hUserToken,
                                         appPath, // Application Name
                                         null,
                                         IntPtr.Zero,
                                         IntPtr.Zero,
                                         false,
                                         dwCreationFlags,
                                         pEnv,
                                         null,
                                         ref startInfo,
                                         out procInfo))
                {
                    iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error();
                    throw new Exception("StartProcessAsCurrentUser: CreateProcessAsUser failed.  Error Code -" + iResultOfCreateProcessAsUser);
                }

                job.AssignProcess(NtProcess.FromHandle(procInfo.hProcess));
                NtThread.FromHandle(procInfo.hThread).Resume();

                iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error();
            } finally {
                CloseHandle(hUserToken);
                if (pEnv != IntPtr.Zero)
                {
                    DestroyEnvironmentBlock(pEnv);
                }
                CloseHandle(procInfo.hThread);
                CloseHandle(procInfo.hProcess);
            }

            return(true);
        }
 public static ProcessDetails FromThread(NtThread thread)
 {
     return(new ProcessDetails()
     {
         Name = thread.ProcessName,
         ImagePath = String.Empty,
         CommandLine = String.Empty,
         ProcessId = thread.ProcessId
     });
 }
 private static NtToken GetProcessToken(NtThread thread)
 {
     try
     {
         return(NtToken.OpenProcessToken(thread.ProcessId));
     }
     catch (NtException)
     {
         return(null);
     }
 }
 private static NtToken GetToken(NtThread thread)
 {
     try
     {
         return(thread.OpenToken());
     }
     catch (NtException)
     {
         return(null);
     }
 }
 private void openProcessTokenToolStripMenuItem_Click(object sender, EventArgs e)
 {
     if (listViewThreads.SelectedItems.Count > 0)
     {
         NtThread thread = listViewThreads.SelectedItems[0].Tag as NtThread;
         if (thread != null)
         {
             TokenForm.OpenForm(GetProcessToken(thread), false);
         }
     }
 }
예제 #17
0
 public ThreadEntry(NtThread handle)
 {
     Handle = handle;
     Tid    = handle.ThreadId;
     try
     {
         Token = handle.OpenToken();
     }
     catch
     {
     }
 }
 private void toolStripMenuItemOpenThreadToken_Click(object sender, EventArgs e)
 {
     if (listViewThreads.SelectedItems.Count > 0)
     {
         NtThread thread = listViewThreads.SelectedItems[0].Tag as NtThread;
         if (thread != null)
         {
             NtToken token = GetToken(thread);
             if (token != null)
             {
                 TokenForm.OpenForm(token, false);
             }
         }
     }
 }
예제 #19
0
        private static bool ArbitraryFilter(NtThread thread, ScriptBlock filter)
        {
            try
            {
                ICollection <PSObject> os = filter.Invoke(thread);
                if (os.Count == 1)
                {
                    return((bool)os.First().BaseObject);
                }
            }
            catch
            {
            }

            return(false);
        }
예제 #20
0
 /// <summary>
 /// Overridden ProcessRecord method.
 /// </summary>
 protected override void ProcessRecord()
 {
     if (InfoOnly)
     {
         if (ProcessId != -1)
         {
             WriteObject(QueryThreadInformation(ProcessId), true);
         }
         else
         {
             WriteObject(QueryThreadInformation(), true);
         }
     }
     else if (Current)
     {
         WriteObject(GetCurrentThread(Access, PseudoHandle));
     }
     else if (ThreadId == -1 && ProcessId == -1)
     {
         IEnumerable <NtThread> threads = NtThread.GetThreads(Access, FromSystem);
         if (FilterScript == null)
         {
             WriteObject(threads, true);
         }
         else
         {
             using (var ths = new DisposableList <NtThread>(threads))
             {
                 WriteObject(ths.Where(t => ArbitraryFilter(t, FilterScript)).Select(t => t.Duplicate()).ToArray(), true);
             }
         }
     }
     else if (ProcessId != -1)
     {
         using (NtProcess process = NtProcess.Open(ProcessId, ProcessAccessRights.MaximumAllowed))
         {
             WriteObject(process.GetThreads(), true);
         }
     }
     else
     {
         WriteObject(NtThread.Open(ThreadId, Access));
     }
 }
예제 #21
0
        static NtProcess LaunchAdminProcess(string executable, string cmdline, StartFlags flags, CreateProcessFlags create_flags, string desktop)
        {
            StartAppinfoService();

            using (Client client = new Client())
            {
                client.Connect();
                create_flags |= CreateProcessFlags.UnicodeEnvironment;
                Struct_0 start_info = new Struct_0();
                int      retval     = client.RAiLaunchAdminProcess(executable, cmdline, (int)flags, (int)create_flags,
                                                                   @"c:\windows", desktop, start_info, new NdrUInt3264(GetDesktopWindow()),
                                                                   -1, out Struct_2 proc_info, out int elev_type);
                if (retval != 0)
                {
                    throw new Win32Exception(retval);
                }

                using (var thread = NtThread.FromHandle(new IntPtr(proc_info.Member8.Value)))
                {
                    return(NtProcess.FromHandle(new IntPtr(proc_info.Member0.Value)));
                }
            }
        }
예제 #22
0
        /// <summary>
        /// Overridden ProcessRecord method.
        /// </summary>
        protected override void ProcessRecord()
        {
            switch (ParameterSetName)
            {
            case "infoonly":
            {
                if (ProcessId != -1)
                {
                    WriteObject(QueryThreadInformation(ProcessId), true);
                }
                else
                {
                    WriteObject(QueryThreadInformation(), true);
                }
            }
            break;

            case "current":
                WriteObject(GetCurrentThread(Access, PseudoHandle));
                break;

            case "all":
            {
                IEnumerable <NtThread> threads = NtThread.GetThreads(Access, FromSystem);
                if (FilterScript == null && First <= 0)
                {
                    WriteObject(threads, true);
                }
                else
                {
                    using (var ths = new DisposableList <NtThread>(threads))
                    {
                        threads = ths;
                        if (FilterScript != null)
                        {
                            threads = threads.Where(t => ArbitraryFilter(t, FilterScript));
                        }
                        if (First > 0)
                        {
                            threads = threads.Take(First);
                        }

                        WriteObject(threads.Select(t => t.Duplicate()).ToArray(), true);
                    }
                }
            }
            break;

            case "pid":
            {
                using (NtProcess process = NtProcess.Open(ProcessId, ProcessAccessRights.MaximumAllowed))
                {
                    WriteObject(process.GetThreads(), true);
                }
            }
            break;

            case "tid":
            {
                if (ProcessId != -1)
                {
                    WriteObject(NtThread.Open(ProcessId, ThreadId, Access));
                }
                else
                {
                    WriteObject(NtThread.Open(ThreadId, Access));
                }
            }
            break;

            case "next":
                WriteObject(NextThread?.GetNextThread(Process, Access) ?? Process.GetFirstThread(Access));
                break;
            }
        }
 private static NtToken GetToken(NtThread thread)
 {
     try
     {
         return thread.OpenToken();
     }
     catch (NtException)
     {
         return null;
     }
 }
예제 #24
0
        static void Main(string[] args)
        {
            bool show_help = false;

            _pid = Process.GetCurrentProcess().Id;

            try
            {
                OptionSet opts = new OptionSet()
                {
                    { "p|pid=", "Specify a PID of a process to impersonate when checking", v => _pid = int.Parse(v.Trim()) },
                    { "n", "Specifes the list of arguments represents names instead of pids", v => _named_process = v != null },
                    { "i", "Use an indentify level token when impersonating", v => _identify_only = v != null },
                    { "t", "Dump accessible threads for process", v => _dump_threads = v != null },
                    { "k", "Dump tokens for accessible objects", v => _dump_token = v != null },
                    { "a", "Start with all accessible threads instead of processes", v => _dump_threads = _all_threads = v != null },
                    { "sddl", "Dump SDDL strings for objects", v => _print_sddl = v != null },
                    { "h|help", "show this message and exit",
                      v => show_help = v != null },
                };

                List <string> pids = opts.Parse(args).Select(s => s.ToLower()).ToList();

                if (show_help)
                {
                    ShowHelp(opts);
                }
                else
                {
                    IEnumerable <ProcessEntry> processes = new ProcessEntry[0];

                    if (_all_threads)
                    {
                        NtThread[] all_threads = null;

                        using (var imp = NtToken.Impersonate(_pid,
                                                             _identify_only ? SecurityImpersonationLevel.Identification : SecurityImpersonationLevel.Impersonation))
                        {
                            if (pids.Count > 0)
                            {
                                List <NtThread> ths = new List <NtThread>();
                                foreach (string pid_name in pids)
                                {
                                    try
                                    {
                                        ths.Add(NtThread.Open(int.Parse(pid_name), ThreadAccessRights.MaximumAllowed));
                                    }
                                    catch (NtException ex)
                                    {
                                        Console.WriteLine("Error opening tid {0} - {1}", pid_name, ex.Message);
                                    }
                                }

                                all_threads = ths.ToArray();
                            }
                            else
                            {
                                all_threads = NtThread.GetThreads(ThreadAccessRights.MaximumAllowed).ToArray();
                            }

                            List <ProcessEntry> procs = new List <ProcessEntry>();

                            foreach (var group in all_threads.GroupBy(t => t.ProcessId))
                            {
                                ProcessEntry entry   = null;
                                NtThread[]   threads = group.ToArray();
                                try
                                {
                                    entry = new ProcessEntry(NtProcess.Open(group.Key, ProcessAccessRights.MaximumAllowed), threads);
                                }
                                catch (NtException)
                                {
                                    entry = new ProcessEntry(group.Key, threads);
                                }
                                procs.Add(entry);
                            }
                            processes = procs;
                        }
                    }
                    else
                    {
                        if (pids.Count > 0 && !_named_process)
                        {
                            List <ProcessEntry> procs = new List <ProcessEntry>();
                            using (var imp = NtToken.Impersonate(_pid,
                                                                 _identify_only ? SecurityImpersonationLevel.Identification : SecurityImpersonationLevel.Impersonation))
                            {
                                foreach (string pid_name in pids)
                                {
                                    try
                                    {
                                        procs.Add(new ProcessEntry(NtProcess.Open(int.Parse(pid_name), ProcessAccessRights.MaximumAllowed)));
                                    }
                                    catch (NtException ex)
                                    {
                                        Console.WriteLine("Error opening pid {0} - {1}", pid_name, ex.Message);
                                    }
                                }
                            }

                            processes = procs;
                        }
                        else
                        {
                            try
                            {
                                using (var imp = NtToken.Impersonate(_pid,
                                                                     _identify_only ? SecurityImpersonationLevel.Identification : SecurityImpersonationLevel.Impersonation))
                                {
                                    processes = NtProcess.GetProcesses(ProcessAccessRights.MaximumAllowed).Select(h => new ProcessEntry(h));
                                }

                                if (_named_process && pids.Count > 0)
                                {
                                    processes = processes.Where(p => pids.Contains(p.Name.ToLower()));
                                }
                            }
                            catch (NtException ex)
                            {
                                Console.WriteLine(ex);
                            }
                        }
                    }

                    List <ProcessEntry> ps = processes.ToList();

                    ps.Sort((a, b) => a.Pid - b.Pid);

                    processes = ps;

                    foreach (ProcessEntry process in processes)
                    {
                        Console.WriteLine("{0}: {1} {2}", process.Pid, process.Name, process.GetGrantedAccessString());
                        if (_print_sddl && process.Handle.IsAccessGranted(ProcessAccessRights.ReadControl))
                        {
                            Console.WriteLine("SDDL: {0}", process.Handle.GetSddl());
                        }

                        if (_dump_token && process.Token != null)
                        {
                            Console.WriteLine("User: {0}", process.Token.User);
                            if (_print_sddl && process.Token.IsAccessGranted(TokenAccessRights.ReadControl))
                            {
                                Console.WriteLine("Token SDDL: {0}", process.Token.GetSddl());
                            }
                        }

                        if (_dump_threads)
                        {
                            foreach (ThreadEntry thread in process.Threads)
                            {
                                Console.WriteLine("-- Thread {0}: {1}", thread.Tid, thread.Handle.GetGrantedAccessString());
                                if (_print_sddl && thread.Handle.IsAccessGranted(ThreadAccessRights.ReadControl))
                                {
                                    Console.WriteLine("---- SDDL: {0}", thread.Handle.GetSddl());
                                }

                                if (_dump_token && thread.Token != null)
                                {
                                    Console.WriteLine("---- Impersonating {0}", thread.Token.User);
                                    if (_print_sddl && thread.Token.IsAccessGranted(TokenAccessRights.ReadControl))
                                    {
                                        Console.WriteLine("---- Token SDDL: {0}", thread.Token.GetSddl());
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
 private static NtToken GetProcessToken(NtThread thread)
 {
     try
     {
         return NtToken.OpenProcessToken(thread.ProcessId);
     }
     catch (NtException)
     {
         return null;
     }
 }
예제 #26
0
 private static bool ArbitraryFilter(NtThread thread, ScriptBlock filter)
 {
     return(filter.InvokeWithArg(false, thread));
 }
        private static bool ArbitraryFilter(NtThread thread, ScriptBlock filter)
        {
            try
            {
                ICollection<PSObject> os = filter.Invoke(thread);
                if (os.Count == 1)
                {
                    return (bool)os.First().BaseObject;
                }
            }
            catch
            {
            }

            return false;
        }
 internal CreateUserProcessResult(SafeKernelObjectHandle process_handle, SafeKernelObjectHandle thread_handle,
   ProcessCreateInfoData create_info,
   SectionImageInformation image_info, ClientId client_id)
 {
     Process = new NtProcess(process_handle);
     Thread = new NtThread(thread_handle);
     ImageFile = new NtFile(new SafeKernelObjectHandle(create_info.Success.FileHandle, true));
     SectionHandle = new NtSection(new SafeKernelObjectHandle(create_info.Success.SectionHandle, true));
     ImageInfo = image_info;
     ClientId = client_id;
     CreateInfo = create_info;
     CreateState = ProcessCreateState.Success;
 }
예제 #29
0
        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.ProcessExit += AppDomain_ProcessExit;
            using (var textWriter = new StreamWriter(@"D:\test.txt"))
            {
                foreach (var arg in args)
                {
                    textWriter.WriteLine(arg);
                }
            }

            try
            {
                if (args[0] == "-p")
                {
                    _process    = NtProcess.Open(int.Parse(args[1]), ProcessAccessRights.MaximumAllowed);
                    _waitHandle = new IntPtr(long.Parse(args[3]));
                }
                else
                {
                    var config = new NtProcessCreateConfig();
                    config.InitFlags   |= ProcessCreateInitFlag.IFEOSkipDebugger;
                    config.ThreadFlags |= ThreadCreateFlags.Suspended;
                    var path = NtFileUtils.DosFileNameToNt(args[0]);
                    config.ConfigImagePath = path;
                    var result = NtProcess.Create(config);
                    _process = result.Process;
                    _thread  = result.Thread;
                }

                while (true)
                {
                    bool beingDebugged;
                    if (_process.Wow64)
                    {
                        PartialPeb32 peb = (PartialPeb32)_process.GetPeb();
                        beingDebugged = peb.BeingDebugged == 1;
                    }
                    else
                    {
                        PartialPeb peb = (PartialPeb)_process.GetPeb();
                        beingDebugged = peb.BeingDebugged == 1;
                    }

                    if (beingDebugged)
                    {
                        break;
                    }

                    Thread.Sleep(100);
                }

                if (_thread != null)
                {
                    _thread.Resume();
                }

                if (_waitHandle != IntPtr.Zero)
                {
                    SetEvent(_waitHandle);
                }
            }
            finally
            {
                cleanUp(false);
            }
        }