Monday, 8 February 2016

I've had a requirement to audit a whole site, where no knowledge of the devices are on there.  This is a combination of scripts taken from:
https://gallery.technet.microsoft.com/scriptcenter/Invoke-TSPingSweep-b71f1b9b
and http://www.truesec.com

The only information I have is the gateways on each site should be at IP x.y.z.1, but also might be at x.y.z.17.  These gateways should reply to a ping.  The ranges are all 10.x.y.z with a mask of 255.255.255.0

The scripts on these sites originally took parameters, I've butchered this script to have hard coded settings.  It looks for the first 18 addresses (line 132).  If there is no reply to a ping by then, assume the range is dead.

If it finds a valid ping reply, the full range is port scanned for the list of ports I'm interested in at line 66.

Once its done, a CSV is produced.  That will be read into SQL so I can lookup which IPs have which ports open on them.  I can infer what types of machines I can see then, e.g.
Port 9100 would be a printer,
443 and 902 might be an ESXi host,
8080, 443 and 21 may be a QNAP


cls


#https://gallery.technet.microsoft.com/scriptcenter/Invoke-TSPingSweep-b71f1b9b
function Invoke-TSPingSweep {
  <#
    .SYNOPSIS
    Scan IP-Addresses, Ports and HostNames

    .DESCRIPTION
    Scan for IP-Addresses, HostNames and open Ports in your Network.
   
    .PARAMETER StartAddress
    StartAddress Range

    .PARAMETER EndAddress
    EndAddress Range

    .PARAMETER ResolveHost
    Resolve HostName

    .PARAMETER ScanPort
    Perform a PortScan

    .PARAMETER Ports
    Ports That should be scanned, default values are: 21,22,23,53,69,71,80,98,110,139,111,
    389,443,445,1080,1433,2001,2049,3001,3128,5222,6667,6868,7777,7878,8080,1521,3306,3389,
    5801,5900,5555,5901

    .PARAMETER TimeOut
    Time (in MilliSeconds) before TimeOut, Default set to 100

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.0.254

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.0.254 -ResolveHost

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.0.254 -ResolveHost -ScanPort

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.0.254 -ResolveHost -ScanPort -TimeOut 500

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.10.254 -ResolveHost -ScanPort -Port 80

    .LINK
    http://www.truesec.com

    .NOTES
    Goude 2012, TrueSec
  #>
  Param(
    [parameter(Mandatory = $true,
      Position = 0)]
    [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")]
    [string]$StartAddress,
    [parameter(Mandatory = $true,
      Position = 1)]
    [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")]
    [string]$EndAddress,
    [switch]$ResolveHost,
    [switch]$ScanPort,
    [int[]]$Ports = @(21,22,23,25,53,69,80,110,123,139,389,443,445,636,901,902,1433,3260,3306,3389,4333,5800,5900,8080,9100),
    [int]$TimeOut = 100
  )
  Begin {
    $ping = New-Object System.Net.Networkinformation.Ping
  }
  Process {
    foreach($a in ($StartAddress.Split(".")[0]..$EndAddress.Split(".")[0])) {
      foreach($b in ($StartAddress.Split(".")[1]..$EndAddress.Split(".")[1])) {
        foreach($c in ($StartAddress.Split(".")[2]..$EndAddress.Split(".")[2])) {
          foreach($d in ($StartAddress.Split(".")[3]..$EndAddress.Split(".")[3])) {
            write-progress -activity PingSweep -status "$a.$b.$c.$d" -percentcomplete (($d/($EndAddress.Split(".")[3])) * 100)
            $pingStatus = $ping.Send("$a.$b.$c.$d",$TimeOut)
            if($pingStatus.Status -eq "Success") {
              if($ResolveHost) {
                write-progress -activity ResolveHost -status "$a.$b.$c.$d" -percentcomplete (($d/($EndAddress.Split(".")[3])) * 100) -Id 1
                $getHostEntry = [Net.DNS]::BeginGetHostEntry($pingStatus.Address, $null, $null)
              }
              if($ScanPort) {
                $openPorts = @()
                for($i = 1; $i -le $ports.Count;$i++) {
                  $port = $Ports[($i-1)]
                  write-progress -activity PortScan -status "$a.$b.$c.$d" -percentcomplete (($i/($Ports.Count)) * 100) -Id 2
                  $client = New-Object System.Net.Sockets.TcpClient
                  $beginConnect = $client.BeginConnect($pingStatus.Address,$port,$null,$null)
                  if($client.Connected) {
                    $openPorts += $port
                  } else {
                    # Wait
                    Start-Sleep -Milli $TimeOut
                    if($client.Connected) {
                      $openPorts += $port
                    }
                  }
                  $client.Close()
                }
              }
              if($ResolveHost) {
                $hostName = ([Net.DNS]::EndGetHostEntry([IAsyncResult]$getHostEntry)).HostName
              }
              # Return Object
              New-Object PSObject -Property @{
                IPAddress = "$a.$b.$c.$d";
                HostName = $hostName;
                Ports = $openPorts
              } | Select-Object IPAddress, HostName, Ports
            }
          }
        }
      }
    }
  }
  End {
  }
}

# Variables don't change
[int16] $x = 0
[int16] $y = 0


# varialbles change
[string] $outputFile = "C:\scripts\scanEntireNetwork\output.csv"
[string] $startingIP = "10.x.y.z"
$startingOctave = 0  # If the IP range starts at zero, change this to 0
$endingOctave = 255  # If you want to only go through half a range (why?), limit this upper value
$rangeCheck = 18 # How many ips to check at the start of the range before the range is skipped
[int16] $xStart = $startingOctave
[int16] $yStart = $startingOctave
[int16] $zStart = $startingOctave




#if (Test-Path $outputFile)
#{
#    Remove-Item $outputFile -Force
#}

for ($x = $xStart; $x -le $endingOctave; $x++)
{
    for ($y = $yStart; $y -le $endingOctave; $y++)
    {
        #$ActiveMachinesAndPorts.Clear()
        $startIP = $startingIP.Replace("x",$x).Replace("y",$y).Replace("z",$startingOctave)
        $endIP = $startingIP.Replace("x",$x).Replace("y",$y).Replace("z",$endingOctave)
        $endCheckIP = $startingIP.Replace("x",$x).Replace("y",$y).Replace("z",$rangeCheck)
        $startIP

        #Check the first 5 addresses for a ping reply
        $quickCheck = Invoke-TSPingSweep -startAddress $startIP -EndAddress $endCheckIP
        if ($quickCheck)
        {
            #If it finds one, check the numbered ports in the entire range
            $ActiveMachinesAndPorts = Invoke-TSPingSweep -startAddress $startIP -EndAddress $endIP -ScanPort

            #Turn the Object into a String
            foreach ($singleMachine in $ActiveMachinesAndPorts)
            {
                $singleMachine.Ports = $singleMachine.Ports -join ","
                #$ActiveMachinesAndPorts.Ports = $ActiveMachinesAndPorts.Ports -join ","
            }

            #Write the data to a CSV
            $ActiveMachinesAndPorts | Export-Csv $outputFile -Append
        }
    }
}