Tuesday, 13 November 2018

Windows PowerShell Remoting: Host Based Investigation and Containment Techniques

In this blog post I will detail how to perform various incident response techniques using native Windows PowerShell functionality. Each method I explain will be able to be executed remotely to allow for efficient investigation and containment of an individual host. For PowerShell response on mass, I recommend familiarising yourself with the Kansa framework.

If you follow my github, you may also notice that many of the techniques listed below are built into my remote powershell triage tool, B2Response, which allows you to perform these actions with ease. Please give it a go and provide feedback!

The techniques which I will cover include:
1) Issuing remote command/shell
2) Retrieving/downloading files
3) Checking for running processes
4) Query registry keys
5) PCAP collection
6) Blocking a domain
7) Blocking an IP
8) Quarantining a host


All of the techniques listed below utilise PowerShell to remotely manage computers within your IT environment. In order for these techniques to work, you must have your environment configured to permit PowerShell remoting and you must be running the commands from a user who has privileges to execute remote PowerShell commands. For more information on how to set this up, please read this article.

Let's get started!

Initial Setup - Establish a Remote Session!

Throughout this blog post, I will be describing how to execute various PowerShell remoting commands. Whilst it is possible to issue these commands individually, I prefer to establish a PowerShell session first, and then refer to this session in subsequent commands.

The reason I prefer to establish a session first is that I use the -NoMachineProfile session option, which restricts creation of a user profile on the remote host. By establishing this session once and then referring to that session for each subsequent command, it reduces the chance that I will forget to include this session option and expose myself on the target machine.
What would I need to prevent profile creation on the remote host?
Preventing creating of your user profile on the remote host will save you lots of potential headache when investigating alerts in a corporate environment. Imagine that you have to investigate your senior executes for suspicious activity. If that senior executive then sees your user profile on his PC, he may think you were snooping on his computer. Save yourself the hassle and setup your session with stealth!

To establish the initial session on the remote host, use the following command (replacing 'remotehost' with the remote host computer name):

$s1 = New-PSsession -ComputerName remotehost -SessionOption (New-PSSessionOption -NoMachineProfile) -ErrorAction Stop

We can now refer to the $s1 variable for subsequent commands and they will be executed through this session.

1) Issuing Remote Commands & Remote Shell

When researching security products, I found it quite surprising that very few products supported remote command execution on the host. When I asked vendors about it, most vendors stated that it was coming very soon on their feature road map, as it was a highly requested feature.

Remote command execution can be very useful for enumerating the current state of the host, and can be achieved very easily with PowerShell. Many commands throughout this blog post are simply applications of the following remote command execution techniques.

PowerShell Prompt
To access the PowerShell session and enter manual commands on the remote host, enter the following command.
Enter-PSSession -Session $s1

Individual PowerShell Command
To execute a single PowerShell command (or command block) on a remote host, enter the following command.
Invoke-Command -ScriptBlock {Get-Process} -Session $s1

PowerShell Script Execution
To execute a PowerShell script on a remote host, enter the following command.
Invoke-Command -file file.ps1 -Session $s1

2) Downloading Files

Sometimes we may want to download a file from a remote host to our local machine in order to perform further analysis. To download a file, execute the following command:

Copy-Item -Path "C:\Users\bob\Downloads\maliciousdoc.docx" -Destination "D:\triage_files" -FromSession $s1I

In this command we are copying the file "C:\Users\bob\Downloads\maliciousdoc.docx' on the remote host to our local D:\triagefiles folder.

A limitation to this method is that you will not able able to download files which are protected (such as registry hives). In order to download these files, you will need to use a third party tool such as RawCopy, which can be remotely executed with ease using B2Response.

3) Check Running Processes

To check running processes, we can remotely execute Get-Process using the following command.
Invoke-Command -ScriptBlock { Get-Process} -Session $s1

4) Query Registry Keys

Querying registry keys can be a useful way to identify the presence of malware on a system. One common registry key I will use as an example is the HKLM\Software\Microsoft\Windows\CurrentVersion\Run key.

What is HKLM\Software\Microsoft\Windows\CurrentVersion\Run ?
This registry key contains a list of programs and their arguments which get executed every time Windows boots. As a result, many malware will add an entry to this registry key so that the malware runs on each boot.
To view the contents of this registry key on our remote host, use the following command

Invoke-Command -ScriptBlock {Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run} -Session $s1

This is useful if you know which  key you need to look in, however there are many other registry keys malware may use to persist on a system. As a good starting point, I would recommend running autorunsc to check multiple locations. B2Response can execute this tool remotely using PowerShell with ease.

5) Packet Capture

Thanks to some fantastic work by nospaceships, it is incredibly easy to capture network traffic into a wireshark compatible PCAP file with PowerShell. This capture method works by using raw sockets to capture IP packets on a specified network interface.
What are raw sockets?
A TCP/IP raw sockets is a type of socket which provides access to the underlying transport provider. In this scenario, it provides access to the specific network interface which allows us to capture the network traffic to a .pcap file.
Implementation of this packet capture method requires two stages.

Stage 1) Identify the network interface to capture on
Executing the following command will list the available network interfaces.

Invoke-Command -ScriptBlock {ipconfig} -Session $s1

In this example, we will be capturing on the wireless interface, which was listed in the output of the ipconfig command.

We need to note down the IPv4 address for stage 2, which in this case is

Stage 2) Run the pcap script
The following script will download nospaceships raw-socket-sniffer script, execute it and save the pcap to 'capture.pcap' in the current working directory of the remote host.

