Back to article
Linux Scapy Guards Your Servers (part 2)
Building a Scapy Toolbox
December 2, 2010
Scapy is a flexible tool for both capturing and generating network traffic, and performing whatever type of analysis you want. In Part 2 Paul Ferrill goes deeper into designing custom tests with just a few lines of code.
With Scapy you can both capture and generate network traffic. In some cases it's necessary to generate a particular traffic stream and then watch what comes back. With Scapy you can build that type of tool with just a few lines of code. It will be helpful to define a few terms before we get too far in order to better understand what Scapy is doing. The OSI seven-layer protocol model is used by Scapy in determining how to construct and interpret the bits flowing across the wire. The physical layer is also known layer 1 and is where things like media, either wired or wireless, connectors and signal levels are defined. Layer two, referred to as the data link layer, is where frames of data travel and use a unique physical or MAC address to identify each node. The next layer up is layer three and is referred to as the network layer. This is the level where you have logical addressing, commonly known as an IP address.
The standard Linux ping command actually uses the Internet Control Message Protocol (ICMP) echo request command to query a specific IP address. ICMP messages happen at the network layer or layer 3. Another way to accomplish the same task is to use Address Resolution Protocol (ARP) to ascertain the hardware address of a specific IP address. Since ARP functions at layer 2, it is one step closer to the physical transport and often will return information quicker than a layer 3 command. The following code snippet will accomplish an ARP ping showing both the MAC and IP address of each discovered node:
>>> arping("192.168.1.0/24", timeout=2)
We can package up that single line command into a running Python program that will accept a target IP address as a parameter as follows:
#!/usr/bin/python from scapy.all import * def usage(): print "Usage: arp-ping.py 192.168.1.0/24" sys.exit(1) if len(sys.argv) != 2: usage() range = sys.argv arping(range, timeout=2)
We could wrap a GUI using Tk around the same functionality with a little more code like this:
from Tkinter import * from scapy.all import conf,arping conf.verb=0 def PingARP(): global myping print str(dst.get()) ans,unans=arping(str(dst.get())) for snd,rcv in ans: textbox.insert(END, rcv.sprintf("%Ether.src% %ARP.psrc%\n")) print rcv.sprintf("%Ether.src% \i %ARP.psrc%\n") root.update() root = Tk() root.wm_resizable(0, 0) frame = frame = Frame(root) label = Label(frame, text="IP address").pack(side=LEFT) dst = Entry(frame) dst.pack(side=LEFT, fill=X, expand=True) frame.pack(fill=X, expand=True) frame = frame = Frame(root) button = Button(frame, text="ARP Ping", command=PingARP) frame.pack(fill=X) frame2 = frame2 = Frame(root) scrollbar = Scrollbar(frame2) scrollbar.pack(side=RIGHT, fill=Y) textbox = Text(frame2) textbox.pack(side=RIGHT, fill=BOTH, expand=True) textbox.config(yscrollcommand=scrollbar.set) scrollbar.config(command=textbox.yview) frame2.pack(fill=BOTH, expand=True) button.pack() frame.pack() root.mainloop()
One last modification to this code changes the default ping to use another Scapy feature that looks for any node with their adapter set to promiscuous mode. That would be a sign of potential threats on your network running a tool like Wireshark. To do this we add the module promiscping to our import line and change one line in the PingARP routine as follows:
Now we have a useful network forensics tool with a relatively small amount of programming. You can use the same basic framework wrapped around any of Scapy's commands to build your own tools.