example.com
) into machine-readable IP addresses (such as 93.184.216.34). To use DNS, you need to send a request to the DNS server. This request contains the domain name we are looking for. The DNS server is trying to find the IP address of this domain in its internal data storage. If found, then returns it. If it cannot find it, it redirects the request to another DNS server, and the process repeats until an IP address is found. DNS messages are usually sent via the UDP protocol.
+ --------------------- + | Headline | + --------------------- + | Question | Question for name server + --------------------- + | Answer | Resource Records (RR) to answer the question + --------------------- + | Authority | RR records pointing to an authorized server + --------------------- + | Advanced | RR records with additional information + --------------------- +
0 1 2 3 4 5 6 7 8 9 ABCDEF + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | ID | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | QR | Opcode | AA | TC | RD | RA | Z | RCODE | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | QDCOUNT | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | ANCOUNT | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | NSCOUNT | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | ARCOUNT | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
AA AA - ID 01 00 - Request parameters 00 01 - Number of questions 00 00 - Number of answers 00 00 - Number of authorized server entries 00 00 - Number of additional entries
0000 0001 0000 0000
, which in hexadecimal format corresponds to 01 00
. This is what a standard DNS query looks like.
0 1 2 3 4 5 6 7 8 9 ABCDEF + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | | / QNAME / / / + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | QTYPE | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | QCLASS | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
example.com
two sections: example and com.
07 65 - for 'example' length 7, e 78 61 - x, a 6D 70 - m, p 6C 65 - l, e 03 63 - at 'com' length 3, c 6F 6D - o, m 00 - zero byte for the end of the field QNAME 00 01 - QTYPE 00 01 - QCLASS
import binascii import socket def send_udp_message(message, address, port): """send_udp_message sends a message to UDP server message should be a hexadecimal encoded string """ message = message.replace(" ", "").replace("\n", "") server_address = (address, port) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: sock.sendto(binascii.unhexlify(message), server_address) data, _ = sock.recvfrom(4096) finally: sock.close() return binascii.hexlify(data).decode("utf-8") def format_hex(hex): """format_hex returns a pretty version of a hex string""" octets = [hex[i:i+2] for i in range(0, len(hex), 2)] pairs = [" ".join(octets[i:i+2]) for i in range(0, len(octets), 2)] return "\n".join(pairs) message = "AA AA 01 00 00 01 00 00 00 00 00 00 " \ "07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 01 00 01" response = send_udp_message(message, "8.8.8.8", 53) print(format_hex(response))
query.py
file and running the $ python query.py
command in the console. It has no external dependencies, and it should work on Python 2 or 3.
AA AA - Same ID as before 81 80 - Other flags, analyze them below. 00 01 - 1 question 00 01 - 1 answer 00 00 - No authorized server records 00 00 - No additional entries.
81 80
to binary format:
8 1 8 0 1000 0001 1000 0000
example.com
07 65 - for 'example' length 7, e 78 61 - x, a 6D 70 - m, p 6C 65 - l, e 03 63 - at 'com' length 3, c 6F 6D - o, m 00 - zero byte for the end of the field QNAME 00 01 - QTYPE 00 01 - QCLASS
0 1 2 3 4 5 6 7 8 9 ABCDEF + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | | / / / NAME / | | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | TYPE | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | CLASS | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | TTL | | | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | RDLENGTH | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - | / Rdata / / / + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
C0 0C - NAME 00 01 - TYPE 00 01 - CLASS 00 00 18 4C - TTL 00 04 - RDLENGTH = 4 bytes 5D B8 D8 22 - RDDATA
NAME
: This URL whose IP address is contained in this response. It is listed in a compressed format:
0 1 2 3 4 5 6 7 8 9 ABCDEF + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + | 1 1 | OFFSET | + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
1100 0000 0000 1100
TYPE
and CLASS
: The same name scheme is used here as in the QTYPE
and QCLASS
above, and the same values.TTL
: A 32-bit unsigned integer that specifies the lifetime of this packet with an answer, in seconds. Before the expiration of this interval, the result can be cached. After the expiration of it should be rejected.RDLENGTH
: The length in bytes of the subsequent RDDATA
section. In this case, its length is 4.RDDATA
: The data we were looking for! These four bytes contain four segments of our IP address: 93.184.216.34.Decimal | Hex | Binary | Decimal | Hex | Binary |
---|---|---|---|---|---|
0 | 0 | 0000 | eight | eight | 1000 |
one | one | 0001 | 9 | 9 | 1001 |
2 | 2 | 0010 | ten | A | 1010 |
3 | 3 | 0011 | eleven | B | 1011 |
four | four | 0100 | 12 | C | 1100 |
five | five | 0101 | 13 | D | 1101 |
6 | 6 | 0110 | 14 | E | 1110 |
7 | 7 | 0111 | 15 | F | 1111 |
Source: https://habr.com/ru/post/346098/