Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having trouble building a Dns Packet in Python

I'm trying to build a dns packet to send over a socket. I don't want to use any libraries because I want direct access to the socket variable that sends it. Whenever I send the DNS packet, wireshark says that it's malformed. What exactly am I doing wrong?

Some things that are wrong with the Dns packet itself: It says it has 256 questions, no class and no type

  class DnsPacketBuilder:

def __init__(self):
    pass

def build_packet(self, url):
    packet = struct.pack("H", 12049)  # Query Ids (Just 1 for now)
    packet += struct.pack("H", 256)  # Flags
    packet += struct.pack("H", 1)  # Questions
    packet += struct.pack("H", 0)  # Answers
    packet += struct.pack("H", 0)  # Authorities
    packet += struct.pack("H", 0)  # Additional
    split_url = url.split(".")
    for part in split_url:
        packet += struct.pack("B", len(part))
        for byte in bytes(part):
            packet += struct.pack("c", byte)
    packet += struct.pack("B", 0)  # End of String
    packet += struct.pack("H", 1)  # Query Type
    packet += struct.pack("H", 1)  # Query Class
    return packet

# Sending the packet
builder = DnsPacketBuilder()
packet = builder.build_packet("www.northeastern.edu")
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', 8888))
sock.settimeout(2)
sock.sendto(bytes(packet), ("208.67.222.222", 53))
print("Packet Sent")
data, addr = sock.recvfrom(1024)
print("Response: " + data)
sock.close()
like image 295
MonkeyBa Avatar asked Jul 17 '14 21:07

MonkeyBa


1 Answers

Your system is using "little endian" byte order natively.

You need to reverse the byte order of the 16-bit fields into "big endian" (aka "network order") using the ">H" format string in struct.pack().

like image 131
Alnitak Avatar answered Nov 20 '22 01:11

Alnitak