Ensure that you replace the -InterfaceIP parameter with the IP address identified in stage 1, or your pcap may be empty.

Invoke-Command -ScriptBlock {
$url = "https://raw.githubusercontent.com/nospaceships/raw-socket-sniffer/master/raw-socket-sniffer.ps1"
Invoke-WebRequest -Uri $url `
        -OutFile "raw-socket-sniffer.ps1"
PowerShell.exe -ExecutionPolicy bypass .\raw-socket-sniffer.ps1 `
        -InterfaceIp "" `
        -CaptureFile "capture.cap"
        } -Session $s1

Because we ran the session with the -NoMachineProfile option, the raw-socket-sniffer.ps1 and capture.cap should be located under C:\Windows\System32.

You can now use the 'Download file' instructions from this blog post to download the capture.pcap to your local system for analysis in WireShark.

6) Blocking a Domain

In this example we will be redirecting malicious traffic destined for http://bad.com/ to the localhost, which effectively blocks network connections to this domain. To do this we will edit the Windows hosts file.
What is the Windows hosts file?
The Windows hosts file is located at C:\Windows\System32\drivers\etc\hosts on Win 7+ and Server 2003+ systems and contains mappings of IP addresses to host names. We can use this to redirect traffic destined for a specific domain to a specific IP address. The file has no extension, but is a normal text file that can be edited with notepad.
What is localhost?
Localhost is a networking term which refers to the current computer. In this scenario, we will be redirecting malicious traffic to localhost, where it will fail to be received, as there is no service listening for the traffic (unless you are running a web server).
Shouldn't we be blocking/sinkholing on the network layer?
Absolutely. Automated domain sinkholing at a network layer is a fantastic control. There are however many scenarios where network sinkholing may not reach all devices in your environment. I've seen many environments where remote devices aren't configured for full tunnel back to on premise firewalls, so the host goes straight out to the internet (bypassing a firewall sinkhole). 
So let's open C:\Windows\System32\drivers\etc\hosts in your favourite text editor (I will use Notepad++) as Administrator and append the following line: bad.com

Save the file.

Now when we visit bad.com in a browser we cannot reach this location, because traffic is being redirected to the localhost, which isn't hosting a web server.

Lets automate this with PowerShell. Copy the following code into Notepad++ and save it as blockdomains.ps1

Add-Content C:\Windows\System32\drivers\etc\hosts "`n127.0.0.1 bad.com"

Note: The `n adds a new line to the file.

Once this script is executed on a host, it will perform the same modification that we manually made to the hosts file. To block multiple domains, simply add additional Add-Content commands to the blockdomains.ps1.

To execute this script on our remote PC, use the script execution command we learnt earlier:
Invoke-Command -file blockdomains.ps1 -Session $s1

7) Blocking an IP

The reasons unknown to me, the Windows firewall is often overlooked as an effective host based firewall.
What is a host based firewall?
A host based firewall is a software firewall that runs on an individual computer which defines what inbound and outbound network connections are allowed to/from that computer.
If you have identified connections to a malicious IP on a host, you can use the Windows firewall to block connections to this IP.

In order to block connections to a specific IP address ( in this example) on a remote host, use the following command:
Invoke-Command -ScriptBlock {New-NetFirewallRule -DisplayName "Block_Malicious_IP" -Direction Outbound LocalPort Any -Protocol TCP -Action Block -RemoteAddress}  -Session $s1

To unblock this IP address, run the following command:
Invoke-Command -ScriptBlock {Remove-NetFirewallRule -DisplayName "Block_Malicious_IP"} -Session $s1

8) Quarantining a Host

Expanding on the Windows firewall's ability to block individual network connections, we can also apply firewall rules to block all outbound network connections, effectively quarantining the infected PC.
What does it mean to quarantine a PC, and why would we do it?
Quarantining a PC is the act of segregating the device at a network level, as to limit the capability for the compromised of that device to spread to, or access, other computing resources within the IT environment.
We can use the following PowerShell command to create a new Windows firewall rule called 'InfoSec_Quarantine' on a remote PC which we would like to quarantine.

Apply Quarantine:
Invoke-Command -ScriptBlock {New-NetFirewallRule -DisplayName InfoSec_Quarantine -Direction Outbound -Enabled True -LocalPort Any -RemoteAddress Any -Action Block} -Session $s1

Once applied, this computer will not be able to initiate any outbound connections to either internal or external (including internet) resources. Don't be surprised if you don't receive feedback from this command, or further commands, as the PC cannot send traffic outbound anymore!

If you would like to roll back this quarantine action, you can simply issue this command to the same device to remove the quarantine firewall rule. This should work, as the host can still receive inbound connections and process the command.

Remove Quarantine:
Invoke-Command -ScriptBlock {Remove-NetFirewallRule -DisplayName InfoSec_Quarantine} -Session $s1


I hope this post has helped some of you get started with PowerShell incident response techniques. If you have additional tasks you would like to perform with PowerShell, give them a go, and feel free to email me at b2dfir@gmail.com if you would like some help, or if you would like me to cover other topics in a future blog post.


  1. This information was very helpful. Thanks for sharing. Firewall Errors Tech Support Number


  2. Thanks for sharing this information with us and it was a nice blog.
    DevOps Training
    DevOps Online Training

  3. I just want to thank you for sharing your information and your site or blog this is simple but nice Information I’ve ever seen i like it i learn something today. PowerShell