July 2nd, 2012

Use PowerShell for Network Host and Port Discovery Sweeps

Doctor Scripto
Scripter

Summary: Guest blogger, Niklas Goude, discusses using Windows PowerShell to perform ping sweeps and port scans on a connected network. Microsoft Scripting Guy, Ed Wilson, is here. This week we have guest blogger Niklas Goude. Before we get to Niklas, I want to mention that you should mark your calendars for September 15, 2012 because that is the date that the second Windows PowerShell Saturday event occurs. It will be held in Charlotte, North Carolina. Attendance is limited, so keep your ears attuned for when registration opens. We will have three tracks and the event will be a lot of fun.

Niklas Goude is a Security Consultant at TrueSec and an MVP in Windows PowerShell. In addition to his work performing security assessments for a variety of clients, he also has extensive experience in using Windows PowerShell to automate and implement Windows environments. He has been speaking at TechDays; SharePoint conferences in the U.S., Australia, and New Zealand; and other events and conferences. He is the author of two books about Windows PowerShell, and he shares his knowledge at PowerShell.nu. He is a member of the TrueSec Expert Team, an independent, elite team of security and infrastructure consultants that operates all over the world. The security team at TrueSec performs various tasks and services related to IT security such as code review, security health checks, and penetration testing. TrueSec also delivers top-notch training sessions in advanced IT security. Check out the TruSec website for additional information. Now, without further ado, here is Niklas… Penetration testing is an important part of improving security in any network environment. A hacker usually only needs to find very few weaknesses (even only one) to compromise important IT systems. An important task for an IT administrator is to identify potential weaknesses and mitigate them. This is the first blog in a weekly series of five where we will talk about basic penetration testing techniques and how they affect misconfigured systems. The series will cover everything from initial network reconnaissance techniques and brute force attacks to advanced extraction of registry secrets to assess dangerous system dependencies. The key learning point is to demonstrate how you can use Windows PowerShell to accomplish almost any task no matter the subject. The secondary learning point is to make you aware of common security issues and misconfigurations that may occur in Microsoft infrastructures today. One important thing to keep in mind is that the vulnerabilities we are looking for exist simply because of misconfigurations made by administrators, such as weak passwords, system dependencies, misconfigurations, and more. I hope you will learn and enjoy!

Note   Today’s blog discusses using Windows PowerShell to perform network discovery. On some networks, use of such techniques is expressly disallowed except for specifically authorized teams and individuals. You must ensure that you have permission to perform the techniques described here prior to using such techniques at work. This also is a good time to emphasize the importance of proper network security configuration. For help with security configuration of your computer, see the Microsoft Safety & Security Center.

Part 1: Scanning

Scanning for IP addresses, MAC addresses, host names, and open ports is a way of finding the available computers on a network and finding out which service each computer publishes. In this blog, we will talk about how this can be performed by using Windows PowerShell.

Scenario

This scenario is based on a Windows domain environment that consists of three machines:

  • DC01: domain controller
  • SRV01: SQL Server and IIS
  • SP01: SharePoint 2010, SQL Server, and IIS

In addition, we have a client on the same network as the domain; however, the client is not a member of the domain. Each command in this scenario is executed from the client.

Configuration

The servers are manually installed by using the default settings. The servers use the Windows Firewalls default settings. The recommended internal firewall design is described in the following Microsoft TechNet Security Bulletin: Internal Firewall Design.

Code

The first step in scanning the network for IP addresses, host names, and open ports is to determine which network we are currently sitting on. The simplest way to do this is to use ipconfig. As you already know, Windows PowerShell has full support for running executables. Simply type ipconfig to find out which network you are on. If you are running Windows PowerShell 3.0, you can also use the new Get-NetIPAddress cmdLlet.

PS > ipconfig

 

Windows IP Configuration

Ethernet adapter Wired Ethernet Connection 2:

  Connection-specific DNS Suffix . :

  Link-local IPv6 Address . . . . . : fe81::3314:cf47:dbc2:935c%11

  IPv4 Address. . . . . . . . . . . : 10.0.0.100

  Subnet Mask . . . . . . . . . . . : 255.0.0.0

  Default Gateway . . . . . . . . . : 10.0.0.1 This example tells us that our IP address is 10.0.0.100 and the subnet is 255.0.0.0. With this information, we can perform a ping sweep on the network to find out if any hosts are reachable. We could, of course, achieve this by using ping.exe. However, there are more efficient ways to perform ping sweeps in a Windows network by using Windows PowerShell. One way is to use the Test-Connection cmdlet, which returns a Win32_PingStatus object that we can investigate in Windows PowerShell. We can also create an instance of System.Net.Networkinformation.Ping by using the New-Object cmdlet. This is the approach we’ll focus on. The following example demonstrates how to create an instance of System.Net.Networkinformation.Ping.

PS > $ping = New-Object System.Net.Networkinformation.ping The Ping class supports a method called Send(), which we can use to send an Internet Control Message Protocol (ICMP) echo request to a computer by simply specifying an IP address. The following example demonstrates how to send an ICMP echo request to 10.0.0.2.

PS > $ping.Send(“10.0.0.2”)

 

Status    : Success

Address    : 10.0.0.2

RoundtripTime : 0

Options    : System.Net.NetworkInformation.PingOptions

Buffer    : {97, 98, 99, 100…} If the computer responds, the status property is set to Success as shown in this example. It’s also possible to add a timeout by using a different overload definition. The timeout specifies the maximum number of milliseconds to wait for the ICMP echo reply message. The following example demonstrates how to ping 10.0.0.10 and wait for 500 milliseconds.

PS > $ping.Send(“10.0.0.10”, 500)

 

Status    : TimedOut

Address    :

RoundtripTime : 0

Options    :

