B9: Looking into routeur Netgear DG834Gv2 - part 3
We will keep the same hierarchy as in the previous post.
Firmware version v1.05.00
Command injection in the DSLencapsulation functionality (post-auth)
Looking into /usr/sbin/setup.cgi
with Ghidra
It is after having exploited this bug from the administrator Web interface and by analyzing the causes of the bug that I could identify the same backdoor previously discovered by Eloi Benoist-Vanderbeken.
It is possible from the Web interface to define the account name to be used within the DSLencapsulation feature.
Example of a HTTP GET request to execute a command on the routeur:
GET /setup.cgi?DSLencapsulation=pppoe&pppoeName=%24%28%2Fbin%2Fbusybox+echo+%24PATH+%3E+%2Ftmp%2FHITPPPOE%29&todo=save&this_file=pppoe.htm&next_file=basic.htm HTTP/1.1
Host: 10.8.0.1
Authorization: Basic YWRtaW46cGFzc3dvcmQ=
The parameter pppoeName
is used within the function set_pppoeName
which
itself calls scfgmgr_set
.
What made me think it was related to the backdoor is the presence of the value
0x53634d4d
which when separated into bytes and converted to ASCII gives us:
>>> "\x53\x63\x4d\x4d"
'ScMM'
FUN_0040b810()
will return the file descriptor related to the socket that
allows to communicate with the services listening on port 32764
. The function
FUN_0040b764
will write to the socket and the function FUN_0040b610
will
read the response from the service.
To summarize we have the following sequence:
set_pppoeName()
scfgmgr_set()
FUN_0040b944()
FUN_0040b810()
(socket creation)FUN_0040b764()
(writing within the socket)FUN_0040b610()
(reading within the socket)
What is important for us is to know what is written in the socket. The function
FUN_0040b810
opens a socket to communicate with the service listening on the
remote port 32764
(0x7ffc
).
The FUN_0040b764
function writes twice in the socket to communicate with the
backdoor. First a header is written and then a payload.
Thanks to this backdoor our command injection
$(/bin/busybox echo $PATH > /tmp/HITPPPOE)
is stored in /tmp/nvram
as:
File: /tmp/nvram
...
pppoe_username=$(/bin/busybox echo $PATH > /tmp/HITPPPOE)
...
Looking into /usr/sbin/rc
with Ghidra
As we have just redefined the DSLencapsulation method to pppoe
, the command
/usr/sbin/rc wan restart > /dev/null 2>&1
is executed by /usr/sbin/setup.cgi
,
and it is the function FUN_00407ce8
within /usr/sbin/rc
that is responsible
for executing the system command that we have injected in the HTTP POST parameter
pppoeName
.
File: FUN_00407ce8.pseudocode
void FUN_00407ce8(int param_1,int param_2,undefined4 param_3,undefined4 param_4) {
...
if (param_1 == 0) {
...
pcVar1 = nvram_get("pppoe_username",pcVar7,pcVar9,param_4);
if (pcVar1 == (char *)0x0) {
pcVar1 = "";
}
...
sprintf(&local_558,
"/usr/sbin/pppd plugin pppoe nas0 user %s password %s %s %s nodetach defaultroute %s %s maxfail 0 %s %s"
,pcVar1,pcVar9,pcVar7,&local_570,&local_5a0,&local_590,&local_158,
"lcp-echo-failure 3 lcp-echo-interval 10 &");
}
else {
...
}
system(&local_558);
...
}
We will now see if the vulnerabilities have been fixed within the updates proposed by Netgear.