Vulnerabilities > CVE-2017-2909 - Infinite Loop vulnerability in Cesanta Mongoose 6.8
Attack vector
NETWORK Attack complexity
LOW Privileges required
NONE Confidentiality impact
NONE Integrity impact
NONE Availability impact
HIGH 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 | 1 |
Common Weakness Enumeration (CWE)
Seebug
bulletinFamily | exploit |
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 |
id | SSV:96831 |
last seen | 2017-11-19 |
modified | 2017-11-09 |
published | 2017-11-09 |
reporter | Root |
title | Cesanta Mongoose DNS Query Compressed Name Pointer Denial Of Service(CVE-2017-2909) |
Talos
id | TALOS-2017-0416 |
last seen | 2019-05-29 |
published | 2017-10-31 |
reporter | Talos Intelligence |
source | http://www.talosintelligence.com/vulnerability_reports/TALOS-2017-0416 |
title | Cesanta Mongoose DNS Query Compressed Name Pointer Denial Of Service |