Search code examples
pythondnsscapynslookup

DNS request with scapy (Python)


I wrote a code that creates a dns packet and sends it. The packet simulates the nslookup -type=soa facebook.com 8.8.8.8 command for example. But for some reason I get a different answer from what the 'nslookup' command returns.

my code dns server output: "a.ns.c10r.facebook.com"

the dns server from nslookup -type=soa facebook.com 8.8.8.8 command: "a.ns.facebook.com"

  • my final goal is to get a site dns server so I would be able to get an authoritative answer for the site ip address with a dns packet.

this is my code:

from scapy.all import *
from scapy.layers.dns import DNS, DNSQR
from scapy.layers.inet import IP, UDP

def main():
    dns_server_request = IP(dst='8.8.8.8') / UDP(dport=53) / DNS(rd=1, qd=DNSQR(qname='www.facebook.com', qtype='SOA'))
    ans = sr1(dns_server_request, verbose=0)
    ans.show()

if __name__ == "__main__":
    main()

someone know what am I doing wrong and how can I fix it?

  • (the dns server that my code is giving not working by the way)

Solution

  • tl;dr: You wanted to query the apex domain, facebook.com, rather than www.


    what am I doing wrong

    (1.) Well, you're using nslookup, for starters. :-)

    One can, of course, obtain useful results from that tool given a bit of care. But I strongly recommend that you prefer dig for all your interactive queries. It is a bit like using tcpdump port domain, in that it defaults to showing you everything that came back from the given nameserver.

    (2.) The domain you query matters.

    Note that "www" is a CNAME pointing at star-mini.c10r.facebook.com. And since FB is a large outfit, it turns out there's a zone cut to support that part of the namespace, so it has its own bailiwick.

    $ dig +noadd any c10r.facebook.com @d.ns.c10r.facebook.com | grep '^c10r' | sort
    c10r.facebook.com.  300 IN  SOA a.ns.c10r.facebook.com. dns.facebook.com. 1715184742 300 600 600 300
    c10r.facebook.com.  3600    IN  NS  a.ns.c10r.facebook.com.
    c10r.facebook.com.  3600    IN  NS  b.ns.c10r.facebook.com.
    c10r.facebook.com.  3600    IN  NS  c.ns.c10r.facebook.com.
    c10r.facebook.com.  3600    IN  NS  d.ns.c10r.facebook.com.
    

    Good question! Kudos for offering us a lovely MRE. It's very clear what you're doing, no need for clarifying comments.


    It's worth noting that there is no requirement for MNAME in an SOA to respond to your queries. It is strictly a private arrangement AXFR detail that happens to be exposed in query results. Many zones will have a so-called "hidden master" that responds to members of the NS set but won't respond to general inet clients.

    When you discover a new zone, as with that SOA result you posted, the most appropriate thing to do is query that zone's NS set and interrogate its delegated nameservers. You can of course also query the MNAME nameserver, but don't be surprised if it doesn't answer or sends back REFUSED.

    Note that dig +trace +norecurse can be quite helpful in figuring out which nameservers are in bailiwick for some deeply nested zone name.