欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

PowerShell脚本开发之批量扫描IP和端口

程序员文章站 2022-03-14 08:01:53
前面的文章中曾经发布了对指定ip进行批量端口扫描的方法和脚本,过powershell收发tcp和udp消息包的方法以及通过powershell尝试登录sqlserver服务...

前面的文章中曾经发布了对指定ip进行批量端口扫描的方法和脚本,过powershell收发tcp和udp消息包的方法以及通过powershell尝试登录sqlserver服务的方法,这构成了psnet程序集用于通过powershell对网络状态进行操作。最近在不断尝试之下,找到了对指定范围的ip段进行扫描和对端口进行扫描的方法,本文将会介绍如何通过powershell批量扫描ip及其对应的端口。

依然在psnet程序集的基础上进行扩展,首先在$env:psspace/psnet/tcpop下创建脚本文件invoke-scanipport.ps1,并在$env:psspace/psnet/tcpop/psnet.psm1中添加对脚本文件的调用:

复制代码 代码如下:

. $env:psspace/psnet/tcpop/invoke-scanipport.ps1

首先对后面代码中将会出现的变量进行介绍:

复制代码 代码如下:

-startaddress[扫描的起始ip地址],与-endaddress配合使用,【此参数必须】
-endaddress[扫描的结束ip地址],【此参数必须】
-resolvehost[是否尝试对主机名尝试进行解析]
-scanport[是否进行端口扫描],如果要扫描端口此选项必须
-allport[是否对所有端口进行扫描],范围为1~65534(注意此选项扫描时间很长建议在选中单个ip的情况下进行使用,并且尽量少使用)
-startport[扫描的起始端口端口],与-endport配合使用,如果此选项与-ports选项同时存在则-port参数失效
-endport[扫描的结束端口]
-ports扫描时默认扫描的端口,如果后续不带参数则仅扫描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如果后续带多个以逗号分割的多个数字则会扫描数字对应的端口,如果只扫描默认的端口,则不需此参数
-timeout超时时间,默认值为100ms(毫秒)

此函数的调用方式如下:

复制代码 代码如下:

invoke-scanipport -startaddress 192.168.10.1 -endaddress 192.168.10.254#扫描ip段
invoke-scanipport -startaddress 192.168.10.1 -endaddress 192.168.10.254 –resolvehost#扫描ip段,并尝试解析ip对应主机名
invoke-scanipport -startaddress 192.168.10.1 -endaddress 192.168.10.254 -resolvehost –scanport#扫描ip段,并尝试扫描默认端口
invoke-scanipport -startaddress 192.168.10.1 -endaddress 192.168.10.254 -resolvehost -scanport -timeout 50 #扫描ip段,尝试扫描默认端口,端口扫描50ms超时
invoke-scanipport -startaddress 192.168.10.1 -endaddress 192.168.10.254 -resolvehost -scanport -port 80 #扫描ip段,并尝试扫描80端口
invoke-scanipport -startaddress 192.168.10.1 -endaddress 192.168.10.1 -resolvehost -scanport –allport#扫描ip,并尝试扫描所有1~65534之间端口
invoke-scanipport -startaddress 192.168.10.1 -endaddress 192.168.10.254 -scanport -starport 21 -endport 81#扫描ip段之间主机所有21至81之间的端口

上图来一张扫描过程中的图片

PowerShell脚本开发之批量扫描IP和端口

扫描结束后的结果:

PowerShell脚本开发之批量扫描IP和端口

代码如下:

复制代码 代码如下:

 =====文件名:invoke-scanipport.ps1=====
function invoke-scanipport {
  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,
    [switch]$allport,
    [int]$startport,
    [int]$endport,
    [int[]]$ports = @(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),
    [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])) {
            $ip = "$a.$b.$c.$d"
            write-progress -activity "scanip ping" -status "$ip" -percentcomplete (($d/($endaddress.split(".")[3])) * 100)
            $pingstatus = $ping.send("$ip",$timeout)
            if($pingstatus.status -eq "success") {
              if($resolvehost) {
                write-progress -activity resolvehost -status "$ip" -percentcomplete (($d/($endaddress.split(".")[3])) * 100) -id 1
                $gethostentry = [net.dns]::begingethostentry($pingstatus.address, $null, $null)
              }
              if($scanport) {
                if($allport) {
                    $ports = @(1..65534)
                }
                if($startport -ne $null -and $endport -ne $null){
                    $ports = @($startport..$endport)
                }
                $openports = @()
                for($i = 1; $i -le $ports.count;$i++) {
                  $port = $ports[($i-1)]
                  write-progress -activity "portscan[$port]$result" -status "$ip" -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
                      $length=$openports.length
                      $result="[find $length ports.last port $port]"
                    }
                  }
                  $client.close()
                }
              }
              if($resolvehost) {
                $hostname = ([net.dns]::endgethostentry([iasyncresult]$gethostentry)).hostname
              }
              # return object
              if ($openports -ne $null)
              {
              write-host "ipaddress" "$ip"
              if ($gethostentry -ne $null)
              {write-host "hostname" $gethostentry}
              write-host "ports" $openports
              }
           }
          }
        }
      }
    }
  }
  end {
  }
}