This is part 2 of the ‘Make our own simple networking tools using Java’. In part 1, we developed a simple command-line packet sniffer and now, we will make a simple Port Scanner (Note: We will not be using Threads, so this scanner will be a slow one, but in the weeks to come, we will make one of those fast ones too!)
We will divide our work into 2 java files:
1) JPortScanConn – This file will take care of the socket
2) JPortScanner – This file will deal with the actual command-line interface and validating user input
The tutorial is divided into three sections:
1) Definitions
2) Installation
3) Writing a simple port scanner
Definitions:
1) Port: A connection point for different protocols to communicate on different machines
2) Socket: (java.net.Socket class)is an object that represents a network connection between two machines. This means that’s the two machines have information about each other, including network location (IP address) and TCP port.
3) Port Scanner: is a software program that allows you to scan a target machine to provide information about the status of ports.
Installation:
Download and install Javatm2 Platform, Standard Edition (J2SEtm) JRE or SDK.java.sun.com/download
Writing a
As we have defined the much needed concepts above, the logic we will try to implement is that we would try to connect to port number x of the target machine, if we are successful, we will declare that the port is open else it is closed!
Ø First let’s make the JPortScanConn.java file:
// Import java.net(This is needed to create sockets and fetch the IP Address!)\\
import java.net.*;
// Create a class JPortScanConn \\
class JPortScanConn
{
// Declare a socket called skt that will make all the connections \\
// Declare integer variable startPort and endPort \\
// Declare an interger array openPorts[] which will hold a list
// of the open ports of the target machine
// Note: 65535 is the maximum number of ports on a machine \\
// Declare a string variable host to store the hostname of the target \\
// Declare an instance of type InetAddress that holds the IP address of the target \\
Socket skt;
int startPort, endPort;
int[] openPorts=new int[65535];
String hostName;
InetAddress hostAddress;
// Create a parameterised constructor to be used if user passes
// all 3 values i.e. for start and end port and the host name \\
JPortScanConn(int startPort, int endPort, String hostName)
{
// Initialize the values for the instance members
// with that passed by the user \\
this.startPort=startPort;
this.endPort=endPort;
this.hostName=hostName;
// Declare a flag named 'open' to hold the status
// of the current scanned port \\
boolean open=false;
// Initialize the hostAddress usning the getByName() method
// of the InetAddress class
// p.s. getByName()throws a UnknownHostException
// if the hostName is invalid \\
try
{
hostAddress=InetAddress.getByName(hostName);
}
catch (UnknownHostException ea) {}
// Initialise all values in the openPorts[] array to 0(closed) \\
for(int i=0;i<65535;i++)
openPorts[i]=0;
System.out.println("Scanning "+hostAddress.getHostAddress()+":");
// Scan the reqired ports by tring to create a connection
// p.s. 'currentport' holds the value of the port with which we
// try to establish a connection on the target machine 'hostAddress' \\
for(int currentPort=startPort,i=0;currentPort<=endPort;currentPort++)
{
try
{
skt= new Socket(hostAddress,currentPort);
// SUCCESS! \\
open=true;
}
catch(java.io.IOException eb)
{
// FAILED! \\
open=false;
}
finally
{
try
{
// Close the connection \\
skt.close();
}
catch(java.io.IOException ec){}
catch(NullPointerException ed){}
}
// Add the port number to the openPorts[] array if the
// connection was established \\
if(open==true)
{
openPorts[i]=currentPort;
// Reset the open flag \\
open=false;
// Move to the next port \\
i++;
}
}
}
// Create another constructor if user wishes to pass only the host name
// and we then scann all the ports \\
JPortScanConn(String hostName) throws UnknownHostException
{
this(1,65535,hostName);
}
// Create a constructor if user wants to scan a single port of the target \\
JPortScanConn(int startPort, String hostName) throws UnknownHostException
{
this(startPort,startPort,hostName);
}
}
Ø Now lets move to JPortScanner.java:
// Create a public class JPortScanner
// p.s. 'public' so that it can use the members and methos of JScanConn class
public class JPortScanner
{
// Make an instance of JPortScanConn
static JPortScanConn jpsc=null;
// Create a method to display the valid synatx for using the port scanner
static void usage()
{
System.out.println("Usage:\njava JPortScanner host [startport] [endport]");
System.out.println("If only startport is specified, the portscanner scans only that port.");
System.out.println("If neither is specified, the portscanner scans all ports from 1-65535");
System.out.println("Examples:\n java JPortScanner google.com \n java JPortScanner google.com 80\n java JPortScanner google.com 80 90");
System.exit(0);
}
// Now comes the psvm() \\
public static void main(String[] args)
{
// If invalid syntax is used for command, display the Usage
if(args.length==0||args.length>3)
{
usage();
}
try
{
// Call the appropriate constructor for the jpsc instance
if(args.length==3 && Integer.parseInt(args[1])<65535>
jpsc = new JPortScanConn(Integer.parseInt(args[1]),Integer.parseInt(args[2]),args[0]);
else if(args.length==1)
jpsc = new JPortScanConn(args[0]);
else if(args.length==2)
jpsc = new JPortScanConn(Integer.parseInt(args[1]),args[0]);
else
throw new NumberFormatException();
}
catch(java.net.UnknownHostException ea)
{
System.out.println("Address cannot be resolved"+ea);
}
catch(NumberFormatException eb)
{
System.out.println("startport and endport must be numbers less than 65535"+eb);
}
// Display the open ports
System.out.println("Open ports are...");
for(int i=0;i<65535;i++)
{
if(jpsc.openPorts[i]!=0)
System.out.println(""+jpsc.openPorts[i]);
}
}
}
That’s it!
Open the console window, move to the appropriate directory and type the following commands:
#javac JPortScanConn.java
#javac JPortScanner.java
#java JPortScanner localhost 25
Now you can go ahead scanning ports on your machine or on any target machine!
Lets Tweak:
Allowing timeouts:
Add an int variable ‘timeout’ to the JPortScanConn class and initialize it to 4000( in ms).
Now, edit the line in JPortScanConn.java:
skt= new Socket(hostAddress,currentPort);
To:
skt= new Socket();
skt.connect(new InetSocketAddress(hostAddress,currentPort),timeout);
1 comments:
Couple of minor optimizations you could make - not really necessary, but fun to think of when ur bored - like I am now...
1. Change the openPorts[] array to a Vector/List/Set. Saves you the bother of using a variable to keep track of the next free index. Collections can often clean up Java code unbelievably - and they're kinda intuitively clear. There's a reason they're built into languages like Python/Ruby as fundamental features.
2. If you do want to use an integer array - don't bother to initialize elements to 0 - that's automatic. But if you do wanna init an array, Arrays.fill() is a quicker way...
3. Yet another way that cleans up some code is to use an array of 65536 booleans for openPorts[]. That way you don't need an open flag - just use openPorts[currentPort]. That should really shrink some code up.
I strongly recommend the third option, for clarity and speed. The first option will probably be marginally slower bcoz of the overhead of managing the data structures.
Post a Comment