Reputation: 13
I am attempting to simulate "ANY" type DNS responses where multiple records are sent in 1 response using Scapy. When I send 1 record the response arrives intact, but when I send multiple records within the same response the packet becomes malformed, I am not sure if I have an error in the Scapy syntax or somewhere else.
Here is the script I am using:
from scapy.all import *
import random
import os
def sendanswer():
##random id for response
setid = random.randint(1,1000)
##random IP address
s1 = random.randint(193,200)
s2 = random.randint(2,254)
s3 = random.randint(2,254)
s4 = random.randint(2,254)
sourceIP = str(s1)+"."+str(s2)+"."+str(s3)+"."+str(s4)
##Any response with 1 answer/Works
any1 = IP(src=sourceIP,dst="192.168.0.100")/UDP(sport=53,dport=53)/DNS(qr=1,id=setid,qd=DNSQR(qname="main.domain.com",qtype="ALL",qclass="IN"),an=(DNSRR(rrname="Main_Server",rdata="200.200.200.200",rclass="IN",type="A")),ar=DNSRROPT(rclass=3000))
##Any response with multiple answers/Returns Malformed Packet
any2 = IP(src=sourceIP,dst="192.168.0.100")/UDP(sport=53,dport=53)/DNS(qr=1,id=setid,qd=DNSQR(qname="main.domain.com",qtype="ALL",qclass="IN"),an=(DNSRR(rrname="Main_Server",rdata="200.200.200.200",rclass="IN",type="A"),DNSRR(rrname="SOA_Main_Server",rdata="200.200.200.200",rclass="IN",type="SOA")),ar=DNSRROPT(rclass=3000))
##I Captured an ANY response using ANY request from Scapy and used same values but it Returns a Malformed Packet
cap = IP(dst="192.168.0.100",proto="udp")/UDP(sport=53,dport=53)/DNS(id=491,qr=1L,opcode="QUERY",aa=1L,tc=0L,rd=0L,ra=1L,z=0L,ad=0L,cd=0L,rcode="ok",qdcount=1,ancount=3,nscount=0,arcount=2,qd=DNSQR(qname='ism.com.',qtype="ALL",qclass="IN"),an=(DNSRR(rrname="ism.com.",type="A",rclass="IN",ttl=600,rdata="192.168.0.100"),DNSRR(rrname="ism.com.",type="NS",rclass="IN",ttl=3600,rdata="ism-ad.ism.com."),DNSRR(rrname="ism.com.",type="SOA",rclass="IN",ttl=3600,rdata="\xc05\nhostmaster\xc0\x0c\x00\x00\x00/\x00\x00\x03\x84\x00\x00\x02X\x00\x01Q\x80\x00\x00\x0e\x10")),ns=None,ar=(DNSRR(rrname="ism-ad.ism.com.",type="A",rclass="IN",ttl=3600,rdata="192.168.0.100"),(DNSRROPT(rrname=".",type="OPT",rclass=3000,extrcode=0,version=0,z="D0",rdlen=0))))
send(any1)
send(any2)
send(cap)
os.system("iptables -A OUTPUT -s 192.168.0.11 -d 192.168.0.100 -p ICMP --icmp-type port-unreachable -j DROP")
sendanswer()
Any input on the subject is appreciated, Thanks.
Upvotes: 1
Views: 2260
Reputation: 21
DNS answers doesn't get added as list and hence end up being malformed. You can create DNS packet with multiple answer as in below manner: Create a new DNS object and then add you desired fields in it.
dns = DNS()
qry1 = DNSQR(qname='www.bing.com',qtype=255)
an1 = DNSRR(rrname='www.bing.com',type=5)
an2 = DNSRR(rrname='www.bing.com',type=28,rdata='2000::1')
an3 = DNSRR(rrname='www.bing.com',type=5)
an4 = DNSRR(rrname='www.bing.com',type=1,rdata='172.1.1.6')
an5= DNSRR(rrname='www.bing.com',type=2)
dns.an = an1/an2/an3/an4/an5
packet = Ether(src = '00:0c:29:02:1d:53', dst='07:08:09:0A:0B:0C') / IPv6(src = "2000::1" , dst = "2000::4") / UDP() / DNS(raw(dns))
Upvotes: 2