http://www.secdev.org/projects/scapy/doc/usage.html
Scapy is a Python interpreter that enables you to create, forge, or decode packets on the network, to capture packets and analyze them, to dissect the packets, etc. It also allows you to inject packets into the network. It supports a wide number of network protocols and it can handle and manipulate wireless communication packets.
Scapy can be used to perform the jobs done by many network tools, such as nmap, hping, arpscan, and tshark (the command line of wireshark).
The concept behind Scapy is that it is cable of sending and receiving packets and it can sniff packets. The packets to be sent can be created easily using the built-in options and the received packets can be dissected. Sniffing of packets helps in understanding what communication is taking place on the network.
Building a packet:
[root@deeptiWorkSpace scapy-2.3.1]# ./run_scapy
INFO: Can't import python gnuplot wrapper . Won't be able to plot.
INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
WARNING: No route found for IPv6 destination :: (no default route?)
Welcome to Scapy (2.3.1)
>>> a=IP(ttl=10)
>>> a
<IP ttl=10 |>
>>> a.src
'127.0.0.1'
>>> a.dst="10.10.12.39"
>>> a
<IP ttl=10 dst=10.10.12.39 |>
>>> a.src
'10.10.16.199'
>>> a.ttl
10
>>> del(a.ttl)
>>> a
<IP dst=10.10.12.39 |>
>>> a.ttl
64
Stacking layers
The / operator has been used as a composition operator between two layers. When doing so, the lower layer can have one or more of its defaults fields overloaded according to the upper layer. (You still can give the value you want). A string can be used as a raw layer.
>>> IP()
<IP |>
>>> IP()/TCP()
<IP frag=0 proto=tcp |<TCP |>>
>>> Ether()/IP()/TCP()
<Ether type=IPv4 |<IP frag=0 proto=tcp |<TCP |>>>
>>> IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"
<IP frag=0 proto=tcp |<TCP |<Raw load='GET / HTTP/1.0\r\n\r\n' |>>>
>>> Ether()/IP()/IP()/UDP()
<Ether type=IPv4 |<IP frag=0 proto=ipencap |<IP frag=0 proto=udp |<UDP |>>>>
>>> IP(proto=55)/TCP()
<IP frag=0 proto=mobile |<TCP |>>
Each packet can be build or dissected (note: in Python _ (underscore) is the latest result):
>>> str(IP())
'E\x00\x00\x14\x00\x01\x00\x00@\x00|\xe7\x7f\x00\x00\x01\x7f\x00\x00\x01'
>>> IP(_)
<IP version=4L ihl=5L tos=0x0 len=20 id=1 flags= frag=0L ttl=64 proto=ip chksum=0x7ce7 src=127.0.0.1 dst=127.0.0.1 |>
>>> a=Ether()/IP(dst="www.slashdot.org")/TCP()/"GET /index.html HTTP/1.0 \n\n"
>>> print a
▒g寫l▒B▒K▒EC@Ґ
▒▒"▒0PP ▒GET /index.html HTTP/1.0
>>> hexdump(a)
0000 D0 67 E5 AF AB 6C 9E 42 EA 4B FC 5F 08 00 45 00 .g...l.B.K._..E.
0010 00 43 00 01 00 00 40 06 D2 90 0A 0A 10 C7 D8 22 .C....@........"
0020 B5 30 00 14 00 50 00 00 00 00 00 00 00 00 50 02 .0...P........P.
0030 20 00 15 8E 00 00 47 45 54 20 2F 69 6E 64 65 78 .....GET /index
0040 2E 68 74 6D 6C 20 48 54 54 50 2F 31 2E 30 20 0A .html HTTP/1.0 .
0050 0A .
>>>
>>> Ether(str(a))
<Ether dst=d0:67:e5:af:ab:6c src=9e:42:ea:4b:fc:5f type=IPv4 |<IP version=4L ihl=5L tos=0x0 len=67 id=1 flags= frag=0L ttl=64 proto=tcp chksum=0xd290 src=10.10.16.199 dst=216.34.181.48 options=[] |<TCP sport=ftp_data dport=http seq=0 ack=0 dataofs=5L reserved=0L flags=S window=8192 chksum=0x158e urgptr=0 options=[] |<Raw load='GET /index.html HTTP/1.0 \n\n' |>>>>
>>> Ether(str(a))
<Ether dst=d0:67:e5:af:ab:6c src=9e:42:ea:4b:fc:5f type=IPv4 |<IP version=4L ihl=5L tos=0x0 len=67 id=1 flags= frag=0L ttl=64 proto=tcp chksum=0xd290 src=10.10.16.199 dst=216.34.181.48 options=[] |<TCP sport=ftp_data dport=http seq=0 ack=0 dataofs=5L reserved=0L flags=S window=8192 chksum=0x158e urgptr=0 options=[] |<Raw load='GET /index.html HTTP/1.0 \n\n' |>>>>
>>> Ether(str(a)).hide_defaults() # Hides all the default values
>>>
Reading PCAP files
==================
You can read packets from a pcap file and write them to a pcap file.
>>> a=rdpcap("/spare/captures/isakmp.cap")
>>> a
<isakmp.cap: UDP:721 TCP:0 ICMP:0 Other:0>
Sending packets
Now that we know how to manipulate packets. Let’s see how to send them. The send() function will send packets at layer 3. That is to say it will handle routing and layer 2 for you. The sendp() function will work at layer 2. It’s up to you to choose the right interface and the right link layer protocol.
>>> send(IP(dst="10.10.16.198")/ICMP())
.
Sent 1 packets.
>>> sendp(Ether()/IP(dst="10.10.16.198",ttl=(1,4)), iface="eth1")
....
Sent 4 packets.
***********************
===== TCP REPLAY =====
***********************
>>> sendp(rdpcap("/tmp/pcapfile")) # tcpreplay
...........
Sent 11 packets.
>>> sendp(rdpcap("/home/dvaidyula/udp_du_bb1_1500.pcap"))
.............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Sent 1501 packets.