Welcome to my first blog post! Today we will be creating a simple packet sniffer in python 3.12.
We will need a couple things in order for this to run properly, but first, lets get the downloads out of the way. Head over to https://npcap.com/dist/ and download the latest version of npCAP. Next, we will download Python 3.12 here and follow the same steps. We will be using Visual Studio Code to write the script, so lets download the latest version now here. Proceed to install all the files we have downloaded thus far. In order to run a crucial part of the script, we also need to have pip installed before we can install scapy.
Step 1: Download get-pip.py
- Open a web browser and navigate to https://bootstrap.pypa.io/get-pip.py.
- Right-click on the page and select “Save As…” to save the file as
get-pip.py
on your computer.
Step 2: Open Command Prompt
- Press
Win + R
, typecmd
, and pressEnter
to open the Command Prompt.
Step 3: Run get-pip.py
Navigate to the directory where you saved get-pip.py
. For example, if you saved it in the Downloads
folder, type:
"python get-pip.py"
Finally, we can now download and install scapy. For this step, we do not need to return to the browser to download, as we now can install it directly from our terminal.
Write pip install scapy
in your terminal and hit enter. The file will automatically install and be ready for use later. You can close the terminal for now.
After downloading and installing all our prerequisites, we can finally begin writing the code in Visual Studio.
Now, some systems may automatically recognize if Python is installed, some may not, so we will ensure that it is indeed installed and ready to use with Visual Studio.
First, open Visual Studio Code and locate the sidebar with various logos. You will click on the button named “Extension”, shown below for reference.
Type in Python into the search bar and install the extension. This will ensure our code is written in Python with no issues. Once installed, head back over to the explorer page on Visual Studio.
Here we will create a new file, so click File > New File. A text box will appear at the top, type python into it, and click create Python File.
A new .py file will be created and prompt you for a name. You can name it to whatever, but I left it default to PythonApplication1.py.
Now we can finally begin writing our code! Lets dive in.
Our first 2 lines for this script will be importing ‘required’ libraries.
Importing Required Libraries:
import argparse
from scapy.all import sniff, wrpcap
argparse: This library is used to handle command-line arguments. It allows the user to specify options like which network interface to sniff on, how many packets to capture, and where to save the output.
scapy.all: This imports key functions from the `scapy
` library.
`sniff
`: Captures network packets.
`wrpcap
`: Writes captured packets to a file in .pcap
format.
Hit Enter x2 to continue the code on Line 4.
Defining the Packet Processing Callback Function:
def packet_callback(packet):
if packet.haslayer('IP'):
ip_src = packet['IP'].src
ip_dst = packet['IP'].dst
print(f"IP Packet: {ip_src} -> {ip_dst}")
def: stands for define in python.
packet_callback: This function is called every time a packet is captured.
- packet.haslayer(‘IP’): Checks if the captured packet contains an IP layer.
- packet[‘IP’].src: Extracts the source IP address from the packet.
- packet[‘IP’].dst: Extracts the destination IP address from the packet.
- print(f”IP Packet: {ip_src} -> {ip_dst}”): Prints the source and destination IP addresses to the console.
This function allows real time analysis of captured packets by printing IP addresses for every packet that has an IP layer.
Hit Enter x2 again, we’re almost done here!
Setting up Command-Line Argument Parsing:
def main():
parser = argparse.ArgumentParser(description="Simple Packet Sniffer")
parser.add_argument('-i', '--interface', type=str, help='Network interface to sniff on', required=True)
parser.add_argument('-c', '--count', type=int, help='Number of packets to capture', default=10)
parser.add_argument('-f', '--filter', type=str, help='BPF filter for packet capture', default='')
parser.add_argument('-o', '--output', type=str, help='Output file to save packets', default='')
argparse.ArgumentParser: Initializes the argument parser with a description of what the script does.
parser.add_argument: Defines various command-line options:
- -i / –interface: Required argument that specifies the network interface to sniff on (e.g., “Wi-Fi” or “Ethernet”).
- -c / –count: Optional argument that sets how many packets to capture. Defaults to 10 if not specified.
- -f / –filter: Optional argument for a BPF (Berkeley Packet Filter) string to filter the packets (e.g., “tcp port 80” to capture only HTTP traffic).
- -o / –output: Optional argument that specifies the file to save the captured packets to. If not specified, packets won’t be saved.
Capturing and Handling Packets:
args = parser.parse_args()
packets = sniff(iface=args.interface, prn=packet_callback, filter=args.filter, count=args.count)
if args.output:
wrpcap(args.output, packets)
args = parser.parse_args(): Parses the command-line arguments provided by the user and stores them in the args
object.sniff(…): Starts the packet capturing process using the parameters provided:
- iface=args.interface: Sniffs on the network interface specified by the user.
- prn=packet_callback: Calls the
packet_callback
function for each captured packet. - filter=args.filter: Applies the user-specified BPF filter to capture specific types of packets.
- count=args.count: Captures the number of packets specified by the user.
wrpcap(…): Saves the captured packets to a .pcap
file if the -o / --output
argument was provided.
Running the Main Function:
if __name__ == '__main__':
main()
This is normal with Python, when the script is executed directly (not imported as a module), the main()
function is called, which starts the packet sniffing process.
Now we’ve finally finished writing our code! Go ahead and save the file if you haven’t already, and open a terminal.
Since I am using Wi-Fi, i will be using this command to start the process.
python PythonApplication1.py -i "Wi-Fi" -c 10 -f "tcp"
As we can see above, we are successfully capturing IP addresses using a TCP filter. We can also change the filter to capture UDP as well, which would also yield the same result.