
ASUS Router infosvr Esecuzione di comandi root tramite UDP Broadcast
Diversi modelli di router ASUS includono un servizio chiamato infosvr che resta in ascolto sulla porta broadcast UDP 9999 sull'interfaccia LAN o WLAN. Viene utilizzato da uno strumento ASUS per facilitare la configurazione del router individuando automaticamente i router sulla sottorete locale. Questo servizio viene eseguito con privilegi di root e contiene una vulnerabilità di esecuzione di comandi non autenticata. Il codice sorgente di questo servizio, così come quello del resto del router, è disponibile presso il sito di supporto ASUS.
Il CVE assegnato a questo problema è CVE-2014-9583 (ahimè, dopotutto non è CVE-2014-10000 :-/).
Attualmente, si presume che tutte le versioni di firmware note per i router interessati (RT-AC66U, RT-N66U, ecc.) siano vulnerabili. I test sono stati eseguiti contro la 3.0.0.376.2524-g0013f52.
I seguenti router/versioni di firmware sono confermati vulnerabili:
| Router | Firmware Version | Verified By |
|---|---|---|
| RT-N66U | 3.0.0.4.376_1071-g8696125 | Friedrich Postelstorfer |
| RT-AC87U | 3.0.0.4.378_3754 | David Longenecker |
| RT-N56U | 3.0.0.4.374_5656 | @argilo |
| RT-AC68U | 3.0.0.4.376_3626-g9a8323e | @Arie |
| DSL-N55U | 3.0.0.4.374_4422-gc83c78f | @S2- |
| DSL-AC68U | 3.0.0.4.376_2158-g340202b | @magJ, @gitFurious |
| RT-AC66R | 3.0.0.4.376_2524-g0013f52 | @asgh |
| RT-AC66R | 3.0.0.4.376_3602 | @facerolling |
| RT-AC55U | 3.0.0.4.376_6587-gaa506e9 | @pellaeon |
| RT-N12HP_B1 | 3.0.0.4.374_1327 | @vittee |
| RT-N16 | 3.0.0.4.220 | @xorrbit |
Inoltre, i router che eseguono firmware basato su asuswrt-merlin supportato dalla community sono vulnerabili prima della versione 376.49_5.
I router che utilizzano revisioni del firmware rilasciate il 12 gennaio 2015 o successivamente non dovrebbero essere interessati. La tabella seguente riporta le segnalazioni di router/firmware non interessati.
| Router | Firmware Version | Verified By |
|---|---|---|
| RT-AC66R | 3.0.0.4.376_3754-g5ef7c1f | @asgh |
| RT-N12HP_B1 | 3.0.0.4.376_3754-g5ef7c1f | @vittee |
Si consideri il seguente estratto dal progetto ASUSWRT-Merlin, che è un fork migliorato del codice ASUS. Puoi visualizzare il file nella sua interezza (consigliato per lulz extra) qui.
177 char *processPacket(int sockfd, char *pdubuf)
178 {
...
202 phdr = (IBOX_COMM_PKT_HDR *)pdubuf;
...
207 if (phdr->ServiceID==NET_SERVICE_ID_IBOX_INFO &&
208 phdr->PacketType==NET_PACKET_TYPE_CMD)
209 {
...
La funzione processPacket viene chiamata dopo la ricezione di un pacchetto di INFO_PDU_LENGTH (512) byte. Il percorso di codice vulnerabile specifico è main->processReq->processPacket. Il servizio esegue quindi il cast del pacchetto a una struttura e verifica che i campi ServiceID e PacketType corrispondano ai valori attesi.
Il blocco seguente contiene quella che si ritiene essere la causa principale di questa vulnerabilità.
222 if (phdr->OpCode!=NET_CMD_ID_GETINFO && phdr->OpCode!=NET_CMD_ID_GETINFO_MANU)
223 {
224 phdr_ex = (IBOX_COMM_PKT_HDR_EX *)pdubuf;
225
226 // Check Mac Address
227 if (memcpy(phdr_ex->MacAddress, mac, 6)==0)
228 {
229 _dprintf("Mac Error %2x%2x%2x%2x%2x%2x\n",
230 (unsigned char)phdr_ex->MacAddress[0],
231 (unsigned char)phdr_ex->MacAddress[1],
232 (unsigned char)phdr_ex->MacAddress[2],
233 (unsigned char)phdr_ex->MacAddress[3],
234 (unsigned char)phdr_ex->MacAddress[4],
235 (unsigned char)phdr_ex->MacAddress[5]
236 );
237 return NULL;
238 }
239
240 // Check Password
241 //if (strcmp(phdr_ex->Password, "admin")!=0)
242 //{
243 // phdr_res->OpCode = phdr->OpCode | NET_RES_ERR_PASSWORD;
244 // _dprintf("Password Error %s\n", phdr_ex->Password);
245 // return NULL;
246 //}
247 phdr_res->Info = phdr_ex->Info;
248 memcpy(phdr_res->MacAddress, phdr_ex->MacAddress, 6);
249 }
Il blocco inizia escludendo un paio di valori OpCode, che presumibilmente non richiedono autenticazione per progettazione. Quindi chiama memcpy e controlla in modo sospetto il valore di ritorno rispetto a zero. Ciò indica fortemente che l'autore intendeva usare memcmp invece. Detto questo, anche se questo controllo fosse implementato correttamente, conoscere l'indirizzo MAC del dispositivo non è certo un'autenticazione sufficiente.
Il blocco seguente è commentato, ma mostra che l'autore a un certo punto ha sperimentato il controllo di una password. Anche se, in questo caso, la password era hardcoded come "admin".
Procedendo, la seguente istruzione switch smista l'elaborazione in base all'OpCode fornito.
251 switch(phdr->OpCode)
252 {
...
428 case NET_CMD_ID_MANU_CMD:
429 {
430 #define MAXSYSCMD 256
431 char cmdstr[MAXSYSCMD];
432 PKT_SYSCMD *syscmd;
...
440 syscmd = (PKT_SYSCMD *)(pdubuf+sizeof(IBOX_COMM_PKT_HDR_EX));
...
443 if (syscmd->len>=MAXSYSCMD) syscmd->len=MAXSYSCMD;
444 syscmd->cmd[syscmd->len]=0;
445 syscmd->len=strlen(syscmd->cmd);
446 fprintf(stderr,"system cmd: %d %s\n", syscmd->len, syscmd->cmd);
447 #if 0
...
512 #endif
513 {
514 sprintf(cmdstr, "%s > /tmp/syscmd.out", syscmd->cmd);
515 system(cmdstr);
Se un attaccante specifica il valore OpCode di NET_CMD_ID_MANU_CMD, il blocco precedente elabora il pacchetto convertendolo in una struttura PKT_SYSCMD. Pertanto, qualsiasi membro di syscmd è completamente controllato dall'attaccante. Prima di prendersi cura (occhiolino) di terminare la stringa di comando con NUL, l'autore esegue il comando alla riga 514. Dopo l'esecuzione del comando, l'output viene letto dal file temporaneo e inviato all'indirizzo sorgente del pacchetto iniziale.
Utenti finali: aggiornate il firmware alla revisione 3.0.0.4.376.3754 o successiva. È importante notare che la funzionalità "Check for Update" del router potrebbe non funzionare correttamente. Controllate manualmente la versione del firmware in esecuzione e, se più vecchia, scaricate/installate il nuovo firmware.
ASUS/Merlin: rimuovete la funzionalità di esecuzione remota dei comandi da questo servizio. Anche se fosse protetto da una forte autenticazione, trasmettere una password in broadcast all'intera rete locale non è certo qualcosa di desiderabile. Se l'esecuzione di comandi è realmente desiderata, dovrebbe essere fornita tramite SSH o un meccanismo sicuro simile.
David Longenecker consiglia di usare uno script (JFFS) in combinazione con l'impostazione nvram script_usbmount per terminare il processo infosvr all'avvio. Per maggiori informazioni, consultate il suo post sul blog.
Eric Sauvageau (@RMerl) consiglia di bloccare la porta 9999 tramite firewall. Per maggiori informazioni, vedete il suo post sul forum Small Net Builder.
In alternativa, disabilitate il servizio infosvr terminando il processo dopo ogni avvio. Per divertimento/ironia extra, usate l'exploit per farlo:
$ ./asus-cmd "killall -9 infosvr"
[...]
NOTA: non riceverete risposta a questo comando. Inoltre, questo dovrà essere fatto ogni volta che il dispositivo viene riavviato.
Dopo la divulgazione iniziale di questo problema, diverse parti hanno affrontato il problema nelle rispettive basi di codice.
2015/01/08 - Eric Sauvageau ha corretto questo problema nella base di codice asuswrt-merlin. La prima release che incorpora la correzione è la 376.49_5. Le sue modifiche possono essere esaminate qui, qui e qui. 2015/01/12 - ASUS ha rilasciato nuove revisioni del firmware per i dispositivi interessati (3.0.0.4.376.3754) che, secondo quanto riferito, non sono vulnerabili.
ASUS ha affrontato il problema assicurandosi che la variabile nvram ateCommand_flag sia impostata a 1 prima di eseguire il comando fornito. Questa variabile non è impostata nelle build tipiche.
loc_404958:
la $v0, 0x400000
addiu $a0, $v0, (aAtecommand_fla - 0x400000) # "ateCommand_flag"
la $v0, 0x400000
addiu $a1, $v0, (g_ascONE - 0x400000) # "1"
la $v0, 0x400000
addiu $t9, $v0, (check_nvram - 0x400000)
jalr $t9 ; check_nvram
nop
lw $gp, 0x290+var_270($fp)
bnez $v0, lbl_execute_command
nop
sw $zero, 0x290+var_14($fp)
b lbl_return_zero
Il repository in cui risiede questo advisory contiene un exploit funzionante per questo problema.
$ ./asus-cmd "nvram show | grep -E '(firmver|buildno|extendno)'"
[*] sent command: nvram show | grep -E '(firmver|buildno|extendno)'
[!] received 512 bytes from 10.0.0.2:37625
0c 15 0033 54ab7bc4 41:41:41:41:41:41
0031 nvram show | grep -E '(firmver|buildno|extendno)'
[!] received 512 bytes from 10.0.0.1:9999
0c 16 0033 54ab7bc4 xx:xx:xx:xx:xx:xx
004e buildno=376
extendno_org=2524-g0013f52
extendno=2524-g0013f52
firmver=3.0.0.4
"ASUSWRT 3.0.0.4.376_1071 - Esecuzione di comandi backdoor LAN"
(questo ha spinto la mia pubblicazione. il suo exploit è anche replicato nella directory others/)
http://www.exploit-db.com/exploits/35688/
"SICUREZZA: buco di sicurezza lato LAN - mitigazione"
http://forums.smallnetbuilder.com/showthread.php?t=21774
"Hai un router Asus? Qualcuno nella tua rete può probabilmente hackerarlo"
http://arstechnica.com/security/2015/01/got-an-asus-router-someone-on-your-network-can-probably-hack-it/
"Un bug ASUS permette a chi è sulla tua rete locale di impadronirsi del tuo router wireless"
http://dnlongen.blogspot.com/2015/01/asus-bug-lets-those-on-your-local.html
"Un exploit consente di hackerare i router Asus dalla rete locale"
http://www.itworld.com/article/2867255/exploit-allows-asus-routers-to-be-hacked-from-local-network.html
"I router wireless Asus possono essere sfruttati da chiunque all'interno della rete"
http://it.slashdot.org/story/15/01/09/1349229/asus-wireless-routers-can-be-exploited-by-anyone-inside-the-network
"La maggior parte dei router Asus colpita da un bug di hijack; pubblicato exploit" http://www.zdnet.com/article/asus-routers-vulnerable-to-network-attack-exploit-published/
"Una falla di esecuzione comandi root affligge i router ASUS" http://threatpost.com/root-command-execution-flaw-haunts-asus-routers/110276