
Cheatsheet per Hardware Hacking
[[TOC]]
250-350 CVCC e GND ben esposti è molto utileGND, IN o RX, OUT o TX e VCC3/4 pin sul PCB
GND
GNDVCC
VCCGND (multimetro su misura di resistenza, di solito )3.3V o 5V), altrimenti la scheda o l'adattatore seriale verranno danneggiatiRX della scheda a TX dell'adattatore e TX della scheda con RX dell'adattatore
VCCsudo lsusb per localizzare l'adattatorels -lart /dev per localizzare tutti i file di dispositivo; il nostro dovrebbe essere uno degli ultimi, di solito ttyUSB0dialout (o essere ), per controllare i nostri gruppi 0 o 1 bit interniTCK, TDI, TDO, TMS e TRST (opzionale)
TCK (Test Clock): il "batterista" o metronomo che detta la velocità del controller. La tensione su questo pin semplicemente pulsa su e giù in un ritmo costante. Ad ogni "battito" del clock, il controller esegue una singola azione.TMS (Test Mode Select): le tensioni sul pin Mode Select controllano quale azione JTAG esegue. Manipolando la tensione su questo pin, si dice a JTAG cosa si vuole che faccia.3.3V o 5V), altrimenti la scheda o l'adattatore seriale verranno danneggiatiopenocd -f $FT232HCONFIGFILE -f $BOARDCONFIGFILE
$FT232HCONFIGFILE: Focaccia board reference$BOARDCONFIGFILE: il file di configurazione della scheda che stai hacking (utile ma forse non ce l'hai, opzionale)
/usr/local, forse qui potresti trovare qualche $BOARDCONFIGFILE utiletelnet localhost 4444
U-Boot 1.1.3)ASIC MT7621A...)mtd->writesize=2048: dimensione pagina (byte)mtd->oobsize=64: dati usati per la correzione errori (byte)devinfo.iowidth=8: dati scritti/letti per operazione (byte)mtd->erasesize=131072: scritture rimanenti dell'EEPROM? (più o meno)TODO SPI DUMP
TODO GDB ATTACH????
/etc/rc/etc/rc.local/etc/rc.conf per informazioni/etc/rc.d//etc/inittab
runlevel
1: modalità utente singolo, shell root, nessuna password, nessun demone in esecuzione3: modalità multituente testuale, prompt di login5: login grafico/etc/init.d/fileIndividua il formato eseguibile di QEMU: qemu-system-$PROCESSOR$ARCHITECTURE
qemu-system-mipselSe conosci la famiglia del processore, puoi specificarla per aiutare QEMU a emulare meglio l'ambiente
$QEMUBIN -cpu helpAbbiamo bisogno di kernel e filesystem root
Trova la versione del kernel, la versione di libc e l'elenco delle librerie usate dall'eseguibile che ci interessa (readelf -d $EXECUTABLE)
mount -tubifs /dev/ubi${UBIDEVNUM}_0 /mnt/filesystem
```
1. Identificare i byte per il modulo kernel
- Durante l'avvio di solito vengono stampate informazioni sulla NAND, guardarle (passaggi sopra) e cercare `NAND ID`, i byte stampati sono in ordine primo, secondo e quarto byte
- Possiamo trovare queste informazioni anche cercando nel datasheet della EEPROM
- Possiamo anche usare `writesize, oobsize, erasesize, iowidth` per trovare [qui](http://www.linux-mtd.infradead.org/faq/nand.html#L_nand_nandsim) il comando corretto
- Altrimenti, tentativi ed errori
2. Analizzare le partizioni della EEPROM stampate all'avvio per trovare le loro dimensioni e nomi, l'ultimo numero nel comando `flash_erase` è la loro dimensione correlata a `erasesize` (uguale a `parts=x,y,z,...`)
3. Caricare le partizioni estratte dal dispositivo in quelle appena create
4. Creare un mountpoint per il filesystem e allegare
- `-O`: specificare l'offset dell'header del volume ID, se sbagliato il sistema dovrebbe comunque dirti il valore giusto; puoi provare valori diversi come `512, 1024, 2048` (tentativi ed errori)
- `-m`: numero del dispositivo `mtd` (vedi punto 3)
- `-d`: numero del dispositivo UBI (vedi punto 5)
5. Montare
- Modalità utente: come wine, esegue solo un binario e lo "traduce" per la nostra architettura
- Note
- Non molto stabile
- Può dare risultati strani
- Come fare
1. Individuare il formato eseguibile di QEMU: `qemu-$PROCESSORE$ARCHITETTURA`
- Esempio: `qemu-mips64`
2. Se QEMU lamenta l'assenza dell'interprete, passare il percorso della **CARTELLA CHE CONTIENE** questo interprete con `-L` (o vedere `man`)
- Per sapere quale interprete viene utilizzato da un eseguibile, usare `readelf -l $ESEGUIBILE`
- Modalità virtualizzazione: non interessante per noi
- Costruzione del kernel e del filesystem root usando buildroot e docker
- Il nostro kernel costruito dovrebbe avere (rispetto al kernel originale)
- Stessa versione del kernel
- Stessa versione di libc (`uClibc, uClibc-ng, musl, dietlibc...`)
- Stesse versioni delle librerie (dell'eseguibile che ci interessa)
1. Cercare la versione di buildroot più vicina alle versioni del nostro dispositivo
- A volte durante l'avvio/esplorazione della memoria scansionata possiamo trovare la versione di buildroot utilizzata (se il dispositivo è stato costruito con buildroot)
2. Trovare una versione di linux compatibile con la versione di buildroot trovata e creare un container docker, [qui](https://github.com/digiampietro/hacking-gemtek/blob/master/docker/Dockerfile) un esempio di dockerfile (i pacchetti sono importanti per eseguire buildroot)
3. Scaricare la versione di buildroot selezionata da [qui](https://buildroot.org/downloads/) e metterla nella cartella condivisa del container docker
4. Eseguire e passare al container docker
5. Estrarre buildroot e `make manual` per creare il manuale di buildroot
6. Usare `make help` per stampare tutti i dispositivi (board) supportati da buildroot; `make $NOMEBOARD` per creare un file di configurazione buildroot della tua board
7. `make menuconfig` (testuale) o `make xconfig` (GUI) per selezionare i moduli del kernel da aggiungere alla nostra build, useremo `make xconfig`
- Qui c'è un esempio/linea guida ma dovrai scoprire da solo quali moduli in particolare ti serviranno per eseguire le tue applicazioni
- Trucco: `Edit->Find` per cercare moduli
- Opzioni
- `Target options`
- Spuntare `Show options and packages that are deprecated or obsolete`
- Spuntare `Build packages with debugging symbols` con il `debug level` più alto
- Spuntare `Strip command for binaries on target` a `None`
- Spuntare `GCC optimization level` a `0`
- `Toolchain`
- Spuntare `Toolchain type` a `Buildroot toolchain`
- Spuntare `Kernel headers` a `Manually specified linux version`
- Spuntare `Custom kernel headers series` a `$VERSIONEKERNELDISPOSITIVO`
- Impostare `Linux version` a `$VERSIONEKERNELDISPOSITIVO`
- Spuntare `C library` a `$LIBRERIACDISPOSITIVO`
- Spuntare `$LIBRERIACDISPOSITIVO version` a `$LIBRERIACDISPOSITIVO $VERSIONELIBRERIADISPOSITIVO`
- Spuntare `Enable large files`
- Spuntare `Enable IPv6`
- Spuntare `Enable RPC`
- Spuntare `Enable WCHAR`
- Spuntare `Thread library implementation` a `linuxthreads`
- Spuntare `Thread library debugging`
- Spuntare `Build cross gdb for the host`
- Spuntare `TUI support`
- Spuntare `Python support`
- Spuntare `GDB debugger version` a `$ULTIMAVERSIONEGDB`
- `System configuration`
- Spuntare `Passwords encoding` a `MD5`
- Spuntare `Init system` a `$SISTEMAINITDISPOSITIVO` (o `BusyBox`)
- Spuntare `/dev management` a `Dynamic using devtmpfs only`
- Spuntare `/bin/sh` a `Busybox default shell`
- Spuntare `Install timezone info`
- `Kernel`
- Impostare `Kernel version` a `$VERSIONEKERNELDISPOSITIVO`
- Spuntare `Kernel binary format` a `vmlinux`
- `Target packages`
- `Compressors and decompressors`
- `bzip2` e `xz-utils`
- `Debugging profiling and benchmark`
- Spuntare `gdb` e `full debugger`
- `Development tools`
- Quello che ti serve
- `Filesystem and flash utilities`
- `mtd, jffs2 and ubi/ubifs tools` (o quello che ti serve)
- `Libraries`
- In generale quello che ti serve (suggerimenti sotto)
- `Crypto`
- `libsha1`
- `libssh2`
- `openssl`
- `JSON/XML`
- `expat`
- `json-c`
- `Networking applications`
- `rsync` e quello che ti serve
- `Shell and utilities`
- `file`
- `Filesystem images`
- `ext2`
- `Host utilities` (non riguarda il dispositivo target, qui parliamo del dispositivo host)
- `host mtd, jffs2 and ubi/ubifs tools`
- `host util-linux`
- Ricordarsi di SALVARE
8. Per salvare permanentemente la configurazione appena definita usare `make savedconfig`
9. Configurare il kernel con `make linux-menuconfig` (testuale) o `make linux-xconfig` (GUI), qui useremo la versione CLI
- Qui c'è un esempio/linea guida ma dovrai scoprire da solo quali moduli in particolare ti serviranno per eseguire le tue applicazioni
- Opzioni
- `Kernel type` -> `Preemption model (Preemptible Kernel (Low-Latency Desktop))` -> `Preemptible Kernel (Low-Latency Desktop)`
- `Kernel type` -> `Device drivers` -> `Memory technology device (MTD) support` -> `NAND device support` -> `Support for NAND flash simulator`
- `Kernel type` -> `Device drivers` -> `Memory technology device (MTD) support` -> `UBI - Unsorted block images` -> `Enable UBI`
- `File systems` -> `Miscellaneous filesystem` -> `JFFS2 support`
- `File systems` -> `Miscellaneous filesystem` -> `UBIFS filesystem support`
- `Save`
10. Configurare `uClibc` (o la tua libreria c) usando `uclibc-menuconfig` (come sempre)
- Abilitare il debugging: `Development/Debugging options` -> `Enable debugging symbols`, se non funziona (errori di compilazione) allora `Development/Debugging options` -> `(Wall) compiler warnings` -> aggiungere `-Wall -ggdb -g3`
- `-ggdb`: fornisce informazioni di debug per l'uso con GDB
- `-g3`: fornisce informazioni di debug extra
- `Save`
- Abilitare le funzionalità come nel nostro dispositivo (tentativi ed errori, se ottieni errori investiga e poi ricostruisci con le funzionalità necessarie)
11. `make`, se ci sono problemi tornare indietro
- Possibili errori di compilazione
- `Need to use -fPIC`
- Aggiungere `--enable-shared` nei moduli del kernel (punto 7) sotto `Toolchain` -> `Additional gcc options` o patchare buildroot
- Salvare i file di configurazione per buildroot con git
- Struttura dell'albero esterno (tree view dei file da comprendere per buildroot) (`br2`)
```
+-- board/
| +-- <company>/ (non sempre usato)
| +-- <boardname>/
| +-- linux.config
| +-- busybox.config
| +-- kernel-defconfig (file di configurazione del kernel)
| +-- <altri file di configurazione>
| +-- post_build.sh (eseguito appena prima di costruire l'immagine, utile per copiare il filesystem root nell'immagine)
| +-- post_image.sh
| +-- rootfs_overlay/ (tutto qui verrà copiato nell'immagine finale)
| | +-- etc/
| | +-- <qualche file>
| +-- patches/
| +-- foo/
| | +-- <qualche patch>
| +-- libbar/
| +-- <altre patch>
|
+-- configs/
| +-- <boardname>_defconfig (configurazione buildroot per la nostra board)
| +-- uClibc.config (opzionale)
+-- patches/
| +-- (qui patch da applicare)
|
+-- Config.in (se si utilizza un albero br2-external)
+-- external.mk (se si utilizza un albero br2-external)
+-- external.desc (se si utilizza un albero br2-external)
```
- Per utilizzare un albero esterno, invocare buildroot in questo modo: `make BR2_EXTERNAL=$PERCORSOALBEROESTERNO $COMANDO`
- Per salvare la configurazione buildroot nel nostro albero esterno: `make BR2_EXTERNAL=$PERCORSOALBEROESTERNO savedefconfig`
- Per salvare la configurazione del kernel nel nostro albero esterno: `make BR2_EXTERNAL=$PERCORSOALBEROESTERNO linux-update-defconfig`
- Per salvare la configurazione uClibc nel nostro albero esterno: `make BR2_EXTERNAL=$PERCORSOALBEROESTERNO BR2_UCLIBC_CONFIG=$PERCORSO DOVE SALVARE LA CONFIGURAZIONE UCLIBC uclibc-update-defconfig`
## Fonti, crediti e ringraziamenti
- Grazie a [Valerio Di Giampietro](https://va.ler.io/) ([@valerio](https://twitter.com/valerio)) per il suo incredibile canale youtube [tutorial](https://www.youtube.com/channel/UCoyNuc5bJ-z4X-6OlpNtJUw) sull'hardware hacking, tutto ciò che è scritto qui è al massimo preso da questi video.
- Grazie a [Luca Bongiorni](https://lockpicking.club/) ([@LucaBongiorni](https://twitter.com/LucaBongiorni)) per i suoi preziosi consigli e strumenti hardware.
- Grazie a mightyohm.com per [Soldering comics](https://mightyohm.com/files/soldercomic/FullSolderComic_EN.pdf)
- Grazie alla community di Reddit [hardwarehacking](https://www.reddit.com/r/hardwarehacking) per avermi aiutato
- [[Noob] Direct PCB soldering (maybe?)](https://www.reddit.com/r/hardwarehacking/comments/lrbtaa/noob_direct_pcb_soldering_maybe/?utm_medium=android_app&utm_source=share)
- Grazie a [Andrew Paul](https://www.youtube.com/channel/UCtfcWatnWeEY_vq_UOL4PDQ) per il tutorial sulla saldatura di vias
- [Manuale di Buildroot](https://buildroot.org/downloads/manual/manual.html)
- [JTAG spiegato](https://blog.senr.io/blog/jtag-explained)
- [OpenOCD - Comandi Flash](http://openocd.org/doc/html/Flash-Commands.html)
- [Informazioni su OpenOCD + JTAG](https://www.allaboutcircuits.com/technical-articles/getting-started-with-openocd-using-ft2232h-adapter-for-swd-debugging/)
- [Hardware hacking cheat sheet - Piccolo PDF](https://github.com/arunmagesh/hw_hacking_cheatsheet/blob/master/cheatsheet_0.1.pdf)
- [OpenOCD](http://openocd.org/)
200kVCC (multimetro su misura di resistenza, di solito 200kOhm)GND (multimetro su misura di tensione, di solito 20V)TX sospetto rispetto a GND (multimetro su misura di tensione, di solito 20V); se la tensione oscilla allora questo pin è probabilmente TX (perché sta inviando dati)RX sospetto rispetto a GND (multimetro su misura di tensione, di solito 20V); se la tensione rimane a 0 allora questo pin è probabilmente RX (perché sta aspettando di ricevere dati)Tabella
| PIN | Resistenza GND | Resistenza VCC | V | Note |
|---|---|---|---|---|
| 1 | ||||
| 2 | ||||
| 3 | ||||
| 4 |
Esempio
115200)H è la funzione di aiuto stampa, usala ovunqueGND della scheda a GND del Jtagulator, pin della scheda 1,2,3 ai canali 1,2,3 del JtagulatorV: imposta la tensione di lavoroU: entra nel menu di identificazione UARTU: avvia l'identificazioneText string to output: defaultStarting channel: canale dove hai messo il pin 1 della schedaEnding channel: canale dove hai messo il pin 3 della schedaIgnore non-printable characters: Sìrootgroups $USERscreen /dev/ttyUSB0 $BAUDRATE per connettersi alla TTY
$BAUDRATE può essere uno di quelli trovati qui$BAUDRATE più comuni
1152009600576003840019200$BAUDRATE potremmo vedere caratteri illeggibili o anche NULLActrl + a -> k -> y: chiudi screen\r\n o \n?
pyserial, la libreria python per comunicazione seriale, esempio:
#!/usr/bin/env python3
import serial
ser = serial.Serial('/dev/ttyUSB0', 115200, tmieout = 0.1)
ser.write(b"HELLO\r\n")
ser.write(b"HELLO\n")
TDI (Test Data-In): il pin che immette dati nel chip. Lo standard JTAG non definisce protocolli per la comunicazione su questo pin. Questo è lasciato al produttore. Dal punto di vista di JTAG, questo pin è semplicemente un metodo di ingresso per 1 e 0 nel chip. Cosa il chip faccia con essi è irrilevante per JTAG.TDO (Test Data-Out): il pin per i dati in uscita dal chip. Come il pin Data-In, i protocolli di comunicazione non sono definiti da JTAG.TRST (Test Reset, opzionale): questo segnale viene utilizzato per resettare JTAG a uno stato noto e buono.5/6 pin o una doppia fila di 10, 12, 14, 20 pin sul PCB
GND
GNDVCC
VCCGND (multimetro su misura di resistenza, di solito 200k)VCC (multimetro su misura di resistenza, di solito 200kOhm)GND (multimetro su misura di tensione, di solito 20V)Tabella
115200)H è la funzione di aiuto, usala ovunqueGND della scheda al GND dello Jtagulator, i pin della scheda 1,2,3... ai canali dello Jtagulator 1,2,3...V: imposta la tensione di lavoroJ: entra nel menu di identificazione JTAGI: identifica con scansione IDCODE, non troverà TDI (veloce), meglio se ho molti pin da identificareB: identifica con scansione BYPASS, troverà TDI (lento), meglio se ho pochi pin da identificareStarting channel: canale dove mettiamo il pin 1 della schedaEnding channel: canale dove mettiamo il pin n della schedaAlready known pins: No, ma potrebbe accelerare il processo se conosciamo già alcuni pin300Ohm o 1kOhm tra questo pin e VCChalt: ferma la CPU (come congelare)
reset: resetta la CPUreg: legge i registri della CPUflash info bank $BANKID o flash info $BANKID: stampa informazioni sul banco di memoria flash $BANKID (penso che banchi = chunk di memoria)flash list: recupera un elenco di array associativi per ogni dispositivo dichiarato con flash bank (in $BOARDCONFIGFILE), numerati da zeroflash banks: stampa un riepilogo di una riga per ogni dispositivo dichiarato con flash bank (in $BOARDCONFIGFILE), numerati da zeroflash write_image erase "$BINTOWRITE" $ADDRTOSTART: scrittura della memoria flash
$BINTOWRITE: può essere bin (binario), ihex (Intel hex), elf (file ELF), s19 (Motorola s19), mem...$ADDRTOSTART: indirizzo da cui iniziare a scrivere (penso che il default sia 0)flash dump_image $OUTFILE $ADDRTOSTART $SIZETODUMP: dump della memoria
$OUTFILE: file binario dove salvare il dump$ADDRTOSTART: indirizzo da cui iniziare a leggere (penso che il default sia 0)$SIZETODUMP: numero di byte da dumpareinit started o qualcosa di simile, probabilmente sarà vicino alla stringa BusyBox o qualcosa di analogohelp è tuo amicobinwalk, file e hexdump -C per verificare se il file dumpato è ok o no e se è compresso o crittografato
binwalk -E analizziamo l'entropia del file
1: file casuale, compresso o crittografato1: eseguibile o file normalebinwalk -e per estrarre segmenti identificabili del filebinwalk non capisce completamente l'immagine dumpata, possiamo usare la tabella delle partizioni dell'EEPROM (se trovata in precedenza) per suddividere manualmente l'immagine dumpata in più immagini utili
dd if=$IN_DUMPED_IMAGE of=$OUT_FILE bs=1024 skip=$BYTES_TO_SKIP_FROM_THE_START count=$HOW_MANY_BYTES_TO_WRITEsha1sum, md5sum o binwalk -W -i per confrontare immagini (se per esempio pensiamo possano essere la stessa immagine)binwalk (o dd se possiamo trovare online come è strutturata la nostra immagine kernel specifica) per leggere il filesystem rootfakeroot -s fakeroot.dat usquashfs -d squashfs-root u04-sqfs.dat
fakeroot: crea un ambiente root fittizio, utile per emulare permessi file, file di dispositivo...
-s fakeroot.dat: salva l'ambiente root fittizio per ripristinarlo successivamente con il comando fakeroot -i fakeroot.dat bashusquashfs: estrae il filesystem squashfs (potrebbe essere diverso nel tuo caso)
-d squashfs-root: cartella di destinazioneu04-sqfs.dat: immagine del filesystem da estrarre/sbin/initfactory mode; se riusciamo a mettere il dispositivo in modalità factory (se esiste), allora hackerarlo è molto più facilegrepfindxargsstringslibfoo.X.Y.ZX.Y.ZX ABI incompatibileY ABI retrocompatibileZ nessun cambiamento ABIX.Y uguale alla libreria originale
X, Y superioreCostruisci usando un sistema di build (seleziona funzionalità e tracciamento automatico delle dipendenze)
Inizia l'emulazione
#!/bin/bash
# This script will build an environment without password for the user root
export QEMU_AUDIO_DRV="none" # ignore audio drivers
qemu-system-${PROCESSOR}${ARCHITECTURE} -M $CPUFAMILY \ # See point 2
-m $RAMSIZE \
-kernel $KERNELPATH \
-nographic \ # No GUI
-hda $FILESYSTEM \
-net nic,model=$NETCARDMODEL \ # Model of net card, driver must be included in kernel
-net user, hostfw=tcp::2222-:22, hostfw=tcp::9000-:9000 \ # 2222 as ssh and 9000 for GDB server
-no-reboot \ # Terminate the machine when is halted
-append "root=/dev/hda console=uart0" # Set root filesystem and console
LD_LIBRARY_PATH come segue (all'interno della macchina): export LD_LIBRARY_PATH=/lib:/usr/lib:$PATHTOORIGINALFILESYSTEMLIBFOLDER#!/bin/bash
# Part 1: Identify bytes for kernel module
modprobe nandsim first_id_byte=$FIRSTBYTE \
second_id_byte=$SECONDBYTE \
third_id_byte=$THIRDBYTE \
fourth_id_byte=$FOURTHBYTE \
cache_file=/root/nandsim.bin \
parts=x,y,z,... # Define partitons size in number of erase blocks; the number of partitions depends on your device, partitions are usually print on boot
# Part 2: Erase partitions created (analyze EEPROM partitions)
flash_erase /dev/mtd0 0 8
flash_erase /dev/mtd1 0 20
# ...
# Part 3: Load partitions dumped from device in the ones just created
nandwrite /dev/mtd0 part0.bin
nandwrite /dev/mtd1 part1.bin
# ...
# Part 4: Create mountpoint for filesystem and attach (if UBIFS)
mkdir /mnt/filesystem
ubiattach -O $N -m $MTDDVENUM -d $UBIDEVNUM
| PIN | Resistenza GND | Resistenza VCC | V | Note |
|---|
| 1 | 30kOhm | 0Ohm | 3.3V | VCC |
| 2 | 4.7kOhm | 34kOhm | 3.3V | 1.6-3.3V all'avvio - TX |
| 3 | INFOhm (multimetro 1) | INFOhm (multimetro 1) | 3.3V | 0V all'avvio - RX |
| 4 | 0Ohm | 30kOhm | 0V | GND |
| PIN | Resistenza GND | Resistenza VCC | V | Note |
|---|
| 1 | ||||
| 2 | ||||
| 3 | ||||
| 4 | ||||
| 5 | ||||
| 6 | ||||
| 7 | ||||
| 8 | ||||
| 9 | ||||
| 10 | ||||
| ... |
Esempio
| PIN | Resistenza GND | Resistenza VCC | V | Note |
|---|---|---|---|---|
| 1 | 1kOhm | 1kOhm | 0V | |
| 2 | 0Ohm | 90Ohm | 0V | GND |
| 3 | INFOhm (multimetro 1) | INFOhm (multimetro 1) | 2.1V | Alta impedenza, TDO? |
| 4 | 90Ohm | 0Ohm | 3.3V | VCC |
| 5 | 4.7kOhm | 4.7kOhm | 3.3V | |
| 6 | INFOhm (multimetro 1) | INFOhm (multimetro 1) | 0V | Non connesso? |
| 7 | 5.7kOhm | 5.7kOhm | 3.3V | |
| 8 | INFOhm (multimetro 1) | INFOhm (multimetro 1) | 0V | Non connesso? |
| 9 | 4.7kOhm | 4.7kOhm | 3.3V | |
| 10 | 0Ohm | 90Ohm | 0V | GND |