---
description: Serial Peripheral Interface
---

# SPI

<figure><img src="https://2314265932-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLZ9hPT4FtAP57VrTApYv%2Fuploads%2FszUfO3hl0uQQDY6KCNYL%2Fimage.png?alt=media&#x26;token=6f61e7ff-0417-4cfb-8aed-7a7239ee8c1a" alt=""><figcaption><p>The bar on top of CS means it's <strong>active low</strong> - 1 is off, 0 is on.</p></figcaption></figure>

**Acronyms for Transmit**:\
SDO = Serial Data Out\
SO = Serial Out\
COPI = Controller Out Peripheral In\
MOSI = Master Out Slave In

**Acronyms for Receive**:\
SDI = Serial Data In\
SI = Serial In\
CIPO = Controller In Peripheral Out\
MISO = Master In Slave Out

## Extract content of SPI

### Through the bootloader (slow)

```bash
MT7620 # md <kernel address>
MT7620 # md 0xbc050000
bc050000: 56190527 d1c425c5 0285d757 dc061100    '..V.%..W.....`.
bc050010: 00000080 00000080 44146a2e 03020505    .........j.D....
bc050020: 5350494d 65704f20 7472576e 6e694c20    MIPS OpenWrt Lin
...
```

Note that when dumping this way we get the memory address on the left, hex data in the middle, and the ascii representation on the right. This is inefficient as we only get 16 bytes of data (32 hex characters) from each line which has a total of 64 bytes.&#x20;

To calculate the speed it would take to dump this way we have this formula:

$$
\frac{baud rate * 0.1}{4} = bytes/second
$$

Bytes per second is arbitrary, so we convert this to seconds per megabyte instead:

$$
\frac{1}{bytes * 10^{-6}} = second / MB
$$

And lastly calculate the time it would take to dump the memory:

$$
\frac{seconds * memory Size}{60} = TimeInMinutes
$$

To put this into practice, lets say we are using baud rate 115200 and want to dump a 8 MB SPI.

$$
\frac{115200*0.1}{4} = 2880 bytes/second
$$

$$
\frac{1}{2880*10^{-6}} = 347.2222..second/MB
$$

$$
\frac{347 * 8}{60} = 46.2666..minutes
$$

Dumping a 8 MB SPI flash over the serial interface with baud rate 115200 would take **46 minutes**.

### Over network with nc (fast)

Dumping over the network with `cat` and `nc` we're removing all the unnecessary characters (memory address + ascii) effectively cutting the extraction time in 4, totaling 8 MB in **11½ minutes**.

```bash
## Setup listener localy
localhost:~$ nc -l 4488 > mtd0 &

## Connect to target and send
localhost:~$ sudo screen /dev/ttyUSB0 115200
target:~$ cat /dev/mtd0 | nc 192.168.101.97 4488

localhost:~$ xxd mtd0 | less
```

### Using Tigard and Flashrom (fastest)

<figure><img src="https://2314265932-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLZ9hPT4FtAP57VrTApYv%2Fuploads%2FInA1EcIrutVDHOoH8pl1%2Fimage.png?alt=media&#x26;token=87ea2433-1ac1-4b6c-8b64-dc2543423dce" alt="" width="563"><figcaption><p>Example of 8-pin SPI flash chip with default layout</p></figcaption></figure>

Using `flashrom` version 1.0 and later, this extraction will take around **6 seconds** for 8 MB SPI.

1. Confirm the pins of the SPI flash chip with the datasheet and clip in accordingly, connecting the Tigard SPI to the SPI flash chip.&#x20;
2. Make sure that the Tigard is set to JTAG/SPI-mode
3. Depending on how the power is connected we need to take one of two options, a or b.&#x20;
4. (_option a_) VCC **is connected serially** between SPI and Microcontroller
   1. Disable the microcontroller by controlling RST (reset). Usually RST is active low so pull down the voltage to 0 on this pin. Confirm this in the microcontroller datasheet.&#x20;
   2. Put Tigard in VTGT mode, supplying no power. Power on the target device normally.
5. (_option b_) VCC **is not serially connected** between SPI and Microcontroller
   1. Connect Tigard to SPI VCC and supply power using 1.8/3.3/5V options.
6. Dump the SPI with `flashrom`

```
$ flashrom -p ft2232_spi:type=2232H,port=B,divisor=4 -r flashdump.bin
..
Found Winbond flash chip "25Q64.V" (8192 kB, SPI) on ft2232_spi.
Reading flash... done.

