Unpacking ASIC firmware

Introduzione

Gli esperti dicono che le criptovalute (come Bitcoin, Monero ed Ethereum) saranno i protagonisti del futuro sistema economico decentralizzato e distribuito. Se questo è vero, allora uno degli argomenti più dibattuti nel campo delle criptovalute, come verificare i pagamenti spendendo il meno possibile in termini di risorse, è particolarmente importante per la criptosicurezza.

Ci sono molti metodi di verifica. La “prova di lavoro” è un metodo di verifica facile da eseguire ma estremamente difficile da creare. Una volta che il miner ha ricevuto le transazioni, risolve un puzzle matematico per aggiungere il nuovo blocco alla blockchain. Poiché questo compito richiede molte risorse, sia economiche (bollette energetiche) che tecniche (CPU, RAM…), i vantaggi derivano dalla costruzione di un circuito specifico utilizzato per aggirare questi costi.

Un circuito integrato per applicazioni specifiche (ASIC) è un circuito integrato creato per risolvere un calcolo molto specifico. Un esempio potrebbe essere il Bitcoin ASIC che sono specializzati nel mining di Bitcoin utilizzando l’algoritmo hash SHA-256. Essendo programmati e sviluppati specificamente per il mining, ci sono pochissime aziende che producono e creano circuiti ASIC. Inoltre, c’è un divario tra coloro che minano con CPU o GPU e quelli che minano con ASIC e questa restrizione crea un punto di fallimento in quanto i governi possono premere i team di sviluppo per includere backdoor o exploit.

Monero è una delle poche criptovalute che sostengono la resistenza ASIC. Secondo il loro post, ASIC potrebbe portare alla centralizzazione del mining che può condurre all’esecuzione di potenziali attacchi come l’attacco 50+1%. In questo articolo, ho intenzione di spiegare perché e fornire ai lettori un esempio che è lo sfruttamento di “Antminer” - un ASIC prodotto da Bitmain.

Analizzare Antminers Firmware

Un pomeriggio noioso, ho deciso di dimostrare che gli ASIC non sono sicuri. Dato che gli ASIC sono prodotti da poche aziende in tutto il mondo. Ho cercato un firmware tramite i motori di ricerca e ho scoperto la società BitMain che fornisce un download di firmware.

Per curiosità, ho scaricato il firmware Antminer-X versione 201904231321.

file Antminer-X-fixed-718M-201904231321-sig.tar.gz
Antminer-Z11-fixed-718M-201904231321-sig.tar.gz: gzip compressed data, last modified: Tue Apr 23 06:45:00 2019, from Unix, original size 12748800

Usando tar, ho decompresso l’archivio tar.gz.

tar xzvf Antminer-X-fixed-718M-201904231321-sig.tar.gz
...
uramdisk.image.gz

Come possiamo vedere, dopo la decompressione dell’archivio, abbiamo ottenuto un uramdisk.image.gz. Tuttavia, questo non contiene solo un file GZ. L’utilità del file ha mostrato che si tratta di un’immagine RAMdisk compressa con gzip e u-boot legacy uImage.

uramdisk.image.gz: u-boot legacy uImage , Linux/ARM, RAMDisk Image (gzip), 12739696 bytes, Tue Apr 23 05:22:28 2019, Load Address: 0x00000000, Entry Point: 0x00000000, Header CRC: 0xEAEC1837, Data CRC: 0xEF02B3B3

Poiché il mio obiettivo non è quello di mostrarvi come estrarre manualmente il file, vorrei introdurre Binwalk - un software di utilità per analizzare, disassemblare ed estrarre le immagini del firmware. Binwalk può essere avviato come modulo python e la scansione della firma è la sua caratteristica più utilizzata. In poche parole, controlla la firma del file e decompatta il file utilizzando un software analitico. Infine, Binwalk non è solo limitato allo sviluppo di firmware. È anche utile per altri tipi di file.

binwalk uramdisk.image.gz 

DECIMAL       HEXADECIMAL     DESCRIPTION
-----------------------------------------------------------------------------
0             0x0             uImage header, header size: 64 bytes, header CRC: 0xEAEC1837, created: 2019-04-23 05:22:28, image size: 12739696 bytes, Data Address: 0x0, Entry Point: 0x0, data CRC: 0xEF02B3B3, OS: Linux, CPU: ARM, image type: RAMDisk Image, compression type: gzip, image name: ""
64            0x40            gzip compressed data, has original file name: "ramdisk.image", from Unix, last modified: 2019-04-23 05:22:26

Puoi estrarre l’immagine del firmware aggiungendo il flag “e” (nota che devi installare determinati software in base alla scansione di binwalk come specificato su Installation guide).

binwalk -e uramdisk.image.gz 

Infatti, quando un file specificato è stato trovato all’interno dell’immagine del firmware, binwalk cerca di estrarlo usando le utility installate in precedenza. Dopo di che, si ottiene la cartella ext-root dove il firmware è stato scompattato.

