Information Security, Web, Networks and Systems

Saturday, June 29, 2013

Hacker's Python 2 - Multi-threaded Port Scanner

12:12 AM Posted by Deepal Jayasekara 4 comments

    I have created a multithreaded port scanner using python. Following is the code of my program. I ran the script in ubuntu. I will describe the meaning of each function and code snippet later in this post.

Download Source Code 

#!/usr/bin/env python
#this is the multithreaded port scanner

import socket, threading, thread

class PortScanner(threading.Thread):
    openportcount = 0
    
    def __init__(self, hostname, portrange):
        threading.Thread.__init__(self)
        self.hostname = hostname
        self.portrange = portrange
        
    def run(self):
        while True:            
            for port in range(self.portrange[0],self.portrange[1]):
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                status = sock.connect_ex((self.hostname,port))
                print status
                if status == 0:
                    #print "from thread %s"%str(threading.current_thread().name)
                    print "open\t%d"%port
                    PortScanner.openportcount+=1
                    sock.close()
                else:
                    pass
            
            thread.exit()
            


def main():
    print "[*] Starting Port Scanner....\n"
    hostname = raw_input("[?] Host name for port scanning : ")
    portrange = list((raw_input("[?] Port range : ").split("-")))
 
 
    lport = int(portrange[0])
    uport = int(portrange[1])
    
    if lport>uport:
        tempport = uport
        uport = lport
        lport = tempport
    
    if uport > 65535:
        uport = 65535
        print "[!] Port must be 0-65535\n[!] Port range set to %d - 65535\n"%lport
    elif lport < 0:
        lport = 0
        print "[!] Port must be 0-65535\n[!] Port range set to 0 - %d\n"%uport
    

    no_of_threads = int(raw_input("[?] No of threads : "))
  
    r = (uport - lport)/no_of_threads
    
    print "\n[+] %d Threads starting...\n"%no_of_threads
 
    threads = []
    for i in range(1,no_of_threads+1):
        uport = lport + r+ 1
        if uport>65535:
            uport=65535
        ports = [lport, uport]
        thread = PortScanner(hostname, ports)
        lport = uport+1
        thread.start()
        threads.append(thread)
    
    for t in threads:
        t.join()
        
    print "\n%d open ports found!"%PortScanner.openportcount
    print "\nDone!"
        
        
if __name__ == "__main__":
    main()
    
   
Functionality in brief

This program uses python's "socket","threading" and "thread" modules. Using socket module, this script tries to establish a connection to each port in the port range in the given host. If the connection can be established to a port, this program detects that port as an open port. Otherwise that port is discarded as a closed port.

Multithreading

  Once the user gives a port range to scan and number of threads for scanning, this program devides the port range into equal sized sub-ranges and assigns them to each thread. Following code illustrates that functionality.

    
    r = (uport - lport)/no_of_threads
    #some other code
    threads = []
    for i in range(1,no_of_threads+1):
        uport = lport + r+ 1
        if uport>65535:
            uport=65535
        ports = [lport, uport]
        thread = PortScanner(hostname, ports)
        lport = uport+1
        thread.start()
        threads.append(thread)

In the PortScanner class which extends Thread class in threading module, "run" function defines the port scanning functionality.

    def run(self):
        while True:            
            for port in range(self.portrange[0],self.portrange[1]):
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                status = sock.connect_ex((self.hostname,port))
                print status
                if status == 0:
                    #print "from thread %s"%str(threading.current_thread().name)
                    print "open\t%d"%port
                    PortScanner.openportcount+=1
                    sock.close()
                else:
                    pass
            
            thread.exit()

In each thread, the port range assigned to it is scanned. I have used the functions connect_ex() to check whether a connection can be established to that port.

Note:-
socket module contains two functions that are used for establishing a connection. One is connect() function and the other is connect_ex() function. connect() function tries to connect to a particular host:port and if fails it raises an exception. How connect_ex() differs from connect() is that, connect_ex() returns integer 0 if a connection can be successfully established. Otherwise it returns a value other than 0. So for the ease of programming, I have used connect_ex() function.



There may be some performance improvements for this code, but I hope this should be useful for you as a beginning to more complicated python scripting. Comments are welcome. :)

4 comments:

Note: Only a member of this blog may post a comment.