diff options
Diffstat (limited to '')
| -rwxr-xr-x | wreath/tools/Enumeration/Linux/nmap | bin | 0 -> 5944464 bytes | |||
| -rw-r--r-- | wreath/tools/Enumeration/Windows/Invoke-Portscan.ps1 | 1108 | 
2 files changed, 1108 insertions, 0 deletions
| diff --git a/wreath/tools/Enumeration/Linux/nmap b/wreath/tools/Enumeration/Linux/nmapBinary files differ new file mode 100755 index 0000000..ba21ce5 --- /dev/null +++ b/wreath/tools/Enumeration/Linux/nmap diff --git a/wreath/tools/Enumeration/Windows/Invoke-Portscan.ps1 b/wreath/tools/Enumeration/Windows/Invoke-Portscan.ps1 new file mode 100644 index 0000000..48de690 --- /dev/null +++ b/wreath/tools/Enumeration/Windows/Invoke-Portscan.ps1 @@ -0,0 +1,1108 @@ +function Invoke-Portscan +{ +<# +.SYNOPSIS + +Simple portscan module + +PowerSploit Function: Invoke-Portscan +Author: Rich Lundeen (http://webstersProdigy.net) +License: BSD 3-Clause +Required Dependencies: None +Optional Dependencies: None + +.DESCRIPTION + +Does a simple port scan using regular sockets, based (pretty) loosely on nmap + +.NOTES + +version .13 + +.PARAMETER Hosts + +Include these comma seperated hosts (supports IPv4 CIDR notation) or pipe them in + +.PARAMETER HostFile + +Input hosts from file rather than commandline + +.PARAMETER ExcludeHosts + +Exclude these comma seperated hosts + +.PARAMETER Ports + +Include these comma seperated ports (can also be a range like 80-90) + +.PARAMETER PortFile + +Input ports from a file + +.PARAMETER TopPorts + +Include the x top ports - only goes to 1000, default is top 50 + +.PARAMETER ExcludedPorts + +Exclude these comma seperated ports + +.PARAMETER Open + +Only show hosts with open ports. + +.PARAMETER SkipDiscovery + +Treat all hosts as online, skip host discovery + +.PARAMETER PingOnly + +Ping scan only (disable port scan) + +.PARAMETER DiscoveryPorts + +Comma separated ports used for host discovery. -1 is a ping + +.PARAMETER Threads + +number of max threads for the thread pool (per host) + +.PARAMETER nHosts + +number of hosts to concurrently scan + +.PARAMETER Timeout + +Timeout time on a connection in miliseconds before port is declared filtered + +.PARAMETER SleepTimer + +Wait before thread checking, in miliseconds + +.PARAMETER SyncFreq + +How often (in terms of hosts) to sync threads and flush output + +.PARAMETER T + +[0-5] shortcut performance options. Default is 3. higher is more aggressive. Sets (nhosts, threads,timeout) +    5 {$nHosts=30;  $Threads = 1000; $Timeout = 750  } +    4 {$nHosts=25;  $Threads = 1000; $Timeout = 1200 } +    3 {$nHosts=20;  $Threads = 100;  $Timeout = 2500 } +    2 {$nHosts=15;  $Threads = 32;   $Timeout = 3000 } +    1 {$nHosts=10;  $Threads = 32;   $Timeout = 5000 } + +.PARAMETER GrepOut + +Greppable output file + +.PARAMETER XmlOut + +output XML file + +.PARAMETER ReadableOut + +output file in 'readable' format + +.PARAMETER AllformatsOut + +output in readable (.nmap), xml (.xml), and greppable (.gnmap) formats + +.PARAMETER noProgressMeter + +Suppresses the progress meter + +.PARAMETER quiet + +supresses returned output and don't store hosts in memory - useful for very large scans + +.PARAMETER ForceOverwrite + +Force Overwrite if output Files exist. Otherwise it throws exception + +.EXAMPLE + +C:\PS> Invoke-Portscan -Hosts "webstersprodigy.net,google.com,microsoft.com" -TopPorts 50 + +Description +----------- +Scans the top 50 ports for hosts found for webstersprodigy.net,google.com, and microsoft.com + +.EXAMPLE + +C:\PS> echo webstersprodigy.net | Invoke-Portscan -oG test.gnmap -f -ports "80,443,8080" + +Description +----------- +Does a portscan of "webstersprodigy.net", and writes a greppable output file + +.EXAMPLE + +C:\PS> Invoke-Portscan -Hosts 192.168.1.1/24 -T 4 -TopPorts 25 -oA localnet + +Description +----------- +Scans the top 20 ports for hosts found in the 192.168.1.1/24 range, outputs all file formats + +.LINK + +http://webstersprodigy.net +#> + +    [CmdletBinding()]Param ( +        #Host, Ports +        [Parameter(ParameterSetName="cmdHosts", + +                   ValueFromPipeline=$True, +                   Mandatory = $True)] +                   [String[]] $Hosts, + +        [Parameter(ParameterSetName="fHosts", +                   Mandatory = $True)] +                   [Alias("iL")] +                   [String]  $HostFile, + +        [Parameter(Mandatory = $False)] +                   [Alias("exclude")] +                   [String] $ExcludeHosts, + +        [Parameter(Mandatory = $False)] +                   [Alias("p")] +                   [String] $Ports, + +        [Parameter(Mandatory = $False)] +                   [Alias("iP")] +                   [String] $PortFile, + +        [Parameter(Mandatory = $False)] +                   [String] $TopPorts, + +        [Parameter(Mandatory = $False)] +                   [Alias("xPorts")] +                   [String] $ExcludedPorts, + +        [Parameter(Mandatory = $False)] +                   [Switch] $Open, + +        #Host Discovery +        [Parameter(Mandatory = $False)] +                   [Alias("Pn")] +                   [Switch] $SkipDiscovery, + +        [Parameter(Mandatory = $False)] +                   [Alias("sn")] +                   [Switch] $PingOnly, + +        [Parameter(Mandatory = $False)] +                   [Alias("PS")] +                   [string] $DiscoveryPorts = "-1,445,80,443", + +        #Timing and Performance +        [Parameter(Mandatory = $False)] +                   [int] $Threads = 100, + +        [Parameter(Mandatory = $False)] +                   [int] $nHosts = 25, + +        [Parameter(Mandatory = $False)] +                   [int] $Timeout = 2000, + +        [Parameter(Mandatory = $False)] +                   [int] $SleepTimer = 500, + +        [Parameter(Mandatory = $False)] +                   [int] $SyncFreq = 1024, + +        [Parameter(Mandatory = $False)] +                   [int] $T, + +        #Output +        [Parameter(Mandatory = $False)] +                   [Alias("oG")] +                   [String] $GrepOut, + +        [Parameter(Mandatory = $False)] +                   [Alias("oX")] +                   [String] $XmlOut, + +        [Parameter(Mandatory = $False)] +                   [Alias("oN")] +                   [String] $ReadableOut, + +        [Parameter(Mandatory = $False)] +                   [Alias("oA")] +                   [String] $AllformatsOut, + +        [Parameter(Mandatory = $False)] +                   [Switch] $noProgressMeter, + +        [Parameter(Mandatory = $False)] +                   [Alias("q")] +                   [Switch] $quiet, + +        [Parameter(Mandatory = $False)] +                   [Alias("F")] +                   [Switch] $ForceOverwrite + +        #TODO add script parameter +        #TODO add resume parameter +    ) + +    PROCESS { + +        Set-StrictMode -Version 2.0 + +        $version = .13 +        $hostList = New-Object System.Collections.ArrayList +        $portList = New-Object System.Collections.ArrayList +        $hostPortList = New-Object System.Collections.ArrayList + +        $scannedHostList = @() + +        function Parse-Hosts +        { +            Param ( +                [Parameter(Mandatory = $True)] [String] $Hosts +            ) + +            [String[]] $iHosts = $Hosts.Split(",") + +            foreach($iHost in $iHosts) +            { +                $iHost = $iHost.Replace(" ", "") + +                if(!$iHost) +                { +                    continue +                } + +                if($iHost.contains("/")) +                { +                    $netPart = $iHost.split("/")[0] +                    [uint32]$maskPart = $iHost.split("/")[1] + +                    $address = [System.Net.IPAddress]::Parse($netPart) + +                    if ($maskPart -ge $address.GetAddressBytes().Length * 8) +                    { +                        throw "Bad host mask" +                    } + +                    $numhosts = [System.math]::Pow(2,(($address.GetAddressBytes().Length *8) - $maskPart)) + +                    $startaddress = $address.GetAddressBytes() +                    [array]::Reverse($startaddress) + +                    $startaddress = [System.BitConverter]::ToUInt32($startaddress, 0) +                    [uint32]$startMask = ([System.math]::Pow(2, $maskPart)-1) * ([System.Math]::Pow(2,(32 - $maskPart))) +                    $startAddress = $startAddress -band $startMask + +                    #in powershell 2.0 there are 4 0 bytes padded, so the [0..3] is necessary +                    $startAddress = [System.BitConverter]::GetBytes($startaddress)[0..3] +                    [array]::Reverse($startaddress) + +                    $address = [System.Net.IPAddress] [byte[]] $startAddress + +                    $hostList.Add($address.IPAddressToString) + +                    for ($i=0; $i -lt $numhosts-1; $i++) +                    { + +                        $nextAddress =  $address.GetAddressBytes() +                        [array]::Reverse($nextAddress) +                        $nextAddress =  [System.BitConverter]::ToUInt32($nextAddress, 0) +                        $nextAddress ++ +                        $nextAddress = [System.BitConverter]::GetBytes($nextAddress)[0..3] +                        [array]::Reverse($nextAddress) + +                        $address = [System.Net.IPAddress] [byte[]] $nextAddress +                        $hostList.Add($address.IPAddressToString) + +                    } + +                } +                else +                { +                    $hostList.Add($iHost) +                } +            } +        } + +        function Parse-ILHosts +        { +           Param ( +                [Parameter(Mandatory = $True)] [String] $HostFile +            ) + +            Get-Content $HostFile | ForEach-Object { +                Parse-Hosts $_ +            } +        } + +        function Exclude-Hosts +        { +            Param ( +                [Parameter(Mandatory = $True)] [String] $excludeHosts +            ) + +            [String[]] $iHosts = $excludeHosts.Split(",") + +            foreach($iHost in $iHosts) +            { +                $iHost = $iHost.Replace(" ", "") +                $hostList.Remove($iHost) +            } +        } + +        function Get-TopPort +        { +            Param ( +                [Parameter(Mandatory = $True)] +                [ValidateRange(1,1000)] +                [int] $numPorts +            ) + +            #list of top 1000 ports from nmap from Jun 2013 +            [int[]] $topPortList = @(80,23,443,21,3389,110,445,139,143,53,135,3306,8080,22 +                        1723,111,995,993,5900,1025,1720,548,113,81,6001,179,1026,2000,8443, +                        8000,32768,554,26,1433,49152,2001,515,8008,49154,1027,5666,646,5000, +                        5631,631,49153,8081,2049,88,79,5800,106,2121,1110,49155,6000,513, +                        990,5357,49156,543,544,5101,144,7,389,8009,9999,5009,7070,5190,3000, +                        5432,1900,3986,13,1029,9,5051,6646,49157,1028,873,1755,2717,4899,9100, +                        119,37,1000,3001,5001,82,10010,1030,9090,2107,1024,2103,6004,1801, +                        5050,19,8031,1041,255,1048,1049,1053,1054,1056,1064,3703,17,808,3689, +                        1031,1044,1071,5901,100,9102,2869,4001,5120,8010,9000,2105,636,1038, +                        2601,1,7000,1066,1069,625,311,280,254,4000,1761,5003,2002,1998,2005, +                        1032,1050,6112,1521,2161,6002,2401,902,4045,787,7937,1058,2383,1033, +                        1040,1059,50000,5555,1494,3,593,2301,3268,7938,1022,1234,1035,1036,1037, +                        1074,8002,9001,464,497,1935,2003,6666,6543,24,1352,3269,1111,407,500, +                        20,2006,1034,1218,3260,15000,4444,264,33,2004,1042,42510,999,3052,1023, +                        222,1068,888,7100,1717,992,2008,7001,2007,8082,512,1043,2009,5801,1700, +                        7019,50001,4662,2065,42,2602,3333,9535,5100,2604,4002,5002,1047,1051,1052, +                        1055,1060,1062,1311,3283,4443,5225,5226,6059,6789,8089,8651,8652,8701,9415, +                        9593,9594,9595,16992,16993,20828,23502,32769,33354,35500,52869,55555,55600, +                        64623,64680,65000,65389,1067,13782,366,5902,9050,85,1002,5500,1863,1864, +                        5431,8085,10243,45100,49999,51103,49,90,6667,1503,6881,27000,340,1500,8021, +                        2222,5566,8088,8899,9071,5102,6005,9101,163,5679,146,648,1666,83,3476,5004, +                        5214,8001,8083,8084,9207,14238,30,912,12345,2030,2605,6,541,4,1248,3005,8007, +                        306,880,2500,1086,1088,2525,4242,8291,9009,52822,900,6101,2809,7200,211,800, +                        987,1083,12000,705,711,20005,6969,13783,1045,1046,1061,1063,1070,1072,1073, +                        1075,1077,1078,1079,1081,1082,1085,1093,1094,1096,1098,1099,1100,1104,1106, +                        1107,1108,1148,1169,1272,1310,1687,1718,1783,1840,2100,2119,2135,2144,2160, +                        2190,2260,2381,2399,2492,2607,2718,2811,2875,3017,3031,3071,3211,3300,3301, +                        3323,3325,3351,3404,3551,3580,3659,3766,3784,3801,3827,3998,4003,4126,4129, +                        4449,5222,5269,5633,5718,5810,5825,5877,5910,5911,5925,5959,5960,5961,5962, +                        5987,5988,5989,6123,6129,6156,6389,6580,6901,7106,7625,7777,7778,7911,8086, +                        8181,8222,8333,8400,8402,8600,8649,8873,8994,9002,9011,9080,9220,9290,9485, +                        9500,9502,9503,9618,9900,9968,10002,10012,10024,10025,10566,10616,10617,10621, +                        10626,10628,10629,11110,13456,14442,15002,15003,15660,16001,16016,16018,17988, +                        19101,19801,19842,20000,20031,20221,20222,21571,22939,24800,25734,27715,28201, +                        30000,30718,31038,32781,32782,33899,34571,34572,34573,40193,48080,49158,49159, +                        49160,50003,50006,50800,57294,58080,60020,63331,65129,691,212,1001,1999,2020, +                        2998,6003,7002,50002,32,2033,3372,99,425,749,5903,43,458,5405,6106,6502,7007, +                        13722,1087,1089,1124,1152,1183,1186,1247,1296,1334,1580,1782,2126,2179,2191,2251, +                        2522,3011,3030,3077,3261,3493,3546,3737,3828,3871,3880,3918,3995,4006,4111,4446, +                        5054,5200,5280,5298,5822,5859,5904,5915,5922,5963,7103,7402,7435,7443,7512,8011, +                        8090,8100,8180,8254,8500,8654,9091,9110,9666,9877,9943,9944,9998,10004,10778,15742, +                        16012,18988,19283,19315,19780,24444,27352,27353,27355,32784,49163,49165,49175, +                        50389,50636,51493,55055,56738,61532,61900,62078,1021,9040,666,700,84,545,1112, +                        1524,2040,4321,5802,38292,49400,1084,1600,2048,2111,3006,6547,6699,9111,16080, +                        555,667,720,801,1443,1533,2106,5560,6007,1090,1091,1114,1117,1119,1122,1131,1138, +                        1151,1175,1199,1201,1271,1862,2323,2393,2394,2608,2725,2909,3003,3168,3221,3322, +                        3324,3390,3517,3527,3800,3809,3814,3826,3869,3878,3889,3905,3914,3920,3945,3971, +                        4004,4005,4279,4445,4550,4567,4848,4900,5033,5080,5087,5221,5440,5544,5678,5730, +                        5811,5815,5850,5862,5906,5907,5950,5952,6025,6510,6565,6567,6689,6692,6779,6792, +                        6839,7025,7496,7676,7800,7920,7921,7999,8022,8042,8045,8093,8099,8200,8290,8292, +                        8300,8383,9003,9081,9099,9200,9418,9575,9878,9898,9917,10003,10180,10215,11111, +                        12174,12265,14441,15004,16000,16113,17877,18040,18101,19350,25735,26214,27356, +                        30951,32783,32785,40911,41511,44176,44501,49161,49167,49176,50300,50500,52673, +                        52848,54045,54328,55056,56737,57797,60443,70,417,714,722,777,981,1009,2022,4224, +                        4998,6346,301,524,668,765,2041,5999,10082,259,1007,1417,1434,1984,2038,2068,4343, +                        6009,7004,44443,109,687,726,911,1461,2035,4125,6006,7201,9103,125,481,683,903, +                        1011,1455,2013,2043,2047,6668,6669,256,406,843,2042,2045,5998,9929,31337,44442, +                        1092,1095,1102,1105,1113,1121,1123,1126,1130,1132,1137,1141,1145,1147,1149,1154, +                        1164,1165,1166,1174,1185,1187,1192,1198,1213,1216,1217,1233,1236,1244,1259,1277, +                        1287,1300,1301,1309,1322,1328,1556,1641,1688,1719,1721,1805,1812,1839,1875,1914, +                        1971,1972,1974,2099,2170,2196,2200,2288,2366,2382,2557,2800,2910,2920,2968,3007, +                        3013,3050,3119,3304,3307,3376,3400,3410,3514,3684,3697,3700,3824,3846,3848,3859, +                        3863,3870,3872,3888,3907,3916,3931,3941,3957,3963,3968,3969,3972,3990,3993,3994, +                        4009,4040,4080,4096,4143,4147,4200,4252,4430,4555,4600,4658,4875,4949,5040,5063, +                        5074,5151,5212,5223,5242,5279,5339,5353,5501,5807,5812,5818,5823,5868,5869,5899, +                        5905,5909,5914,5918,5938,5940,5968,5981,6051,6060,6068,6203,6247,6500,6504,6520, +                        6550,6600) +            $numPorts-- +            $portList.AddRange($topPortList[0..$numPorts]) +        } + +        function Parse-Ports +        { +            Param ( +                [Parameter(Mandatory = $True)] [String] $Ports, +                [Parameter(Mandatory = $True)] $pList +            ) + +            foreach ($pRange in $Ports.Split(",")) +            { + +                #-1 is a special case for ping +                if ($pRange -eq "-1") +                { +                    $pList.Add([int]$pRange) +                } +                elseif ($pRange.Contains("-")) +                { +                    [int[]] $range = $pRange.Split("-") +                    if ($range.Count -ne 2 -or $pRange.Split("-")[0] -eq "" -or $pRange.split("-")[1] -eq "") +                    { +                        throw "Invalid port range" +                    } + +                    $pList.AddRange($range[0]..$range[1]) +                } +                else +                { +                    $pList.Add([int]$pRange) +                } + +            } +            foreach ($p in $pList) +            { +                if ($p -lt -1 -or $p -gt 65535) +                { +                    throw "Port $p out of range" +                } +            } +         } + +        function Parse-IpPorts +        { +           Param ( +                [Parameter(Mandatory = $True)] [String] $PortFile +            ) + +            Get-Content $PortFile | ForEach-Object { +                Parse-Ports -Ports $_ -pList $portList +            } +        } + +        function Remove-Ports +        { +            Param ( +                [Parameter(Mandatory = $True)] [string] $ExcludedPorts +            ) + +            [int[]] $ExcludedPorts = $ExcludedPorts.Split(",") + +            foreach ($x in $ExcludedPorts) +            { +                $portList.Remove($x) +            } +        } + +        function Write-PortscanOut +        { +            Param ( +                [Parameter(Mandatory = $True, ParameterSetName="Comment")] [string] $comment, +                [Parameter(Mandatory = $True, ParameterSetName="HostOut")] [string] $outhost, +                [Parameter(Mandatory = $True, ParameterSetName="HostOut")] [bool] $isUp, +                [Parameter(Mandatory = $True, ParameterSetName="HostOut")] $openPorts, +                [Parameter(Mandatory = $True, ParameterSetName="HostOut")] $closedPorts, +                [Parameter(Mandatory = $True, ParameterSetName="HostOut")] $filteredPorts, +                [Parameter()] [bool] $SkipDiscovery, +                [Parameter()] [System.IO.StreamWriter] $grepStream, +                [Parameter()] [System.Xml.XmlWriter] $xmlStream, +                [Parameter()] [System.IO.StreamWriter] $readableStream + +            ) +            switch ($PSCmdlet.ParameterSetName) +            { +                "Comment" +                { + +                    Write-Verbose $comment + +                    if ($grepStream) { +                        $grepStream.WriteLine("# " + $comment) +                    } +                    if ($xmlStream) { +                        $xmlStream.WriteComment($comment) +                    } +                    if ($readableStream) { +                        $readableStream.WriteLine($comment) +                    } +                } +                "HostOut" +                { +                    $oPort = [string]::join(",", $openPorts.ToArray()) +                    $cPort = [string]::join(",", $closedPorts.ToArray()) +                    $fPort = [string]::join(",", $filteredPorts.ToArray()) + +                    if ($grepStream) { +                       #for grepstream use tabs - can be ugly, but easier for regex +                       if ($isUp -and !$SkipDiscovery) { +                            $grepStream.writeline("Host: $outhost`tStatus: Up") +                        } +                        if ($isUp -or $SkipDiscovery) { +                            if ($oPort -ne "") { +                                $grepStream.writeline("Host: $outhost`tOpen Ports: $oPort") +                            } +                            if ($cPort -ne "") { +                                $grepStream.writeline("Host: $outhost`tClosed Ports: $cPort") +                            } +                            if ($fPort -ne "") { +                                $grepStream.writeline("Host: $outhost`tFiltered Ports: $fPort") +                            } +                        } +                        elseif (!$SkipDiscovery) { +                            $grepStream.writeline("Host: $outhost`tStatus: Down") +                        } +                    } +                    if ($xmlStream) { +                        $xmlStream.WriteStartElement("Host") + +                        $xmlStream.WriteAttributeString("id", $outhost) +                        if (!$SkipDiscovery) { +                            if ($isUp) { +                                $xmlStream.WriteAttributeString("Status", "Up") +                             } +                             else { +                                $xmlStream.WriteAttributeString("Status", "Downs") +                             } +                        } + +                        $xmlStream.WriteStartElement("Ports") +                        foreach($p in $openPorts) { +                            $xmlStream.writestartElement("Port") +                            $xmlStream.WriteAttributeString("id", [string]$p) +                            $xmlStream.WriteAttributeString("state", "open") +                            $xmlStream.WriteEndElement() + +                        } +                        foreach ($p in $closedPorts) { +                            $xmlStream.writestartElement("Port") +                            $xmlStream.WriteAttributeString("id", [string]$p) +                            $xmlStream.WriteAttributeString("state", "closed") +                            $xmlStream.WriteEndElement() +                        } +                        foreach ($p in $filteredPorts) { +                            $xmlStream.writestartElement("Port") +                            $xmlStream.WriteAttributeString("id", [string]$p) +                            $xmlStream.WriteAttributeString("state", "filtered") +                            $xmlStream.WriteEndElement() +                        } + +                        $xmlStream.WriteEndElement() +                        $xmlStream.WriteEndElement() +                    } +                    if ($readableStream) { +                        $readableStream.writeline("Porscan.ps1 scan report for $outhost") +                        if ($isUp) { +                            $readableStream.writeline("Host is up") +                        } + +                        if ($isUp -or $SkipDiscovery) { + +                            $readableStream.writeline(("{0,-10}{1,0}" -f "PORT", "STATE")) + +                            [int[]]$allports = $openPorts + $closedPorts + $filteredPorts +                            foreach($p in ($allports| Sort-Object)) +                            { +                                if ($openPorts.Contains($p)) { +                                    $readableStream.writeline(("{0,-10}{1,0}" -f $p, "open")) +                                } +                                elseif ($closedPorts.Contains($p)) { +                                    $readableStream.writeline(("{0,-10}{1,0}" -f $p, "closed")) +                                } +                                elseif ($filteredPorts.Contains($p)) { +                                    $readableStream.writeline(("{0,-10}{1,0}" -f $p, "filtered")) +                                } +                            } + +                        } +                        elseif(!$SkipDiscovery) { +                            $readableStream.writeline("Host is Down") +                        } +                        $readableStream.writeline("") +                    } +                } +            } +        } + +        #function for Powershell v2.0 to work +        function Convert-SwitchtoBool +        { +            Param ( +                [Parameter(Mandatory = $True)] $switchValue +            ) +            If ($switchValue) { +                return $True +            } +            return $False +        } + +        try +        { + +            [bool] $SkipDiscovery = Convert-SwitchtoBool ($SkipDiscovery) +            [bool] $PingOnly = Convert-SwitchtoBool ($PingOnly) +            [bool] $quiet  = Convert-SwitchtoBool ($quiet) +            [bool] $ForceOverwrite  = Convert-SwitchtoBool ($ForceOverwrite) + +            ######### +            #parse arguments +            ######### + +            [Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath + +            if ($PsCmdlet.ParameterSetName -eq "cmdHosts") +            { +                foreach($h in $Hosts) +                { +                    Parse-Hosts($h) | Out-Null +                } +            } +            else +            { +                Parse-ILHosts($HostFile) | Out-Null +            } +            if($ExcludeHosts) +            { +                Exclude-Hosts($ExcludeHosts) +            } +            if (($TopPorts -and $Ports) -or ($TopPorts -and $PortFile)) +            { +                throw "Cannot set topPorts with other specific ports" +            } +            if($Ports) +            { +                Parse-Ports -Ports $Ports -pList $portList | Out-Null +            } +            if($PortFile) +            { +                Parse-IpPorts($PortFile) | Out-Null +            } +            if($portList.Count -eq 0) +            { +                if ($TopPorts) +                { +                    Get-TopPort($TopPorts) | Out-Null +                } +                else +                { +                    #if the ports still aren't set, give the deftault, top 50 ports +                    Get-TopPort(50) | Out-Null +                } +            } +            if ($ExcludedPorts) +            { +                Remove-Ports -ExcludedPorts $ExcludedPorts | Out-Null +            } + +            if($T) +            { +                switch ($T) +                { +                    5 {$nHosts=30;  $Threads = 1000; $Timeout = 750 } +                    4 {$nHosts=25;  $Threads = 1000; $Timeout = 1200 } +                    3 {$nHosts=20;  $Threads = 100;  $Timeout = 2500 } +                    2 {$nHosts=15;  $Threads = 32;   $Timeout = 3000 } +                    1 {$nHosts=10;  $Threads = 32;   $Timeout = 5000 } +                    default { +                        throw "Invalid T parameter" +                    } +                } +            } + +            $grepStream = $null +            $xmlStream = $null +            $readableStream = $null + +            if($AllformatsOut) +            { +                if ($GrepOut -or $XmlOut -or $ReadableOut) { +                     Write-Warning "Both -oA specified with other output... going to ignore -oG/-oN/-oX" +                } +                $GrepOut = $AllformatsOut + ".gnmap" +                $XmlOut = $AllformatsOut + ".xml" +                $ReadableOut = $AllformatsOut + ".nmap" +            } +            if ($GrepOut) { +                if (!$ForceOverwrite -and (Test-Path $GrepOut)) { +                    throw "Error: $AllformatsOut already exists. Either delete the file or specify the -f flag" +                } +                $grepStream = [System.IO.StreamWriter] $GrepOut +            } +            if ($ReadableOut) { +                if (!$ForceOverwrite -and (Test-Path $ReadableOut)) { +                    throw "Error: $ReadableOut already exists. Either delete the file or specify the -f flag" +                } +                $readableStream = [System.IO.StreamWriter] $ReadableOut +            } +            if ($XmlOut) { +                if (!$ForceOverwrite -and (Test-Path $XmlOut)) { +                    throw "Error: $XmlOut already exists. Either delete the file or specify the -f flag" +                } + +                $xmlStream =   [System.xml.xmlwriter]::Create([string]$XmlOut) +                $xmlStream.WriteStartDocument() +                $xmlStream.WriteStartElement("Portscanrun") +                $xmlStream.WriteAttributeString("version", $version) + +            } + +            Parse-Ports -Ports $DiscoveryPorts -pList $hostPortList | Out-Null + +            $startdate = Get-Date +            $myInvocationLine = $PSCmdlet.MyInvocation.Line +            $startMsg = "Invoke-Portscan.ps1 v$version scan initiated $startdate as: $myInvocationLine" + +            #TODO deal with output +            Write-PortscanOut -comment $startMsg -grepStream $grepStream -xmlStream $xmlStream -readableStream $readableStream + +            #converting back from int array gives some argument error checking +            $sPortList = [string]::join(",", $portList) +            $sHostPortList = [string]::join(",", $hostPortList) + +            ######## +            #Port Scan Code - run on a per host basis +            ######## +            $portScanCode = { +                param ( +                    [Parameter( Mandatory = $True)] [string] $thost, +                    [Parameter( Mandatory = $True)][bool] $SkipDiscovery, +                    [Parameter( Mandatory = $True)][bool] $PingOnly, +                    [Parameter( Mandatory = $True)][int] $Timeout, +                    [Parameter( Mandatory = $True)] $PortList, +                    [Parameter( Mandatory = $True)] $hostPortList, +                    [Parameter( Mandatory = $True)][int] $maxthreads) +                Process +                { +                $openPorts = New-Object System.Collections.ArrayList +                $closedPorts = New-Object System.Collections.ArrayList +                $filteredPorts = New-Object System.Collections.ArrayList + +                $sockets = @{} +                $timeouts = New-Object Hashtable + +                #set maximum $async threads +                $fThreads = New-Object int +                $aThreads = New-Object int +                [System.Threading.ThreadPool]::GetMaxThreads([ref]$fThreads, [ref]$aThreads) | Out-Null +                [System.Threading.ThreadPool]::SetMaxThreads($fthreads,$maxthreads) | Out-Null + +                function New-ScriptBlockCallback { +                    param( +                        [parameter(Mandatory=$true)] +                        [ValidateNotNullOrEmpty()] +                        [scriptblock]$Callback +                    ) + +                    #taken from http://www.nivot.org/blog/post/2009/10/09/PowerShell20AsynchronousCallbacksFromNET +                    if (-not ("CallbackEventBridge" -as [type])) { +                        Add-Type @" +                            using System; + +                            public sealed class CallbackEventBridge +                            { +                                public event AsyncCallback CallbackComplete = delegate { }; + +                                private CallbackEventBridge() {} + +                                private void CallbackInternal(IAsyncResult result) +                                { +                                    CallbackComplete(result); +                                } + +                                public AsyncCallback Callback +                                { +                                    get { return new AsyncCallback(CallbackInternal); } +                                } + +                                public static CallbackEventBridge Create() +                                { +                                    return new CallbackEventBridge(); +                                } +                            } +"@ +                    } + +                    $bridge = [CallbackEventBridge]::Create() +                    Register-ObjectEvent -InputObject $bridge -EventName CallbackComplete -Action $Callback | Out-Null + +                    $bridge.Callback + +                } + +                function Test-Port { + +                    Param ( +                        [Parameter(Mandatory = $True)] [String] $h, +                        [Parameter(Mandatory = $True)] [int] $p, +                        [Parameter(Mandatory = $True)] [int] $timeout +                    ) + +                    try { +                        $pAddress = [System.Net.IPAddress]::Parse($h) +                        $sockets[$p] = new-object System.Net.Sockets.TcpClient $pAddress.AddressFamily + +                    } +                    catch { +                        #we're assuming this is a host name +                        $sockets[$p] = new-object System.Net.Sockets.TcpClient +                    } + +                     +                    $scriptBlockAsString = @" + +                        #somewhat of a race condition with the timeout, but I don't think it matters +                        if ( `$sockets[$p] -ne `$NULL) +                        { +                            if (!`$timeouts[$p].Disposed) { +                                `$timeouts[$p].Dispose() +                            } + +                            `$status = `$sockets[$p].Connected; +                            if (`$status -eq `$True) +                            { +                                #write-host "$p is open" +                                `$openPorts.Add($p) +                            } +                            else +                            { +                                #write-host "$p is closed" +                                `$closedPorts.Add($p) + +                            } +                            `$sockets[$p].Close(); + +                            `$sockets.Remove($p) +                        } +"@ +                    $timeoutCallback = @" +                        #write-host "$p is filtered" +                        `$sockets[$p].Close() +                        if (!`$timeouts[$p].Disposed) { +                            `$timeouts[$p].Dispose() +                            `$filteredPorts.Add($p) +                        } +                        `$sockets.Remove($p) +"@ + +                    $timeoutCallback = [scriptblock]::Create($timeoutCallback) + +                    $timeouts[$p] = New-Object System.Timers.Timer +                    Register-ObjectEvent -InputObject $timeouts[$p] -EventName Elapsed -Action $timeoutCallback | Out-Null +                    $timeouts[$p].Interval = $timeout +                    $timeouts[$p].Enabled = $true + +                    $myscriptblock = [scriptblock]::Create($scriptBlockAsString) +                    $x = $sockets[$p].beginConnect($h, $p,(New-ScriptBlockCallback($myscriptblock)) , $null) + +                } + +                function PortScan-Alive +                { +                    Param ( +                        [Parameter(Mandatory = $True)] [String] $h +                    ) + +                    Try +                    { + +                        #ping +                        if ($hostPortList.Contains(-1)) +                        { +                            $ping = new-object System.Net.NetworkInformation.Ping +                            $pResult = $ping.send($h) +                            if ($pResult.Status -eq "Success") +                            { +                                return $True +                            } +                        } +                        foreach($Port in $hostPortList) +                        { +                            if ($Port -ne -1) +                            { +                                Test-Port -h $h -p $Port -timeout $Timeout +                            } +                        } + +                        do { +                            Start-Sleep -Milli 100 +                            if (($openPorts.Count -gt 0) -or ($closedPorts.Count -gt 0)) { +                                return $True +                            } +                        } +                        While ($sockets.Count -gt 0) + +                    } +                    Catch +                    { +                        Write-Error "Exception trying to host scan $h" +                        Write-Error $_.Exception.Message; +                    } + +                    return $False +                } + +                function Portscan-Port +                { +                    Param ( +                        [Parameter(Mandatory = $True)] [String] $h +                    ) + +                    [string[]]$Ports = @() + +                    foreach($Port in $Portlist) +                    { +                        Try +                        { +                            Test-Port -h $h -p $Port -timeout $Timeout +                        } +                        Catch +                        { +                            Write-Error "Exception trying to scan $h port $Port" +                            Write-Error $_.Exception.Message; +                        } +                    } +                } +                [bool] $hostResult = $False + +                if(!$SkipDiscovery) +                { +                    [bool] $hostResult = PortScan-Alive $thost +                    $openPorts.clear() +                    $closedPorts.clear() +                    $filteredPorts.Clear() +                } +                if((!$PingOnly) -and ($hostResult -or $SkipDiscovery)) +                { +                    Portscan-Port $thost +                } +                while ($sockets.Count -gt 0) { +                    Start-Sleep -Milli 500 +                } + +                return @($hostResult, $openPorts, $closedPorts, $filteredPorts) +                } +            } + +            # the outer loop is to flush the loop. +            # Otherwise Get-Job | Wait-Job could clog, etc + +            [int]$saveIteration = 0 +            [int]$computersDone=0 +            [int]$upHosts=0 +            while (($saveIteration * $SyncFreq) -lt $hostList.Count) +            { + +                Get-Job | Remove-Job -Force +                $sIndex = ($saveIteration*$SyncFreq) +                $eIndex = (($saveIteration+1)*$SyncFreq)-1 + +                foreach ($iHost in $hostList[$sIndex..$eIndex]) +                { +                    $ctr = @(Get-Job -state Running) +                    while ($ctr.Count -ge $nHosts) +                    { +                        Start-Sleep -Milliseconds $SleepTimer +                        $ctr = @(Get-Job -state Running) +                    } + +                    $computersDone++ +                    if(!$noProgressMeter) +                    { +                        Write-Progress -status "Port Scanning" -Activity $startMsg -CurrentOperation "starting computer $computersDone"  -PercentComplete ($computersDone / $hostList.Count * 100) +                    } + +                    Start-Job -ScriptBlock $portScanCode -Name $iHost -ArgumentList @($iHost, $SkipDiscovery, $PingOnly, $Timeout, $portList, $hostPortList, $Threads)  | Out-Null +                } + +                Get-Job | Wait-Job | Out-Null + +                foreach ($job in Get-Job) +                { +                    $jobOut = @(Receive-Job $job) +                    [bool]$hostUp = $jobOut[0] +                    $jobName = $job.Name + +                    $openPorts = $jobOut[1] +                    $closedPorts = $jobOut[2] +                    $filteredPorts = $jobOut[3] + +                    if($hostUp) { +                        $upHosts ++ +                    } + +                    if (!$quiet) +                    { +                        if($open){ +                            if($openPorts){ +                                $hostDate = Get-Date +                                $hostObj = New-Object System.Object +                                $hostObj | Add-Member -MemberType Noteproperty -Name Hostname -Value $jobName +                                $hostObj | Add-Member -MemberType Noteproperty -Name alive -Value $hostUp +                                $hostObj | Add-Member -MemberType Noteproperty -Name openPorts -Value $openPorts +                                $hostObj | Add-Member -MemberType Noteproperty -Name closedPorts -Value $closedPorts +                                $hostObj | Add-Member -MemberType Noteproperty -Name filteredPorts -Value $filteredPorts +                                $hostObj | Add-Member -MemberType NoteProperty -Name finishTime -Value $hostDate +                                $scannedHostList += $hostobj +                            } +                        } +                        else { +                            $hostDate = Get-Date +                            $hostObj = New-Object System.Object +                            $hostObj | Add-Member -MemberType Noteproperty -Name Hostname -Value $jobName +                            $hostObj | Add-Member -MemberType Noteproperty -Name alive -Value $hostUp +                            $hostObj | Add-Member -MemberType Noteproperty -Name openPorts -Value $openPorts +                            $hostObj | Add-Member -MemberType Noteproperty -Name closedPorts -Value $closedPorts +                            $hostObj | Add-Member -MemberType Noteproperty -Name filteredPorts -Value $filteredPorts +                            $hostObj | Add-Member -MemberType NoteProperty -Name finishTime -Value $hostDate +                            $scannedHostList += $hostobj +                        } +                    } + +                    Write-PortscanOut -outhost $jobName -isUp $hostUp -openPorts $openPorts -closedPorts $closedPorts -filteredPorts $filteredPorts -grepStream $grepStream -xmlStream $xmlStream -readableStream $readableStream -SkipDiscovery $SkipDiscovery +                } + +                if ($grepStream) { +                    $grepStream.flush() +                } +                if ($xmlStream) { +                    $xmlStream.flush() +                } +                if($readableStream) { +                    $readableStream.flush() +                } + +                $saveIteration ++ +            } + +            $enddate = Get-Date +            $totaltime = ($enddate - $startdate).TotalSeconds +            $endMsg = "Port scan complete at $enddate ($totaltime seconds)" +            if (!$SkipDiscovery) { +                $endMsg += ", $upHosts hosts are up" +            } + +            Write-PortscanOut -comment $endMsg -grepStream $grepStream -xmlStream $xmlStream -readableStream $readableStream + +            if($grepStream) { +                $grepStream.Close() +            } +            if ($xmlStream) { +                $xmlStream.Close() +            } +            if($readableStream) { +                $readableStream.Close() +            } + +            return $scannedHostList + +        } +        Catch +        { +            Write-Error $_.Exception.Message; +        } +    } +} | 
