Scripting Packet Analysis and Modification

Thomas Whitton


What you should take away from this presentation?

  1. What it is possible to do and how easy it is.
  2. An overview of the techniques and libraries available to you.
  3. A comparison of these techniques and libraries i.e. when you should use what?

Why the hell do we want to know about scripting packet analysis and modification?

The idea behind using scripting to analyse and modify packet data is that tools can created for a very specific task that other people may not have thought up yet.

We can't always rely on someone having the exact same problem and creating an opensource tool for the job.

And with using a scripting language the tool can probably be a couple of lines of code, plus everyone knows at least one scripting language (right?).

Packet Analysis

Why not use current tools?

For 99% of your packet analysis Wireshark does a pretty damn good job

A couple of cases in which it might be preferable to use a scripting language:

  • Wireshark/Tshark cannot be installed on a system easily and the pcap (from a tcpdump) can't be copied over
  • The scenario you need to find is way too complicated to be caught by a standard Wireshark filter

Packet Modification

Why not use current tools?

There are some cool tools available for packet modification, however, none are feature rich and as widely used as wireshark.

They are all for very specific tasks, where as we might like to do something very different.

Scripting Techniques and Libraries

  • dpkt - A python library for dealing with packet data
  • scapy - A widely used python library for analysing the network and more
  • packetfu - A ruby library for dealing with packet data

Example Use Cases

  • Editing a pcap file only changing specific packets
  • Finding a very specific set of packets in a tcp stream
  • Hand crafting packets
  • Sending packets without using tcprelay
  • Sending and receiving packets and then doing something with them
  • Combine the above to create custom tools to help us to further automate our processes


  • Works
  • asn.1 decoder

  • Lacks features
  • Too verbose
  • Development stopped
  • No documentation

