Vulnerabilities > CVE-2017-2909 - Infinite Loop vulnerability in Cesanta Mongoose 6.8

047910
CVSS 7.5 - HIGH
Attack vector
NETWORK
Attack complexity
LOW
Privileges required
NONE
Confidentiality impact
NONE
Integrity impact
NONE
Availability impact
HIGH
network
low complexity
cesanta
CWE-835

Summary

An infinite loop programming error exists in the DNS server functionality of Cesanta Mongoose 6.8 library. A specially crafted DNS request can cause an infinite loop resulting in high CPU usage and Denial Of Service. An attacker can send a packet over the network to trigger this vulnerability.

Vulnerable Configurations

Part Description Count
Application
Cesanta
1

Seebug

bulletinFamilyexploit
description### Summary An infinite loop programming error exists in the DNS server functionality of Cesanta Mongoose 6.8 library. A specially crafted DNS request can cause an infinite loop resulting in high CPU usage and Denial Of Service. An attacker can send a packet over network to trigger this vulnerability. ### Tested Versions Cesanta Mongoose 6.8 ### Product URLs https://cesanta.com/ ### CVSSv3 Score 7.5 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H ### CWE CWE-835: Loop with Unreachable Exit Condition ('Infinite Loop') ### Details Mongoose is a monolithic library implementing a number of networking protocols, including HTTP, MQTT, DNS and others. It is designed with embedded devices in mind and as such is used in many IoT devices and runs on virtually all platforms. In a DNS request packet, a name can be compressed to save space. The compression in question relies on pointers to parts of the domain name already present in the packet. When decompressing the names, the DNS server software must look up those pointers and substitute them accordingly. In the Mongoose library, the function `mg_dns_uncompress_name` is responsible for decompressing names and a special case for pointers is handled: ``` while ((chunk_len = *data++)) { [3] int leeway = dst_len - (dst - old_dst); if (data >= end) return 0; if (chunk_len & 0xc0) { [1] uint16_t off = (data[-1] & (~0xc0)) << 8 | data[0]; if (off >= msg->pkt.len) { return 0; data = (unsigned char *) msg->pkt.p + off; [2] continue; ``` The name chunk pointer is encoded in a single byte having 2 most significant bits set (0xc0) and rest are an offset to the actual name. In the above code, at [1], a check is performed to see if the current chunk is actually a pointer, and if so, the offset is extracted instead. At [2], this offset is used to advance the parser by adding it to start of the packet. The loop then continues at [3]. In the above code, no check is performed to see if the calculated offset refers to the same position, or if the pointer points to another pointer. No valid DNS query should have a pointer pointing to another pointer and precisely that kind packet will cause an infinite loop in the above code. An example packet: ``` 00000000: 0020 a577 0120 0001 0000 0000 0001 c00c . .w. .......... 00000010: 0000 0000 0100 0100 0029 1000 0000 0000 .........)...... 00000020: 0000 0a … ``` At offset 14 above, we have a start of name chunk, which specifies a pointer (0xc0), followed by 0x0c which represents it’s offset from the start of the packet, past the 2 ID bytes. When parsing this packet, function `mg_dns_uncompress_name` will enter an infinite loop, because the first chunk points to itself. This causes 100% CPU usage and Denial Of Service. ### Timeline * 2017-08-30 - Vendor Disclosure * 2017-10-31 - Public Release
idSSV:96831
last seen2017-11-19
modified2017-11-09
published2017-11-09
reporterRoot
titleCesanta Mongoose DNS Query Compressed Name Pointer Denial Of Service(CVE-2017-2909)

Talos

idTALOS-2017-0416
last seen2019-05-29
published2017-10-31
reporterTalos Intelligence
sourcehttp://www.talosintelligence.com/vulnerability_reports/TALOS-2017-0416
titleCesanta Mongoose DNS Query Compressed Name Pointer Denial Of Service