CTXz 7523958603 README: Added banner
Signed-off-by: CTXz <ctx.xda@gmail.com>
2023-06-18 04:44:06 +02:00
2023-06-17 18:19:08 +02:00
2023-06-17 18:19:08 +02:00
2023-06-18 04:44:06 +02:00
2023-06-17 18:19:08 +02:00
2023-06-18 03:38:05 +02:00
2023-06-18 04:44:06 +02:00

STM32F1 Pico Pwner

Banner

A Pi Pico implementation of Johannes Obermaier's, Marc Schink's and Kosma Moczek's Glitch and FPB attack to bypass RDP (read-out protection) level 1 on STM32F1 chips.

The paper describing the attack can be found here along with its original implementation here

Table of Contents

Usage

What you'll need to get started

  • A PC running Linux
  • A Raspberry Pi Pico
  • A debug probe (e.g. a ST-Link V2)
  • A STM32F1 target board (in this repo's case a Blue Pill is used)

Pre-requisites

Please ensure the following dependencies are installed on your system:

Additionally, install the following dependencies if you intend to build the attack board and target board exploit firmware yourself:

The instructions also rely that you have a basic understanding of how to build Pico SDK based projects, as well as how to use a STM32F1 compatible debug probe along with OpenOCD. It also pre-supposes that you have a basic understanding of how to connect your Pi Pico to your target STM32F1 board.

Cloning the repository

To get started, clone this repository and enter it:

$ git clone https://github.com/CTXz/stm32f1-picopwner.git
$ cd stm32f1-picopwner

Building and flashing the attack firmware onto the Pi Pico

If you wish to skip the build process and just flash the attack firmware onto your Pi Pico, you can download the pre-built attack_v1.0.uf2 file from the releases page

Start out be entering the attack directory:

$ cd attack

Next, edit the CMakelists.txt file to point to the location of your Pico SDK installation. For that you'll need to edit the following line:

set(PICO_SDK_PATH "/usr/share/pico-sdk")

Replace /usr/share/pico-sdk with the path to your Pico SDK installation.

Next, create a build directory and run cmake and make:

$ mkdir build
$ cd build
$ cmake ..
$ make

If everything went well, you should now have a attack.uf2 file in your build directory. Put your Pi Pico into bootloader mode and copy the attack.uf2 file onto it.

Building the target board exploit firmware

If you wish to skip the build process and just flash the target board exploit firmware onto your target STM32F1 board, you can download the pre-built target.bin file from the releases page

The attack relies on the target STM32F1 board getting a exploit firmware temporarily flashed onto its SRAM. This firmware contains a two-stage exploit that will dump the target board's flash memory to the serial port upon completion.

To compile the target firmware, enter the target directory and run make:

$ cd target
$ make

If everything went well, you should now have a target.bin file in your target directory. This file will be flashed onto the target board's SRAM during the attack.

Hardware Setup

Prior to connecting your Pi Pico to your target board, ensure that the BOOT1 pin (typically PB2, but please refer to your chips datasheet) on your target board is permanently set high by using a Pull-Up resistor (1k - 100k) to 3.3V. Neglecting to use a pull-up resistor to drive BOOT1 high can have severe consequences, potentially damaging the pin. This is because the BOOT1 pin is also used as a GPIO pin, and driving it as a low output without a pull-up resistor could cause a direct short.

Next, connect your Pi Pico to your target board as shown in the table bellow:

Pi Pico STM32F1
GND GND
GPIO0 / UART0_TX USART1_RX
GPIO1 / UART0_RX USART1_TX
GPIO2 VDD
GPIO4 NRST
GPIO5 BOOT0

Should the USART1 pins on your target STM32F1 board be occupied, you will have to alter the target board exploit firmware to use a different USART peripheral. This is discussed in more detail in the How does the attack work? section.

Bellow is a picture that shows the hardware setup using a Blue Pill board:

Blue Pill Example

Executing the attack

  1. Begin by connecting connecting the Pi Pico to your PC via USB. Your Pi Pico as well as the target board should now be powered on.

If the Pi Pico does not power on, something is either shorting or the target board is drawing too much current. If the target board draws too much current, you may need to buffer the power pin (GPIO2) with a BJT or a MOSFET.

  1. Next, connect your debug probe (ex. ST-Link V2) to your target STM32F1 board.
  2. Create a new terminal window in the top of this repository and run the dump script:
$ python3 dump.py -p /dev/ttyACMx -o dump.bin

Where /dev/ttyACMx is the serial port that your Pi Pico is connected to. If left unspecified, the script will attempt to use /dev/ttyACM0 by default. dump.bin is the file that the target board's flash memory will be dumped to. If left unspecified, the script will not write the dump to a file but only print it to the terminal.

Note: If you decided to use a release binary instead of building the target firmware yourself, you will need to specify the path to the binary using the -t flag or else the script will attempt to look for the binary in target/target.bin by default.

  1. From this point on, simply follow the instructions printed by the script.

Troubleshooting

Should the dump script not output anything, the following issues could be the cause:

  • The debug probe is still connected to the target board
  • The BOOT1 pin on the target board is being set high
  • The Pi Pico has not been connected properly to the target board (Ensure the GNDs are connected!)
  • The Pi Pico has not been flashed with the attack firmware
  • The power draw of the target board is too high for the Pi Pico to handle (Try buffering the power pin with a BJT or MOSFET)
  • The power board has a too high capacitance on the power and/or reset pins (Try removing any power and/or reset capacitors)
  • The STM32F1 board is not genuine or maybe too new (there are rumors that the exploit has been patched in 2020+ revisions of STM32F1 chips)

If the dump script worked, you should now have a complete dump of the target board's flash memory in the dump.bin file (or whatever you named it). Please note that it is normal for the dump to contain a lot of 0xFF bytes at the end. This is because unsused flash memory is typically erased to 0xFF bytes.

How does the attack work?

Relevant STM32F1 properties

Due to the attacks complexity, we must first introduce a couple of the STM32F1's properties that make the attack possible.

Read-Out Protection (RDP)

Given that this whole repository is about circumventing RDP Level 1, we will skip explaining the differce between RDP Level 0, 1 and 2 (does not apply to F1 chips) and instead focus on the properties of RDP Level 1 that make the attack possible.

When RDP Level 1 is set, the device will lock down access to flash memory as soon as either of the following conditions are met:

  • Condition 1: A debug probe is connected to the device
  • Condition 2: The device is booted into System Memory Mode (BOOT0 pin is set high, BOOT1 pin is set low), aka. "Bootloader Mode"
  • Condition 3: The device boots from SRAM (BOOT0 and BOOT1 pins are set high), starting execution at address 0x20000000

It is important to know, that the read-out protection lock caused by condition 1 will persist even after the debug probe is disconnected and even after a device reset has occured! In other words, it persists until the next power cycle after the probe has been disconnected. The read-out protection lock caused by condition 2 and 3 will only persist until the next device reset.

As we'll see later, the attack uses a glitching exploit to ridden the lock of conidition 1 and then uses a 2-stage firmware exploit to get rid of the locks caused by condition 2 and 3.

The Flash Patch and Breakpoint Unit (FPB)

The Arm Cortex-M3 (which the STM32F1 series uses) features something called the Flash Patch and Breakpoint Unit (FPB). The FPB possesses comparators that enable the setup of "patches" which redirect execution to a specified address when a particular memory address is accessed. It is important to know that these "patches" conveniently persist even after a device reset. Furthermore, the FPB lacks protection, allowing it to be configured even from code executed in SRAM.

The FPB is used in the attack to trick the device into executing code from SRAM when it supposed to execute code from flash memory. More details on this will be given further below where we discuss the whole attack in detail.

SRAM

A critical part of the attack is the ability to execute exploit code from SRAM. Unlike flash memory, the contents of SRAM are lost as soon as the device loses power. Well, see, this is not entirely true. The SRAM of the STM32F1 suffers from data retention which means that the contents of SRAM will persist for a very short period of time even after the device loses power.

SRAM and DRAM Data Retention Example of measured data retention, presumably not from a STM32F1. Source

This property of the SRAM will be exploited in the attack to preserve SRAM contents even after power cycling the STM32F1 in order to ridden the RDP lock caused by the debug probe.

2-Stage Exploit Firmware

The last part that needs a seperate explanation is the 2-Stage exploit firmware that will be loaded into the STM32F1's SRAM. The code for the target exploit firmware can be found in the target directory.

Stage 1

The first stage of the exploit firmware is responsible for patching the FPB (Flash Patch and Breakpoint unit) to intercept a reset vector fetch (by patching 0x00000004). This interception redirects the execution to the second stage entry point of the exploit firmware located in the SRAM. I.e. once the patch has been applied, we can reset the STM32F1 and let it "boot from flash" (thus ridden the RDP lock caused by booting into SRAM), and yet the device will still execute the second stage of the exploit firmware. This effectively tricks the STM32F1 into executing code from SRAM when it is supposed to execute code from flash memory.

Stage 2

By the time stage-2 has been entered, the read-out protection has been completely circumvented. The second stage of the exploit firmware simply reads and dumps the contents of the flash memory to the serial port, where it is then read by the Pi Pico and further directed to the host computer via USB.

The Attack

With all of the above explained, we can now finally explain the attack in detail. The steps bellow assume the hardware setup described in the Hardware Setup section.

Step 1: Preparation

During the first step, the debug probe is connected to the target STM32F1 board. This will cause condition 1 of the RDP lock to be triggered. The debug probe is then used to load the exploit firmware into SRAM and is then disconnected from the target board. As already mentioned above, condition 1 of the RDP lock will persist until the device is power cycled!

Step 2: Power Glitching

The goal here is to get rid of the RDP lock caused by condition 1, as well as booting into SRAM. To achieve this without wiping the exploit firmware from SRAM, we will use a power glitching attack. The attack board (Pi Pico) will first prepare BOOT0 high and toggle the power of the target board off (using GPIO2). After switching the power off, the attack board will monitor the NRST pin's logic state (using GPIO4) and immidiately restore power once it the NRST pin drops low. Due to the short time it takes for the NRST pin to drop low, the SRAM contents will remain preserved (due to data retention) and the STM32F1 will boot into SRAM since BOOT0 and BOOT1 are now both high. The RDP lock caused by condition 1 will also be ridden since the debug probe is not connected to the target board anymore and a power cycle has occured.

Power Glitching Source

Step 3: Exploit Firmware - Stage 1

The STM32F1 is now booted into SRAM and the exploit firmware's first stage is executed. Altough we have gotten rid of the RDP lock caused by condition 1, we we are now faced with the RDP lock caused by condition 3. As already described above, the first stage of the exploit firmware will patch the reset vector fetch address to jump to the second stage of the exploit firmware. Once the patch has been applied, the attack board pulls the BOOT0 pin low and resets the target board using the NRST pin. The STM32F1 will receive a reset interrupt and execute a reset vector fetch which will cause it to jump to the second stage of the exploit firmware. Simultaneously the rdp lock caused by condition 3 has been ridden since the STM32F1 believes is now booting from flash memory again (BOOT0 is low).

Step 4: Exploit Firmware - Stage 2

The STM32F1 is now executing the second stage of the exploit firmware. The second stage simply reads and dumps the contents of the flash memory to the serial port, where it is then read by the Pi Pico and further directed to the host computer via USB. Once the dump is complete, the exploit firmware will stop sending data to the serial port and the attack is complete.

Description
Dump read-out protected STM32F1's with a Pi Pico - A Pi Pico implementation of @JohannesObermaier's, Marc Schink's and Kosma Moczek's Glitch and FPB attack to bypass RDP (read-out protection) level 1 on STM32F1 chips
Readme 23 MiB
Languages
Python 46.5%
C 28.4%
CMake 9.8%
Assembly 8.2%
Makefile 7.1%