Part V: PowerShell Multithreading – Asyncronous Network and Host Discovery Scanner

Part V of my Get-SecNetMap “Mini-Module”:

  1. Get-SecNetMap
  2. Get-SecPortScan
  3. Get-SecIPRange
  4. Convert-SecIPAddress
  5. Get-SecArpTable (This Post)

You can download the module source files here:


The Get-SecArpTable is more or less a framework surrounding the already existing executable ARP.exe. The only issue with simply calling ARP.exe in your scripts is that the output is all strings. This function is designed to parse the output of the ARP table and return a PSObject so that it can be used in scripts and other functions more easily.

One of the key features in this function is the ability to test the local Arp table for poisoning, and also the ability to spoof a static entry in the local Arpcache in order to poison it. The only restriction is that editing the ARP table requires administrative access.. 🙁

Lets take a look at some screenshots.

The testPoisen parameter shown here will scan entire local subnet so all entries are shown in the ARP table. Then it will see if duplicate entries exist.

ARP Poisen

To spoof a static entry into the ARP table, you will need admin rights.

ARP Poisen

See here how there are duplicate entires

ARP Poisen

Testing once more shows that the ARP table is poisoned and some basic recommendations.

ARP Poisen

[sourcecode language=”powershell” wraplines=”false” collapse=”false”]
Function Get-SecArpTable {
Retrieves ARP table and allows to test if ARP poisened, or choose to spoof ARP cache

Displays and modifies the IP-to-Physical address translation tables used by
address resolution protocol (ARP)

Changing your ARP table requires Admin

Adds a static entry into the ARP cache. Beauty is that this method creates NO network traffic and doesnt alert IDS 🙂

Switch to allow script to process an integer into an IP address

Convert-SecIPAddress -toINT


Convert-SecIPAddress -fromINT 3232235877

Name: Test-ArpPoisen.ps1
Author: SecureKomodo
Version: 1.0

Param (



[Parameter(Position=0,Mandatory = $True,ParameterSetName=”Spoof”)]

[Parameter(Position=0,Mandatory = $True,ParameterSetName=”Spoof”)]


Begin {

# Ping the localhost subnet to build ARP cache
if ($testPoisen){
Write-Verbose “Finding active hosts on subnet…”
Get-SecNetMap -sSN -Silent | Out-Null

if ($Spoof -or $Delete){
If (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] “Administrator”)) {
Write-Warning “You do not have Administrator rights to edit the ARP table!`nPlease re-run this script as an Administrator!”
} # End if Spoof specified

if ($Spoof) { (ARP.EXE -s $InternetAddress $PhysicalAddress)}

Process {

# Hack to retrieve and convert arp table as an object and then determine if poisened since PS doesnt do this natively
Write-Verbose “Retrieving ARP Table”
(ARP.EXE -a) | ForEach-Object {
$ArpCache += New-Object PSObject -Property @{
IP = ($_ -split “s+”)[1]
MAC = ($_ -split “s+”)[2]
Type =($_ -split “s+”)[3]

if ($testPoisen) {
Write-Verbose “Testing if ARP table is Poisened”
#Show only entires with duplicate entries = Poisened
$DuplicateMac = $ArpCache.Mac | Group-Object | Where-Object {$_.Count -gt 1}
$DuplicateIP = $ArpCache.IP | Group-Object | Where-Object {$_.Count -gt 1}

if(($DuplicateMac.Count -lt 2) -or ($DuplicateMac -eq “”)){Write-Output “Poisened: $False”}
else {Write-Warning “Poisened: $True – Please delete your arp table and contact your Security Administrator!”
Return $ArpCache | Sort-Object MAC

} # End testPoisen

if ($Delete){ (ARP.EXE -d *) }

} # End Process

End {

if (!$testPoisen -and !$Spoof) {

if ($Delete) {
Test-Connection -Count 1 -BufferSize 8 -Quiet | Out-Null
} else {Return $ArpCache}

} #End End

} # End Get-SecArpTable

Hope you enjoy!

Tags// ,