lost and found ( for me ? )

Showing posts with label tcpdump. Show all posts
Showing posts with label tcpdump. Show all posts

tcpreplay 3.4.4: replay DNS capture file with tcpreplay

Here are trial and error logs when replaying a DNS capture file with tcpreply.

tcpreplay machine: 192.168.10.15
target machine (DNS Server): 192.168.10.12

install tcpreplay via apt-get
# tail -1 /etc/lsb-release
DISTRIB_DESCRIPTION="Ubuntu 13.04"

# uname -ri
3.8.0-35-generic x86_64

# apt-get install tcpreplay –y

# tcpreplay --version
tcpreplay version: 3.4.4 (build 2450) (debug)
Copyright 2000-2010 by Aaron Turner <aturner at synfin dot net>
Cache file supported: 04
Not compiled with libdnet.
Compiled against libpcap: 1.3.0
64 bit packet counters: enabled
Verbose printing via tcpdump: enabled
Packet editing: disabled
Fragroute engine: disabled
Injection method: PF_PACKET send()



prepare a capture data for tcpreplay.
on the tcpreplay box,
# tcpdump -i br0 udp dst port 53 -w dns_dump.cap

# dig @192.168.10.12 isc.org any +bufsize=4096 +ignore

# file dns_dump.cap
dns_dump.cap: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 65535)

replay the cap file
# tcpreplay --loop=1 --intf1=br0 dns_dump.cap
sending out br0
processing file: dns_dump.cap
Actual: 1 packets (78 bytes) sent in 0.03 seconds.              Rated: 2600.0 bps, 0.02 Mbps, 33.33 pps
Statistics for network device: br0
       Attempted packets:         1
       Successful packets:        1
       Failed packets:            0
       Retried packets (ENOBUFS): 0
       Retried packets (EAGAIN):  0

cap date on the NS server
# tshark -i eth0 port 53
Running as user "root" and group "root". This could be dangerous.
Capturing on eth0
 0.000000 192.168.10.15 -> 192.168.10.12 DNS 78 Standard query 0x5718  ANY isc.org

checksum problem?
Let’s compare checksum between dig cap and tcpreplay cap.

[ dig cap ]

IP header
   Total Length: 64
   Identification: 0x43b6 (17334)
   Flags: 0x00
       0... .... = Reserved bit: Not set
       .0.. .... = Don't fragment: Not set
       ..0. .... = More fragments: Not set
   Fragment offset: 0
   Time to live: 64
   Protocol: UDP (17)
   Header checksum: 0xa18b [correct]
       [Good: True]
       [Bad: False]
   Source: 192.168.10.15 (192.168.10.15)
   Destination: 192.168.10.12 (192.168.10.12)



UDP header
User Datagram Protocol, Src Port: domain (53), Dst Port: 60739 (60739)
   Source port: domain (53)
   Destination port: 60739 (60739)
   Length: 44
   Checksum: 0x95a9 [validation disabled]
       [Good Checksum: False]
       [Bad Checksum: False]

[ tcpreplay cap ]

IP header
   Total Length: 64
   Identification: 0x43aa (17322)
   Flags: 0x00
       0... .... = Reserved bit: Not set
       .0.. .... = Don't fragment: Not set
       ..0. .... = More fragments: Not set
   Fragment offset: 0
   Time to live: 64
   Protocol: UDP (17)
   Header checksum: 0xa197 [correct]
       [Good: True]
       [Bad: False]
   Source: 192.168.10.15 (192.168.10.15)
   Destination: 192.168.10.12 (192.168.10.12)

UDP header
User Datagram Protocol, Src Port: 50164 (50164), Dst Port: domain (53)
   Source port: 50164 (50164)
   Destination port: domain (53)
   Length: 44
   Checksum: 0x95a9 [validation disabled]
       [Good Checksum: False]
       [Bad Checksum: False]

It seems that there are no problems about checksum, I think.

How about using a cap file captured with tshark
# tshark -i br0 udp dst port 53 -w tshark_dig.pcap

# dig @192.168.10.12 isc.org any +bufsize=4096

# file tshark_dig.pcap
tshark_dig.pcap: pcap-ng capture file - version 1.0

# tcpreplay --loop=1 --intf1=br0 tshark_dig.pcap
sending out br0
processing file: tshark_dig.pcap
Actual: 1 packets (78 bytes) sent in 0.04 seconds.              Rated: 1950.0 bps, 0.01 Mbps, 25.00 pps
Statistics for network device: br0
       Attempted packets:         1
       Successful packets:        1
       Failed packets:            0
       Retried packets (ENOBUFS): 0
       Retried packets (EAGAIN):  0

