WIP - PowerShell for Pentesters
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.
Last updated
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.
Last updated
This document is still in progress...
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 OS work to our advantage once we've obtained access to a system.
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.
We can call Windows DLL functions from within PowerShell.
We can use it to bypass application whitelisting implementations by running the usual OS commands from from the PowerShell CLI.
Many tools are already available to us for a large amount of purposes related to penetration testing.
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.
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.
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.
PowerShell is typically used by administrators as it provides great functionality and flexibility in regards 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, and it's built on top of it.
It also provides convenient access to the .NET Framework API, Component Object Model (COM) and Windows Management Instrumentation (WMI) which is another plus in regards to persistence methods and ways we can gather information.
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.
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 regards to detection, loggin and more restrictive modes.
In 2016, Powershell 6.0 (Powershell Core) was made available for several different platforms, including some major Linux distributions, MacOS and also as a Docker container image:
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.
In most cases, accessing the CLI is as simple as just typing powershell
in the Windows search filed from the Start menu.
Alternatively, the shortcut to PowerShell can be found within %appdata%\Microsoft\Windows\Start Menu\Programs\Windows PowerShell
directory.
Sometimes the shortcuts are unavailable; the PowerShell executable itself can be found in the C:\Windows\System32\WindowsPowerShell\v1.0
directory.
If other versions are available on the system, they can be found in their corresponding version paths.
A note regarding 32-bit and 64-bit PowerShell executables
If you're operating on a 64-bit system, the location of the 64-bit PowerShell executable can be found in
c:\Windows\System32\WindowsPowerShell
.While the 32-bit version being located in the
C:\Windows\SysWOW64\WindowsPowerShell
directory.This can be a bit confusing considering the directory naming convention.
Nonetheless, we can determine whether we're running in a 32-bit or 64-bit PowerShell environment from the CLI with the following command:
PS C:\> [Environment]::Is64BitProcess
.Which should return
True
if the current PowerShell process is 64-bit.On a 32-bit system, the executable will be in its usual location of:
c:\Windows\System32\WindowsPowerShell\*
.
When possible, we should try and launch PowerShell as the Administrator user as this will give us access to functions which we would be otherwise unable to access as Lower-Privileged user.
We can right-click on the Shortcut or Executable and select "Run As Administrator".
Examples were tested on Windows 10.
Argument
Description
-ExecutionPolicy
PowerShell execution policy determines which scripts if any, we can run and can easily be disabled with the Bypass
or Unrestricted
arguments:
powershell.exe -ExecutionPolicy Bypass .\scr.ps1
powershell.exe -ExecutionPolicy Unrestricted .\scr.ps1
powershell.exe -ep Bypass
powershell.exe -ex by
-WindowStyle
Hides the PowerShell window when used with the Hidden
argument:
powershell.exe -WindowStyle Hidden .\scr.ps1
powershell.exe -W h
powershell.exe -Wi hi
-Command
Used to specify a Command or Script Block to run:
powershell -Command Get-Process
powershell -command "& { Get-EventLog -LogName security }"
-EncondedCommand
Used to execute base64 encoded scripts or commands:
powershell.exe -EncodedCommand $encodedCommand
powershell.exe -enco
powershell.exe -ec
-NoProfile
Don't load any PowerShell profiles. Profiles are essentially scripts that run when the PowerShell executable is launched and can interfere with our operations:
powershell.exe -NoProfile .\scr.ps1
-Version
We can use it to downgrade the version of PowerShell. Requires that older versions are still installed on the target:
powershell.exe -Version 2
Similar to Linux Man Pages. Obtain info related to any function, alias, module or cmdlet that PowerShell is aware of.
Allows us to list all cmdlets, aliases, functions workflows, filters scripts and any applications that are available for us to use in PowerShell.
Running Get-Command
cmdlet without arguments will simply list all commands, but we can also use the -Name parameter to list any that are useful to us. For instance we can list all functions related to modification of the Windows Firewall with the following command:
"command-lets" are a big part of how we will leverage PowerShell for our offensive purposes.
Light-weight PowerShell scripts that perform a single function (can be as small as 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).
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 the processed via a pipeline (|
).
Every cmdlet has it's 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"
For example: just running
Get-ChildItem
cmdlet without any other arguments or options, returns four columns namedMode
,LastWriteTime
,Length
andName
.But by piping the output of a cmdlet to the
Format-List
cmdlet, rather than columns an names we can return all named properties associates with its objects in a different list-like format:
An example of this processing of cmdlet output objects with pipelines would be something like the following, where a list of process is returned to be sorted with unique values, selecting the ProcessName
objects:
We can also redirect the results of our pipeline operation to a file using a standard Redirect Operator (>
):
Get-Process
will give a list of all processes. To get all of the information (properties) associated with all of the processes, we can pipe it to the Format-List *
cmdlet and wildcard argument.
This will give us a better idea of how we can filter the data for specific properties.
We can further extend this to get information about specific processes and paths to their executables, by using the Format-List
cmdlet and also specifying the Path
property name:
This one has an alias: ls
.
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:
select
is an alias for the Select-Object
cmdlet.
We return all information about the Operating System:
Saving the information we're gathering to a file is important as well. We can either redirect the output of the pipeline operation to a file with the (>
) Redirect Operator as we saw in an earlier example or sometimes, we may need the results in a different format for processing.
For this we can pipe all of the output to the Export-Csv
cmdlet and save the results in CSV format:
For access to Windows Registry hives, PowerShell provides a convenient method with the following command, so we can easily navigate into areas we might be interested in with cd
which is the alias for Set-Location
and furthermore list contents of our current hive with Get-ChildItem
cmdlet or ls
:
Along with the -Path
and -Pattern
args is yet another useful PowerShell command we can use to scour the system for files containing certain strings.
Use this cmdlet to display the full contents of the passwords.txt
file.
Alternatively we can obtain the same results by usign the Get-ChildItem
cmdlet alias with the recursive parameter (ls -r
) which lists files within a directory recursively, then, search for file types of .txt
with the -File
parameter.
We'll then pipe that to the ForEach-Object
alias which is %
and a script block {}
that searches for the string pass*
in all files in the path specified with the alias for the Select-String
cmdlet (sls
):
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.
Running it without parameters or arguments simply returns a three column list of all services.
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:
A module 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 module.
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.
There are also several different types of modules:
Dynamic Modules, created dynamically by scripts using the New-Module
cmdlet
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:
Modules wanted to be used need to be imported into the current PowerShell session first:
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 that module (think of PowerSploit).
Download PowerSploit.
PS C:\> $env:PSModulePath
: modules will need to be copied into this path. Cam be something like C:\Users\user\Documents\WindowsPowerShell\Modules
.
Launch PowerShell Console and Import-Module PowerSploit
.
Run Get-Module
.
Run Get-Command -Module PowerSploit
to list all of the PowerSploit associated module with the -Module
parameter.
Get help: Get-Help Write-HihackDLL
.
Antivirus alert
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 a directory.
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.
PowerShell scripts can contain as little as a few commands to automate some tasks or be as comples as contain parameters, script arguments, loops, functions, and anything else related to capabilities that PowerShell offers as a scripting language.
Running a PowerShell console, using the (dot-backslash) .\
notation for a script in our directory.
A very basic example of a PowerShell script which takes a file name as an argument would be something like:
The above script simply takes a file name as an argument for which it creates a variable called $file
and runs the Get-Content
cmdlet on our variable.
Now if we run this file while supplying the name of a file, in this case, users.txt
which contains several usernames:
If we run the script without arguments, PowerShell will ask us for the file, since mandatory=$true
has been set for the parameter function in our script.
Alternatively, rather than writing a .ps1
script file, we could also just create a variable $file
for our user.txt
file, and then call the Get-Content
script against our variable, directly from the shell:
PowerShell supports several "loop statements" which we can utilize for different tasks. We can loop statements to iterate through files, PowerShell object collections, and even conduct port scans.
PowerShell allows us to use a number of loop statements for our purposes:
for()
foreach()
while()
do {something} while()
do {something} until()
Check a more detail help information with
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", which are partly comprised of collections of properties, along with "methods" that we can use to manipulate the objects.
When we run Get-Process
cmdlet along with the Format-List *
command, we get a list of all process along with their properties.
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 pipeline command:
The GetMember
cmdlet will give us an idea of all of the methods for associated objects, as we can see below for the Get-Process
objects. Several methods that might be of interest to us for the Get-Process
objects might be Kill
or Start
which we could use to kill or start processes.
In addition to using the built-in cmdlets to access a large number of objects, which we can then manipulate, we can also create .Net Objects which greatly extends our capabilities using New
Object` cmdlet.
These can be either created as a Type
of the .Net Framework class, using fully qualified names of .NET classes or we can use the ProgID
of a COM object.
In this example:
We create a variable called $webclient
which instantiates the System.Net.WebClient
.NET class, which is used to create a web client.
We then create another variable $payload_url
which is the URL to our payload.
The $file
variable is then used as the location to which we want to save the payload on the target system.
And finally, we call the $webclient
variable with the Downloadfile
method which downloads our payload.exe
to the target.
The ability to download and execute files on our target system is, of course, a necessary process in our quest to maintain footholds and persistence within a target network.
Being able to do so with tools that are already built-in to the OS (ex, Living-off-the-land) is even more important as it helps evade endpoint security measures and application whitelisting solutions by using tools that are likely already "trusted".
Additionally, being able to download and execute files with PowerShell is even more advantageous in many cases, since we're able to operate entirely within the memory process of PowerShell and can avoid dropping artifacts to disk in many cases.
There are two primary ways we can download and execute code in regard to strictly using PowerShell and built in .Net classes or COM objects:
An executable or script is downloaded to disk, which can then be executed by PowerShell itself, or by using other executables on the system to execute our code.
An executable or script is downloaded and run within the PowerShell process memory, and never touches the disk (preferred method).
A summary of methods that we can use for "In-Memory" execution with PowerShell version 2.0 (preferred methods):
Net.WebClient DownloadString method
Net.WebClient DownloadData method
Net.WebClient OpenRead method
.NET [Net.HttpWebRequest] class
Word.Application COM Object
Excel.Application COM Object
InternetExplorer.Application COM Object
MsXml2.ServerlXmlHttp COM Object
Certutil.exe w/ -ping argument
A summary of methods we can use for "Disk-Based" execution with PowerShell version 2.0:
Net.WebClient DownloadFile method
BITSAdmin.exe
Certutil.exe w/ -urlcache argument
These two methods (in-memory and disk-based) are usually accomplished using what are commonly referred as "Download Cradles" and use the "System.Net.WebClient" .Net System Class among other classes, COM objects or other Windows-native executables to achieve this.
Most of the time we'll use the New-Object
cmdlet, which will allow us to create instances (objects) of either .Net or COM objects.
Net.WebClient DownloadString Method
The most common download cradle we'll see in the field uses the "iex" or Invoke-Expression
alias along with the Net.WebClient
class and the DownloadString
method, which downloads and executes a remotely hosted PowerShell script:
We can also break the above PowerShell commands down and execute them directly via the console with something like:
The DownloadString
method will execute our remote script in the PowerShell process memory, so in regard to not dropping an artifact to disk, it's a great way to stay under the radar of endpoint security solutions, that are monitoring PowerShell memory.
Evasion Tip: SSL Certificate!
It should be noted that where possible when hosting your remote PowerShell script, to have an SSL certificate configured on the attacker machine. This will help in evading over-the-wire heuristics as our traffic will go over HTTPS.
Evasion Tip: Rename to gif!
Another trick we can use which might help in evading basic file extension heuristics is to give our PowerShell script a different extension, for instance, logo.gif
. PowerShell will still execute it as a .ps1
script.
Evasion Tip: Headers
In this way, we decrease our probability of being detected, as this can help to evade detection mechanism that are flagging on abnormal user-agent strings crossing the wire:
Net.WebClient DownloadFile Method
Another Net.Webclient class method we can use is the DownloadFile
method. This method will download your executable to disk.
Although noisy and not recommended, if trying to remain stealthy, it's still sometimes a handy method to quickly download a file to the target system.
It should also be noted that the Net.WebClient class methods can be configured to use the systems' proxy and default credentials:
Net.WebRequest class
We can use this class to download and execute scripts on a target, in memory.
System.Xml.XmlDocument class
Allows to execute a PowerShell command (or any system command) contained within an attacker hosted XML document and is another great way to execute PowerShell code in memory, and in a way that is likely not detected, especially when combined with a server over HTTPS.
We just create an XML file with the following contents that we'll host on our attacker machine:
Next, once our XML file is hosted, we can use the System.Xml.XmlDocument
class with the Load
method to download and execute it:
COM Objects for Download & Execution
We can also use COM Objects to both download and execute scripts on a target system. Some of the COM objects available to us for this purpose are:
Msxml2.XMLHTTP
Microsoft.XMLHTTP
InternetExplorer.Application
Excel.Application
Word.Application
MsXml2.ServerXmlHttp
WinHttp.WinHttpRequest.5.1 (Not Proxy Aware)
We can utilize the COM objects in the same way we do with the Net.WebClient objects, by using the New-Object
cmdlet, but with the -ComObject
parameter.
WinHttp.WinHttpRequest.5.1. COM Object
ExecutionPolicy Bypass and Hidden Window
A great tool we can use to help us cract obfuscated download cradles is known as Invoke-CradleCrafter
by Daniel Bohannon.
As endpoint security solutions catch up with attacker methods and implement numerous heuristics and detection signatures to catch PowerShell commands as they are being executed, we turn to obfuscation as a layer in helping us evade those defenses.
One of the more well-known frameworks w can use for this purpose is Daniel Bohannon's Invoke-Obfuscation
, which offers some excellent options we can use to obfuscate and encode our PowerShell commands or script blocks using a number of methods including AES encryption with the "SecureString" mthod, to special characters and even whitespace encoding.
Download the Invoke-Obfuscation
framework into our module's directory (check PowerSploit section: $env:PSModulePath
.
Run Import-Module Invoke-Obfuscation
Run Invoke-Obfuscation
We have several different options we can use to obfuscate our PowerShell commands:
TOKEN
: obfuscate PowerShell command tokens.
AST
: AST nodes (PS 3 or greater).
STRING
: obfuscate entire command as a String.
ENCODING
: obfuscate via encoding.
COMPRESS
: convert entire command to one-liner and compress.
LAUNCHER
: obfuscate command args w/Launcher techniques (run once at end).
First, in order to tell Invoke-Obfuscation
what we'd like to obfuscate exactly, we first need to use the SET SCRIPTBLOCK
command.
The download cradle from the previous slide, when executed on our target, will use the Net.WebClient class and will download and execute our Get-ProcessPaths.ps1
script from our attacker machine, which will simply list running process on our target.
Let's set that as the SCRIPTBLOCK
in Invoke-Obfuscation
as the command we want to obfuscate with the SET SCRIPTBLOCK
command:
Once we select and run the reverse obfuscation, Invoke-Obfuscation
presents us with the command it used to create the obfuscated string block, along with the result of the command, which can be just copied and pasted to our target system in a PowerShell prompt.
There's an ENCODING
method too, which provides a bit more obfuscation and is a bit harder to detect (as "Special Characters".
If we're operating from a Windows command prompt on the target, instead of a PowerShell console, we can use the pwershell.exe -Command
option to run our obfuscated commands, by just encapsulating the encoded result with quotes.
Important: be careful to create commands that don't exceed
cmd.exe
's maximum length.
RESET
method is used to clear previous encodings.
In addition to obfuscating our PowerShell commands, we can also create obfuscated launcher commands to run our obfuscated code on the target using LAUNCHER
option. For instance, if we want to use WMIC
to launch our obfuscated code, we can quickly generate a command to do so.
The process for using the LAUNCHER
option is that we first create our obfuscated commands as we did previously:
We SET SCRIPTBLOCK
with the code we want to execute.
We select an obfuscation method to generate the obfuscated command.
We then use the LAUNCHER
option as the end of this process (like RUNDLL method).
And then the command line options we'd like to use as well, in this case, we'll choose '0' for No Execution Flags.
The resulting string is an obfuscated command that utilizes rundll32.exe
with the SHELL32.DLL
function (ShellExec_runDLL
) which will launch our obfuscated PowerShell code on the target.
Invoke-Obfuscation
also includes a tutorial option if you're stuck and need some guidance on some of its options.
Although not really a recommended "obfuscation" method since it can be easily detected by Antivirus and other heuristics, considering it's just base64 encoding.
The -EncodedCommand
parameter allows us to execute encoded commands or script blocks which contain characters which might interfere with the processing of our command via Windows command prompt.
In simpler terms, it makes complex commands "digestible" by PowerShell by encoding everything with Base64.
To encode a command that will add a new user admin1" to the local administrator's group:
We can then get the results of our encoded command with the Write-Host
cmdlet against our $encodedCommand
variable:
PowerShell is largely a tool we use for post-exploitation simply due to its capability and its availability on systems we have access to.
Naturally, it is a post-exploitation tool. However, we can also use it to conduct Information Gathering and Reconnaissance as well.
There are several third-party tools, built-in cmdlets and frameworks that exist that can help us with these tasks.
One tool we can use for efficient discovery of hosts on a network and is included with the PowerSploit framework is the Invoke-Portscan
cmdlet.
First we can utilize Infoke-PortScan
to execute a ping scan (-PingOnly
) against our target network range in CIDR notation with the -Hosts
parameter in an attempt to identify live hosts:
We can also supply a file containing a list of IP addresses with the -HostFile
parameter. The results of which will show True
for live hosts:
For a tool similar to what we're used for enumerating files and directories asdirb
, dirsearch
, we can use PowerSploit too. Get-HttpStatus
works in conjunction with a dictionary (-Path
) like other similar tools, and when used in conjunction with the Where-Object
alias (?
) will return a list of pages or directories on the server:
Another useful cmdlet we can use for host discovery and is part of Carlos Perez's Posh-SecMod framework is Invoke-ARPScan
and may generate fewer alerts than your usual SYN or TCP scan.
Posh-SecMod has several useful cmdlets we can use for host discovery purposes among others.
For reverse DNS lookups, we can use this cmdlet against a target CIDR block:
Important!
Nishang and its various modules will likely be detected by AV software if imported directly into the target system. Therefore it's important to make sure that most of the tools and scripts we invoke should be invoked via download cradles that support in-memory execution.
Nishang - Gather - Copy VSS
The Copy-VSS
module will attempt to copy the SAM database using the VSS service, and if run on a domain controller will try and copy the NTDS.dit
and contents on the SYSTEM registry hive.
The command will copy the contents of the SYSTEM registry hive and the SAM file to the current directory on the target, which can be cracked offline.
Nishang - Gather - Get-Information
The Get-Information
cmdlet will get us a good deal of system information including:
PuTTY trusted hosts
PuTTY Saved sessions
Recently used commands
Shares on the target machine
Environment Variables
Current user details
SNMP information
Installed applications
Domain Name
Content of hosts file
Running Services
Account Policy
Local Users
Local Groups
WLAN info
We can download and execute it in memory with our Net.Webclient DownloadString download craddle:
Nishang - Gather - Get-PassHints
Dumps the saved Password Hints for users on the system:
Nishang - Gather - InvokeMimikatz
This cmdlet will dump clear-text credentials (or hashes) from memory. Note that we can also pass command line parameters to any of the modules that have additional options as part of our download cradle commands:
There are plenty of other very useful Nishang "gather" modules which will come in handy for our post-exploitation purposes.
Nishang - Bruteforcing MSSQL, Active Directory, WEB and FTP
As part of its catalog, Nishang includes a great brute force tool Invoke-BruteForce
. We can use this to brute force Active Directory accounts, SQL Server, Web or FTP servers. The great thing about a brute force tool written in PowerShell is that we can execute the attack from our target host as long as we copy a file containing usernames and passwords to our target:
Invoke-BruteForce
is also a great tool for executing a password spray attack against Active Directory. Just ensure your password list contains a single password.
Nishang - Reverse PowerShell Shell (Netcat)
The Invoke-PowerShellTCP
cmdlet within the Nishang framework provides an excellent way to obtain a reverse PowerShell shell from our target host back to a netcat listener.
Keep in mind that if using this method, take into consideration that the traffic is traversing the wire in cleartext between attacker and target.
Although a great an undetected (by AV soft) method to get a reverse shell from PowerShell, over-the-wire heuristics (SIEM) may pick up some of the back and forth chatter if that type of solution has been implemented within an organization.
To use this, we should first fire up a netcat listener on our attacker machine:
Next we can simply invoke it using a download cradle from the target system, this time, from a Windows command prompt on the target:
On our listener, we should receive a connect back from the target, into a PowerShell prompt.
There are several different shells, both bind, reverse, ICMP, UDP shells and some more complex "rat"-type shells we can utilize from Nishang:
Invoke-JSRatRundll.ps1
Invoke-PoshRatHttp.ps1
Invoke-PoshRatHttps.ps1
Invoke-PowerShellcmp.ps1
Invoke-PowerShellTcp.ps1
Invoke-PowerShellTcpOneLine.ps1
Invoke-PowerShellTcpOneLineBind.ps1
Invoke-PowerShellUdp.ps1
Invoke-PowerShellUdpOneLine.ps1
Invoke-PowerShellWmi.ps1
Invoke-PsGcat.ps1
Invoke-PsGcatAgent.ps1
Remove-PoshRat.ps1
In addition to the "Gather" and other modules we've covered, we can find a script for mostly any phase of our post-exploitation within the Nishang Framework with utilities in the following categories:k
As with other frameworks, there are several categories in PowerSploit we can use for our post-exploitation purposes:
AntivirusBypass
Code Execution
Exfiltration
Mayhem
Persistence
Privesc
Recon
ScriptModification
PowerSploit - PowerUp
this module belongs to the "privesc" category. We can first import the Privesc.psm1
module from within the Privesc Modules directory and have a look at some of the options we have:
PowerUp
has plenty of options to explore. We can run any of those functions or scripts independently, but this module includes an Invoke-AllChecks
function that will run all functions related to the Privesc module looking for misconfigurations, permissions issues with services, opportunities for DLL hijacking and a number of other useful checks.
We can invoke it on the target after we've imported the Privesc.psm1
module with all the Invoke-AllChecks
command:
The output will also indicate an "AbuseFunction" we can use to further exploit the target.
PowerUp also gives us the option to save all results to an HTML file with the -HTMLReport
flag and will generate an HTML file we can use to investigate any paths to privilege escalation. The file will be saved in the current directory.
PowerSploit - DLL Injection
The "CodeInjection" category in PowerSploit gives us some options in regards to several methods we can inject our own code into existing processes on the target system, whether it be via DLL injection, injecting our own custom ShellCode into an existing process or using WMI to execute commands on the target.
Invoke-DLLInjection
script is commonly used, injecting an attacker-defined DLL into any existing process ID on the target system.
The first requirement will be generating a DLL. This can be done in a number of ways, but most commonly we can just use Metasploit's msfvenom to generate one with the following command:
This will execute a cmd.exe
prompt on the target when injected. You can also create a DLL that will spawn a meterpreter reverse shell for instance.
The DLL will need to be downloaded to the target. This can be done in any number of ways, but we can use the Net.WebClient "DownloadFile" download cradle method for that:
We should next identify a process on the target system we'd like to inject our DLL into. We can simply run the ps
command from the PowerShell console.
We'll run the ps
command with a Where-Object
statement to look for a process that matches notepad
and we'll inject our DLL into that process.
Once we've downloaded our DLL to the target, and identified the process we're going to inject into, we can use another download cradle (this time DownloadString
method) to download and execute the InvokeDLLInjection.ps1
script from our attacker system, along with the correct arguments for injecting our DLL into that existing process:
Once that is complete, if we run the ps
command again, we can confirm that we now have a cmd
process which has been spawned from our DLL injection operation, which is created in a new process thread.
A great explanation of the basics of how DLL injection works can be found here:
Another excellent PowerShell tool which allows us to get SYSTEM privileges via a parent process, which then spawns a child process which effectively inherits the SYSTEM access privileges of the parent.
Although this tool needs to be run as Administrator, it's a great way to evade application whitelisting solutions by being able to inject ourselves into an already signed or other trusted process.
Once we have downloaded the psgetsys.ps1
script to our target, we can source it and execute its class function with the following commands:
But before that, we need to identify some SYSTEM processes and choose one we can "piggyback" onto:
This command should return a list of all SYSTEM-owned processes along with the PIDs and process names.
Now that we have a PID for a SYSTEM-owned process, we can continue with our execution of psgetssystem
. This will launch a cmd.exe
prompt but as a child process of the SYSTEM-owned process (ZeroConfigService
) and as a result, our "child" process will also be SYSTEM:
We can confirm this by running a tool like Process Explorer, to see that our cmd.exe
process has been spawned as a child process of the ZeroConfigService
process and is also SYSTEM.
In an attack scenario, we could easily launch a meterpreter executable payload as SYSTEM and get a SYSTEM shell from the target machine.
Another great post-exploitation framework. Its main advantage is that it implements PowerShell functionality without requiring the existence of PowerShell on a target machine.
It is in a world of its own in regard to other frameworks in that it utilizes its own built-in listener, agents and modules to compromise and conduct all facets of post-exploitation from information gathering to privilege escalation, lateral movement, persistence and also integrates with the MetaSploit Framework.