Ok PowerShell seems to be quite popular right now in the context of penetration testing. In this article I'm going to try to explain why and share with you a small script I made while learning it.

Wait, but what is powershell?

PowerShell is a powerful scripting enviroment available for modern Windows Systems (btw version 6.0 core is opensource on github!)
It is built on top of the .NET framework and it provides a convenient way to interact with it and many more Windows components like COM or WMI.
It is the swiss knife for every system administrator who wants to automate tasks in a Windows Enviroment.

Why is it used in pentesting?

The usage of powershell has gained popularity in pentesting because of the concept called "Living off the land". What does it mean? Basically it means that if you compromise a system and use built-in tools to exfiltrate informations and compromise other machines in the network it is very hard to detect your malicious activity.
Plus with powershell it is possible to execute code without touching the disk, a big punch in the AV face.

So recalling the classical pentesting cycle:
(Image taken from: https://blog.redcanari.com/2015/10/26/top-5-questions-to-ask-your-next-penetration-tester/)

your powershell activity goes into the post exploitation phase, meaning that you can use it to gather information on the compromised system and help you to compromise more machines in the network.

The script

Fine, enough talk, it's time to code.
For learning purpose I built this script that does a small, but useful thing: After a compromise, look at the ARP table and scan a few ports of each host in order to gain more situational awarness.
This is the full code, we are going to discuss this line-per-line:

Get-NetNeighbor -AddressFamily IPv4 | % {
    foreach($port in $ports) { 
            $socket = new-object System.Net.Sockets.TcpClient($ip, $port);
                "$ip listening to port $port";
  • $ports=(80,445,3389,22,21); Defines what ports to scan.
  • Get-NetNeighbor -AddressFamily IPv4 This cmdlet gets every entry of the ARP table which has an IPv4 address associated at it


  • The pipe (|) has a meaning very close to to the bash's one, but in powershell each cmdlet returns an object not a string printed out on stdout (like bash). We can access the methods and attributes of the returned object.
  • % is a shortcut (an alias in the powershell terminology) that stands for: "iterate for every object", in this case with the pipe we are passing a list of objects associated with ARP entries, so this iterate for every entry.
  • $ip=$_.ipaddress; Saves in a variable the current IP address, the $_ symbol is used to access the current element of the iteration.
  • foreach($port in $ports) { Wow, similar to python, an alternative way to cycle through objects! Quite self explanatory, cycles through the ports.
  • try We are going to connect to some hosts, if the connection fails it will rise an error and we don't want our script to fail because it finds a closed port!
  • $socket = new-object System.Net.Sockets.TcpClient($ip, $port);Attempts the connection with the tuple (IP, Port)
  • If($socket.Connected){ Checks if the socket is connected
  • "$ip listening to port $port"; $socke.Close() if it is connected, print it and close the socket.

A few lines, but a good starting point for learning this powerful scripting language!
This is the one-liner version of the script:

$ports=(80,445,3389,22,21);Get-NetNeighbor -AddressFamily IPv4 | % { $ip=$_.ipaddress; foreach($port in $ports) { try{$socket = new-object System.Net.Sockets.TcpClient($ip, $port); If($socket.Connected){  "$ip listening to port $port"; $socket.Close()}}catch{}} }

pwn a machine, enter a powershell session and write it into the CLI.


nice and useful, it will become part of my post exploitation scripts!