We’ve seen a lot of cool applications for scapy in your network tools, but a good inspiration for new tools is to look at existing tools to figure out how they do their job. We will be emulating some nmap & Angry IP Scanner type features and creating the following tools:

TCP Port Range Scanner

This is a fairly basic tool to test whether a host has specific TCP ports open and listening. We start out by defining our host and ports to scan and then move on to the fun stuff. Using a random TCP source port to help obfuscate the attack (although most firewalls are smarter than this nowadays), we send a TCP SYN packet to each destination TCP port specified. If we get no response or a TCP RST in return, we know that the host is filtering or not listening on that port. If we get an ICMP unreachable or error response, we also know the host is not willing to take requests on that port. But, if we get an expected TCP SYN/ACK response, we will send a RST so the host doesn’t keep listening for our ACK since we already know the host is listening on that port. Here’s the code:

For more information on TCP behavior and how this was created, visit: Port Scanning Using Scapy

ICMP Ping Sweep

This script is an extension of our ICMP ping utility from the Sending and Receiving example. We will use a network given with a CIDR mask to specify the hosts to run the ping scan on. Then, using a Python for loop we iterate through each address and try pinging. If the response times out or returns an ICMP error (such as unreachable or admin deny), we know that the host is not up or is blocking ICMP. Otherwise, if we receive a response we know that host is online. Check out the code here:

NOTE: This could certainly be made much faster with threading since this is mostly IO bound (waiting for network responses), however that is outside the scope of this article.
In this example, the WARNING: Mac address to reach destination not found. Using broadcast. is telling us that Scapy doesn’t know the destination ARP address to send the packet to. This is only showing up because I am running this test on my locally connected network. If I were running this scan on a different network, Scapy would use the gateway MAC address for the L2 destination.

Combining the Two

Those first two tools are cool, but you know what would be cooler? Combining them! With a new tool that combines those two features, we can scan a subnet for online hosts and then also run a TCP scan on the online hosts.

To get this new tool up and running, we can pretty much use the existing code with just a couple changes. We can get rid of the single host variable since we’ll be using the network statment (this can define a single host using the /32 CIDR mask). Also, to keep the code clean and easy to understand we should move our TCP scan to it’s own function so we can call that on any hosts that respond to the ICMP ping request. Here’s the code and some example output:

That output is a little noisy for my taste, so if we remove some of the print statements like in this example here, we get the following output:

This is just the basics for building tools like this. The formatting can be customized to print out how you want and you can scan more ports if needed. Use these as starting points to build The Ultimate Network Tool and let me know what you create!

Series Navigation<< Scapy p.09 – Scapy and DNSScapy p.11 – Scapy Resources >>

This post was originally published on

Leave a Reply

Your email address will not be published. Required fields are marked *