dpkt examples

 import dpkt
 from dpkt.asn1 import decode
 from dpkt.ip import IP
 from dpkt.icmp import ICMP
 from ipaddr import *

 def pcap_test():
     with open("test.pcap") as f:
         pcap = dpkt.pcap.Reader(f)
         for ts, buf in pcap:
             eth = dpkt.ethernet.Ethernet(buf)
             ip =
             if type( == dpkt.ip.IP:
                 src = IPAddress(Bytes(ip.src))
                 dst = IPAddress(Bytes(ip.dst))
                 print str(src) + " -> " + str(dst)
                 tcp =
                 port = tcp.dport
                 print "%s, %d" % (port, len(
                 if tcp.dport == 80 and len( > 0:
                     http = dpkt.http.Request(


 def creation_test():
     ip = IP(src=v4_int_to_packed(IPAddress("")._ip), dst=v4_int_to_packed(IPAddress("")._ip), p=1)
     print ip.v # 4
     print ip.src # '\x01\x02\x03\x04'
     print # ''
     icmp = ICMP(type=8, data=ICMP.Echo(id=123, seq=1, data='foobar'))
     print icmp # ICMP(type=8, data=Echo(id=123, seq=1, data='foobar'))
     print len(icmp) # 15 = icmp
     ip.len += len(
     print ip
     # IP(src='\x01\x02\x03\x04', dst='\x05\x06\x07\x08', len=34, p=1, data=ICMP(type=8, data=Echo(id=123, seq=1, data='foobar')))
     pkt = str(ip)
     print pkt # 'E\x00\x00"\x00\x00\x00\x00@\x01j\xc8\x01\x02\x03\x04\x05\x06\x07\x08\x08\x00\xc0?\x00{\x00\x01foobar'
     print IP(pkt) # IP(src='\x01\x02\x03\x04', dst='\x05\x06\x07\x08', sum=27336, len=34, p=1, data=ICMP(sum=49215, type=8, data=Echo(id=123, seq=1, data='foobar')))

 def asn1_test():
     s = '0\x82\x02Q\x02\x01\x0bc\x82\x02J\x04xcn=Douglas J Song 1, ou=Information Technology Division, ou=Faculty and Staff, ou=People, o=University of Michigan, c=US\n\x01\x00\n\x01\x03\x02\x01\x00\x02\x01\x00\x01\x01\x00\x87\x0bobjectclass0\x82\x01\xb0\x04\rmemberOfGroup\x04\x03acl\x04\x02cn\x04\x05title\x04\rpostalAddress\x05\x0ftelephoneNumber\x04\x04mail\x04\x06member\x04\thomePhone\x04\x11homePostalAddress\x04\x0bobjectClass\x04\x0bdescription\x04\x18facsimileTelephoneNumber\x04\x05pager\x04\x03uid\x04\x0cuserPassword\x04\x08joinable\x04\x10associatedDomain\x04\x05owner\x04\x0erfc822ErrorsTo\x04\x08ErrorsTo\x04\x10rfc822RequestsTo\x04\nRequestsTo\x04\tmoderator\x04\nlabeledURL\x04\nonVacation\x04\x0fvacationMessage\x04\x05drink\x04\x0elastModifiedBy\x04\x10lastModifiedTime\x04\rmodifiersname\x04\x0fmodifytimestamp\x04\x0ccreatorsname\x04\x0fcreatetimestamp'
     print decode(s) # [(48, [(2, 11), (99, [(4, 'cn=Douglas J Song 1, ou=Information Technology Division, ou=Faculty and Staff, ou=People, o=University of Michigan, c=US'), (10, '\x00'), (10, '\x03'), (2, 0), (2, 0), (1, '\x00'), (135, 'objectclass'), (48, [(4, 'memberOfGroup'), (4, 'acl'), (4, 'cn'), (4, 'title'), (4, 'postalAddress'), (4, 'telephoneNumber'), (4, 'mail'), (4, 'member'), (4, 'homePhone'), (4, 'homePostalAddress'), (4, 'objectClass'), (4, 'description'), (4, 'facsimileTelephoneNumber'), (4, 'pager'), (4, 'uid'), (4, 'userPassword'), (4, 'joinable'), (4, 'associatedDomain'), (4, 'owner'), (4, 'rfc822ErrorsTo'), (4, 'ErrorsTo'), (4, 'rfc822RequestsTo'), (4, 'RequestsTo'), (4, 'moderator'), (4, 'labeledURL'), (4, 'onVacation'), (4, 'vacationMessage'), (4, 'drink'), (4, 'lastModifiedBy'), (4, 'lastModifiedTime'), (4, 'modifiersname'), (4, 'modifytimestamp'), (4, 'creatorsname'), (4, 'createtimestamp')])])])]


  • Simple to use
  • Tons of features
  • Widely used
  • Good documentation

  • Not really actively developed

Scapy Examples

 from scapy.all import *

 def pcap_test():
     pkts = rdpcap("test.pcap")
     pkts[0][IP].src = ''
     wrpcap("result.pcap", pkts[0])

 def show_test():
     # requires root privelages
     pkts = sniff(iface="wlan0", filter="icmp", count=10)
     print len(pkts)


 def sniff_test():
     # requires root privelages
     # same filter expression used by wireshark capture filters and tcpdump
     pkts = sniff(iface="wlan0", filter="icmp", count=10)
     pkts = sniff(iface="wlan0", filter="tcp and host", count=10, prn=pkt_print)
     def pkt_print(pkt):
         print pkt[IP].src + "->" + pkt[IP].dst

 def create_test():
     a=Ether()/IP(dst="")/TCP()/"GET /index.html HTTP/1.0 \n\n"

 def send_test():
     sendp(rdpcap("test.pcap")) # tcpreplay
     # inter is sleep time between packets and loop > 0 means carry on until keyboard interupt
     sendp("I'm travelling on Ethernet", iface="eth1", loop=1, inter=0.2)
     # fuzz randomises default values

 def sending_and_receiving_test():

 def filter_test():
     pkts = rdpcap("test.pcap")
     pkts.filter(lambda x: TCP in x)


  • Clean API
  • Simple to use
  • Actively developed
  • Good documentation

  • Lacks features
  • Uses Ruby :)

Packetfu Examples

 require 'packetfu'
 include PacketFu
 iface = "wlan0"

 def sniff_test(iface)
   # requires root privelages
   cap = => iface, :start => true) do |p|
     pkt = Packet.parse p
     if pkt.is_ip?
       next if pkt.ip_saddr == Utils.ifconfig(iface)[:ip_saddr]
       packet_info = [pkt.ip_saddr, pkt.ip_daddr, pkt.size, pkt.proto.last]
       puts "%-15s -> %-15s %-4d %s" % packet_info

 def creation_test()
   pkt =
   pkt.ip_saddr = ""
   pkt.tcp_spot = "80"

 def send_test()
   pkt =
   pkt.ip_id = 0xbabe
   pkt.ip_saddr = ""
   pkt.ip_daddr = ""
   pkt.payload = "hello"
   3.times { pkt.to_w("wlan0") }

 def hex_test()
   pkt =
   pkt.ip_saddr = ""
   pkt.tcp_sport = "80"
   # prints out the hex of the packet
   puts pkt.inspect_hex

 def read_and_write_pcap_test()
   # use as singleton
   pfile =
   pkts = pfile.read_packets("test.pcap")
   pfile.array_to_file(:filename => "result.pcap", :array => pkts)