Coding a Port Scanner with Python
Tags: ethicalhacking, security, cybersecurity, penetrationtesting
Published: 2023-04-04 05:34:51

Port scanning is a way for determining which ports on a network device are open, whether it's a server, a router, or a regular machine. To simply put it, a port scanner is just a script or a program that is designed to probe a host for open ports.

In this blog, I will show you step-by-step how to code a simple port scanner using the pre-installed socket library. The idea of making the port scanner is to connect to a host (it could be a website, server, or any device which is connected to a network/ internet) through a list of ports. If the scanner establishes a connection, then that means the port is open. 

**DISCLAIMER: THIS IS ONLY FOR EDUCATIONAL PURPOSES ONLY. DO NOT USE THIS ON A HOST THAT YOU DO NOT HAVE PERMISSION TO TEST. PORT SCANNING IS NOT ILLEGAL UNLESS IT IS USED TO GAIN UNAUTHORIZED ACCESS OR BREACH PRIVACY.**

First things first, if you want to print in colors, you will need to install colorama (this is completely optional): 

```
pip 3 install colorama
```

With that out of the way, now we can actually start coding the scanner. First, let's import the `socket` module: 

```
import socket # for connecting to the host 
from colorama import init, Fore

# adding some colors (optional)
init()
GREEN = Fore.GREEN
RESET = Fore.RESET
GRAY = Fore.LIGHTBLACK_EX

```
_**The socket module is a module already built in the Python standard library, so you don't need to install it.**_

`colorama` is used later when the program prints the ports that are open or closed (again this is optional) 

Next, let's create a function that will be used to decide whether a port is open or not: 

```
def is_port_open(host, port):
    
    #determines whether the host has the port open
    # creates a new socket
    s = socket.socket()
    try:
        # tries to connect to host using that port
        s.connect((host, port))
        # make a timeout if you want it a little faster (means less accuracy)
        # s.settimeout(0.2) <-- if you want to add a timeout 
    except:
        # cannot connect (port is closed) and returns false 
        return False
    else:
        # the connection is established (port is open)
        return True

```

the `s.connect((host,port))` function attempts to connect the socket to a remote address using the `(host,port)` tuple (Tuples are used to store multiple items in a single variable), it will bring up an exception when it fails to connect to the host, so that is why we put that code into a try-expcept block so when the exception is brought up, it tells us that the port is closed (otherwise it is open). 

Lastly, we can use the function we just made above and repeat it over a number of ports: 

```
# asks user to enter a port 
host = input("Enter the host:")
# repeat over ports, from 1 to 1024
for port in range(1, 1024):
    if is_port_open(host, port):
        print(f"{GREEN}[+] {host}:{port} is open      {RESET}")   #prints green text for open ports 
    else:
        print(f"{GRAY}[!] {host}:{port} is closed    {RESET}", end="\r") #prints gray text for closed ports 
```
This part of the code will scan all ports from 1 to 1024. You can freely change the range if you so choose, but keep in mind that if you increase the range it will take longer to complete scanning. 

## Potential Issues

Upon running the code, you will notice that the script isn't the fastest. You can change this by adding a timeout of 200 milliseconds (using `settimeout(0.2)`. Keep in mind that this will reduce the accuracy of the scanning, especially if you have high latency. 

If you want, the full source code is on [Github](https://github.com/sleepyrob0t/simple-portscanner-python).