Buffer    : {} If we wanted to perform a ping sweep on multiple computers, we could simply take advantage of the Windows PowerShell pipeline support, and pipe any number of given IP addresses to the Send() method.

PS > “10.0.0.2”,”10.0.0.3″ | ForEach-Object { $ping.Send($_, 500) }

 

Status    : Success

Address    : 10.0.0.2

RoundtripTime : 0

Options    : System.Net.NetworkInformation.PingOptions

Buffer    : {97, 98, 99, 100…}

 

Status    : Success

Address    : 10.0.0.3

RoundtripTime : 0

Options    : System.Net.NetworkInformation.PingOptions

Buffer    : {97, 98, 99, 100…} Now that we know how to perform a simple ping sweep by using Windows PowerShell, let’s take a look at how to use Windows PowerShell to resolve a host name. The System.Net.DNS class contains a static method, GetHostEntry(), which we can use to ask the DNS server for the host name that is associated with a given IP address.

PS > [Net.DNS]::GetHostEntry(“10.0.0.3”)

 

HostName          Aliases          AddressList        

——–          ——-          ———– 
SRV01.hacme.local      {}             {10.0.0.3}        

SRV01.hacme.local      {}             {10.0.0.3 It is also possible to ask the DNS server for the host name Async by using the BeginGetHostEntry() and the EndGetHostEntry() methods that are supported by System.Net.DNS. Next, let us look at how to determine which ports are open on a system. The System.Net.Sockets.TcpClient class supports the Connect() method, which we can use to connect to a given IP address and port. First we create an instance to System.Net.Sockets.TcpClient.

PS > $tcpClient = New-Object System.Net.Sockets.TCPClient Next, we use the Connect() method and try to connect to a specific IP address and port. In the following example, we test if port 445 is open. Port 445 is the SMB port. If the connection is successful, the Connected property is set to True as shown here:

PS > $tcpClient = New-Object System.Net.Sockets.TCPClient

PS > $tcpClient.Connect(“10.0.0.2”,445)

PS > $tcpClient.Connected

True If the connection fails, an error message is displayed and the Connected property is False.

PS > $tcpClient.Connect(“10.0.0.2”,1234)

Exception calling “Connect” with “2” argument(s):

“A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 10.0.0.2:1234”

At line:1 char:1+ $tcpClient.Connect(“10.0.0.2”,1234)

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  + CategoryInfo     : NotSpecified: (:) [], MethodInvocationException

  + FullyQualifiedErrorId : SocketException

PS > $tcpClient.Connected

False It is also possible to test the port’s Async by using the BeginConnect() method. These are the basic steps that we need to perform a network scan by using Windows PowerShell. The nice thing about Windows PowerShell is that we can reuse the code by placing it in a function and simply calling the function instead of typing the code every time we want to perform a network scan. The following example demonstrates the Invoke-TSPingSweep function in action.

PS > Invoke-TSPingSweep -StartAddress 10.0.0.1 -EndAddress 10.0.0.10 -ResolveHost -ScanPort

 

IPAddress          HostName          Ports           

———          ——–          —–           

10.0.0.2          DC01.hacme.local      {53, 139, 389, 445…} 

10.0.0.3          SRV01.hacme.local     {21, 80, 139, 445…}

10.0.0.10          SP01.hacme.local      {80, 139, 445}     The function uses the code described in this post and supports the following parameters:

  • StartAddress
  • EndAddress
  • ResolveHost
  • ScanPort
  • Ports
  • Timeout

Using the functionality of Windows PowerShell makes it very easy to search for specific ports that are returned from a network scan to determine if a computer is running a specific service. For example, if we wanted to find all computers running SQL Server, we could simply store the output in a variable and use the Where-Object cmdlet to retrieve each object where the Port 1433 is open.

PS > $pingSweep = Invoke-TSPingSweep -StartAddress 10.0.0.1 -EndAddress 10.0.0.10 -ResolveHost -ScanPort

PS > $pingSweep | Where-Object { $_.Ports -eq “1433” }

 

IPAddress          HostName          Ports           

———          ——–          —–           

10.0.0.3          SRV01.hacme.local     {21, 80, 139, 445…}

 

PS > $pingSweep | Where-Object { $_.Ports -eq 80 }

 

IPAddress          HostName          Ports           

———          ——–          —–           

10.0.0.3          SRV01.localdomain     {21, 80, 139, 445…}  

10.0.0.10          SP01.localdomain      {80, 139, 445}  There are, of course, other tools that you can use when performing network scans. One such tool is the Nmap security scanner, which has the possibility to perform the tasks described previously and a lot more.  As I mentioned earlier, Windows PowerShell has full support for executables, so another approach for performing a network scan would be to invoke nmap.exe and parse the XML output into a Windows PowerShell custom object to utilize the benefits of Windows PowerShell when working with the ouput. The following example demonstrates how to run nmap.exe and output the results to an XML document.

PS > & ‘C:Nmapnmap.exe’ -F 10.0.0.1/24 -oX C:tempnmap.xml Next, we can use Get-Content and read the content of the XML document. By adding the [xml] data type and placing the cmdlet within parenthesis, the content is read as an XML object.

PS > $nmap = [xml](Get-Content C:tempnmap.xml)

PS > $nmap.nmaprun.host

 

starttime : 1340110002

endtime  : 1340110018

status  : status

address  : {address, address}

hostnames :

ports   : ports

times   : times

Downloads

  • To download this entire code sample, see Invoke-TSPingSweep in the Script Center Repository.
  • Additional functions and code related to security are available on the TruSec website.
  • For more information about Nmap, see the NMAP.ORG site.

~Niklas I want to thank Niklas for an interesting and informative blog. Security Week will continue tomorrow with Part 2 of Niklas’s security series. I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

0 comments

Discussion are closed.