Questo articolo rappresenta la Parte 3 della serie "Code injection attacks su architetture Harvard" della Rubrica Firmware Reload di Elettronica Open Source.
UNA POSSIBILE REALIZZAZIONE
A completamento di quanto abbiamo detto nell'articolo precedente, proviamo ora a vedere come si potrebbe realizzare un attacco di questo tipo sulle architetture Harvard, utilizzando diversi scenari, in base alla dimensione del pacchetto da iniettare. Ricordiamo che i sensori presenti in questa rete utilizzano un bootloader per installare l’immagine di un programma applicativo nella relativa memoria di ciascun modulo. Consideriamo un primo scenario dove non è presente alcuna limitazione dimensionale del pacchetto. L’idea potrebbe essere quella di utilizzare la funzionalità di bootloader, con i necessari argomenti correttamente impostati, al fine di copiare il codice già in precedenza inserito nella program memory. È assolutamente impossibile chiamare direttamente il bootloader, ma, al contrario, possiamo sfruttare quella che viene chiamata una “riprogrammazione“ meta-gadget, composta da una catena di gadget. In questo caso, ogni gadget utilizza una sequenza di istruzioni del bootloader, comprensiva di diverse variabili che vengono estratte dallo stack. Questa sequenza, per diventare operativa, deve essere utilizzata insieme ad uno stack predisposto allo scopo, o fake stack. Questo stack deve contenere le variabili del gadget, comprensive della variabile che contiene l’indirizzo di memoria di programma in cui copiare il codice, gli indirizzi dei diversi gadget e il codice da iniettare nel nodo. A questo proposito, la Figura 1 può rappresentare un valido esempio. Un altro caso che si può considerare è la possibilità di utilizzare pacchetti piccoli, aventi dimensione non superiore a 28 byte. Per superare questo limite si inietta nella data memory non utilizzata un fake stack e solo successivamente si invoca la riprogrammazione meta-gadget per copiare il malware nella zona programmi. Al fine di raggiungere questo obiettivo, ci si deve preoccupare di mettere a punto un injection meta-gadget che inserisce un byte dallo stack verso uno specifico indirizzo presente nella memoria dati. Come pone in evidenza la Figura 1, questo fake stack deve contenere diversi elementi, tra cui l’indirizzo del fake frame pointer, l’indirizzo di destinazione, 0x800, dove sarà inserito il malware, e l’indirizzo che identifica l’entry pointer del codice malware nella program memory. L’ampiezza di questo stack è di circa 305 byte, di cui solo 16 byte identificano il malware binary code.
Il procedimento di questo particolare attacco può essere chiarito in questo modo. Per prima cosa, occorre costruire una stack fake contenente il codice malware che deve essere inserito nella memoria programmi. Successivamente, si invia al nodo un pacchetto appositamente predisposto che sovrascrive l’indirizzo di ritorno salvato nello stack con l’indirizzo dell’injection meta-gadget: questo meta-gadget copia il primo byte dello stack falso (che è stato iniettato nello stack) a un dato indirizzo A in memoria dati. Il meta-gadget si conclude con una istruzione ret che recupera l’indirizzo di ritorno dallo stack falso (il valore è poi impostato con uno 0). Successivamente, si riavviano i sensori e si ritorna a un stato conoscibile. L’attaccante, però, non ha concluso la sua opera. In effetti, questo invia un secondo pacchetto appositamente predisposto il quale inietta il secondo byte dello stack falso all’indirizzo A + 1 e riavvia di nuovo il sensore: questo si deve ripetere per ogni byte che l’attaccante voglia inserire in memoria. A questo punto, dopo un certo numero di pacchetti, possiamo disporre in memoria, all’indirizzo A, l’intero fake stack. L’attaccante invia poi un altro pacchetto, anche questo appositamente predisposto, utilizzato per richiamare la riprogrammazione meta-gadget. Questo meta-gadget copia il malware (contenuto nel fake stack) nella program memory e lo esegue.
WORM
Ricordiamo che i worm sono programmi che si replicano da sistema a sistema senza servirsi di un file ospite. Ciò li distingue dai virus, che si diffondono tramite file ospiti infetti. Anche se alcuni worm possono trovarsi all’interno di altri file, ad esempio in documenti Word o Excel, c’è una differenza tra il modo in cui i worm e i virus utilizzano il file ospite. Di solito, il worm rilascia un documento che contiene già la macro worm al suo interno. L’intero documento che viaggia da computer a computer è dunque da considerarsi il worm. Il malware realizzato in precedenza può di certo autopropagarsi, ossia può essere convertito in un worm. In sostanza, una volta che il malware viene installato esegue l’attacco per cui è stato configurato a tutti i suoi vicini. Si costruisce, in questo modo, uno stack fasullo, ossia fake, che contiene il proprio codice e lo immette byte per byte nei suoi vicini. La differenza principale è che il codice iniettato non deve contenere solo il malware, ma anche l’autopropagazione del codice, cioè il codice che costruisce lo stack falso e invia i pacchetti. Il codice iniettato deve essere più ampio per assicurare questa funzionalità e la limitazione principale della tecnica di iniezione è che esso può solo essere usato per iniettare una pagina (ossia 256 byte) di codice. Se il malware è più grande di una pagina ha bisogno di essere diviso in parti di 256 byte che dovrebbero essere iniettate separatamente. Tuttavia, a causa della limitata dimensione del pacchetto e l’overhead introdotto dal byte-iniezione gadget, solo un byte dello stack falso può essere iniettato per pacchetto.