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之间的端口
上图来一张扫描过程中的图片
扫描结束后的结果:
代码如下:
复制代码 代码如下:
=====文件名: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 {
}
}