How to Build a Port Vulnerability Scanner in Python

Posted in /  

How to Build a Port Vulnerability Scanner in Python
vinaykhatri

Vinay Khatri
Last updated on June 16, 2024

    Mostly all the open ports use a banner or service software on which they run. If you do not know how to get the port banner name in Python, click here to read that tutorial.

    In this Python tutorial, we will write a Python script that checks if a Port banner is vulnerable or not. To achieve our goal, we will be using the brute force technique in which we will have a list of the vulnerable banners in a txt file, and we will compare our local host ports banner with them. Here are the steps we will follow to create a Port Vulnerability scanner in Python

    • First, we will create a port scanner and save the port number and its banner in the lists.
    • Then using the Python file handling , we will check if any port banner present in our
      vulnerable_banner.txt file.
    • If yes, we will print that the port is vulnerable.

    That's the basic outline of how we will write our Python script, but before diving into the code, let's discuss the libraries and dependencies we will be using to write our Python script.

    Required libraries and dependencies

    Python socket library

    socket is the defacto Python library for socket programming. It is a Python standard module, and in this tutorial, we will be using this module to scan ports and retrieve the open ports banner.

    Python IPy Library

    Python IPy is a lightweighted open-source third part library. As the Library name suggests, it is used to handle IPv4 and IPv6 addresses and networks in Python. And in this tutorial, we will be using this library to check if the user entered a valid IP address or domain name. Because in our program, we will be giving users to enter the target IP address or the domain name.

    As IPy is a third-party package; we need to install it for our Python environment. Run the following pip install command on your terminal or command prompt to install IPy.

    pip install IPy

    Python threading module

    Although multi-threading is not available in Python but using, threading we can simulate multiple threading in Python as concurrent execution of threads. Port scanning is a very slow process, so we will be using threading in our program to make the scanning faster.

    Vulnerable banners text file

    To check for the vulnerable ports, we will be using brute force, in which we will already have a txt file (vulnerable_banners.txt) that contains vulnerable banners. And we will read those vulnerable banners from the file and check our localhost or target IP address using those services or banners. vulnerable_banners.txt

    3Com 3CDaemon FTP Server Version 2.0 
    220-FileZilla Server version 0.9.41 beta 
    Ability Server 2.34 
    CCProxy Telnet Service Ready 
    ESMTP TABS Mail Server for Windows NT
    FreeFloat Ftp Server (Version 1.00) 
    IMAP4rev1 MDaemon 9.6.4 ready 
    MailEnable Service, Version: 0-1.54 
    NetDecision-HTTP-Server 1.0
    PSO Proxy 0.9 
    SAMBAR Sami FTP Server 2.0.2 
    Spipe 1.0 
    TelSrv 1.5 
    WDaemon 6.8.5 
    WinGate 6.1.1
    Xitami 
    YahooPOPs! Simple Mail Transfer Service Ready

    Here is the list of some of the vulnerable banners. You can copy and paste these banners into your local system as a text file.

    I would recommend you save the vulnerable_banners.txt file in the same directory or folder where you are writing the Python script.

    Now we are all set with the dependencies, it's time to open your best Python IDE or text editor and code along.

    How to Build a Port Vulnerability Scanner in Python

    We will begin our Python script by importing the required module.

    import socket 
    from IPy import IP
    import threading

    Also, let's define two Python empty lists that will store the open port and its corresponding banner.

    ports = []   #to store open port
    banners =[]   #to store open port banner

    To keep our code module, let's define a function port_scanner(target, port) that will scan for the open port and store the open port number and its banner name in ports and banners lists.

    def port_scanner(target,port):
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(5)
            try:
                trarget_ip =IP(target)     #check if target is an IP address
            except:
                target_ip = socket.gethostbyname(target)     #check if the target is a domain name or locahost
    
    
            s.connect((target_ip, port))
            try:
                #get banner name
                banner_name = banner(s).decode()
                ports.append(port)
    
                #store banner_name in banners list
                banners.append(banner_name.strip())
            except:
                pass
        except:
            pass

    The outermost try statement block handles the exception for socket connection to the port. The socket.socket(socket.AF_INET, socket.SOCK_STREAM) function initializes the socket object s . settimeout(5) function will fail the connection if the socket cannot connect the port within 5 seconds.

    Next, The inner try and except block check if the target is a valid IP address or not. The IP() function check if the value is a valid IP. The socket.gethostname() function returns the IP address of the target domain. The connect((target_ip, port)) function will connect to the specified target_ip port number.

    Further, The banner(s) function will return the banner name of the connected socket. decode() function will decode the byte object to a string. The ports.append(port) and banners.append(banner_name.strip()) statements will store the open ports and their banner name(if any) in the ports and banners list.

    Now let's define a banner() function that will return the banner of the connected socket (if any).

    #get the banner name
    def banner(s):
        return s.recv(1024)

    The recv(1024) function will return the port banner name in 1024 bytes string. Now let's scan the first 5000 ports by calling the port_scanner() function with threading.

    #scan for first 5051
    for port in range(1,5051):
        thread = threading.Thread(target =port_scanner, args=[target,port])
        thread.start()

    if you do not know how the threading module work in Python, click here to check our threading tutorial. Now let's read our vulnerable_banners.txt file and check if any open port has a vulnerable banner service.

    with open("vulnerable_banners.txt", "r") as file:
        data = file.read()
        for i in range(len(banners)):
            if banners[i] in data:
                print(f"[!]Vulneribility found: {banners[i]} at port {ports[i]}")

    Now Put all the code together and execute.

    Python Program for Port scanner vulnerability

    import socket 
    from IPy import IP
    import threading
    
    
    ports = []   #to store open port
    banners =[]   #to store open port banner
    
    
    def port_scanner(target,port):
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(5)
            try:
                trarget_ip =IP(target)     #check if target is an IP address
            except:
                target_ip = socket.gethostbyname(target)     #check if the target is a domain name or locahost
    
            s.connect((target_ip, port))
            try:
                #get banner name
                banner_name = banner(s).decode()
                ports.append(port)
    
                #store banner_name in banners list
                banners.append(banner_name.strip())
            except:
                pass
        except:
            pass
    
    #get the banner name
    def banner(s):
        return s.recv(1024)
    
    target = input("Enter Target IP address, localhost or domain name eg www.eg.com: ")
    
    #scan for first 5051
    for port in range(1,5051):
        thread = threading.Thread(target =port_scanner, args=[target,port])
        thread.start()
    
    with open("vulnarable_banners.txt", "r") as file:
        data = file.read()
        for i in range(len(banners)):
            if banners[i] in data:
                print(f"[!]Vulneribility found: {banners[i]} at port {ports[i]}")

    Output

    Enter Target IP address, localhost or domain name eg www.eg.com: localhost
    [!]Vulneribility found: 220-FileZilla Server version 0.9.41 beta at port 21

    Here I have a check for the Port vulnerability of my local system; that's why I mentioned localhost as a target input IP. And you can see that I receive a vulnerability found message for my port 21. This is becaue my port 21 banner is present in the vulnerable_banners.txt file.

    Conclusion

    Now let's conclude the above tutorial. In this tutorial, you learned how to write a Python script to check the Port vulnerability. The above program is not efficient for all the port scanner vulnerability tests. The above program is based on brute force and is only able to show those vulnerable ports whose banners are already defined in the vulnerable_banners.txt file.

    You can look out for more vulnerable port banners or services in google and add them to your text file for a better result.

    People are also reading:

    Leave a Comment on this Post

    0 Comments