Giter Club home page Giter Club logo

pslanscan's Introduction

PSLANScan

version

PSLANScan is a PowerShell module for layer 2 host discovery via ARP. It quickly finds live hosts on your network segment given a list of IP addresses, even if the hosts have ICMP/ping blocked by a firewall.

Installation

Via PowerShell Gallery

Install-Module -Name PSLANScan -Scope CurrentUser

Via Git

Clone the repository and run .\build.ps1 deploy.

This will install several modules if you do not already have them, see build.ps1 for details. These are only required for the build process and are not otherwise used by PSLANScan.

Manually

Copy the files from src to $Home\Documents\WindowsPowerShell\Modules\PSLANScan for PowerShell 5.1 or $Home\Documents\PowerShell\Modules\PSLANScan for PowerShell 7, and rename the .ps1 file(s) to .psm1.

Usage

Find-LANHosts [-IP <String[]>] [-NetAdapter <CimInstance[]>] [-DelayMS <int>] [-ClearARPCache]

Examples

Find-LANHosts
Find-LANHosts -ClearARPCache -DelayMS 5
Get-NetAdapter -Name Ethernet | Find-LANHosts
Get-NetAdapter | ? {($_ | Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue) -ne $null} | Find-LANHosts
Get-NetRoute -DestinationPrefix 0.0.0.0/0 | Get-NetAdapter | Find-LANHosts
$IPs = 1..254 | % {"192.168.0.$_"}
Find-LANHosts $IPs
1..254 | % {"192.168.1.$_"} | Find-LANHosts -ClearARPCache
1..254 | % {"10.1.1.$_"} | Find-LANHosts -DelayMS 5

More info

See this blog post for further details.

pslanscan's People

Contributors

mdjx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

pslanscan's Issues

Does the UDP client connection need to be closed are re-initialised for each new IP address?

Hey,

I was scanning the Internat for a native PS way to run an ARP scan and came across your blog and hence GitHub repo. I thought "great, this is exactly what I need". I even thought "awesome" when I noted one of your examples was to pipe in the interface that has been assigned the default gateway, so ignoring VNets and the like. However, on running Find-LANHosts with a set of IP addresses, I noted something odd.

The returned list from the arp cache was a lot smaller than I anticipated. Running a Wireshark scan after flushing the ARP cache, I noted that relatively few ARP requests were being sent. Slow the function down by running it through the VS Code debugger, it seems that seven though you are looping through the IPs in the relevant array, the Connect method only connects to the first IP that was used after the Udpclient was initiated. Hence, I only see an ARP request for the first IP in the array.

The function then only returns items that are already in the arp cache or makes it to the catch before it completes.

Based on https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.udpclient?view=net-6.0, I think that you need to call the Close method of the Udpclient, then initialise a new Udpclient for each IP address.

