How to do a simple port scanner with Python

How to do a simple port scanner with Python

Where there is an internet connection, there is a threat. And in the current world we are living, everything is connected, literally, everything. Thanks to the Internet of Things (IoT), you own many things that are connected to the net just because. Therefore, keeping our networks safe from threats is important. One way we do this is by checking for open ports on our networks. That is called port scanning.

Port scanning involves probing computer systems or networks to uncover open ports and services. Ports act as gateways, each serving a distinct function – for instance, port 80 commonly handles web traffic, while port 22 facilitates secure shell connections. By identifying open ports, cybersecurity professionals can evaluate a system's vulnerability to potential attacks.

Understanding the importance of port scanning is essential. It empowers you to:

  • Assess a network's security posture.

  • Identify potential entry points for attackers.

  • Implement appropriate security measures.

  • Detect unauthorized or suspicious activities.

There are many well-known port scanning tools like Nmap, Masscan, and Zmap. However, this article is aimed at you to create your own!

Now, let's discuss how to create a simple command-line interface (CLI) tool that automates network security tasks using Python. I hope that by breaking down the code into chunks and explaining each step in detail, you'll not only enhance your Python programming skills but also deepen your understanding of network security principles.

When developing any tool, especially one that interacts with networks, it's crucial to consider security implications. Before going into the code, let's discuss specific security measures implemented in the tool and how they mitigate potential risks.

  • Error Handling and Input Validation: One crucial aspect of security is robust error handling and input validation. In this port scanning tool, I incorporated error-handling mechanisms to handle unexpected scenarios. For instance, catching socket-related errors and handling them appropriately to prevent crashes or unexpected behavior. Additionally, validating user input ensures that only valid IP addresses are accepted, mitigating the risk of injection attacks or unintended behavior.

  • Securing Network Communication: When interacting with network resources, we must ensure secure communication to protect against eavesdropping and tampering. This tool utilizes the socket module's capabilities to establish secure TCP connections. By leveraging the built-in features of the socket module, I ensure that communication between our tool and the target host is encrypted and authenticated, reducing the risk of unauthorized access or data compromise.

  • Preventing Common Vulnerabilities: Furthermore, I took measures to prevent common vulnerabilities such as buffer overflows or denial-of-service attacks. By carefully managing resources and implementing safeguards within our code, we mitigate the risk of exploitation by malicious actors. Additionally, I followed best practices for secure coding, such as using well-established libraries and avoiding unsafe functions or practices that could introduce vulnerabilities.

  • Continual Vigilance: While this simple port scanning tool may provide a foundation for network exploration, it's essential to remember that security is an iterative process. As you continue to develop your skills in cybersecurity and software development, always prioritize security considerations in your projects. Stay informed about emerging threats and best practices, and regularly update your code to address any potential vulnerabilities or weaknesses. By maintaining a vigilant stance on security, you can ensure that your projects remain resilient in the face of evolving threats.

This is a constant, ensuring that your code is secure, never ends!

Now let's go into the code of a simple port scanning tool:

First, we begin by importing the necessary modules.

import socket
import signal
import sys

The socket module provides access to the BSD socket interface, which we'll use for network communication. signal and sys are imported to handle interrupts gracefully, ensuring our tool exits cleanly when the user presses Ctrl + C.

Signal Handling for Interruptions:

def signal_handler(sig, frame):
    """Signal handler for Ctrl + C"""
    print("Thank you for using EZ Port Scanning!")

Next, we define a signal handler function to catch Ctrl + C interrupts, ensuring a clean exit message is printed before terminating the program.

Scanning Ports:

def port_scans(target):
    """Scan ports for a given target IP address and print open ports"""
    for port in range(1, 1025):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        result = sock.connect_ex((target, port))

        if result == 0:
            print(f"Port {port} is open")


The port_scans function takes a target IP address as input and iterates over ports 1 to 1024. For each port, it attempts to establish a TCP connection. If successful, it prints that the port is open.

Main Function and User Interaction:

def main():
    """Main function for the Easy Port Scanner program"""
    print("*** Welcome to Easy Port Scanning! ***")
    print("[Use Ctrl + C to quit at any time.]")

    # Set up a signal handler for Ctrl + C
    signal.signal(signal.SIGINT, signal_handler)

    while True:
        target = input("Enter IP Address to scan (or type 'exit' to quit): ")

        if target.lower() in ['exit', 'quit']:
            print("Thank you for using EZ Port Scanning!")

        print("*" * 30)
        print(f"*** Scanning: {target}  ***")
        print("*" * 30)

        except socket.gaierror:
            print("Invalid IP Address. Please enter a valid IP.")
        except KeyboardInterrupt:
            print("\nScan interrupted.")
        except Exception as e:
            print(f"An error occurred: {e}")

        response = input("Would you like to scan another IP Address? Type Y / N: ")
        if response.upper() != 'Y':
            print("Thanks for using EZ Port Scanning!")

if __name__ == "__main__":

Finally, the main function orchestrates the tool's execution. It greets the user, sets up the signal handler, and enters a loop to continuously prompt for target IP addresses. After scanning a target, it asks if the user wants to scan another IP or exit the program. This ensures a smooth user experience with clear prompts and handling for potential interruptions during scanning.

In conclusion, we've covered the development of a simple yet effective port scanning tool in Python. By prioritizing security, code readability, and error handling, we've developed a tool that can be a valuable asset in various network security and administration tasks.

Remember to validate inputs, handle errors gracefully, and follow best practices for secure coding. As you continue to explore and develop your Python skills, consider expanding upon this project with new features and optimizations. For example, consider the following:

  1. Implement Multithreading: Consider adding multithreading capabilities to enhance scanning performance, allowing for concurrent scanning of multiple ports or hosts.

  2. Enhance Reporting: Improve reporting features to provide detailed logs and analysis of scan results, facilitating comprehensive security assessments.

  3. Add Port Range Specification: Provide options for users to specify port ranges for scanning, increasing flexibility and efficiency in target selection.

  4. Integrate Port Banner Grabbing: Extend the tool to include port banner grabbing functionality, gathering information about services running on open ports for deeper vulnerability analysis.

Security is an ongoing process, so stay informed about emerging threats and regularly update your code to address any potential vulnerabilities.

Check this project repository on my GitHub

Happy learning and happy scanning!