In this blog post, we'll dive into the creation of an advanced port scanner using Python and Scapy, a powerful packet manipulation library. Scapy allows for fine-grained control over network packets, making it an ideal choice for developing custom network tools.
We'll implement a simple TCP port scanner first, and then add the capability for SYN port scanning, also known as half-open scanning, which sends TCP SYN packets to a target's ports. If a port responds with a SYN-ACK, it indicates the port is open. The scanner then sends an RST to avoid completing the TCP handshake.
Disclaimer: This tutorial is for educational purposes only. Unauthorized port scanning is illegal and unethical. Always obtain explicit permission before scanning any network or system. Use this knowledge responsibly and within legal boundaries.Introduction
The TCP handshake (also known as three-way handshake) is the way socket connections are established in the TCP protocol, TCP is focused on reliability of data transfer, so this handshake is a way to ensure both machines are ready to exchange information.
Simple TCP scanner
Let's create a function in python to do the full TCP handshake on a desired host and port, establishing a connection.
Here we create a socket, and try to connect to the host and port. If successfull we return True
, and if not we return False
.
SYN scanner
For this type of scan, we will need to install a library called scapy and import it into our script
pip install scapy
Scapy allows us to manually craft a SYN packet and detect the type of response we get from the host
Here, we create a packet with the 'S' flag, which means it's a SYN packet.
The flags can also be represented in hexadecimal format, and that's how we're checking the response, where 0x12
represents a SYN-ACK
response, and 0x14
represents an RST-ACK
response.
RST responses are used to terminate a connection, meaning that the communication attempt is denied, that's what we send when we find an open port to avoid finishing the three-way handshake.
Threading
For now, our functions can only scan a single port, but usually while pentesting we need to scan multiple ports, or a range of ports. Let's create a queue and multiple threads to execute our port scanning over multiple ports quickly.
First, we need to import some native python libraries and create the worker functions for our two types of scans
Then, we can create a method to create and start our threads. I'm making it receive the worker as a parameter so it can work with both scanners
Then it's easy to execute our scans with multithreading by simply calling our threaded_scan
function, like so
And now we can run our port scanner script! Note that we need to run as root since the scapy lib uses some network functionality that is prohibited by the OS to regular users.
To run this without sudo, you need to give python access to these network capabilities using the following command:
setcap cap_net_raw=eip /usr/bin/pythonX.X
Where X.X
is your python version.
Either way, running our script should give a result like this
$ sudo python main.py
Running full tcp scan:
Port 80: Closed
Port 3000: Open
Port 8080: Closed
Port 6333: Open
Port 6334: Open
Port 11434: Open
Running syn scan:
Port 80: Closed
Port 3000: Open
Port 8080: Closed
Port 6333: Open
Port 6334: Open
Port 11434: Open
And there's our python port scanner. I hope this tutorial was useful for you, if you enjoy my content, subscribe for free to receive my weekly newsletter with more tech-related content.
Full source code of all my projects is also available for paying members, if you want to support my work, consider subscribing as a PLUS or PRO member. Thanks!