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> /// 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)); } }
/// <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)); } }
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); } }
/// <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; } }