$ ls -alh flashdump.bin
-rw-rw-r-- 1 void void 8.0M Nov 21 12:56 flashdump.bin
```

{% hint style="info" %}
**NOTE:** To figure out if VCC is connected serially you can use a multimeter in continuity mode with one probe on the VCC pin of the SPI, and the other on VCC pin of the microcontroller.
{% endhint %}

If you for some reason need to compile a new or custom version of `flashrom` the programmer `ft2232_spi` will not be enabled by default. To enable it compile like this (case sensitive):

```bash
$ make CONFIG_FT2232_SPI=yes
```

***

## Pin to Pwn

Pin to Pwn is a glitching/fault injection attack used to disrupt the boot sequence of a device, possibly resulting in the attacker gaining access to U-BOOT and/or kernel shell. This attack is very time sensitive and hard to accomplish, it will take an experienced tester around 5-10 tries to execute the attack before succeeding.&#x20;

* Using fault injection when kernel is loading into RAM could result in a **U-BOOT prompt**.
* Using fault injection during the init process could result in a **root shell** depending on fallback procedure

A device with very fast kernel boot sequence will make it hard to jam the pin in there at the right time. To bypass this we can write code to do the fault injection at the right time, instead of doing it manually.&#x20;

<figure><img src="https://2314265932-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLZ9hPT4FtAP57VrTApYv%2Fuploads%2FZaD0dhiBmijmDPZ0urGE%2Fimage.png?alt=media&#x26;token=8ffdf18f-b945-4c89-9391-dbe66dee059c" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="https://2314265932-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLZ9hPT4FtAP57VrTApYv%2Fuploads%2FASQT0AGDu0x5Qz4K5cMZ%2Fimage.png?alt=media&#x26;token=7e451cea-4813-4160-a425-53ba6ea7c391" alt=""><figcaption><p>Shorting flash pins manually using a pin</p></figcaption></figure>

<figure><img src="https://2314265932-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLZ9hPT4FtAP57VrTApYv%2Fuploads%2FeJ9004FGfrwGkmtUMKmp%2Fimage.png?alt=media&#x26;token=e1c9203c-6c8c-4f08-b8be-3c56bd82a9f8" alt=""><figcaption><p>Logic analyzer showing the boot process of a device</p></figcaption></figure>

On a serial flash we want to short the Serial Output and Chip Select pins.

<figure><img src="https://2314265932-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLZ9hPT4FtAP57VrTApYv%2Fuploads%2FIkM8lauAaUlaCpccQGJj%2Fimage.png?alt=media&#x26;token=9d810215-4e6d-4fe5-84aa-c033a6d376b0" alt="" width="299"><figcaption><p>Short SO and CS on 8-pin serial flash</p></figcaption></figure>

On a parallel flash TSOP48 short the Command Latch and Address Latch pins.

<figure><img src="https://2314265932-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLZ9hPT4FtAP57VrTApYv%2Fuploads%2FJ3Rf24MMpeUx3w4JgBrT%2Fimage.png?alt=media&#x26;token=d809d12b-5650-46fa-b507-c9408a0bf6f8" alt=""><figcaption><p>Short CL and AL on 48-pin parallel flash</p></figcaption></figure>

**HOWTO**:

1. Identify all flash devices. Use datasheet to find interesting pins.
2. Monitor boot process with logic analyzer to see timers.&#x20;
3. Identify how / when the device fails.
4. Try several times. For an experienced tester it will take 5-10 tries.&#x20;
5. Reboot the device after every try.

More in-depth information [HERE](https://www.youtube.com/watch?v=KRNTv3oXDkE\&ab_channel=DEFCONConference).
