Offensive and Defensive PowerShell - I

PowerShell is a powerful shell with so many features and abilities. It has been developed to facilitate system administrators’ work and their control over the system. As shown in Figure 1, PowerShell is one of the most used languages on GitHub. Such a strong and powerful language can be thought without taking attention of the offensive side. Thus, PowerShell is heavily used in recent cyber attacks. The attention of the offensive side and drastically increase in intensive powershell usage as resulted by getting attention and concentration of the defensive side.

Language Graph on GitHub

Language Graph on GitHub

This article is prepared to answer the following questions and give ideas for the audience. How to attack the systems by using PowerShell? How to bypass PowerShell security precautions? How to detect malicious usage of PowerShell? How to protect PowerShell environment?


PowerShell (PowerShell Core) is an advanced command line application developed by Microsoft as an alternative to Windows Command Prompt (cmd.exe) and Windows Script Host. Microsoft has improved PowerShell to simplify management tasks and solve problems quickly. It greatly simplifies the tasks of system administrators and allows system administrators to easily access and perform tasks through PowerShell on systems located in both local and remote environments. For example, a system administrator can do almost anything on Active Directory without ever using the graphical user interface simply by using PowerShell.

System administrators can customize their operations with PowerShell Scripts that they develop, or they can use the specific commands that come with the default Verb-Noun naming scheme called Cmdlet. PowerShell has full access to system functions. So by using using WMI and COM objects you can do almost anything over system administration, full access to the .NET Framework is also possible.

In the future, PowerShell will replace the traditional Command Prompt as being the default Windows terminal interface. After the release of PowerShell’s source code in 2016, PowerShell became available on Linux and Mac OS X operating systems as well. The first version (PowerShell v1.0) was released for Windows XP SP2, Windows Server 2003 and Windows Vista operating systems. However, In 2006 installation of PowerShell was required to use it in these operating systems. PowerShell has become available by default installation in all Windows operating systems after Vista and Server 2008.

The following table shows the PowerShell’s version which became by default installation and the supported version information.

Operating System Installled Version Supported Versions
7 2.0 2.0, 3.0, 4.0
Server 2008 R2 2.0 2.0, 3.0, 4.0
8 3.0 3.0
Server 2012 3.0 3.0, 4.0
8.1 4.0 4.0
Server 2012 R2 4.0 4.0
10 5.0 2.0, 3.0, 4.0
Server 2016 5.0 2.0, 3.0, 4.0


By default, Cmdlet’s (Command-Let) are specific commands and they have Verb-Noun naming patterns (eg Get-Service, GetProcess). They are different from normal commands because Cmdlets are .NET Framework Classes, not standalone executables.

Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

PS C:\Users\hlldz> Get-Process
Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
    232      13     3760      15864       0,09   1376   1 conhost
    228      12     3756      15344       0,55   3108   1 conhost
    227      13     3800      17480       0,06   4600   1 conhost
    232      12     3756      14796       0,48   4880   1 conhost
    388      12     1492       3588               580   0 csrss
    296      15     1556       3748               660   1 csrss

If you want to see what the Cmdlets are available in PowerShell or if you want to call any desired Cmdlets, you can accomplish that by executing the command “Get-Command” with “name of Cmdlet” as an argument. The following screenshot shows the use of command.

Get-Command Cmdlet

Get-Command Cmdlet


Pipeline is a set of data processing elements connected in series, where the output of one element is the input of the next one. PowerShell supports the pipelining. Hence, you can easily make changes to multiple items or a specific subset of thousands of items with a single line of code in PowerShell. And you can use these edited objects to collect data or perform actions on other related objects as well.




The Remoting feature comes with PowerShell v2 which allows system administrators to access and manage other systems from a central point through PowerShell. With PowerShell v3, the Remoting feature has been renewed and improved. This feature does not only cover Windows systems, it also covers Linux and Mac OS X operating systems. Once PowerShell has been open source, it has also become available for the relevant operating systems.

For instance, you want to access PowerShell on the remote system to run a command or any PowerShell script. One of the first things that comes to mind is that you can do Remote Desktop Connection (RDP), then access PowerShell via windows graphical user interface and reach your goal by typing the command. However with PowerShell Remoting feature accessing PowerShell on the remote system is as easy as running command on local PowerShell instance. This feature makes all the RDP activity trivial. To have Remoting abilities, Remoting feature must be enabled and allowed on the target system. Just like an SSH connection to remote systems, having access to terminal interface of remote system has never been easy as before.

