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