Comprendere il firmware

Dato che abbiamo già estratto il firmware, cominciamo a capire come funziona AntMiner. Nella cartella, abbiamo la struttura di base di un’immagine firmware basata su Unix e tutte le funzionalità funzionano allo stesso modo di Linux o di qualsiasi distribuzione Unix.

ser@hack:~/asic/_extracted# ls
bin  etc  lib  mnt  sbin  usr  var  www	

Abbiamo la cartella bin che contiene tutti i binari per il sistema (come ls, file ecc.). Per prima cosa, facciamo un’immersione profonda nella cartella etc che contiene “file di configurazione specifici del sistema per l’host”. Un file chiamato os-release ci mostra alcune informazioni sul sistema operativo.

PRETTY_NAME="The Ångström Distribution"

Il firmware è basato su Angstrom Distribution, e più in dettaglio come hostname può confermare, il firmware è stato sviluppato con beaglebone utility.

Ho anche scoperto un vecchio repository di BitMain su Github che contiene le istruzioni per costruire il firmware con i sorgenti. Tuttavia, ho controllato questo repository per una semplice ragione: non è stato aggiornato dal 2015. Pertanto, ha alcuni problemi di sicurezza che devono essere risolti. Sicuramente, quel repository non è sicuro e non consiglierei di costruire l’immagine del firmware basandosi su di esso.

Il file lighttpd-htdigest.user include i dettagli per gli account predefiniti.

root:antMiner Configuration:23c2a2d78c0d20ec069097d7d20c4392

Come riportato in questo thread su Bitcointalk, l’hash “23c2a2d78c0d20ec069097d7d20c4392” è un hash md5 di “root:antMiner Configuration:root” (senza virgolette) il :root alla fine è la password dell’interfaccia web.

Il file shadow.factory contiene l’hash SHA-512 dell’account root.

root:$6$saaYvC9T$PqLC9JWHDZsWYmpB0b0Zf.34b1m5/r9U6A8PPig2qzxAyUN78pyI/vi7OZrCA0T2y1fT5UNFtPiBYuCyBTA610:15975:0:99999:7:::

Qualcuno potrebbe criticarmi e spiegare che è ovvio che ci sono password predefinite nel dispositivo. Tuttavia, il mio obiettivo non era quello di evidenziare il fatto che c’erano credenziali di default e la configurazione del dispositivo non richiede il cambiamento immediato della password di root.

Continuando l’esplorazione, possiamo osservare la cartella www che ha i file per la Web Api utilizzata per impostare il miner.

Digging into web interface

Il minatore ASIC può essere configurato tramite una semplice interfaccia web. Le pagine sono servite da lighttpd versione 1.4.32, una vecchia versione del popolare e leggero web server.

La vecchia versione ha le seguenti vulnerabilità di sicurezza tra molte altre:

  • CVE-2013-4508 - lighttpd, quando SNI è abilitato, configura cifrari SSL deboli, il che rende più facile per gli attaccanti remoti di dirottare le sessioni inserendo pacchetti nel flusso di dati client-server o ottenere informazioni sensibili attraverso lo sniffing della rete;
  • CVE-2013-4559 - lighttpd non controlla il valore di ritorno delle funzioni setuid, setgid, o setgroups, il che potrebbe far sì che lighttpd venga eseguito come root se viene riavviato e permette agli aggressori remoti di ottenere privilegi, come dimostrato da più chiamate alla funzione clone che fanno fallire setuid quando viene raggiunto il limite del processo utente;
  • CVE-2013-4560 - La vulnerabilità Use-after-free permette agli aggressori remoti di causare un denial of service (segmentation fault e crash) attraverso vettori non specificati.
  • CVE-2014-2323 - La vulnerabilità di SQL injection in mod_mysql_vhost.c permette agli attaccanti remoti di eseguire comandi SQL arbitrari attraverso il nome dell’host;
  • CVE-2014-2324 - Multiple directory traversal vulnerability permettono agli attaccanti remoti di leggere file arbitrari attraverso un “..” nel nome dell’host;

Poiché non ho un Antminer a casa, ho patchato la mia installazione locale lighttp con gli script CGI presentati nel firmware.

L’interfaccia è basata su script CGI eseguiti in /bin/sh (bash shell). Questo è molto interessante poiché tutti gli script vengono eseguiti come utente root, quindi tutti i comandi iniettati vengono eseguiti con i privilegi più alti.

Scoprire i problemi

Uno dei file che analizzerò si chiama “upgrade.cgi”. Questo file serve per aggiornare o sostituire il firmware con uno personalizzato. Ho pensato che questo fosse un buon punto per iniziare l’indagine poiché è uno script critico per il processo.

Infatti, durante l’aggiornamento, ci deve essere un sistema parallelo che possa garantire le funzionalità minime del sistema operativo (come il supporto delle funzioni di copia) per passare dal vecchio al nuovo firmware.

