INE PowerShell for Pentesters Course File
INE PowerShell for Pentesters Course File
Course Introduction
Alexis Ahmed
Senior Penetration Tester @HackerSploit
Offensive Security Instructor @INE
aahmed@ine.com
@HackerSploit
@alexisahmed
Course
Topic
Overview
+ Introduction To PowerShell
+ PowerShell Fundamentals
+ PowerShell Scripting
+ Leveraging PowerShell For Exploitation & Post-
Exploitation
+ AV Evasion & Obfuscation With PowerShell
+ Basic familiarity with
TCP & UDP
Prerequisites
+ Basic familiarity with
Windows
Learning
Objectives: + Students will get an introduction to PowerShell
+ Students will have an understanding of the inner workings of
PowerShell and the various components that make up the
language
+ Students will be able to write their own PowerShell scripts
for automation
+ Students will be able to utilize PowerShell for exploitation &
post-exploitation
+ Students will be able to utilize PowerShell for AV Evasion &
Obfuscation
Let’s Get Started!
Introduction To PowerShell
1.2 What IS Powershell?
+ Powershell is a powerful built-in Command Line
Interpreter or “shell,” and task-oriented scripting
language environment found on most current
Windows Operating Systems starting with Windows
7, and through to Windows 2008 R2 and onward.
https://en.wikipedia.org/wiki/PowerShell
https://en.wikipedia.org/wiki/Command-line_interface#Command-
line_interpreter
1.2 What IS Powershell?
+ Powershell is typically used by administrators as it
provides great functionality and flexibility in regard to
managing Windows systems and automating tasks,
which is mostly the reason why it’s the perfect tool
when it comes to our process as penetration testers.
+ Powershell is tightly integrated with the .NET
framework (built on top of it actually).
https://en.wikipedia.org/wiki/.NET_Framework
1.2 What IS Powershell?
+ It also provides convenient access to the .NET
Framework API, Component Object Model (COM) and
Windows Management Instrumentation (WMI), which
is another plus in regard to persistence methods and
ways we can gather information as we’ll see later.
https://en.wikipedia.org/wiki/Component_Object_Model
https://en.wikipedia.org/wiki/Windows_Management_Instrumentation
1.2 What IS Powershell?
+ Most of the time, we’ll either be working with scripts
commonly identified by the “.ps1” file extension, or
through what are known as “Cmdlets” (native Powershell
commands) of which we can also create our own, and other
times, we’ll be interacting directly with via the Powershell
CLI.
https://docs.microsoft.com/en-us/powershell/scripting/developer/cmdlet/cmdlet-overview?view=powershell-7
1.2 What IS Powershell?
+ An important point to note as we navigate through the
upcoming topics is that more recent versions of Powershell,
specifically 5.0 and onward, introduce some potential
hurdles in regard to detection, logging and more restrictive
modes, which we will cover workarounds for briefly.
https://blogs.msdn.microsoft.com/powershell/2018/01/10/powershell-core-6-0-generally-available-ga-and-supported/
References
+ Cmdlet Overview: https://docs.microsoft.com/en-
us/powershell/scripting/developer/cmdlet/cmdlet-
overview?view=powershell-7
+ Command-line Interpreter: https://en.wikipedia.org/wiki/Command-
line_interface#Command-line_interpreter
+ Component Object Model (COM):
https://en.wikipedia.org/wiki/Component_Object_Model
+ Investigating PowerShell: Command and Script Logging:
https://www.crowdstrike.com/blog/investigating-powershell-command-
and-script-logging/
References
+ .NET Framework: https://en.wikipedia.org/wiki/.NET_Framework
+ PowerShell: https://github.com/powershell/powershell
+ PowerShell Constrained Language Mode:
https://blogs.msdn.microsoft.com/powershell/2017/11/02/powershell-
constrained-language-mode/
+ PowerShell Core 6.0: Generally Available (GA) and Supported!:
https://blogs.msdn.microsoft.com/powershell/2018/01/10/powershell-
core-6-0-generally-available-ga-and-supported/
+ PowerShell Wiki: https://en.wikipedia.org/wiki/PowerShell
+ PowerShell Versions: https://en.wikipedia.org/wiki/PowerShell#Versions
References
+ Windows Management Instrumentation (WMI):
https://en.wikipedia.org/wiki/Windows_Management_Instrumentation
Why Powershell?
1.1 Why Powershell?
+ Powershell is a powerful built-in shell and scripting
environment we can utilize as penetration testers
considering its wide-spread availability on all modern
Windows-based systems.
+ The use of Powershell allows us to take advantage of
the “living-off-the-land” concept, where using tools
that are built-in to the Operating System work to our
advantage once we’ve obtained access to a system.
https://en.wikipedia.org/wiki/PowerShell
https://www.secureworks.com/blog/living-off-the-land
1.1 Why Powershell?
There are many advantages to using Powershell as it relates to
penetration testing, with some of them being:
+ Many organizations aren’t actively hunting for Powershell activity
since it is usually considered a “trusted” application.
+ We can use Powershell to run, download or execute code, entirely
within the memory process of the Powershell executable, helping
us evade endpoint security solutions.
+ We can use it to interface with the .NET and other Windows APIs.
1.1 Why Powershell?
Advantages (continued):
+ We can call Windows DLL functions from within
Powershell.
+ We can use it to bypass application whitelisting
implementations by running the usual operating system
commands from the Powershell CLI.
+ Many tools are already available to us for a large number of
purposes related to penetration testing.
https://github.com/PowerShellMafia/PowerSpl
oit
1.1 Why Powershell?
+ Having access to all of those things through
Powershell helps us reduce our footprint and evade
defense mechanisms while conducting post-
exploitation tasks.
+ Powershell is also easy to use, and there are many
scripts and frameworks written that we can utilize for
our offensive purposes.
1.1 Why Powershell?
+ Furthermore, it doesn’t take much to create our own
scripts to carry out some of our tasks as we’ll see in
the modules that follow.
References
+ Living Off the Land:
https://www.secureworks.com/blog/living-off-the-land
+ PowerShell: https://en.wikipedia.org/wiki/PowerShell
+ PowerSploit:
https://github.com/PowerShellMafia/PowerSploit
The PowerShell CLI
2.1 The PowerShell CLI
+ For our first task, we should become familiar with the
PowerShell Command Line Interface (CLI).
+ The PowerShell CLI provides us with access to built-in
cmdlets, modules, functions, features, and provides a
way to create tasks, functions, variables interactively,
and more, directly from the CLI.
http://radar.oreilly.com/2013/06/powershell-command-line-
introduction.html
2.1 The PowerShell CLI
-ExecutionPolicy
+ The PowerShell execution policy determines which scripts if any,
we can run and can easily be disabled with the “Bypass” or
“Unrestricted” arguments.
C:\> powershell.exe -ExecutionPolicy Bypass .\script.ps1
https://docs.microsoft.com/en-
us/powershell/module/microsoft.powershell.core/about/about_script_blocks?view=powershell-6
2.1.1 Basic Usage
-EncodedCommand:
+ The -EncodedCommand parameter is used to execute
base64 encoded scripts or commands.
https://docs.microsoft.com/en-us/powershell/scripting/developer/cmdlet/cmdlet-overview?view=powershell-7
2.2 Cmdlets
+ Next, we’ll cover some of the ways we can leverage
other useful cmdlets for our purposes.
2.2 Cmdlets
Let’s first generally summarize what cmdlets are:
+ Light-weight PowerShell scripts that perform a single
function (Can be as small as a few lines of code).
+ Instances of .NET Framework classes derived from the
Cmdlet Base Class and provide access to system
functions.
+ Cmdlets are native commands in PowerShell (We can
also create our own).
https://msdn.microsoft.com/en-us/library/gg145045(v=vs.110).aspx
https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.cmdlet?redirectedfrom=MSDN&view=powershellsdk-1.1.0
2.2 Cmdlets
cmdlets summarization continued:
+ Typically written in a “Verb-Noun” file name format
which helps us determine their function (e.g., Invoke-
Command).
+ Typically used to return output to other Cmdlets to be
then processed via a pipeline (|).
https://www.petri.com/understanding-the-powershell-
pipeline
2.2 Cmdlets
+ Every cmdlet has its own set of parameters which can
be discovered through the Get-Help cmdlet as we’ve
seen previously.
IMPORTANT:
+ It should be noted that most cmdlets, by default, when
run without other parameters will return a limited set
of information or “Columns.”
2.2 Cmdlets
+ For example, just running the “Get-ChildItem” cmdlet
without any other arguments or options, returns four
columns named “Mode,” “LastWriteTime,” “Length”
and “Name”.
2.2 Cmdlets
+ But by piping the output of
a cmdlet to the “Format- PS C:\> Get-ChildItem | Format-List *
https://technet.microsoft.com/en-
us/library/hh750381.aspx
2.2 Cmdlets
+ These names whether in list format or the default
column format are important, as we can use those to
filter the output of cmdlet objects for specific
properties, as we’ll see shortly.
2.2.1 Pipelining
+ The results of all cmdlet output, are usually referred to
as “objects.”
+ These objects can be further processed using what is
known as “pipelining,” similar to how we can chain
commands together in a Linux bash shell for instance
with the Pipe Operator (|).
https://www.petri.com/understanding-the-powershell-
pipeline
2.2.1 Pipelining
+ An example of this processing of cmdlet output objects
with pipelines would be something like the following:
https://github.com/rebootuser/LinEnu
2.2.2.1 Get-Process
+ We can also append multiple property names to the
Format-List cmdlet, and obtain the processes Paths,
and associated PID’s (Id) for instance:
PS C:\> Get-Process chrome, firefox | Sort-Object -Unique | Format-List Path,Id
https://github.com/rebootuser/LinEnu
2.2.2.2 Get-ChildItem
+ Something that’s good to know about cmdlets is that most of them have
“Aliases.” For instance, the “Get-ChildItem” cmdlet which simply lists items
in a directory, can be alternatively called by issuing the “ls” command, which
is an alias for the Get-ChildItem cmdlet.
+ We would get the same exact results by simply just running “Get-ChildItem.”
2.2.2.2 Get-ChildItem
+ To find what the aliases are for a specific cmdlet, we can use the
“Get-Alias” cmdlet with the “-Definition” parameter followed by
a cmdlet name, like in the following example:
PS C:\Users> Get-Alias -Definition Get-ChildItem
+ We will learn more about how we can use the “ForEach-Object” cmdlet a bit later for certain
tasks.
2.2.2.8 Get-Service
+ The “Get-Service” cmdlet will get us information regarding
currently installed services and can be useful in the case we can
identify a service which might be vulnerable to a privilege
escalation exploit.
2.2.2.8 Get-Service
+ Running it without parameters or arguments simply returns
a three column list of all services.
PS C:\> Get-Service
2.2.2.8 Get-Service
+ We can extend those results, as we’ve seen before, with the
“Sort-Object” cmdlet. In this example, all services starting with
“s*” in descending order and sorting by the “Status” property.
PS C:\> Get-Service “s*” | Sort-Object Status -Descending
Cmdlets Conclusion
+ As we can see, there are many ways and variations of using
cmdlets, pipelines and aliases we can leverage to conduct tasks
that are relevant to our objectives, and different ways to craft
commands we can use to achieve similar results.
References
+ Cmdlet Class: https://msdn.microsoft.com/en-
us/library/system.management.automation.cmdlet(v=vs.85).aspx
+ Cmdlets: https://docs.microsoft.com/en-
us/powershell/scripting/developer/cmdlet/cmdlet-
overview?view=powershell-7
+ LinEnum: https://github.com/rebootuser/LinEnum
+ .NET Framework Class Library: https://msdn.microsoft.com/en-
us/library/gg145045(v=vs.110).aspx
+ Understanding the PowerShell Pipeline:
https://www.petri.com/understanding-the-powershell-pipeline
References
+ Windows PowerShell: The Many Ways to a Custom Object:
https://technet.microsoft.com/en-us/library/hh750381.aspx
PowerShell Modules
2.3 Modules
+ A module, in simplest terms, is a set of PowerShell
functionalities grouped together in the form of a single file
that will typically have a “.psm1” file extension.
+ Modules are typically comprised of several components.
+ However, not all components are necessary for the
functionality of a module.
https://docs.microsoft.com/en-us/powershell/scripting/developer/module/writing-a-windows-powershell-module?view=powershell-7
2.3 Modules
The components that can make up a typical module are:
+ Any number of powershell scripts (.ps1) or other code files,
such as a managed cmdlet assembly.
+ Additional Assemblies, Help files, or scripts.
+ A module manifest file.
+ A directory which is used to contain all of the above.
https://docs.microsoft.com/en-us/powershell/scripting/developer/module/how-to-write-a-powershell-module-manifest?view=powershell-7
2.3 Modules
There are also several different types of modules:
+ Script Modules (We’ll be working with these for the most
part)
+ Binary Modules
+ Manifest Modules
+ Dynamic Modules (Created dynamically by scripts using the
“New-Module” cmdlet)
https://docs.microsoft.com/en-us/powershell/scripting/developer/module/how-to-write-a-powershell-script-module?view=powershell-7
https://docs.microsoft.com/en-us/powershell/scripting/developer/module/how-to-write-a-powershell-binary-module?view=powershell-7
https://docs.microsoft.com/en-us/powershell/scripting/developer/module/how-to-write-a-powershell-module-manifest?view=powershell-7
https://msdn.microsoft.com/en-us/library/dd878337(v=vs.85).aspx
2.3.1 Get-Module
+ Modules are typically “imported” into the current
PowerShell session. To obtain a list of all currently
imported modules, we can use the “Get-Module” cmdlet. In
the example below, we can see all of the currently
imported modules for the current PowerShell session.
PS C:\> Get-Module
2.3.1 Get-Module
+ We can also list all modules available to us for importing with
the “-ListAvailable” parameter, which returns a long list of
available modules.
PS C:\> Get-Module -ListAvailable
2.3.1 Get-Module
PS C:\> Get-Module -ListAvailable
2.3.2 Import-Module
+ As we’ve mentioned, modules that we want to use,
will first need to be imported into our current
PowerShell session. This, can be done with the
“Import-Module” cmdlet, as follows:
PS C:\> Import-Module .\module.psm1
https://github.com/rebootuser/LinEnu
m
2.3.2 Import-Module
+ Once we import a PowerShell module, all of its various
cmdlets and other components become available to us, and
we can simply then execute the cmdlets that are part of the
module.
+ As an example, let’s take a quick look at the popular
PowerShell exploitation framework “PowerSploit”, and
how we would go about importing all of its functionality
into our current PowerShell session.
https://github.com/PowerShellMafia/PowerSploit
2.3.2 Import-Module
+ Its usage and installation is straightforward, and we
should be able to get it up and running in just a few
steps.
2.3.2 Import-Module
+ First, we download the PowerSploit package to our
local machine from the following location:
https://github.com/PowerShellMafia/PowerSploit/archi
ve/master.zip
2.3.2 Import-Module
+ The PowerSploit modules will need to be copied into one of the
module paths specified by the “$Env:PSModulePath” PowerShell
environment variable. To find these paths, simply type the above
into your PowerShell Console:
PS C:\> $Env:PSModulePath
+ For our purposes, we’ll use the local user's module path, which is
in:
C:\users\user\Documents\WindowsPowerShell\Modules
2.3.2 Import-Module
+ We’ll need to then create a “PowerSploit” folder in our
chosen Modules directory, where we will copy all of
the contents of the PowerSploit archive into.
2.3.2 Import-Module
Important note on PowerSploit and Antivirus:
+ Many exploitation frameworks, will be detected as “hacking
tools” and other signatures by a number of Antivirus solutions.
This is somewhat “normal”, it’s Antivirus just doing its job, in this
case, at detecting strings within the powershell scripts as being
malicious, or flagging on names of modules, etc. Either way, you
can create an exclude directory for your AV software for the
purpose of this lesson and download the modules into that
directory for now.
2.3.2 Import-Module
+ Once we’ve downloaded the PowerSploit archive,
extracted it and copied all of its contents into our
chosen module directory into a folder called
“PowerSploit”, we can then launch a PowerShell
console.
2.3.2 Import-Module
+ We can then import all of the PowerSploit modules into our
current session with the Import-Module cmdlet, and if we run the
“Get-Module” cmdlet, we can see it’s now included in our list of
currently imported modules.
PS C:\> Import-Module PowerSploit
PS C:\> Get-Module
2.3.2 Import-Module
+ To list all of the PowerSploit associated cmdlets (of which there
are many), we can use the “Get-Command” cmdlet, and specify
the PowerSploit module with the –Module parameter:
PS C:\> Get-Command -Module PowerSploit
2.3.2 Import-Module
+ Furthermore, there are help files for all of the modules. For help on a
specific PowerSploit cmdlet, we simply run the Get-Help cmdlet, for
instance, getting help on the “Write-HijackDLL” PowerSploit cmdlet:
PS C:\> Get-Help Write-HihackDLL
2.3.2 Import-Module
+ We will cover other modules we can use for our
offensive purposes in sections that follow.
References
+ How to Write a PowerShell Binary Module:
https://docs.microsoft.com/en-
us/powershell/scripting/developer/module/how-to-write-a-powershell-
binary-module?view=powershell-7
+ How to Write a PowerShell Script Module:
https://docs.microsoft.com/en-
us/powershell/scripting/developer/module/how-to-write-a-powershell-
script-module?view=powershell-7
References
+ How to write a PowerShell module manifest:
https://docs.microsoft.com/en-
us/powershell/scripting/developer/module/how-to-write-a-powershell-
module-manifest?view=powershell-7
+ LinEnum: https://github.com/rebootuser/LinEnum
+ New-Module: http://go.microsoft.com/fwlink/?LinkId=141554
+ PowerSploit: https://github.com/PowerShellMafia/PowerSploit
+ PowerSploit-master.zip:
https://github.com/PowerShellMafia/PowerSploit/archive/master.zip
References
+ Writing a Windows PowerShell Module: https://docs.microsoft.com/en-
us/powershell/scripting/developer/module/writing-a-windows-
powershell-module?view=powershell-7
PowerShell Scripts
2.4 Scripts
+ Scripts are another element of our leveraging of PowerShell as
an offensive tool, and most of the time, this is probably the most
common way we will utilize PowerShell for most tasks.
+ PowerShell Scripts are usually identified by the “.ps1” extension,
the “1” indicating not the version of PowerShell, but rather the
PowerShell engine.
+ For the most part, we’ll be dealing with the .ps1 file.
2.4 Scripts
+ PowerShell scripts can contain as little as a few commands to
automate some tasks or be as complex as to contain parameters,
script arguments, loops, functions, and anything else related to
the capabilities that PowerShell offers as a scripting language.
+ Running a powershell script is as simple as calling it from the
powershell console, using the (dot-backslash) .\ notation for a
script in our current directory*.
PS C:\> .\example.ps1
* You may have to bypass the current execution policy (as shown earlier) before you execute the script of your choosing.
2.4 Scripts
+ A very basic example of a PowerShell script which takes a
file name as an argument would be something like the
following:
example.ps1
+ foreach()
+ while()
+ do {something} while()
+ do {something} until()
2.4.1 Loop Statements
+ And as we can with mostly everything in PowerShell, we
can get help on any of those statements with the “Get-
Help” cmdlet:
PS C:\> Get-Help about_Foreach
PS C:\> Get-Help about_For
PS C:\> Get-Help about_Do
PS C:\> Get-Help about_While
2.4.1 Loop Statements
+ Loops are generally divided into two parts, a loop
statement, and a loop body and will also contain variables
as seen in the example below:
+ In the first line, we’re creating a variable called “$services” which will
return the Get-Service objects collection as a result of running the “Get-
Service” cmdlet.
+ We then use the “foreach()” loop statement to create a new variable
“$service” to contain each resulting object of the $services variable, and
finally, we’re telling PowerShell to return the name of each $service with
the “.Name” property in the loop body, between the {} brackets.
2.4.1 Loop Statements
2.4.1.1 ForEach-Object
+ Furthermore, we can use several built-in cmdlets for constructing loop
statements, specifically the “ForEach-Object” and “Where-Object”
cmdlets.
+ The previous example could be similarly accomplished by using the
“Get-Service” and “ForEach-Object” cmdlets and pipeline, as follows:
PS C:\> Get-Service | ForEach-Object {$_.Name}
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-6
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-6
2.4.1.2 Where-Object
+ The “Where-Object” cmdlet allows us to select objects within a collection based
on their property values in regard to when used for a loop. In the following
example, we’re using the “Get-ChildItem” cmdlet to list the contents of a
“Powershell” directory, while piping that output to the “Where-Object” cmdlet
with the -match parameter to only return files that contain “xls” within their name:
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-6
2.4.1.3 Powershell TCP Port Scanner
+ A great example of a useful loop which the uses the
“foreach” statement, is a TCP Port Scanner we can create
entirely via the shell as a one-liner:
PS C:\> $ports=(81,444);$ip="192.168.13.250"; foreach ($port in
$ports) {try{$socket=New-Object
System.Net.Sockets.TcpClient($ip,$port);} catch{}; if ($socket -eq
$null) {echo $ip":"$port" - Closed";}else{echo $ip":"$port" -
Open"; $socket = $null;}}
2.4.1.3 Powershell TCP Port Scanner
+ We can just as well put the contents of the above, into a
“Scan-Ports.ps1” file in this case, for easy execution:
Define $ports
and $ip variables
PS C:\Users\user\Desktop> .\Scan-Ports.ps1
References
+ ForEach-Object: https://docs.microsoft.com/en-
us/powershell/module/microsoft.powershell.core/foreach-
object?view=powershell-6
+ Where-Object: https://docs.microsoft.com/en-
us/powershell/module/microsoft.powershell.core/where-
object?view=powershell-6
PowerShell Objects
2.5 Objects
+ Objects are essentially a representation of data that is
provided as a result of running a cmdlet.
+ Rather than with other scripting languages where data is
output as text most of the time, PowerShell is different in
that the data being output originates from classes within
the .NET Framework in the form of “objects.”
+ Objects are partly comprised of collections of properties, along
with “methods” that we can use to manipulate the objects.
2.5 Objects
+ Let’s take the Get-Process cmdlet as an example.
+ When we run the Get-Process cmdlet along with the
“Format-List *” command, as we’ve seen earlier, we get a
list of all processes along with their properties.
2.5 Objects
+ If we take a look at the “firefox” process object for example,
we can see it contains a number of different properties,
(Name, Id, Path) to name a few.
2.5 Objects
+ Each of the objects also has multiple methods that we can
use to manipulate a particular object.
+ To get a list of methods for objects associated with a
cmdlet, we can use the “Get-Member” cmdlet as part of a
pipeline command, like the following:
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/new-object?view=powershell-6
https://msdn.microsoft.com/en-us/library/system.type(v=vs.110).aspx
2.5.1 Creating .NET Objects
+ As an example of creating a basic object based off of a
.NET class with the “New-Object” cmdlet, we can use the
“Net.WebClient” .NET system class to download a file to a
target system with the following code: