ISC Stormcast For Monday, October 31st, 2022 https://isc.sans.edu/podcastdetail.html?id=8236

NMAP without NMAP - Port Testing and Scanning with PowerShell

Published: 2022-10-31
Last Updated: 2022-10-31 01:52:42 UTC
by Rob VandenBrink (Version: 1)
4 comment(s)

Ever needed to do a portscan and didn't have nmap installed?  I've had this more than once on an internal pentest or more often just on run-rate "is that port open? / is there a host firewall in the way?" testing.

Often we see folks doing something cludgy with telnet or ftp, but Powershell Test-NetConnection (tnc for short) does a fine job of spot testing for an open port or to see if an IP is in use.

For a quick ping test, run tnc with just the target host as an argument:

PS L:\> tnc 8.8.8.8

ComputerName           : 8.8.8.8

RemoteAddress          : 8.8.8.8

InterfaceAlias         : Ethernet 2

SourceAddress          : 192.168.122.201

PingSucceeded          : True

PingReplyDetails (RTT) : 15 ms    

For a quick traceroute:

PS L:\> tnc 8.8.8.8 -traceroute

ComputerName           : 8.8.8.8

RemoteAddress          : 8.8.8.8

InterfaceAlias         : Ethernet 2

SourceAddress          : 192.168.122.201

PingSucceeded          : True

PingReplyDetails (RTT) : 13 ms

TraceRoute             : 192.168.122.1

                         99.254.226.1

                         66.185.90.177

                         24.156.147.129

                         209.148.235.222

                         72.14.216.54

                         108.170.228.0

                         172.253.69.113

                         8.8.8.8

Limiting the hopcount of traceroute:

PS L:\> tnc 8.8.8.8 -traceroute -hops 3

WARNING: Trace route to destination 8.8.8.8 did not complete. Trace terminated :: 66.185.90.177

ComputerName           : 8.8.8.8

RemoteAddress          : 8.8.8.8

InterfaceAlias         : Ethernet 2

SourceAddress          : 192.168.122.201

PingSucceeded          : True

PingReplyDetails (RTT) : 16 ms

TraceRoute             : 192.168.122.1

                         99.254.226.1

                         66.185.90.177

Testing an open port:

PS L:\> tnc 8.8.8.8 -port 443

ComputerName     : 8.8.8.8

RemoteAddress    : 8.8.8.8

RemotePort       : 443

InterfaceAlias   : Ethernet 2

SourceAddress    : 192.168.122.201

TcpTestSucceeded : True

Or, for a (not so) quick port scan:

$ip = "192.168.122.241"

$result = @()

for ($port = 9099; $port -le 9101 ; $port ++) {

   $result += (tnc $ip -port $port) | select remoteport, tcptestsucceeded

   }

PS L:\> $result

RemotePort TcpTestSucceeded

---------- ----------------

      9099            False

      9100             True

      9101            False

Or if you just want the open ports:

$ip = "192.168.122.241"

$result = @()

for ($port = 9099; $port -le 9101 ; $port ++) {

   $a = (tnc $ip -port $port) | select remoteport, tcptestsucceeded

   if ($a.tcptestsucceeded ) {

        $result += $a

        }

   }

As you may have noticed, tnc is a decent tool for testing a single port, but for a portscan it makes for the slowest tool ever.  It is however a a great tool for troubleshooting an individual service because the syntax is so easy to remember in a pinch.  Using Net.Sockets directly makes for a much faster scan, with slightly more complicated syntax:

new-object system.net.sockets.tcpclient -argumentlist "192.168.122.241","9100"

(yes, system.net.sockets.udpclient is also a thing, everything below works for udp too)

So our port scanner morphs to:

$targetservers = "192.168.122.241", "192.168.122.1"

$ports = "22","23","80","443","9100"

$result = @()

foreach ($target in $targetservers) {

    foreach ($port in $ports) {

       $a = new-object system.net.sockets.tcpclient -argumentlist $target,$port

       if ($a.connected) {

           $r = new-object -type psobject

           $r | add-member -membertype noteproperty -name host -value $target

           $r | add-member -membertype noteproperty -name port -value $port

           $r | add-member -membertype noteproperty -name state -value "Open"

           $result += $r

           }

       }

    }

Hmm, this still takes forever to come back from closed ports.  How about this adding in a 100ms timeout on each connection - you can play with that number as needed:

$targetservers = "192.168.122.241", "192.168.122.1"

$ports = "22","23","80","443","9100"

$result = @()

foreach ($target in $targetservers) {

    foreach ($port in $ports) {

        $obj = new-Object system.Net.Sockets.TcpClient

        $connect = $obj.BeginConnect($target,$port,$null,$null)

        $Wait = $connect.AsyncWaitHandle.WaitOne(100,$false)

        If (-Not $Wait) {

            write-host $target 'port' $port 'Closed - Timeout'

        }

        else {

            $value = "Open"

            write-host $target 'port' $port $value

            $r = new-object -type psobject

            $r | add-member -membertype noteproperty -name host -value $target

            $r | add-member -membertype noteproperty -name port -value $port

            $r | add-member -membertype noteproperty -name state -value $value

            $result += $r

        }

    }

}

192.168.122.241 port 22 Closed - Timeout

192.168.122.241 port 23 Closed - Timeout

192.168.122.241 port 80 Open

192.168.122.241 port 443 Open

192.168.122.241 port 9100 Open

192.168.122.1 port 22 Open

192.168.122.1 port 23 Closed - Timeout

192.168.122.1 port 80 Open

192.168.122.1 port 443 Open

192.168.122.1 port 9100 Closed - Timeout

 

PS L:\> $result

host            port state

----            ---- -----

192.168.122.241 80   Open

192.168.122.241 443  Open

192.168.122.241 9100 Open

192.168.122.1   22   Open

192.168.122.1   80   Open

192.168.122.1   443  Open

You can of course play with this final script as needed - For instance if you wanted to do a whole range of ports you might change the"foreach ($port in $ports)" loop back to a for loop:

$lport = 0
$hport = 65535
for ($port = $lport; $port -le $hport ; $port ++)

Or if you wanted to scan a /24 subnet, you might change the "foreach ($target in $targetservers) " loop to:
$net = "192.168.122."
for ($h = 1; $h -le 254 ; $h++)
    $target = $net+$h

This set of approaches is NOT meant to replace NMAP - for instance I can't tell you for instance how often I use NMAP scripts in a week!  However, if you are testing a site-to-site VPN, testing a router or firewall ACL, or checking a host firewall, almost always the host you are testing from is a customer's server, and you won't have NMAP available.  Considering that for so many people, the go-to test is to install a telnet (bad idea), then test for an open port using "telnet <target> <port>", with success being a blank screen, these approaches give you a LOT quicker and a LOT more reliably.

If you've got a any improvements to these scripts. in particular maybe a better way to indicate why a port might be not open (for instance - did it time out, send an ICMP port unreachable ro send a RST?) - by all means post to our comment section.  The scripts and snips I posted are only as good as they needed to be the last time I needed them, by all means lets make these better!


References:
Test-Netconnection:
https://learn.microsoft.com/en-us/previous-versions/windows/powershell-scripting/dn372891(v=wps.630)

system.Net.Sockets.TcpClient
https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient?view=net-6.0

 

===============
Rob VandenBrink
rob@coherentsecurity.com

4 comment(s)

Comments

cwqwqwq
eweew<a href="https://www.seocheckin.com/edu-sites-list/">mashood</a>
WQwqwqwq[url=https://www.seocheckin.com/edu-sites-list/]mashood[/url]
dwqqqwqwq mashood
[https://isc.sans.edu/diary.html](https://isc.sans.edu/diary.html)
[https://isc.sans.edu/diary.html | https://isc.sans.edu/diary.html]
What's this all about ..?
password reveal .
<a hreaf="https://technolytical.com/">the social network</a> is described as follows because they respect your privacy and keep your data secure:

<a hreaf="https://technolytical.com/">the social network</a> is described as follows because they respect your privacy and keep your data secure. The social networks are not interested in collecting data about you. They don't care about what you're doing, or what you like. They don't want to know who you talk to, or where you go.

<a hreaf="https://technolytical.com/">the social network</a> is not interested in collecting data about you. They don't care about what you're doing, or what you like. They don't want to know who you talk to, or where you go. The social networks only collect the minimum amount of information required for the service that they provide. Your personal information is kept private, and is never shared with other companies without your permission
https://thehomestore.com.pk/

Diary Archives