Operating System Default Remoting State
7 Disable
Server 2008 R2 Disable
8 Disable
Windows Server 2012 Enable
8.1 Disable
Windows Server 2012 R2 Enable
10 Disable
Server 2016 Enable

PowerShell’s Remoting feature allows you to run scripts on remote systems. Many Cmdlets in PowerShell also have additional features such as working in remote systems and getting the results. Instead of providing this feature for each cmdlet, Microsoft has developed the Remoting feature so that all infrastructure can communicate over one secure protocol.

Enabling Remoting

The Enable-PSRemoting Cmdlet can be used to activate the remoting feature. When running the cmdlet with -Force parameter, Remoting service will be activated directly without any confirmation and the necessary settings will be made. When the cmdlet is used without the -Force parameter, confirmation will be prompt. It starts the WinRM service and sets it to run automatically at startup. Then It sets up the listener, and starts listening to connections from any IP addresses. It concludes the process with activating Firewall rules for the ports of Remoting feature.

How Remoting Feature Works?

In Figure 4 below, the infrastructure of the PowerShell Remoting feature has been tried to be schematized. In our scenario, we have two different systems thats are named as “Client 1” and “Client 2”. System named as “Client 1” wants to connect to the system named as “Client 2” system via PowerShell’s Remoting feature.

The Infrastructure of PowerShell Remoting Feature

The Infrastructure of PowerShell Remoting Feature

1- The system named as “Client 1”, communicates with its own WSMan (Web Services for Management) service. WSMan is an HTTP (S)-based protocol with the ability to encapsulate many other protocols. By default the remoting feature uses the HTTP protocol, however the connection can be encrypted easily by using the HTTPS protocol.

2- The system named as “Client 2”, the WinRM Service is running. This service can have one or more Listeners, and each Listener waits for WSMan traffic for a specific IP address and a specific port number from a specific protocol (HTTP or HTTPS). Listeners are created to identify the any received traffic by the WinRM service. We are talking about PowerShell here and a PowerShell session will start on the system of “Client 2”.

In Figure 4, the powershell.exe process seems to be starting in the system of Client 2, but this is done only for easy understanding. Under normal conditions, the process named wsmprovhost.exe will start, not powershell.exe.

Execution Policy

Execution Policy, are the policies that determine how it should work in which conditions for PowerShell. Execution Policy; can be set for the local system, any user or any PowerShell session. This can also be done via Group Policy for users or systems. The default Execution Policy levels in PowerShell are given in the following table.

Operating System Default Execution Policy Level
7 Restricted
Server 2008 R2 Restricted
8 Restricted
Windows Server 2012 Restricted
8.1 Restricted
Windows Server 2012 R2 Remote Signed
10 Restricted
Server 2016 Remote Signed

Execution Policy is not a security measure as it is known and can be easily overcome. It has been developed to prevent the damage they cause users run the script by accident.

Restricted is the most trusted policy because it allows only interactive PowerShell access. This means that you can only run commands individually. This policy is not concerned with where the scripts come from (via the local network or the internet), whether they are signed or not, and is not allowed to run any scripts.

AllSigned, in this policy, only scripts signed by trusted authorities on PowerShell are allowed. In addition, when a signed script is executed, confirmation is requested.

RemoteSigned can run scripts on the local system in this policy but must be signed by trusted authorities for scripts downloaded over the internet. Also, there is no need to get any confirmation while scripts are running.

Unrestricted, no restrictions; all Windows PowerShell scripts can be run. The warning will only be displayed if the script is downloaded from the internet.

Bypass, there is no restriction, no warning, or a confirmation mechanism in this policy. Every script can be run.

Undefined, no Execution Policy is assigned. If no Execution Policy is assigned for the specified scopes, the Restriced policy will be assigned by default.

The Get-ExecutionPolicy Cmdlet can be used to find the Execution Policy level in PowerShell. If you want to change the level of Execution Policy, in PowerShell session running on Administrator rights; The Set-ExecutionPolicy Cmdlet can be run.

At the same time, Execution Policy change without the need for any extra rights when starting a new PowerShell session -executionpolicy parameter is used. The value of the parameter can be set to whatever level is desired, the Execution Policy for the new PowerShell session to be started will be set as desired. The sample operation is shown in the following screen image.

Execution Policy

Execution Policy