Multi-label DNS mdns_parse_qn Denial Of Service Vulnerability #8
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
geekman (2018-01-16) repo owner
Summary
An exploitable NULL pointer dereference vulnerability exists in the tinysvcmdns library version 2017-11-05. A specially crafted packet can make the library dereference a NULL pointer leading to server crash and denial of service. An attacker needs to send a DNS query to trigger this vulnerability.
Details
The main_loop function in mdnsd.c is used to continuously send and receive MDNS packets:
At [1] data is received and stored in pkt_buffer, which is then sent to function mdns_parse_pkt at [2] for parsing. mdns_parse_pkt will return the parsed packet as an mdns_pkt structure which is later processed at [3] by process_mdns_pkt.
mdns_parse_pkt in mdns.c internally allocates space for the new mdns_pkt structure at [4] which is populated by calling mdns_parse_qn at [5] for every defined question (the num_qn field). Note that off is used to keep track of the position of the current MDNS query to parse within the raw packet buffer.
mdns_parse_qn is used for parsing the MDNS questions section of the packet buffer. At [6] the function uncompress_nlabel is called and its return value is stored in the name field of the new rr_entry at [7].
The uncompress_nlabel function is used to parse a name label and return its uncompressed form. The compression format implemented is described in RFC 1035. This function takes as parameter the packet buffer, its size, and the offset in the packet where the label to uncompress is found.
The check at [8] ensures that the offset specified is within the bounds of the packet buffer. If the offset is out of bounds, NULL is returned. As we can see, no checks are performed at [6] on the return value of uncompress_nlabel, thus allowing for storing NULL in rr->name at [7].
Later on, the name field could get dereferenced, causing a denial of service.
Indeed this happens inside process_mdns_pkt, which is called at [3], right after the packet is parsed. Note that other paths that lead to a NULL dereference might exist.
The function cycles over the list of parsed MDNS queries, and extracts at [9] the name of an rr_entry using nlabel_to_str.
As we can see nlabel_to_str doesn't expect to receive a NULL name since it is dereferenced at [10].
Exploit Proof-of-Concept
The following proof of concept shows how to crash the tinysvcmdns daemon.
Since no "question" chunk is defined at the end of the packet, off will be equal to pkt_len and this will make uncompress_nlabel return NULL.
Credit
Discovered by Claudio Bozzato, Yves Younan, Lilith Wyatt <(^_^)> and Aleksandar Nikolic of Cisco Talos.
http://talosintelligence.com/vulnerability-reports/
TALOS-2017-0486
CVE-2017-12130
geekman (2018-01-16) reporter
changed status to resolved
Fixed in 9a1cbc0.