Scanner.jar
The Scanner.jar is a simple client application which scans a server or
an workstation for open
ports from 1 - 65536.
The
operating system used: Solaris x86 and the Java IDE: Netbeans !
Notice:
The purpose of this
exercise is pure educational, to learn about Java and networking. This
application will run with any JDK 1.4.2_x version available from
java.sun.com. It is working fine with the latest version, Java 5 too. However this package does not run with JDK
1.3 or previous versions.
Method 1: Single threaded application
Package: Scanner.jar
Source: Main.java
This is a single threaded application which will try to look for any
open ports.
The main logic behind this is explained below: the scanner will try to
access
the range 1 - 65536 looking for any open ports using the Socket() method
try {
InetAddress addr = InetAddress.getByName(host);
System.out.println("Searching for open ports between 1 - 65536");
System.out.println("Please wait...(CTRL-C to stop the process)");
for
(int i = 1; i < 65536; i++) {
Socket s = null;
try {
s = new Socket(addr,i);
System.out.println("Port: " + i + " open on " + host );
}
catch (IOException ex) {
}
finally {
try {
if (s != null) s.close();
}
catch (IOException ex) {}
}
}
//for
} //try
catch (UnknownHostException
ex) {
System.err.println(ex);
}
}
Some results:
$ time java -client
-jar Scanner.jar
Searching for open ports between 1 - 65536
Please wait...(CTRL-C to stop the process)
Port: 21 open on localhost
Port: 22 open on localhost
Port: 23 open on localhost
Port: 25 open on localhost
Port: 79 open on localhost
Port: 111 open on localhost
Port: 513 open on localhost
Port: 514 open on localhost
Port: 515 open on localhost
Port: 587 open on localhost
Port: 631 open on localhost
Port: 898 open on localhost
Port: 4045 open on localhost
Port: 4999 open on localhost
Port: 5987 open on localhost
Port: 5988 open on localhost
Port: 6000 open on localhost
Port: 7100 open on localhost
Port: 9010 open on localhost
Port: 32786 open on localhost
Port: 32787 open on localhost
Port: 32788 open on localhost
Port: 32789 open on localhost
Port: 32790 open on localhost
Port: 32791 open on localhost
Port: 32792 open on localhost
Port: 32795 open on localhost
Port: 32796 open on localhost
Port: 33221 open on localhost
Port: 36314 open on localhost
Port: 36317 open on localhost
Port: 36359 open on localhost
Port: 36360 open on localhost
Port: 36389 open on localhost
Port: 36391 open on localhost
Port: 36393 open on localhost
Port: 36394 open on localhost
Port: 36395 open on localhost
Port: 36396 open on localhost
Port: 36397 open on localhost
Port: 36400 open on localhost
Port: 36401 open on localhost
Port: 36402 open on localhost
Port: 36403 open on localhost
Port: 36406 open on localhost
Port: 36409 open on localhost
Port: 36455 open on localhost
Port: 36460 open on localhost
Port: 58787 open on localhost
real
1h32m7.01s
user
0m8.28s
sys
0m7.23s
Next the scanner will
be implemented using threads to improve the performance, if any.
Method 2: An improved version: multi-threaded
Package: Scanner2.jar
Source: Main2.java
One thing many network client applications, or most likely servers, are
using is: threads. To see if we can improve the performance of our
scanner we will introduce threads and as well to make the things a bit
easier and more flexible the scanner will ask for hostname, startPort,
endPort and the number of threads from user.
stefan@nereid>java
-jar Scanner2.jar
Usage: java -jar Scanner2.jar
hostname startPort endPort noThreads
public class Main2 {
public static PortScannerWorker t = null;
public static String host = "localhost";
/** Creates a new instance of Main */
public Main2() {
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code
application logic here
...
long startTime =
System.currentTimeMillis();
try {
System.out.println("Searching for open ports between 1 - 65536");
System.out.println("Please wait...(CTRL-C to stop the process)");
host = InetAddress.getByName(args[0]);
System.out.println("host: "+host+" threads: "+threads);
ports = new PortHandler(firstPort, lastPort);
for (int i = 0; i < threads; i++){
t = new PortScannerWorker(("Worker"+i), ports);
t.start();
}
while(t.isAlive()) Thread.sleep(30);
} //try
catch (Exception ex) {
System.err.println("Error:" + ex);
ex.printStackTrace();
}
long endTime =
System.currentTimeMillis();
System.out.println("Time spend for port scan:" +
(millisecondsToString(endTime -
startTime)));
}
public static String
millisecondsToString(long time) {
// retunr the time as a String
}
}
class PortScannerWorker extends Thread {
PortHandler _ports = null;
public PortScannerWorker(String name,
PortHandler ports)
{
super(name);
_ports = ports;
}
public void run() {
Port port = null;
boolean quit = false;
while (!quit) {
port = null;
synchronized(_ports)
{
if (!_ports.hasMoreElements()) {
quit = true;
return;
}
port = (Port) _ports.nextElement();
}
if (null != port) port.scan(this.getName());
}
}//run
}
class PortHandler implements Enumeration
{
InetAddress host = null;
int _firstPort = 0;
int _lastPort = 0;
int _nextPort = 0;
public PortHandler(int first, int last){
_firstPort = first;
_nextPort = first;
_lastPort = last;
}
public boolean hasMoreElements(){
return (_nextPort
<= _lastPort);
}
public Object nextElement(){
return new
Port(_nextPort++);
}
}//class PortHandler
class Port
{
int _port = -1;
Port(int port){
_port = port;
}
void scan(String name) {
try {
Socket s = new Socket(Main2.host, _port);
System.out.println("Port open " + _port + " discovered by thread "
+ name + " at " +
new GregorianCalendar().get(Calendar.HOUR_OF_DAY) + ":" +
new GregorianCalendar().get(Calendar.MINUTE) + ":" +
new GregorianCalendar().get(Calendar.SECOND));
s.close();
}
catch (IOException e)
{
}
}//scan
public static String
millisecondsToString(long time) {
int seconds = (int)
((time / 1000) % 60);
String secondsStr =
(seconds < 10 ? "0" : "") + seconds;
return new
String(secondsStr);
}
}//class Port
And at the end let's check some results: using the scanner with 500
threads.
PID USERNAME
SIZE RSS STATE PRI NICE
TIME CPU PROCESS/NLWP
727 stefan 75M
47M sleep 59 0 0:00:59 2.4%
thunderbird-bin/11
1160
stefan 102M 30M sleep
59 0 0:00:07 1.8% java/508
1095 stefan 64M 42M
sleep 47 4 0:03:09 1.1%
mozilla-bin/3
672 stefan 25M
13M sleep 59 0 0:00:24 0.8%
metacity/1
729 stefan 73M
46M sleep 59 0 0:00:56 0.7%
gnome-terminal/2
...
The scanner is represented by the 1160 PID number having 508 threads (8
internal JVM threads+ 500 our threads). The real size segment of the
process got bigger a bit since each thread has its own stack occupying
space.
stefan@nereid>time java -jar
Scanner2.jar localhost 1 65536 500
Searching for open ports
between 1 - 65535
Please wait...(CTRL-C to stop
the process)
host: localhost/127.0.0.1
threads: 500
Port open 21 discovered by
thread Worker3 at 14:31:4
Port open 25 discovered by
thread Worker4 at 14:31:4
Port open 22 discovered by
thread Worker2 at 14:31:4
Port open 111 discovered by
thread Worker36 at 14:31:4
Port open 515 discovered by
thread Worker171 at 14:31:4
Port open 587 discovered by
thread Worker5 at 14:31:11
Port open 631 discovered by
thread Worker1 at 14:31:14
Port open 898 discovered by
thread Worker6 at 14:31:34
Port open 4045 discovered by
thread Worker17 at 14:35:23
Port open 4999 discovered by
thread Worker14 at 14:36:6
Port open 5987 discovered by
thread Worker0 at 14:36:47
Port open 5988 discovered by
thread Worker0 at 14:36:47
Port open 6000 discovered by
thread Worker76 at 14:36:48
Port open 7100 discovered by
thread Worker149 at 14:37:33
Port open 9010 discovered by
thread Worker118 at 14:38:31
Port open 32775 discovered by
thread Worker85 at 14:50:58
Port open 32776 discovered by
thread Worker85 at 14:50:58
Port open 32777 discovered by
thread Worker85 at 14:50:58
Port open 32778 discovered by
thread Worker85 at 14:50:58
Port open 32779 discovered by
thread Worker85 at 14:50:58
Port open 32780 discovered by
thread Worker85 at 14:50:58
Port open 32781 discovered by
thread Worker85 at 14:50:58
Port open 32784 discovered by
thread Worker85 at 14:50:58
Port open 32785 discovered by
thread Worker85 at 14:50:58
Port open 32789 discovered by
thread Worker84 at 14:50:58
Port open 32786 discovered by
thread Worker83 at 14:50:58
Port open 32831 discovered by
thread Worker379 at 14:50:59
Port open 32832 discovered by
thread Worker379 at 14:50:59
Port open 32865 discovered by
thread Worker160 at 14:51:1
Port open 32866 discovered by
thread Worker160 at 14:51:1
Port open 32868 discovered by
thread Worker160 at 14:51:1
Port open 32869 discovered by
thread Worker160 at 14:51:1
Port open 32870 discovered by
thread Worker160 at 14:51:1
Port open 32871 discovered by
thread Worker160 at 14:51:1
Port open 32872 discovered by
thread Worker160 at 14:51:1
Port open 32875 discovered by
thread Worker160 at 14:51:1
Port open 32877 discovered by
thread Worker172 at 14:51:1
Port open 32879 discovered by
thread Worker172 at 14:51:1
Port open 32882 discovered by
thread Worker172 at 14:51:1
Port open 32883 discovered by
thread Worker172 at 14:51:1
Port open 32885 discovered by
thread Worker172 at 14:51:1
Port open 32876 discovered by
thread Worker160 at 14:51:1
Port open 32918 discovered by
thread Worker85 at 14:51:2
Port open 32923 discovered by
thread Worker85 at 14:51:2
Port open 32947 discovered by
thread Worker85 at 14:51:2
Port open 34119 discovered by
thread Worker108 at 14:51:34
Port open 36208 discovered by
thread Worker379 at 14:52:31
Time spend for port
scan:00:35:21.728
real 36m28.94s
user 0m12.02s
sys
0m7.27s
So, the total execution time, using 500 threads, has been
35minutes compared with 1h and 30minutes as previous in Method 1.
However the time of 30minutes is far too long. In the next section we
will understand why.
Conclusions:
Two scanners applications were presented: a single threaded and a
multi-threading one. The multi-threading client was presented to show
how can you use threads, sockets under Java.
Another open issue was: the time of the scanning process. Scanning for
open ports under Solaris x86 took a very, very long time. Why ?
Solaris (x86 or SPARC) defends itself against a DoS - the SYN attack.
By default Solaris has this protection ON (hmm ... very nice :))
comparing with RedHat 9 based on kernel 2.4.x where the scanning went
in couple of seconds without to have this protection. To disable this
protection as root try:
# ndd -set /dev/tcp
tcp_rst_sent_rate_enabled 0
and you can put it on back:
# ndd -set /dev/tcp
tcp_rst_sent_rate_enabled 1
To demonstrate the results after changing the RST parameter we started
again Scanner2 to look for all open ports. The CPU consumption went
very high and the total time was reduced to: 18seconds !
stefan@nereid>time java -jar
Scanner2.jar localhost 1 65535 500
Searching for open ports between 1 - 65536
Please wait...(CTRL-C to stop the process)
host: localhost/127.0.0.1 threads: 500
Port open 21 discovered by thread Worker0 at 15:15:1
Port open 22 discovered by thread Worker0 at 15:15:1
Port open 25 discovered by thread Worker0 at 15:15:1
Port open 111 discovered by thread Worker0 at 15:15:1
Port open 515 discovered by thread Worker236 at 15:15:2
Port open 587 discovered by thread Worker236 at 15:15:2
Port open 631 discovered by thread Worker236 at 15:15:2
Port open 898 discovered by thread Worker208 at 15:15:2
Port open 4045 discovered by thread Worker212 at 15:15:3
Port open 4999 discovered by thread Worker247 at 15:15:3
Port open 5987 discovered by thread Worker248 at 15:15:3
Port open 5988 discovered by thread Worker248 at 15:15:3
Port open 7100 discovered by thread Worker385 at 15:15:4
Port open 9010 discovered by thread Worker440 at 15:15:4
Port open 6000 discovered by thread Worker248 at 15:15:4
Port open 32775 discovered by thread Worker245 at 15:15:9
Port open 32776 discovered by thread Worker245 at 15:15:9
Port open 32777 discovered by thread Worker245 at 15:15:9
Port open 32778 discovered by thread Worker245 at 15:15:9
Port open 32779 discovered by thread Worker245 at 15:15:9
Port open 32780 discovered by thread Worker245 at 15:15:9
Port open 32781 discovered by thread Worker245 at 15:15:9
Port open 32784 discovered by thread Worker456 at 15:15:9
Port open 32785 discovered by thread Worker456 at 15:15:9
Port open 32789 discovered by thread Worker315 at 15:15:9
Port open 32786 discovered by thread Worker261 at 15:15:9
Port open 32831 discovered by thread Worker297 at 15:15:9
Port open 32832 discovered by thread Worker297 at 15:15:9
Port open 32865 discovered by thread Worker462 at 15:15:9
Port open 32866 discovered by thread Worker462 at 15:15:9
Port open 32868 discovered by thread Worker462 at 15:15:9
Port open 32869 discovered by thread Worker462 at 15:15:9
Port open 32870 discovered by thread Worker462 at 15:15:9
Port open 32871 discovered by thread Worker462 at 15:15:9
Port open 32872 discovered by thread Worker462 at 15:15:9
Port open 32875 discovered by thread Worker494 at 15:15:9
Port open 32876 discovered by thread Worker494 at 15:15:9
Port open 32877 discovered by thread Worker494 at 15:15:9
Port open 32879 discovered by thread Worker252 at 15:15:9
Port open 32882 discovered by thread Worker280 at 15:15:9
Port open 32883 discovered by thread Worker280 at 15:15:9
Port open 32885 discovered by thread Worker281 at 15:15:9
Port open 32918 discovered by thread Worker32 at 15:15:9
Port open 32923 discovered by thread Worker66 at 15:15:9
Port open 34119 discovered by thread Worker158 at 15:15:10
Port open 36208 discovered by thread Worker486 at 15:15:10
Port open 63312 discovered by thread Worker303 at 15:15:16
Time spend for port scan:00:00:15.544
real 0m15.97s
user 0m8.48s
sys 0m5.67s
Trying as well to decrease the number of threads, by reducing the CPU
and memory consumption, returned similar results, in fact got better
results than the multi-threading one:
stefan@nereid>time java -jar
Scanner2.jar localhost 1 65535 1
Searching for open ports between 1 - 65536
Please wait...(CTRL-C to stop the process)
host: localhost/127.0.0.1 threads: 1
Port open 21 discovered by thread Worker0 at 15:17:33
Port open 22 discovered by thread Worker0 at 15:17:33
Port open 25 discovered by thread Worker0 at 15:17:33
Port open 111 discovered by thread Worker0 at 15:17:34
Port open 515 discovered by thread Worker0 at 15:17:34
Port open 587 discovered by thread Worker0 at 15:17:34
Port open 631 discovered by thread Worker0 at 15:17:34
Port open 898 discovered by thread Worker0 at 15:17:34
Port open 4045 discovered by thread Worker0 at 15:17:35
Port open 4999 discovered by thread Worker0 at 15:17:35
Port open 5987 discovered by thread Worker0 at 15:17:36
Port open 5988 discovered by thread Worker0 at 15:17:36
Port open 6000 discovered by thread Worker0 at 15:17:36
Port open 7100 discovered by thread Worker0 at 15:17:36
Port open 9010 discovered by thread Worker0 at 15:17:36
Port open 32775 discovered by thread Worker0 at 15:17:41
Port open 32776 discovered by thread Worker0 at 15:17:41
Port open 32777 discovered by thread Worker0 at 15:17:41
Port open 32778 discovered by thread Worker0 at 15:17:41
Port open 32779 discovered by thread Worker0 at 15:17:41
Port open 32780 discovered by thread Worker0 at 15:17:41
Port open 32781 discovered by thread Worker0 at 15:17:41
Port open 32784 discovered by thread Worker0 at 15:17:41
Port open 32785 discovered by thread Worker0 at 15:17:41
Port open 32786 discovered by thread Worker0 at 15:17:41
Port open 32789 discovered by thread Worker0 at 15:17:41
Port open 32831 discovered by thread Worker0 at 15:17:41
Port open 32832 discovered by thread Worker0 at 15:17:41
Port open 32865 discovered by thread Worker0 at 15:17:41
Port open 32866 discovered by thread Worker0 at 15:17:41
Port open 32868 discovered by thread Worker0 at 15:17:41
Port open 32869 discovered by thread Worker0 at 15:17:41
Port open 32870 discovered by thread Worker0 at 15:17:41
Port open 32871 discovered by thread Worker0 at 15:17:41
Port open 32872 discovered by thread Worker0 at 15:17:41
Port open 32875 discovered by thread Worker0 at 15:17:41
Port open 32876 discovered by thread Worker0 at 15:17:41
Port open 32877 discovered by thread Worker0 at 15:17:41
Port open 32879 discovered by thread Worker0 at 15:17:41
Port open 32882 discovered by thread Worker0 at 15:17:41
Port open 32883 discovered by thread Worker0 at 15:17:41
Port open 32885 discovered by thread Worker0 at 15:17:41
Port open 32918 discovered by thread Worker0 at 15:17:41
Port open 32923 discovered by thread Worker0 at 15:17:41
Port open 34119 discovered by thread Worker0 at 15:17:42
Port open 36208 discovered by thread Worker0 at 15:17:42
Port open 63312 discovered by thread Worker0 at 15:17:47
Time spend for port scan:00:00:14.482
real 0m14.81s
user 0m7.21s
sys 0m5.33s
Disabling the RST protection makes the scan procedure very fast. In
fact with the protection OFF and with a high number of threads Scanner2
performs worse than using only one thread !
REMEMBER: By default the
protection is ON meaning your server is protected against such of DoS
attack and when you are switching that OFF you are vulnerable to a DoS
attack.