same issue. DNS server does not replay the answer.
# tshark -i eth0 port 53
Running as user "root" and group "root". This could be dangerous.
Capturing on eth0
 0.000000 192.168.10.15 -> 192.168.10.12 DNS 78 Standard query 0xf9d4  ANY isc.org

How about re-calculating checksum with tcprewrite

[ tcprewrite: tcpdump cap file ]

# tcprewrite --fixcsum --infile=dns_dump.cap --outfile=out_dns_dump.cap

# tcpreplay --loop=1 --intf1=br0 out_dns_dump.cap
sending out br0
processing file: out_dns_dump.cap
Actual: 1 packets (78 bytes) sent in 0.03 seconds.              Rated: 2600.0 bps, 0.02 Mbps, 33.33 pps
Statistics for network device: br0
       Attempted packets:         1
       Successful packets:        1
       Failed packets:            0
       Retried packets (ENOBUFS): 0
       Retried packets (EAGAIN):  0

Okay.
190.106051 192.168.10.15 -> 192.168.10.12 DNS 78 Standard query 0x5718  ANY isc.org
190.106191 192.168.10.12 -> 192.168.10.15 DNS 78 Standard query response 0x5718

I was able to replay pcap file from both tcpdump pcap and tshark pcap after issuing fixing checksum with tcprewrite.

[ tcprewrite: tshark cap file ]

# tcprewrite --fixcsum --infile=tshark_dig.pcap --outfile=out_tshark_dig.pcap

# tcpreplay --loop=1 --intf1=br0 out_tshark_dig.pcap
sending out br0
processing file: out_tshark_dig.pcap
Actual: 1 packets (78 bytes) sent in 0.03 seconds.              Rated: 2600.0 bps, 0.02 Mbps, 33.33 pps
Statistics for network device: br0
       Attempted packets:         1
       Successful packets:        1
       Failed packets:            0
       Retried packets (ENOBUFS): 0
       Retried packets (EAGAIN):  0

Okay.
382.992509 192.168.10.15 -> 192.168.10.12 DNS 78 Standard query 0xf9d4  ANY isc.org
382.992657 192.168.10.12 -> 192.168.10.15 DNS 78 Standard query response 0xf9d4

Seen from the result, the problem on this issue seemed to be caused by checksum..

Seen from the tcpreplay documents, it describes that
Forcing Checksum Calculation
Many network cards support TCP/UDP/IP checksum offloading, so if you capture traffic which was generated by the same system, the checksums will be incorrect. This can obviously cause problems later on when you try replaying the traffic. By using the --fixcsum flag, you can force tcprewrite to fix the checksums. Note, tcprewrite will automatically fix checksums when editing packets.
$ tcprewrite --fixcsum --infile=input.pcap --outfile=output.pcap

[ sample usage ]

replay the cap file at top speed
# tcpreplay --loop=1000 -t -q --intf1=br0 out_dns_dump.cap

--loop=1000 : repeat 1,000 times
--loop=0: repeat forever until Ctrl-C is pressed

send 1,000 pps
# tcpreplay -q --loop=100 --pps=1000 --intf1=br0 out_dns_dump.cap


Python scapy: generate DNS queries from a pcap file collected with tcpdump

Here is sample scapy script how to generate UDP DNS queries from a pcap file collected with tcpdump.

Prepare a pcap file ( capture only resolvers -> DNS servers packet )
Please note that this script can not read a pcap file collected with wireshark.
# file tcpdump_dns_queries.pcap
tcpdump_dns_queries.pcap: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 500)

# tcpdump -r tcpdump_dns_queries.pcap  -n | head -10
reading from file tcpdump_dns_queries.pcap, link-type EN10MB (Ethernet)
18:27:31.733097 IP 192.168.27.17.40930 > 192.168.122.127.53: 16978 SOA? 1zznbxb487.wue.bar.com. (40)
18:27:31.763683 IP 192.168.27.18.13962 > 192.168.122.127.53: 30924 NS? gx42ilp0sc.iqu.bar.com. (40)
18:27:31.778066 IP 192.168.27.19.15052 > 192.168.122.127.53: 60958 SOA? 2wnwtq8eo7.mx2.bar.com. (40)
18:27:31.786013 IP 192.168.27.20.50300 > 192.168.122.127.53: 28299 SOA? n3prpfvea7.pqj.bar.com. (40)