As an example, I think this does the trick (but I'm no expert here, so creating and closing Udpclients like this might be inefficient :) )

<#
    .SYNOPSIS
    Quickly finds host on a local network using ARP for discovery

    .DESCRIPTION
    Uses ARP requests to determine whether a host is present on a network segment.

    As APR is a Layer 2 mechanism, the list of IP addesses need to be on the same network as the device running the script.

    .PARAMETER IP
    Optional. Specifies one or more IP addresses to scan for. Typically this will be a list of all usable hosts on a network.

    .PARAMETER NetAdapter
    Optional. Specifies one or more NetAdaper (CimInstance) objects from Get-NetAdapter. These interfaces will have attached subnets detected and used for the scan.

    If both the IP and NetAdapter parameters are omitted, all network adapters will be enumerated and local subnets automatically determined. This may require elevated priviliges.
    Please note that this can include adapters with very high host counts (/16, etc) which will take considerable time to enumerate.

    .PARAMETER DelayMS
    Optional. Specifies the interpacket delay, default is 2ms. Can be increased if scanning unreliable or high latency networks.

    .PARAMETER ClearARPCache
    Optional. Clears the ARP cache before starting a scan. This is recommended, but may require elevated priviliges.

    .EXAMPLE
    Find-LANHosts

    .EXAMPLE
    Find-LANHosts -ClearARPCache -DelayMS 5

    .EXAMPLE
    Get-NetAdapter -Name Ethernet | Find-LANHosts

    .EXAMPLE
    Get-NetAdapter | ? {($_ | Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue) -ne $null} | Find-LANHosts

    .EXAMPLE
    Get-NetRoute -DestinationPrefix 0.0.0.0/0 | Get-NetAdapter | Find-LANHosts

    .EXAMPLE
    $IPs = 1..254 | % {"10.250.1.$_"}
    Find-LANHosts -IP $IPs

    .EXAMPLE
    1..254 | % {"192.168.1.$_"} | Find-LANHosts -ClearARPCache

    .EXAMPLE
    1..254 | % {"10.1.1.$_"} | Find-LANHosts -DelayMS 5

    .LINK
    https://github.com/mdjx/PSLANScan
#>
function Find-LANHosts {
    [Cmdletbinding(DefaultParameterSetName = "IPBlock")]

    Param (
        [Parameter(Mandatory = $false, ValueFromPipeline, ParameterSetName = "IPBlock")]
        [string[]]$IP = $null,

        [Parameter(Mandatory = $false, ValueFromPipeline, ParameterSetName = "Interface")]
        [CimInstance[]]$NetAdapter = $null,

        [Parameter(Mandatory = $false, Position = 2)]
        [ValidateRange(0, 15000)]
        [int]$DelayMS = 2,

        [switch]$ClearARPCache
    )

    Begin {

        $ASCIIEncoding = New-Object System.Text.ASCIIEncoding
        $Bytes = $ASCIIEncoding.GetBytes("!")
        #$UDP = New-Object System.Net.Sockets.Udpclient

        if ($ClearARPCache) {
            $ARPClear = arp -d 2>&1
            if (($ARPClear.count -gt 0) -and ($ARPClear[0] -is [System.Management.Automation.ErrorRecord]) -and ($ARPClear[0].Exception -notmatch "The parameter is incorrect")) {
                Throw $ARPClear[0].Exception
            }
        }

        $IPList = [System.Collections.ArrayList]@()
        $Timer = [System.Diagnostics.Stopwatch]::StartNew()
        Write-Verbose "Beginning scan"
    }

    Process {

        if (($null -eq $IP) -and ($null -eq $NetAdapter)) {
            if ($VerbosePreference -eq "SilentlyContinue") { [array]$IP = Get-IPs -ReturnIntRange }
            else {[array]$IP = Get-IPs -ReturnIntRange -Verbose }
        }

        if ($PsCmdlet.ParameterSetName -eq "Interface") {
            if ($VerbosePreference -eq "SilentlyContinue") {[array]$IP = Get-IPs -NetAdapter $NetAdapter -ReturnIntRange }
            else { [array]$IP = Get-IPs -NetAdapter $NetAdapter -ReturnIntRange -Verbose }
        }

        if ($IP.Count -lt 1) {
            Write-Error "IP Count is less than 1, please check provided IPs or Adapter for valid address space"
        }

        if ($null -ne $IP.FirstIPInt) {
            $IP | ForEach-Object {
                $CurrentIPInt = $_.FirstIPInt
                Do {
                    $UDP = New-Object System.Net.Sockets.Udpclient
                    $CurrIP = [IPAddress]$CurrentIPInt
                    $CurrIP = ($CurrIP).GetAddressBytes()
                    [Array]::Reverse($CurrIP)
                    $CurrIP = ([IPAddress]$CurrIP).IPAddressToString
                    #$UDP.Connect($CurrIP, 1)
                    #[void]$UDP.Send($Bytes, $Bytes.length)
                    [void]$UDP.Send($Bytes, $Bytes.length, $CurrIP, 1)
                    [void]$IPList.Add($CurrIP)
                    if ($DelayMS) {
                        [System.Threading.Thread]::Sleep($DelayMS)
                    }

                    $CurrentIPInt++
                    $UDP.Close()
                } While ($CurrentIPInt -le $_.LastIPInt)
            }
        }
        else {
            $IP | ForEach-Object {
                $UDP = New-Object System.Net.Sockets.Udpclient
                #$UDP.Connect($_, 1)
                #[void]$UDP.Send($Bytes, $Bytes.length)
                [void]$UDP.Send($Bytes, $Bytes.length, $_, 1)
                [void]$IPList.Add($_)
                if ($DelayMS) {
                    [System.Threading.Thread]::Sleep($DelayMS)
                }
                $UDP.Close()
            }
        }
    }

    End {
        $Hosts = arp -a
        $Timer.Stop()

        if ($Timer.Elapsed.TotalSeconds -gt 15) {
            Write-Warning "Scan took longer than 15 seconds, ARP entries may have been flushed. Recommend lowering DelayMS parameter"
        }

        $Hosts = $Hosts | Where-Object { $_ -match "dynamic" } | % { ($_.trim() -replace " {1,}", ",") | ConvertFrom-Csv -Header "IP", "MACAddress" }
        $Hosts = $Hosts | Where-Object { $_.IP -in $IPList }

        Write-Output $Hosts
    }
}

Find-LANHosts -IP $IPs

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.