Introduzione
Di recente abbiamo appreso che HP DVLabs ha scoperto almeno dieci vulnerabilità nel Range Extender Wi-Fi Belkin N300 Dual-Band (F9K1111). In risposta a ciò, Belkin ha rilasciato la versione 1.04.10 del firmware. Poiché si tratta del primo aggiornamento rilasciato per l'F9K1111 e non ci sono state segnalazioni pubbliche di vulnerabilità, abbiamo pensato che sarebbe stato interessante dare un'occhiata più approfondita.
Disimballaggio dell'aggiornamento
Per iniziare la nostra analisi, abbiamo scaricato l'aggiornamento del firmware dal fornitore. Abbiamo utilizzato uno strumento per il firmware chiamato binwalk per decomprimere l'aggiornamento:
$ binwalk -Me F9K1111_WW_1.04.10_upg.bin
Il risultato è un filesystem SquashFS estratto dall'aspetto piuttosto standard che rappresenta la radice del dispositivo, come si vede di seguito.

Ora, per eseguire il bindiff, dovremo interagire un po' con l'hardware per ottenere i file nel loro stato pre-patched.
Ottenere il firmware di base
Per analizzare il firmware di base, abbiamo bisogno di un modo per scaricare i dati dal dispositivo fisico. Per farlo, dobbiamo prima rimuovere il dispositivo dal suo involucro.

In rosso e in blu sono evidenziate le possibili vie di recupero del firmware, rispettivamente il chip flash SPI e l'interfaccia UART. Anche se abbiamo visto un certo livello di attività sull'UART, procederemo analizzando l'immagine di base sul chip flash SPI. La piedinatura del chip in questione, MX25L1606e, è facilmente reperibile presso Macronix.

Dopo aver preso questo foglio e aver rimosso il chip, siamo pronti a cablare il nostro GoodFET in base alla piedinatura generica a 8 pin di cui sopra.

Dopo aver collegato i pin 7 e 8, verifichiamo che tutto sia collegato correttamente con
$ python goodfet.spiflash info
Quindi possiamo eseguire goodfet.spiflash dump per ottenere il contenuto del chip.
$ python goodfet.spiflash dump s

Infine, possiamo eseguire una rapida stringa sul file risultante per assicurarci che il dump sia legittimo (cioè che contenga almeno alcune stringhe leggibili).

Il file binario risultante può essere scompattato con binwalk come prima.
Diffusione dell'aggiornamento
Spostando entrambi i filesystem scompattati su un computer Windows e inserendoli in WinMerge, si può notare che non è cambiato molto.

I file compiler_data, version e FUNCTION_SCRIPT non contengono modifiche interessanti (a parte forse alcuni dati che potrebbero essere utili per il fingerprinting). Anche la modifica a util_system.asp non è molto interessante. Quindi, in linea di massima, si tratta delle modifiche apportate da Belkin a Webs, il server Web di GoAhead.
Analisi delle reti
La Zero Day Initiative di HP ha nominato le vulnerabilità con quelli che sembrano essere i nomi delle funzioni o degli ingressi interessati. I nomi sono i seguenti:
- formWpsStart pinCode Vulnerabilità all'esecuzione remota di codice
- formWlanSetupWPS wps_enrolee_pin Vulnerabilità dell'esecuzione di codice remoto
- Vulnerabilità dell'esecuzione di codice remoto di formWlanMP
- Vulnerabilità dell'esecuzione di codice remoto in formBSSetSitesurvey
- Vulnerabilità dell'esecuzione di codice remoto di formHwSet
- Vulnerabilità di esecuzione del codice remoto di formConnectionSetting
- Vulnerabilità di esecuzione di codice remoto di formAccept
- Vulnerabilità dell'esecuzione di codice remoto per formiNICWpsStart
- Vulnerabilità dell'esecuzione di codice remoto in formUSBStorage
Quindi, dopo aver caricato la versione patchata di webs in IDA, abbiamo cercato formHwSet nell'elenco delle funzioni e non abbiamo trovato nulla. In effetti molte di queste funzioni non sono state trovate. Se si consulta Bindiff, si può vedere che 7 funzioni sono state rimosse durante l'aggiornamento:

Questi dati corrispondono a quelli del bollettino ZDI. In effetti, tutte le funzioni elencate negli avvisi ZDI sono state rimosse, tranne formWlanSetupWPS e formBSSetSitesurvey. Esaminiamo le funzioni rimosse.
moduloUsbStorage
La prima funzione che consideriamo è formUsbStorage. Dopo aver dato una rapida lettura alla funzione, è abbastanza ovvio quale sia il problema. La variabile POST sub_dir, a cui si accede tramite la funzione webs API websGetVar di GoAhead, viene utilizzata in una chiamata a system, consentendo l'iniezione di comandi.

Questo codice può essere attivato tramite:
wget --post-data="sub_dir=vectra;reboot" http://belkin.range/goform/formUSBStorage
moduloWlanMP
Un errore simile si riscontra nel modulo actionformWlanMP. Tracciando le chiamate a websGetVar, vediamo alcune possibilità.

Seguendo le indicazioni di Forwared, vediamo che queste poche possibilità funzionano tutte come vie di iniezione nella chiamata di sistema: abbiamo scelto ateFunc.

Questo codice può essere attivato tramite:
wget --post-data="ateFunc=;reboot;" http://belkin.range/goform/formWlanMP
formHwSet
C'è un'altra iniezione di comandi qui, questa volta stiamo usando la variabile [sic] Anntena.

Questo codice può essere attivato tramite:
wget --post-data="Anntena=;reboot;" http://belkin.range/goform/formHwSet
formImpostazione della connessione
In questo caso, abbiamo un'iniezione di comandi nel parametro timeOut della funzione formConnectionSetting.

Questo codice può essere attivato tramite:
wget --post-data="timeOut=1;reboot;" http://belkin.range/goform/formConnectionSetting
moduloBSSetSitesurvey
A questo punto, abbiamo già battuto il cavallo di battaglia delle funzioni eliminate. Diamo un'occhiata alla più significativa delle funzioni che Belkin ha deciso di non eliminare: formBSSetSitesurvey. Ecco una panoramica:

Dopo essersi spaventati, si può ingrandire e vedere che il cambiamento principale è che Belkin ha aggiunto una funzione chiamata strcat_escape, usata in tutta la funzione sulle fonti che provengono da websGetVar.

This strcat_escape function takes 3 buffers - dst, src, and tokens. The function uses nested loops to search the src string for existence of any of the tokens to be escaped, if found they are escaped before being copied into dst. In the pictured case token_of_none_quotation is passed as tokens which is defined as"\\\"'$()<>` #&*
Abbiamo reimplementato questa funzione in C dal binario webs e possiamo vedere l'output previsto:

Questa stringa (presumibilmente corretta) viene poi passata normalmente al sistema tramite sprintf come prima.

L'efficacia di questo cerotto dipende da alcuni fattori:
- La funzione strcat_escape funziona completamente come previsto
- strcat_escape non provoca involontariamente buffer overflow ;-)
- strcat_escape viene utilizzato per tutti gli input dell'utente che finiscono al sistema
- Abbiamo contattato Belkin per alcuni di questi punti.
Conclusione
Sappiamo tutti che la sicurezza del codice dei dispositivi incorporati è un problema. Qui vediamo che anche nei dispositivi rilasciati nel 2014 rimane un problema.