Here is sample script
scapy can not generate some qury types, e.g. ANY.
If there are query types in the pcap file which scapy can not generate, scapy will use qury type A.
# cat generate_DNS_from_cap.py –n
    1  #!/usr/bin/env python
    2
    3  ###
    4  # Usage: python generate_DNS_from_cap.py pcap_file targetIP device_name
    5  ###
    6
    7  from scapy.all import *
    8  import sys
    9
   10  # check number of arguments
   11  argvs = sys.argv
   12  argc = len(argvs)
   13  if (argc != 4):
   14          print 'Usage # python %s pcap_file dstip device_name' % argvs[0]
   15          quit()
   16
   17  # load a cap file
   18  pkts = rdpcap(argvs[1])
   19
   20  dstip = argvs[2]
   21  nic = argvs[3]
   22
   23  # define query type
   24  type_lists = { 0:"ANY", 255:"ALL",1:"A", 2:"NS", 3:"MD", 4:"MD", 5:"CNAME", 6:"SOA", 7: "MB",8:"MG",9:"MR",10:"NULL",11:"WKS",12:"PTR",13:"HINFO",14:"MINFO",15:"MX",16:"TXT",17:"RP",18:"AFSDB",28:"AAAA", 33:"SRV",38:"A6",39:"DNAME"}
   25
   26  # define class
   27  class_lists = {1: 'IN', 2: 'CS', 3: 'CH', 4: 'HS', 255: 'ANY'}
   28
   29  # build DNS packets from the pcap file and generate DNS queries
   30  for i in range(0,len(pkts)):
   31          # IP protocol or not
   32          if 2048 == pkts[i][Ether].type:
   33
   34                  # UDP packet or not
   35                  if 17 == pkts[i][IP].proto:
   36
   37                          # Dst port 53 or not
   38                          if 53 == pkts[i][UDP].dport:
   39
   40                                  # chek qtype is in the qtype_lists
   41                                  if pkts[i][UDP][DNS][DNSQR].qtype in [0,255,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,28,33,38,39]:
   42                                          srcip = pkts[i][IP].src
   43                                          #dstip = pkts[i][IP].dst
   44                                          txid=pkts[i][IP][DNS].id
   45                                          query_name=pkts[i][DNS][DNSQR].qname
   46                                          query_type=type_lists[pkts[i][DNS][DNSQR].qtype]
   47                                          query_class=class_lists[pkts[i][DNS][DNSQR].qclass]
   48
   49                                          sr1(IP(src="%s" % srcip,dst="%s" % dstip)/UDP(sport=RandShort(), dport=53)/DNS(rd=1,qd=DNSQR(qname="%s" % query_name,qtype="%s" % query_type,qclass="IN")),iface="%s" % nic,retry=False,timeout=0.1,verbose=False)
   50
   51                                  # if qtypes is not in the list, send A DNS queries
   52                                  else:
   53                                          srcip = pkts[i][IP].src
   54                                          #dstip = pkts[i][IP].dst
   55                                          txid=pkts[i][IP][DNS].id
   56                                          query_name=pkts[i][DNS][DNSQR].qname
   57                                          query_type=1
   58                                          query_class=class_lists[pkts[i][DNS][DNSQR].qclass]
   59                                          sr1(IP(src="%s" % srcip,dst="%s" % dstip)/UDP(sport=RandShort(), dport=53)/DNS(rd=1,qd=DNSQR(qname="%s" % query_name,qtype="%s" % query_type,qclass="IN")),iface="%s" % nic,retry=False,timeout=0.1,verbose=False)
   60
   61          # not DNS packet
   62          else:
   63                  pass

Let’s run the script.

Usage: python generate_DNS_from_cap.py pcap_file targetIP device_name

DNS queries are sent from pcap file’s source IPs, which means that this script generate DNS with spoofed IPs.

You can specify a pcap file name, target IP and which device you want to use.

run the script
# ./generate_DNS_from_cap.py tcpdump_dns_queries.pcap 192.168.10.11 eth0

on the target server
# tshark -i eth0 port 53
Running as user "root" and group "root". This could be dangerous.
Capturing on eth0
 0.000000 192.168.30.67 -> 192.168.10.11 DNS Standard query A 22uuwtmm6u.o7y.bar.com
 0.156157 192.168.30.68 -> 192.168.10.11 DNS Standard query NS ox1pvj1rl7.mfc.bar.com
 0.289077 192.168.30.69 -> 192.168.10.11 DNS Standard query SOA zmtxb7lenf.ixk.bar.com
 0.426993 192.168.30.70 -> 192.168.10.11 DNS Standard query SOA 3j1efgk8sd.7dj.bar.com
 0.587145 192.168.30.71 -> 192.168.10.11 DNS Standard query A hxdbbj9a52.qeu.bar.com
 0.724314 192.168.30.72 -> 192.168.10.11 DNS Standard query AAAA 5bbt7hd1a8.ghr.bar.com
 0.872228 192.168.30.73 -> 192.168.10.11 DNS Standard query AAAA d18nxdpj2t.mdy.bar.com
 1.004146 192.168.30.74 -> 192.168.10.11 DNS Standard query SOA 141jo097n9.gxp.bar.com
 1.136820 192.168.30.75 -> 192.168.10.11 DNS Standard query MX 16y1tmxbgj.9zr.bar.com