ID SSV:96835 Type seebug Reporter Root Modified 2017-11-09T00:00:00
Description
Summary
An exploitable arbitrary memory read vulnerability exists in the MQTT packet parsing functionality of Cesanta Mongoose 6.8. A specially crafted MQTT packet can cause an arbitrary out-of-bounds memory read and write potentially resulting in information disclosure, denial of service and remote code execution. An attacker needs to send a specially crafted MQTT packet over network to trigger this vulnerability.
Mongoose is a monolithic library implementing a number of networking protocols, including HTTP, MQTT, MDNS 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.
While parsing an MQTT packet with variable length header no check is performed to assure the calculated payload length corresponds to the actual received packet. An arbitrary length is used in pointer arithmetic leading to arbitrary memory access. Variable payload length in mqtt packet is encoded by 7 bit fields with 8th bit in a byte being used as continuation bit. The following code from the parse_mqtt function decodes this:
```
/ decode mqtt variable length /
do
In the above code, no check is performed on the calculated len value which can be arbitrarily large. By the MQTT standard, the largest MQTT packet can be at most 256 megabytes. Further, a following check is performed:
end = p + len;
if (end > io->buf + io->len + 1)
return -1;
In the above code, end should point to the end of message, and the if tries to check if it’s in bounds of the buffer, but since the check is comparing pointers, an integer overflow can cause end to wrap around and point before the start of message buffer, while still having huge len value calculated before.
This can cause further memory corruption down the line when actually handling the commands sent in the packet. For example, this can be exploited by sending a “PUBLISH” command, which ends up notifying all the clients subscribed to a certain topic. Still in the parse_mqtt function we see:
```
case MG_MQTT_CMD_PUBLISH: {
if (MG_MQTT_GET_QOS(header) > 0)
mm->message_id = getu16(p);
p += 2;
p = scanto(p, &mm->topic);
mm->payload.p = p;
mm->payload.len = end - p;
break;
```
The above code deals with the “PUBLISH” command and uses the end pointer and p to calculate the length, due to the previous integer overflow , end can point to before p leading to a large payload.len value which is later used when sending the notification to subscribed clients.
With precise memory layout control, this can be abused to cause an arbitrary write which could lead to remote code execution. On the other hand, there is a potential to abuse this vulnerability to leak large amount of data from the process as the overflown value is used when sending data to clients. The vulnerability can be triggered by sending the supplied proof of concept packet to sample mqtt_broker application supplied with the library. It should be noted that depending on memory layout, the proof of concept packet might not crash the application, but it does trigger the bug.
Crash Information
Valgrind output:
==118470== Memcheck, a memory error detector
==118470== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==118470== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==118470== Command: ../../../vanilla/mongoose/examples/mqtt_broker/mqtt_broker
==118470==
MQTT broker started on 0.0.0.0:8113
ffff==118470== Invalid read of size 1
==118470== at 0x4C3236C: memcpy@GLIBC_2.2.5 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x403E95: mbuf_insert (mongoose.c:1073)
==118470== by 0x40EB8D: mg_mqtt_prepend_header (mongoose.c:9824)
==118470== by 0x40ECCA: mg_mqtt_publish (mongoose.c:9843)
==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)
==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)
==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)
==118470== by 0x4071B6: mg_call (mongoose.c:2051)
==118470== by 0x408362: mg_recv_common (mongoose.c:2505)
==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)
==118470== by 0x40A712: mg_handle_tcp_read (mongoose.c:3376)
==118470== by 0x40AC8A: mg_mgr_handle_conn (mongoose.c:3501)
==118470== Address 0x5ce0796 is 6 bytes inside a block of size 10 free'd
==118470== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x4C2FDB7: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)
==118470== by 0x404055: mbuf_append (mongoose.c:1096)
==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)
==118470== by 0x408158: mg_send (mongoose.c:2463)
==118470== by 0x40ECA4: mg_mqtt_publish (mongoose.c:9841)
==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)
==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)
==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)
==118470== by 0x4071B6: mg_call (mongoose.c:2051)
==118470== by 0x408362: mg_recv_common (mongoose.c:2505)
==118470== Block was alloc'd at
==118470== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)
==118470== by 0x404055: mbuf_append (mongoose.c:1096)
==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)
==118470== by 0x408158: mg_send (mongoose.c:2463)
==118470== by 0x40EC51: mg_mqtt_publish (mongoose.c:9836)
==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)
==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)
==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)
==118470== by 0x4071B6: mg_call (mongoose.c:2051)
==118470== by 0x408362: mg_recv_common (mongoose.c:2505)
==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)
==118470==
==118470== Invalid write of size 1
==118470== at 0x4C32372: memcpy@GLIBC_2.2.5 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x403E95: mbuf_insert (mongoose.c:1073)
==118470== by 0x40EB8D: mg_mqtt_prepend_header (mongoose.c:9824)
==118470== by 0x40ECCA: mg_mqtt_publish (mongoose.c:9843)
==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)
==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)
==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)
==118470== by 0x4071B6: mg_call (mongoose.c:2051)
==118470== by 0x408362: mg_recv_common (mongoose.c:2505)
==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)
==118470== by 0x40A712: mg_handle_tcp_read (mongoose.c:3376)
==118470== by 0x40AC8A: mg_mgr_handle_conn (mongoose.c:3501)
==118470== Address 0x5ce0798 is 8 bytes inside a block of size 10 free'd
==118470== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x4C2FDB7: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)
==118470== by 0x404055: mbuf_append (mongoose.c:1096)
==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)
==118470== by 0x408158: mg_send (mongoose.c:2463)
==118470== by 0x40ECA4: mg_mqtt_publish (mongoose.c:9841)
==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)
==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)
==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)
==118470== by 0x4071B6: mg_call (mongoose.c:2051)
==118470== by 0x408362: mg_recv_common (mongoose.c:2505)
==118470== Block was alloc'd at
==118470== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)
==118470== by 0x404055: mbuf_append (mongoose.c:1096)
==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)
==118470== by 0x408158: mg_send (mongoose.c:2463)
==118470== by 0x40EC51: mg_mqtt_publish (mongoose.c:9836)
==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)
==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)
==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)
==118470== by 0x4071B6: mg_call (mongoose.c:2051)
==118470== by 0x408362: mg_recv_common (mongoose.c:2505)
==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)
==118470==
==118470== Invalid write of size 2
==118470== at 0x4C32723: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x403EBE: mbuf_insert (mongoose.c:1075)
==118470== by 0x40EB8D: mg_mqtt_prepend_header (mongoose.c:9824)
==118470== by 0x40ECCA: mg_mqtt_publish (mongoose.c:9843)
==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)
==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)
==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)
==118470== by 0x4071B6: mg_call (mongoose.c:2051)
==118470== by 0x408362: mg_recv_common (mongoose.c:2505)
==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)
==118470== by 0x40A712: mg_handle_tcp_read (mongoose.c:3376)
==118470== by 0x40AC8A: mg_mgr_handle_conn (mongoose.c:3501)
==118470== Address 0x5ce0790 is 0 bytes inside a block of size 10 free'd
==118470== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x4C2FDB7: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)
==118470== by 0x404055: mbuf_append (mongoose.c:1096)
==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)
==118470== by 0x408158: mg_send (mongoose.c:2463)
==118470== by 0x40ECA4: mg_mqtt_publish (mongoose.c:9841)
==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)
==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)
==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)
==118470== by 0x4071B6: mg_call (mongoose.c:2051)
==118470== by 0x408362: mg_recv_common (mongoose.c:2505)
==118470== Block was alloc'd at
==118470== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)
==118470== by 0x404055: mbuf_append (mongoose.c:1096)
==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)
==118470== by 0x408158: mg_send (mongoose.c:2463)
==118470== by 0x40EC51: mg_mqtt_publish (mongoose.c:9836)
==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)
==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)
==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)
==118470== by 0x4071B6: mg_call (mongoose.c:2051)
==118470== by 0x408362: mg_recv_common (mongoose.c:2505)
==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)
==118470==
==118470== Syscall param socketcall.sendto(msg) points to unaddressable byte(s)
==118470== at 0x54F799D: send (send.c:26)
==118470== by 0x40A40E: mg_write_to_socket (mongoose.c:3316)
==118470== by 0x40ACC2: mg_mgr_handle_conn (mongoose.c:3508)
==118470== by 0x40B6C9: mg_socket_if_poll (mongoose.c:3694)
==118470== by 0x407935: mg_mgr_poll (mongoose.c:2232)
==118470== by 0x4022A6: main (mqtt_broker.c:43)
==118470== Address 0x5ce0790 is 0 bytes inside a block of size 10 free'd
==118470== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x4C2FDB7: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)
==118470== by 0x404055: mbuf_append (mongoose.c:1096)
==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)
==118470== by 0x408158: mg_send (mongoose.c:2463)
==118470== by 0x40ECA4: mg_mqtt_publish (mongoose.c:9841)
==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)
==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)
==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)
==118470== by 0x4071B6: mg_call (mongoose.c:2051)
==118470== by 0x408362: mg_recv_common (mongoose.c:2505)
==118470== Block was alloc'd at
==118470== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)
==118470== by 0x404055: mbuf_append (mongoose.c:1096)
==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)
==118470== by 0x408158: mg_send (mongoose.c:2463)
==118470== by 0x40EC51: mg_mqtt_publish (mongoose.c:9836)
==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)
==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)
==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)
==118470== by 0x4071B6: mg_call (mongoose.c:2051)
==118470== by 0x408362: mg_recv_common (mongoose.c:2505)
==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)
Timeline
2017-08-30 - Vendor Disclosure
2017-10-31 - Public Release
{"type": "seebug", "lastseen": "2017-11-19T12:04:38", "href": "https://www.seebug.org/vuldb/ssvid-96835", "cvss": {"score": 0.0, "vector": "NONE"}, "modified": "2017-11-09T00:00:00", "reporter": "Root", "description": "### Summary\r\nAn exploitable arbitrary memory read vulnerability exists in the MQTT packet parsing functionality of Cesanta Mongoose 6.8. A specially crafted MQTT packet can cause an arbitrary out-of-bounds memory read and write potentially resulting in information disclosure, denial of service and remote code execution. An attacker needs to send a specially crafted MQTT packet over network to trigger this vulnerability.\r\n\r\n### Tested Versions\r\nCesanta Mongoose 6.8\r\n\r\n### Product URLs\r\nhttps://cesanta.com/\r\n\r\n### CVSSv3 Score\r\n9.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H\r\n\r\n### CWE\r\nCWE-190: Integer Overflow or Wraparound\r\n\r\n### Details\r\nMongoose is a monolithic library implementing a number of networking protocols, including HTTP, MQTT, MDNS 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.\r\n\r\nWhile parsing an MQTT packet with variable length header no check is performed to assure the calculated payload length corresponds to the actual received packet. An arbitrary length is used in pointer arithmetic leading to arbitrary memory access. Variable payload length in mqtt packet is encoded by 7 bit fields with 8th bit in a byte being used as continuation bit. The following code from the `parse_mqtt` function decodes this:\r\n```\r\n /* decode mqtt variable length */\r\n do \r\n\r\n\r\n len += (*p & 127) << 7 * (p - &io->buf[1]);\r\n while ((*p++ & 128) != 0 && ((size_t)(p - io->buf) <= io->len));\r\n```\r\n\r\nIn the above code, no check is performed on the calculated `len` value which can be arbitrarily large. By the MQTT standard, the largest MQTT packet can be at most 256 megabytes. Further, a following check is performed:\r\n```\r\nend = p + len;\r\nif (end > io->buf + io->len + 1) \r\n return -1;\r\n```\r\n\r\nIn the above code, `end` should point to the end of message, and the `if` tries to check if it\u2019s in bounds of the buffer, but since the check is comparing pointers, an integer overflow can cause `end` to wrap around and point before the start of message buffer, while still having huge `len` value calculated before.\r\n\r\nThis can cause further memory corruption down the line when actually handling the commands sent in the packet. For example, this can be exploited by sending a \u201cPUBLISH\u201d command, which ends up notifying all the clients subscribed to a certain topic. Still in the `parse_mqtt` function we see:\r\n```\r\n case MG_MQTT_CMD_PUBLISH: {\r\n if (MG_MQTT_GET_QOS(header) > 0) \r\n mm->message_id = getu16(p);\r\n p += 2;\r\n\r\n p = scanto(p, &mm->topic);\r\n\r\n mm->payload.p = p;\r\n mm->payload.len = end - p;\r\n break;\r\n```\r\n\r\nThe above code deals with the \u201cPUBLISH\u201d command and uses the `end` pointer and `p` to calculate the length, due to the previous integer overflow , `end` can point to before `p` leading to a large `payload.len` value which is later used when sending the notification to subscribed clients.\r\n\r\nWith precise memory layout control, this can be abused to cause an arbitrary write which could lead to remote code execution. On the other hand, there is a potential to abuse this vulnerability to leak large amount of data from the process as the overflown value is used when sending data to clients. The vulnerability can be triggered by sending the supplied proof of concept packet to sample `mqtt_broker` application supplied with the library. It should be noted that depending on memory layout, the proof of concept packet might not crash the application, but it does trigger the bug.\r\n\r\n### Crash Information\r\n```\r\n Valgrind output:\r\n==118470== Memcheck, a memory error detector\r\n==118470== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.\r\n==118470== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info\r\n==118470== Command: ../../../vanilla/mongoose/examples/mqtt_broker/mqtt_broker\r\n==118470== \r\nMQTT broker started on 0.0.0.0:8113\r\nffff==118470== Invalid read of size 1\r\n==118470== at 0x4C3236C: memcpy@GLIBC_2.2.5 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x403E95: mbuf_insert (mongoose.c:1073)\r\n==118470== by 0x40EB8D: mg_mqtt_prepend_header (mongoose.c:9824)\r\n==118470== by 0x40ECCA: mg_mqtt_publish (mongoose.c:9843)\r\n==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\r\n==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\r\n==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\r\n==118470== by 0x4071B6: mg_call (mongoose.c:2051)\r\n==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\r\n==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\r\n==118470== by 0x40A712: mg_handle_tcp_read (mongoose.c:3376)\r\n==118470== by 0x40AC8A: mg_mgr_handle_conn (mongoose.c:3501)\r\n==118470== Address 0x5ce0796 is 6 bytes inside a block of size 10 free'd\r\n==118470== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x4C2FDB7: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\r\n==118470== by 0x404055: mbuf_append (mongoose.c:1096)\r\n==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\r\n==118470== by 0x408158: mg_send (mongoose.c:2463)\r\n==118470== by 0x40ECA4: mg_mqtt_publish (mongoose.c:9841)\r\n==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\r\n==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\r\n==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\r\n==118470== by 0x4071B6: mg_call (mongoose.c:2051)\r\n==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\r\n==118470== Block was alloc'd at\r\n==118470== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\r\n==118470== by 0x404055: mbuf_append (mongoose.c:1096)\r\n==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\r\n==118470== by 0x408158: mg_send (mongoose.c:2463)\r\n==118470== by 0x40EC51: mg_mqtt_publish (mongoose.c:9836)\r\n==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\r\n==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\r\n==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\r\n==118470== by 0x4071B6: mg_call (mongoose.c:2051)\r\n==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\r\n==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\r\n==118470== \r\n==118470== Invalid write of size 1\r\n==118470== at 0x4C32372: memcpy@GLIBC_2.2.5 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x403E95: mbuf_insert (mongoose.c:1073)\r\n==118470== by 0x40EB8D: mg_mqtt_prepend_header (mongoose.c:9824)\r\n==118470== by 0x40ECCA: mg_mqtt_publish (mongoose.c:9843)\r\n==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\r\n==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\r\n==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\r\n==118470== by 0x4071B6: mg_call (mongoose.c:2051)\r\n==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\r\n==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\r\n==118470== by 0x40A712: mg_handle_tcp_read (mongoose.c:3376)\r\n==118470== by 0x40AC8A: mg_mgr_handle_conn (mongoose.c:3501)\r\n==118470== Address 0x5ce0798 is 8 bytes inside a block of size 10 free'd\r\n==118470== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x4C2FDB7: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\r\n==118470== by 0x404055: mbuf_append (mongoose.c:1096)\r\n==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\r\n==118470== by 0x408158: mg_send (mongoose.c:2463)\r\n==118470== by 0x40ECA4: mg_mqtt_publish (mongoose.c:9841)\r\n==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\r\n==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\r\n==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\r\n==118470== by 0x4071B6: mg_call (mongoose.c:2051)\r\n==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\r\n==118470== Block was alloc'd at\r\n==118470== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\r\n==118470== by 0x404055: mbuf_append (mongoose.c:1096)\r\n==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\r\n==118470== by 0x408158: mg_send (mongoose.c:2463)\r\n==118470== by 0x40EC51: mg_mqtt_publish (mongoose.c:9836)\r\n==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\r\n==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\r\n==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\r\n==118470== by 0x4071B6: mg_call (mongoose.c:2051)\r\n==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\r\n==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\r\n==118470== \r\n==118470== Invalid write of size 2\r\n==118470== at 0x4C32723: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x403EBE: mbuf_insert (mongoose.c:1075)\r\n==118470== by 0x40EB8D: mg_mqtt_prepend_header (mongoose.c:9824)\r\n==118470== by 0x40ECCA: mg_mqtt_publish (mongoose.c:9843)\r\n==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\r\n==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\r\n==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\r\n==118470== by 0x4071B6: mg_call (mongoose.c:2051)\r\n==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\r\n==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\r\n==118470== by 0x40A712: mg_handle_tcp_read (mongoose.c:3376)\r\n==118470== by 0x40AC8A: mg_mgr_handle_conn (mongoose.c:3501)\r\n==118470== Address 0x5ce0790 is 0 bytes inside a block of size 10 free'd\r\n==118470== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x4C2FDB7: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\r\n==118470== by 0x404055: mbuf_append (mongoose.c:1096)\r\n==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\r\n==118470== by 0x408158: mg_send (mongoose.c:2463)\r\n==118470== by 0x40ECA4: mg_mqtt_publish (mongoose.c:9841)\r\n==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\r\n==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\r\n==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\r\n==118470== by 0x4071B6: mg_call (mongoose.c:2051)\r\n==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\r\n==118470== Block was alloc'd at\r\n==118470== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\r\n==118470== by 0x404055: mbuf_append (mongoose.c:1096)\r\n==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\r\n==118470== by 0x408158: mg_send (mongoose.c:2463)\r\n==118470== by 0x40EC51: mg_mqtt_publish (mongoose.c:9836)\r\n==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\r\n==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\r\n==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\r\n==118470== by 0x4071B6: mg_call (mongoose.c:2051)\r\n==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\r\n==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\r\n==118470== \r\n==118470== Syscall param socketcall.sendto(msg) points to unaddressable byte(s)\r\n==118470== at 0x54F799D: send (send.c:26)\r\n==118470== by 0x40A40E: mg_write_to_socket (mongoose.c:3316)\r\n==118470== by 0x40ACC2: mg_mgr_handle_conn (mongoose.c:3508)\r\n==118470== by 0x40B6C9: mg_socket_if_poll (mongoose.c:3694)\r\n==118470== by 0x407935: mg_mgr_poll (mongoose.c:2232)\r\n==118470== by 0x4022A6: main (mqtt_broker.c:43)\r\n==118470== Address 0x5ce0790 is 0 bytes inside a block of size 10 free'd\r\n==118470== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x4C2FDB7: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\r\n==118470== by 0x404055: mbuf_append (mongoose.c:1096)\r\n==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\r\n==118470== by 0x408158: mg_send (mongoose.c:2463)\r\n==118470== by 0x40ECA4: mg_mqtt_publish (mongoose.c:9841)\r\n==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\r\n==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\r\n==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\r\n==118470== by 0x4071B6: mg_call (mongoose.c:2051)\r\n==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\r\n==118470== Block was alloc'd at\r\n==118470== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\r\n==118470== by 0x404055: mbuf_append (mongoose.c:1096)\r\n==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\r\n==118470== by 0x408158: mg_send (mongoose.c:2463)\r\n==118470== by 0x40EC51: mg_mqtt_publish (mongoose.c:9836)\r\n==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\r\n==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\r\n==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\r\n==118470== by 0x4071B6: mg_call (mongoose.c:2051)\r\n==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\r\n==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\r\n```\r\n\r\n### Timeline\r\n* 2017-08-30 - Vendor Disclosure\r\n* 2017-10-31 - Public Release", "bulletinFamily": "exploit", "references": [], "viewCount": 4, "status": "cve,details", "sourceHref": "", "cvelist": ["CVE-2017-2892"], "enchantments_done": [], "title": "Cesanta Mongoose MQTT Payload Length Remote Code Execution(CVE-2017-2892)", "id": "SSV:96835", "sourceData": "", "published": "2017-11-09T00:00:00", "enchantments": {"score": {"value": 5.4, "vector": "NONE", "modified": "2017-11-19T12:04:38", "rev": 2}, "dependencies": {"references": [{"type": "cve", "idList": ["CVE-2017-2892"]}, {"type": "talos", "idList": ["TALOS-2017-0399"]}, {"type": "talosblog", "idList": ["TALOSBLOG:BF9B74979C194FA29647576078478DE0"]}], "modified": "2017-11-19T12:04:38", "rev": 2}, "vulnersScore": 5.4}, "immutableFields": []}
{"cve": [{"lastseen": "2021-02-02T06:36:44", "description": "An exploitable arbitrary memory read vulnerability exists in the MQTT packet parsing functionality of Cesanta Mongoose 6.8. A specially crafted MQTT packet can cause an arbitrary out-of-bounds memory read and write potentially resulting in information disclosure, denial of service and remote code execution. An attacker needs to send a specially crafted MQTT packet over the network to trigger this vulnerability.", "edition": 4, "cvss3": {"exploitabilityScore": 3.9, "cvssV3": {"baseSeverity": "CRITICAL", "confidentialityImpact": "HIGH", "attackComplexity": "LOW", "scope": "UNCHANGED", "attackVector": "NETWORK", "availabilityImpact": "HIGH", "integrityImpact": "HIGH", "baseScore": 9.8, "privilegesRequired": "NONE", "vectorString": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", "userInteraction": "NONE", "version": "3.0"}, "impactScore": 5.9}, "published": "2017-11-07T16:29:00", "title": "CVE-2017-2892", "type": "cve", "cwe": ["CWE-190"], "bulletinFamily": "NVD", "cvss2": {"severity": "HIGH", "exploitabilityScore": 10.0, "obtainAllPrivilege": false, "userInteractionRequired": false, "obtainOtherPrivilege": false, "cvssV2": {"accessComplexity": "LOW", "confidentialityImpact": "PARTIAL", "availabilityImpact": "PARTIAL", "integrityImpact": "PARTIAL", "baseScore": 7.5, "vectorString": "AV:N/AC:L/Au:N/C:P/I:P/A:P", "version": "2.0", "accessVector": "NETWORK", "authentication": "NONE"}, "impactScore": 6.4, "obtainUserPrivilege": false}, "cvelist": ["CVE-2017-2892"], "modified": "2017-11-28T18:26:00", "cpe": ["cpe:/a:cesanta:mongoose:6.8"], "id": "CVE-2017-2892", "href": "https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-2892", "cvss": {"score": 7.5, "vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P"}, "cpe23": ["cpe:2.3:a:cesanta:mongoose:6.8:*:*:*:*:*:*:*"]}], "talos": [{"lastseen": "2020-07-01T21:25:01", "bulletinFamily": "info", "cvelist": ["CVE-2017-2892"], "description": "# Talos Vulnerability Report\n\n### TALOS-2017-0399\n\n## Cesanta Mongoose MQTT Payload Length Remote Code Execution\n\n##### October 31, 2017\n\n##### CVE Number\n\nCVE-2017-2892 \n\n### Summary\n\nAn exploitable arbitrary memory read vulnerability exists in the MQTT packet parsing functionality of Cesanta Mongoose 6.8. A specially crafted MQTT packet can cause an arbitrary out-of-bounds memory read and write potentially resulting in information disclosure, denial of service and remote code execution. An attacker needs to send a specially crafted MQTT packet over network to trigger this vulnerability.\n\n### Tested Versions\n\nCesanta Mongoose 6.8\n\n### Product URLs\n\n<https://cesanta.com/>\n\n### CVSSv3 Score\n\n9.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H\n\n### CWE\n\nCWE-190: Integer Overflow or Wraparound\n\n### Details\n\nMongoose is a monolithic library implementing a number of networking protocols, including HTTP, MQTT, MDNS 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.\n\nWhile parsing an MQTT packet with variable length header no check is performed to assure the calculated payload length corresponds to the actual received packet. An arbitrary length is used in pointer arithmetic leading to arbitrary memory access. Variable payload length in mqtt packet is encoded by 7 bit fields with 8th bit in a byte being used as continuation bit. The following code from the `parse_mqtt` function decodes this:\n \n \n /* decode mqtt variable length */\n do \n \n \n len += (*p & 127) << 7 * (p - &io->buf[1]);\n while ((*p++ & 128) != 0 && ((size_t)(p - io->buf) <= io->len));\n \n\nIn the above code, no check is performed on the calculated `len` value which can be arbitrarily large. By the MQTT standard, the largest MQTT packet can be at most 256 megabytes. Further, a following check is performed:\n \n \n end = p + len;\n if (end > io->buf + io->len + 1) \n return -1;\n \n\nIn the above code, `end` should point to the end of message, and the `if` tries to check if it\u2019s in bounds of the buffer, but since the check is comparing pointers, an integer overflow can cause `end` to wrap around and point before the start of message buffer, while still having huge `len` value calculated before.\n\nThis can cause further memory corruption down the line when actually handling the commands sent in the packet. For example, this can be exploited by sending a \u201cPUBLISH\u201d command, which ends up notifying all the clients subscribed to a certain topic. Still in the `parse_mqtt` function we see:\n \n \n case MG_MQTT_CMD_PUBLISH: {\n if (MG_MQTT_GET_QOS(header) > 0) \n mm->message_id = getu16(p);\n p += 2;\n \n p = scanto(p, &mm->topic);\n \n mm->payload.p = p;\n mm->payload.len = end - p;\n break;\n \n\nThe above code deals with the \u201cPUBLISH\u201d command and uses the `end` pointer and `p` to calculate the length, due to the previous integer overflow , `end` can point to before `p` leading to a large `payload.len` value which is later used when sending the notification to subscribed clients.\n\nWith precise memory layout control, this can be abused to cause an arbitrary write which could lead to remote code execution. On the other hand, there is a potential to abuse this vulnerability to leak large amount of data from the process as the overflown value is used when sending data to clients. The vulnerability can be triggered by sending the supplied proof of concept packet to sample `mqtt_broker` application supplied with the library. It should be noted that depending on memory layout, the proof of concept packet might not crash the application, but it does trigger the bug.\n\n### Crash Information\n \n \n Valgrind output:\n ==118470== Memcheck, a memory error detector\n ==118470== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.\n ==118470== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info\n ==118470== Command: ../../../vanilla/mongoose/examples/mqtt_broker/mqtt_broker\n ==118470== \n MQTT broker started on 0.0.0.0:8113\n ffff==118470== Invalid read of size 1\n ==118470== at 0x4C3236C: memcpy@GLIBC_2.2.5 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x403E95: mbuf_insert (mongoose.c:1073)\n ==118470== by 0x40EB8D: mg_mqtt_prepend_header (mongoose.c:9824)\n ==118470== by 0x40ECCA: mg_mqtt_publish (mongoose.c:9843)\n ==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\n ==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\n ==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\n ==118470== by 0x4071B6: mg_call (mongoose.c:2051)\n ==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\n ==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\n ==118470== by 0x40A712: mg_handle_tcp_read (mongoose.c:3376)\n ==118470== by 0x40AC8A: mg_mgr_handle_conn (mongoose.c:3501)\n ==118470== Address 0x5ce0796 is 6 bytes inside a block of size 10 free'd\n ==118470== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x4C2FDB7: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\n ==118470== by 0x404055: mbuf_append (mongoose.c:1096)\n ==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\n ==118470== by 0x408158: mg_send (mongoose.c:2463)\n ==118470== by 0x40ECA4: mg_mqtt_publish (mongoose.c:9841)\n ==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\n ==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\n ==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\n ==118470== by 0x4071B6: mg_call (mongoose.c:2051)\n ==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\n ==118470== Block was alloc'd at\n ==118470== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\n ==118470== by 0x404055: mbuf_append (mongoose.c:1096)\n ==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\n ==118470== by 0x408158: mg_send (mongoose.c:2463)\n ==118470== by 0x40EC51: mg_mqtt_publish (mongoose.c:9836)\n ==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\n ==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\n ==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\n ==118470== by 0x4071B6: mg_call (mongoose.c:2051)\n ==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\n ==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\n ==118470== \n ==118470== Invalid write of size 1\n ==118470== at 0x4C32372: memcpy@GLIBC_2.2.5 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x403E95: mbuf_insert (mongoose.c:1073)\n ==118470== by 0x40EB8D: mg_mqtt_prepend_header (mongoose.c:9824)\n ==118470== by 0x40ECCA: mg_mqtt_publish (mongoose.c:9843)\n ==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\n ==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\n ==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\n ==118470== by 0x4071B6: mg_call (mongoose.c:2051)\n ==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\n ==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\n ==118470== by 0x40A712: mg_handle_tcp_read (mongoose.c:3376)\n ==118470== by 0x40AC8A: mg_mgr_handle_conn (mongoose.c:3501)\n ==118470== Address 0x5ce0798 is 8 bytes inside a block of size 10 free'd\n ==118470== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x4C2FDB7: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\n ==118470== by 0x404055: mbuf_append (mongoose.c:1096)\n ==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\n ==118470== by 0x408158: mg_send (mongoose.c:2463)\n ==118470== by 0x40ECA4: mg_mqtt_publish (mongoose.c:9841)\n ==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\n ==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\n ==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\n ==118470== by 0x4071B6: mg_call (mongoose.c:2051)\n ==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\n ==118470== Block was alloc'd at\n ==118470== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\n ==118470== by 0x404055: mbuf_append (mongoose.c:1096)\n ==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\n ==118470== by 0x408158: mg_send (mongoose.c:2463)\n ==118470== by 0x40EC51: mg_mqtt_publish (mongoose.c:9836)\n ==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\n ==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\n ==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\n ==118470== by 0x4071B6: mg_call (mongoose.c:2051)\n ==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\n ==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\n ==118470== \n ==118470== Invalid write of size 2\n ==118470== at 0x4C32723: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x403EBE: mbuf_insert (mongoose.c:1075)\n ==118470== by 0x40EB8D: mg_mqtt_prepend_header (mongoose.c:9824)\n ==118470== by 0x40ECCA: mg_mqtt_publish (mongoose.c:9843)\n ==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\n ==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\n ==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\n ==118470== by 0x4071B6: mg_call (mongoose.c:2051)\n ==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\n ==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\n ==118470== by 0x40A712: mg_handle_tcp_read (mongoose.c:3376)\n ==118470== by 0x40AC8A: mg_mgr_handle_conn (mongoose.c:3501)\n ==118470== Address 0x5ce0790 is 0 bytes inside a block of size 10 free'd\n ==118470== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x4C2FDB7: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\n ==118470== by 0x404055: mbuf_append (mongoose.c:1096)\n ==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\n ==118470== by 0x408158: mg_send (mongoose.c:2463)\n ==118470== by 0x40ECA4: mg_mqtt_publish (mongoose.c:9841)\n ==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\n ==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\n ==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\n ==118470== by 0x4071B6: mg_call (mongoose.c:2051)\n ==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\n ==118470== Block was alloc'd at\n ==118470== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\n ==118470== by 0x404055: mbuf_append (mongoose.c:1096)\n ==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\n ==118470== by 0x408158: mg_send (mongoose.c:2463)\n ==118470== by 0x40EC51: mg_mqtt_publish (mongoose.c:9836)\n ==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\n ==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\n ==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\n ==118470== by 0x4071B6: mg_call (mongoose.c:2051)\n ==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\n ==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\n ==118470== \n ==118470== Syscall param socketcall.sendto(msg) points to unaddressable byte(s)\n ==118470== at 0x54F799D: send (send.c:26)\n ==118470== by 0x40A40E: mg_write_to_socket (mongoose.c:3316)\n ==118470== by 0x40ACC2: mg_mgr_handle_conn (mongoose.c:3508)\n ==118470== by 0x40B6C9: mg_socket_if_poll (mongoose.c:3694)\n ==118470== by 0x407935: mg_mgr_poll (mongoose.c:2232)\n ==118470== by 0x4022A6: main (mqtt_broker.c:43)\n ==118470== Address 0x5ce0790 is 0 bytes inside a block of size 10 free'd\n ==118470== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x4C2FDB7: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\n ==118470== by 0x404055: mbuf_append (mongoose.c:1096)\n ==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\n ==118470== by 0x408158: mg_send (mongoose.c:2463)\n ==118470== by 0x40ECA4: mg_mqtt_publish (mongoose.c:9841)\n ==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\n ==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\n ==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\n ==118470== by 0x4071B6: mg_call (mongoose.c:2051)\n ==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\n ==118470== Block was alloc'd at\n ==118470== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\n ==118470== by 0x403F74: mbuf_insert (mongoose.c:1080)\n ==118470== by 0x404055: mbuf_append (mongoose.c:1096)\n ==118470== by 0x409E83: mg_socket_if_tcp_send (mongoose.c:3167)\n ==118470== by 0x408158: mg_send (mongoose.c:2463)\n ==118470== by 0x40EC51: mg_mqtt_publish (mongoose.c:9836)\n ==118470== by 0x40F9A2: mg_mqtt_broker_handle_publish (mongoose.c:10104)\n ==118470== by 0x40FAF4: mg_mqtt_broker (mongoose.c:10136)\n ==118470== by 0x40E648: mqtt_handler (mongoose.c:9712)\n ==118470== by 0x4071B6: mg_call (mongoose.c:2051)\n ==118470== by 0x408362: mg_recv_common (mongoose.c:2505)\n ==118470== by 0x408393: mg_if_recv_tcp_cb (mongoose.c:2509)\n \n\n### Timeline\n\n2017-08-30 - Vendor Disclosure \n2017-10-31 - Public Release\n\n##### Credit\n\nDiscovered by Aleksandar Nikolic of Cisco Talos.\n\n* * *\n\nVulnerability Reports Next Report\n\nTALOS-2017-0400\n\nPrevious Report\n\nTALOS-2017-0398\n", "edition": 7, "modified": "2017-10-31T00:00:00", "published": "2017-10-31T00:00:00", "id": "TALOS-2017-0399", "href": "http://www.talosintelligence.com/vulnerability_reports/TALOS-2017-0399", "title": "Cesanta Mongoose MQTT Payload Length Remote Code Execution", "type": "talos", "cvss": {"score": 7.5, "vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P"}}], "talosblog": [{"lastseen": "2017-12-25T19:52:52", "bulletinFamily": "blog", "cvelist": ["CVE-2017-2891", "CVE-2017-2892", "CVE-2017-2893", "CVE-2017-2894", "CVE-2017-2895", "CVE-2017-2909", "CVE-2017-2921", "CVE-2017-2922"], "description": "<i>These vulnerabilities were discovered by Aleksandar Nikolic of Cisco Talos</i><br /><br />Today, Talos is disclosing several vulnerabilities that have been identified in Cesanta Mongoose server. <br /><br />Cesanta Mongoose is a library implementing a number of networking protocols, including HTTP, MQTT, MDNS and others. It is designed with embedded devices in mind and as such is used in many IoT devices and runs on virtually all popular IoT platforms. The small size of the software enables any Internet-connected device to function as a web server. Mongoose is available under GPL v2 and commercial licenses.<br /> All these discovered vulnerabilities are fixed in version <a href=\"https://github.com/cesanta/mongoose/releases/tag/6.10\">6.10</a> of the library. <br /><br /><a name='more'></a><br /><br /><h2 id=\"h.t35gb7jnv6c3\">Vulnerability Details</h2><br /><h3 id=\"h.p7ist89g16m5\">TALOS-2017-0398 (CVE-2017-2891) - Cesanta Mongoose HTTP Server CGI Remote Code Execution Vulnerability</h3><br /><a href=\"http://www.talosintelligence.com/reports/TALOS-2017-0398\">TALOS-2017-0398</a> manifests itself as an exploitable use-after-free vulnerability that exists in the HTTP server implementation of Cesanta Mongoose 6.8. An ordinary HTTP POST request with a CGI target can cause a reuse of a previously freed pointer potentially resulting in remote code execution. An attacker needs to send this HTTP request over the network to trigger this vulnerability.<br /><br /><h3 id=\"h.bm8o08jc6uoq\">TALOS-2017-0399 (CVE-2017-2892) - Cesanta Mongoose MQTT Payload Length Remote Code Execution</h3><br /><a href=\"http://www.talosintelligence.com/reports/TALOS-2017-0399\">TALOS-2017-0399</a> manifests itself as an exploitable arbitrary memory read vulnerability that exists in the MQTT packet parsing functionality of Cesanta Mongoose 6.8. A specially crafted MQTT packet can cause an out of bounds and arbitrary memory read and write, potentially resulting in information disclosure, denial of service and remote code execution. An attacker needs to send a specially crafted MQTT packet over the network to trigger this vulnerability.<br /><br /><h3 id=\"h.nlmk6epmqnt6\">TALOS-2017-0400 (CVE-2017-2893) - Cesanta Mongoose MQTT SUBSCRIBE Command Denial Of Service</h3><br /><a href=\"http://www.talosintelligence.com/reports/TALOS-2017-0400\">TALOS-2017-0400</a> describes an exploitable NULL pointer dereference vulnerability that exists in the MQTT packet parsing functionality of Cesanta Mongoose 6.8. An MQTT SUBSCRIBE packet can cause a NULL pointer dereference leading to a server crash and denial of service. An attacker needs to send a specially crafted MQTT packet over the network to trigger this vulnerability.<br /><br /><h3 id=\"h.8tgqw5hpxxx3\">TALOS-2017-0401 (CVE-2017-2894) - Cesanta Mongoose MQTT SUBSCRIBE Multiple Topics Remote Code Execution</h3><br /><a href=\"http://www.talosintelligence.com/reports/TALOS-2017-0401\">TALOS-2017-0401</a> is an exploitable stack buffer overflow vulnerability that exists in the MQTT packet parsing functionality of Cesanta Mongoose 6.8. A specially crafted MQTT SUBSCRIBE packet can cause a stack buffer overflow resulting in remote code execution. An attacker needs to send a specially crafted MQTT packet over the network to trigger this vulnerability.<br /><br /><h3 id=\"h.cx86aeyjt9mm\">TALOS-2017-0402 (CVE-2017-2895) - Cesanta Mongoose MQTT SUBSCRIBE Topic Length Information Leak</h3><br /><a href=\"http://www.talosintelligence.com/reports/TALOS-2017-0402\">TALOS-2017-0402</a> documents an exploitable arbitrary memory read vulnerability that exists in the MQTT packet parsing functionality of Cesanta Mongoose 6.8. A specially crafted MQTT SUBSCRIBE packet can cause an out of bounds and arbitrary memory read potentially resulting in information disclosure and denial of service. An attacker needs to send a specially crafted MQTT packet over the network to trigger this vulnerability.<br /><br /><h3 id=\"h.cr2a58dhmjy1\">TALOS-2017-0416 (CVE-2017-2909) - Cesanta Mongoose DNS Query Compressed Name Pointer Denial Of Service</h3><br /><a href=\"http://www.talosintelligence.com/reports/TALOS-2017-0416\">TALOS-2017-0416</a> describes an infinite loop programming error that 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. <br /><br /><h3 id=\"h.yl3fl4awfow9\">TALOS-2017-0428 (CVE-2017-2921) - Cesanta Mongoose Websocket Protocol Packet Length Code Execution Vulnerability</h3><br /><a href=\"http://www.talosintelligence.com/reports/TALOS-2017-0428\">TALOS-2017-0428</a> is an exploitable memory corruption vulnerability that exists in the Websocket protocol implementation of Cesanta Mongoose 6.8. A specially crafted websocket packet can cause an integer overflow leading to a heap buffer overflow resulting in denial of service and potentially remote code execution. An attacker may be able to send a specially crafted websocket packet over the network to trigger this vulnerability.<br /><br /><h3 id=\"h.dj3eivlw70fj\">TALOS-2017-0429 (CVE-2017-2922) - Cesanta Mongoose Websocket Protocol Fragmented Packet Code Execution Vulnerability</h3><br /><a href=\"http://www.talosintelligence.com/reports/TALOS-2017-0429\">TALOS-2017-0429</a> describes an exploitable memory corruption vulnerability that exists in the Websocket protocol implementation of Cesanta Mongoose 6.8. A specially crafted websocket packet can cause a buffer to be allocated while leaving stale pointers which can lead to use-after-free vulnerability that can be exploited to achieve remote code execution. An attacker may be able to send a specially crafted websocket packet over the network to trigger this vulnerability.<br /><br />For the full technical details of these vulnerabilities, please refer to the vulnerability advisories that are posted on our website:<br /><br /><a href=\"http://www.talosintelligence.com/vulnerability-reports/\">http://www.talosintelligence.com/vulnerability-reports/</a><br /><br /><h2 id=\"h.f31c7khmn6lo\">Discussion</h2><br />IoT devices often have limited processing and memory resources but they also require lightweight and resilient communications protocols. One of the protocols frequently used for IoT and mobile messaging applications is MQ Telemetry Transport (MQTT).<br /><br /><a href=\"http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html\">MQTT</a> is a lightweight network protocol used for publish/subscribe messaging between devices. MQTT is a standard protocol accepted by the OASIS consortium for the adoption of open standards. <br /><br />The protocol is designed to be open, simple and easy to implement, allowing thousands of lightweight clients to be supported by a single server. The design attempts to minimize bandwidth requirements while attempting to ensure reliability of delivery.<br /><br />Cesanta Mongoose is a popular communications library designed for implementation as a lightweight embedded library supporting several server and client application layer protocols, such as <a href=\"https://www.w3.org/Protocols/\">HTTP</a>, MQTT, <a href=\"https://www.w3.org/TR/2011/WD-websockets-20110929/\">WebSockets</a>, <a href=\"https://www.isc.org/community/rfcs/dns/\">DNS</a> and <a href=\"https://tools.ietf.org/html/rfc7252\">CoAP</a>. It is designed with embedded devices in mind and as such is used in many IoT devices and runs on virtually all popular IoT platforms.<br /><br />These vulnerabilities discovered by Talos may allow attackers to take over implementations of vulnerable versions of the Cesanta Mongoose server and control individual devices as well as the associated servers running it. Users are recommended to work with the affected device vendors to ensure that the latest security patches for Cesanta Mongoose are applied to all vulnerable devices and applications. <br /><br /><h2 id=\"h.610e9o9vgbc4\">Coverage</h2><br />The following Snort Rules detect attempts to exploit these vulnerabilities. Please note that additional rules may be released at a future date and current rules are subject to change pending additional vulnerability information. For all current rule information, please refer to your Firepower Management Center or Snort.org.<br /><br />Snort Rules: <br /><br /><ul><li>23039 - 23040</li></ul><br /><br /><div class=\"feedflare\">\n<a href=\"http://feeds.feedburner.com/~ff/feedburner/Talos?a=geK06cY9cxs:QobJuzBhpB0:yIl2AUoC8zA\"><img src=\"http://feeds.feedburner.com/~ff/feedburner/Talos?d=yIl2AUoC8zA\" border=\"0\"></img></a>\n</div><img src=\"http://feeds.feedburner.com/~r/feedburner/Talos/~4/geK06cY9cxs\" height=\"1\" width=\"1\" alt=\"\"/>", "modified": "2017-10-31T15:59:27", "published": "2017-10-31T08:12:00", "href": "http://feedproxy.google.com/~r/feedburner/Talos/~3/geK06cY9cxs/vulnerability-spotlight-multiple_31.html", "id": "TALOSBLOG:BF9B74979C194FA29647576078478DE0", "type": "talosblog", "title": "Vulnerability Spotlight: Multiple Vulnerabilities in Cesanta Mongoose Server", "cvss": {"score": 7.8, "vector": "AV:NETWORK/AC:LOW/Au:NONE/C:NONE/I:NONE/A:COMPLETE/"}}]}