Durante la mia ricerca, ho trovato un CVE report 2018-11220 che descrive un potenziale problema di sicurezza. Quando un archivio tar viene caricato nell’interfaccia web, l’antminer lo estrae e cerca di eseguire il file chiamato restoreConfig.sh. Ho deciso di indagare di più.

Prima di tutto, l’upgrade.cgi riceve una risposta POST dall’utente che contiene il nome del file e il contenuto del file. Il file non controlla la firma (se quello caricato è un tar, un txt o un pdf), ma invece crea il file sotto la directory /tmp/. I seguenti comandi vengono eseguiti per estrarre l’archivio.

mkdir $file
cd $file
tar zxf -

Sembra che il CVE 2018-11220 sia stato risolto introducendo due controlli della firma dei file utilizzando lo strumento openssl e la chiave pubblica bitmain-pub.pem. Qui, l’azienda Bitmain ha aggiunto un controllo poiché teoricamente il flash del dispositivo con un firmware non ufficiale e non fidato rompe l’accordo tra l’azienda e l’utente finale.

openssl dgst -sha256 -verify /etc/bitmain-pub.pem -signature  runme.sh.sig  runme.sh >/dev/null  2>&1

Poi lo script eseguirà bash runme.sh. All’interno del file runme.sh verrà eseguito un altro controllo per verificare il contenuto di uramdisk_image che è l’immagine che contiene la cartella ’ext-root’ che vi ho mostrato prima. Per eseguire il controllo, OpenSSL verrà chiamato per analizzare il “fileinfo” che include gli hash di parte dei file.

md5hashmd5hashmd5hashmd5hashmd5hashmd5hash fileinfo
shmd5hashmd5hashmd5hashmd5hashmd5hashmd5ha runme.sh
hashmd5hashmd5hashmd5hashmd5hashmd5hashmd5 runme.sh.sig
[no hashes are present for .bin files]

È possibile bypassare questo controllo della firma del file? Certamente! Ricordate che non ci sono hash per i file .bin! Questa è la parte del contenuto di runme.sh. Puoi individuare il problema?

...
if [ -e BOOT.bin ]; then
	flash_erase /dev/mtd0 0x0 0x40 >/dev/null 2>&1
	nandwrite -p -s 0x0 /dev/mtd0 BOOT.bin >/dev/null 2>&1
fi

if [ -e devicetree.dtb ]; then
	flash_erase /dev/mtd0 0x1A00000 0x1 >/dev/null 2>&1
	nandwrite -p -s 0x1A00000 /dev/mtd0 devicetree.dtb >/dev/null 2>&1
fi

if [ -e uImage ]; then
	flash_erase /dev/mtd0 0x2000000 0x40 >/dev/null 2>&1
	nandwrite -p -s 0x2000000 /dev/mtd0 uImage >/dev/null 2>&1
fi
..

Non viene eseguito alcun controllo sui file bin. In primo luogo, per ogni file, il comando flash_erase cancellerà la parte all’interno della partizione specificata (dato esempio, per devicetree.dtb cancellerà da 0x1A00000 a 0x200000 -1). In secondo luogo, tutti i file saranno montati nella stessa partizione.

Teoricamente, puoi montare qualsiasi kernel tu voglia, anche uno maligno! Non c’è bisogno di modificare nessun file in particolare, basta aggiungere i file bin modificati ma con lo stesso nome “boot.bin” sarà “boot.bin”.

Il problema è il controllo che viene effettuato solo nel file chiamato “fileinfo” e nei file in esso descritti.

Questo mostra come si può rompere la firma dei file e possibilmente come si può iniettare software maligno ricostruendo l’immagine del firmware. Tuttavia, questi non sembrano gli unici problemi che riguardano l’Antminer Z11 poiché alcune versioni hanno ancora la funzione di aggiornamento del firmware senza controllo della firma.

Un esempio dato di un possibile attacco potrebbe essere cambiare l’indirizzo del miner con il tuo. Combinando questo attacco con alcune precauzioni (come rendere false le transazioni al vostro bersaglio), potreste rubare tutti i guadagni dall’ASIC. Anche l’iniezione di programmi maligni è possibile!

Conclusione

Bug e difetti sono caratteristiche intrinseche dello sviluppo del software. Al momento della creazione il software ha dei problemi. L’arte di risolvere i bug è l’arte di ritardare il più possibile la probabilità che i bug si verifichino. Nello sviluppo di infrastrutture critiche, i problemi potrebbero influenzare la disponibilità e la stabilità del programma.

Gli ASIC sono strumenti critici per gestire il consenso di una criptovaluta. Immaginate se scoprissimo un nuovo bug in cui potremmo spegnere tutti i dispositivi nella stessa rete, il che significa che non siamo in grado di minare attraverso di loro. Questo sarebbe dirompente e amplificherebbe gli attacchi alle blockchain.

Bitmain ha la sicurezza come obiettivo principale? Una criptovaluta dovrebbe vietare un hardware specifico per il mining? Gli ASIC sono sicuri per la rete di criptovalute?