Build a Port Scanner in Python

Learn via video courses
Topics Covered

Overview

A port scanner is a crucial asset for any network administrator or security professional, as it allows you to discover open ports on a target system. This knowledge is essential for identifying potential vulnerabilities and securing a network against potential threats. By using Python, we will create a simple yet effective port scanner that can be used to identify open ports in a host or entire network.

Introduction to Port Scanner in Python

In computer networking, a port refers to a virtual endpoint for communication between software applications. These ports are numbered, and each number is associated with a specific type of service. For instance, HTTP typically uses port 80, while HTTPS uses port 443. The major functions of port are:

  • Ports play a crucial role in enabling multiple services to operate simultaneously on a single device.
  • They ensure that data packets are correctly delivered to the appropriate application or service.
  • For example, when you visit a website, your web browser communicates with the web server's port 80 (or 443 for secure connections) to fetch the webpage.

Vulnerabilities of Open Ports

While open ports are essential for network communication, they can also pose significant security risks if left unattended. An open port that is not being used by any active service can potentially become an entry point for malicious actors. They can exploit vulnerabilities in services listening on open ports, leading to unauthorized access or even a complete compromise of the system.

Port Scanning

Port scanning is the technique used to identify open ports on a target system. It involves sending a series of messages to a range of port numbers, observing the responses, and determining whether a port is open, closed, or filtered. The different types of port scanning are:

types of port scanning

  1. TCP Connect Scan:
    This is one of the most common port scanning techniques. It attempts to establish a full TCP connection with the target port. If successful, it indicates that the port is open.
  2. SYN Scan:
    Also known as half-open scanning, this technique sends a SYN packet to the target. If the port is open, it responds with a SYN-ACK packet. The scanner then sends an RST packet to tear down the connection, making it less detectable than a full connect scan.
  3. UDP Scan:
    While TCP is connection-oriented, UDP is connectionless. UDP scanning involves sending UDP packets to various ports and analyzing the responses. If a port is open, it may respond with an error message, indicating its status.
  4. FIN Scan:
    This technique leverages the FIN flag in a TCP packet. An open port will not respond, while a closed port will respond with an RST packet.
  5. XMAS Scan:
    Similar to the FIN scan, the XMAS scan sends packets with multiple flags set (FIN, PSH, URG). A lack of response suggests an open port.
  6. Null Scan:
    This technique involves sending a packet with no flags set. If the port is open, it typically won't respond.

Port Scanner Using Sockets in Python

A socket serves as an endpoint for communication between two machines over a network. A socket is a combination of a port and an address for communication. It allows data to flow in and out of a device, enabling applications to send and receive information.

Sockets in Port Scanning

When it comes to port scanning, sockets are used for establishing connections with remote ports on a target system. Python's socket library grants us the ability to create, configure, and utilize sockets in our programs. By leveraging the functionalities provided by this library, we can create a port scanner that efficiently interacts with ports on a target machine.

The process of port scanning involves the following steps:

  1. Creation of a socket.
  2. Attempts to connect to a specific port on the target system.
  3. If the connection is successful, it signifies that the port is open and actively accepting connections.
  4. If the connection is unsuccessful or refused, it indicates that the port is closed or filtered.

Socket Functions

Python's socket library provides a flexible and powerful toolset for handling network operations. It allows us to define the type of socket (IPv4 or IPv6), the transport protocol (TCP or UDP), and configure various settings to customize the behavior of the socket.

socket functions

Before we dive into writing the program, let's familiarize ourselves with some key socket functions:

socket():

  • Function:
    Creates a new socket object.
  • Parameters:
    • family:
      Specifies the address family (e.g., socket.AF_INET for IPv4, socket.AF_INET6 for IPv6).
    • type:
      Indicates the socket type (e.g., socket.SOCK_STREAM for TCP, socket.SOCK_DGRAM for UDP).
    • proto:
      Optionally specifies the protocol. If not provided, the default protocol for the specified socket type is used.
  • Return Value:
    Returns a new socket object.

bind():

  • Function:
    Associates a socket with a specific network interface and port number.
  • Parameters:
    • address:
      A tuple containing the IP address and port number to bind the socket to (e.g., ('127.0.0.1', 8080)).
  • Return Value:
    None.

listen():

  • Function:
    Puts the socket in server mode, waiting for incoming connections.
  • Parameters:
    • backlog:
      Specifies the maximum number of queued connections (usually a positive integer).
  • Return Value:
    None.

accept():

  • Function:
    Accepts an incoming connection, returning a new socket object representing the connection, and the address of the client.
  • Parameters:
    None.
  • Return Value:
    Returns a tuple containing a new socket object for the accepted connection and the client's address.

connect():

  • Function:
    Establishes a connection to a remote server.
  • Parameters:
    • address:
      A tuple containing the remote server's IP address and port number (e.g., ('example.com', 80)).
  • Return Value:
    None.

connect_ex():

  • Function:
    Attempt a connection to a remote server at a specified address and port.
  • Parameters:
    • address:
      address: The IP address of the remote server.
    • port:
      The port number on the remote server.
  • Return Value:
    An integer value that indicating the status connection status. The value 0 indicates that the connection was successful. This means the port is open and actively accepting connections. An error code is returned if an error occurs during the connection attempt.

send()

  • Function:
    Sends data to the connected socket.
  • Parameters:
    • data:
      The data to be sent, usually in bytes.
  • Return Value:
    Returns the number of bytes sent.

recv()

  • Function:
    Receives data from the connected socket.
  • Parameters:
    • buffer_size:
      The maximum amount of data to be received at once.
  • Return Value:
    Returns the received data as bytes.

close()

  • Function:
    Closes the socket, releasing any resources associated with it.
  • Parameters:
    None.
  • Return Value:
    None.

Writing a program using Python Sockets

Output:

Explanation

  • The #!/usr/bin/env python3 is known as a shebang line. It tells the system to use Python 3 to execute the script.
  • The subprocess module, provides a way to spawn new processes, connect to their input/output/error pipes, and obtain their return codes. The `subprocess.call('clear', shell=True) method is used to clear the terminal screen.
  • The sys module, provides access to some variables used or maintained by the interpreter and to functions that interact with the interpreter.

The overall work flow of the code is:

  1. The script prompts the user to input a remote host for scanning.
  2. It resolves the host name to an IP address using the socket.gethostbyname() function.
  3. The script then initiates a loop to check each port from 1 to 1024.
  4. For each port, it attempts to establish a connection with the remote server using a socket object with IPv4 and TCP.
  5. If the connection is successful, it prints that the port is open.
  6. The script handles cases where the user interrupts the scan with Ctrl+C or if there are errors in hostname resolution or socket connection.

You can also add a banner to the display using the pyfiglet library in Python. You can install the library using the pip install pyfiglet command and use the following code to display banner

The figlet_format function from the pyfiglet library is used to generate a banner. The desired text for banner should be passed as an argument to this function. For the above code a banner with the text "Your Banner Text" will be generated.

Conclusion

  • A Port Scanner in Python is a crucial tool for network administrators and security professionals to identify open ports on a target system.
  • Ports act as virtual endpoints for network communication, allowing different services to operate simultaneously on a single device.
  • Open ports can be potential security vulnerabilities, making port scanning an essential part of network security.
  • Python, with its socket library, provides the capability to create, configure, and interact with sockets for low-level network operations.
  • Socket functions like socket(), bind(), listen(), and accept() are pivotal for establishing and managing network connections.
  • The connect_ex() function acts as an indicator for open ports by returning 0 for an open port or successful connection. The function attempts to connect to a remote server at a specified address and port.
  • The port scanner uses sockets to scan a range of ports on a target host and identifies open ports.