While the Das U-Boot bootloader should be known, the UBI Filesystem is a little bit rarer. Here a few notes on how to work with it.
Scenario
- Embedded device
- UART header with active terminal
- Running
Linux version 3.10.12 (jenkins@jenkins2) (gcc version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 unknown)
- Shell is password protected
- U-Boot is accesible
Steps
Identify the Correct Memory Device, Option 1
Run printenv
, search for bootcmd=
and process it
bootcmd=run flash_flash
flash_flash=run flashargs addmisc;ubi part system_sw;ubifsmount data;setenv bootargs $(bootargs) fw_number=0;ubifs_genload $(loadaddr) fw/0/;bootm $(loadaddr);setenv bootargs $(bootargs) fw_number=1;ubifs_genload $(loadaddr) fw/1/;bootm $(loadaddr)
loadaddr=0x83000000
ubi part system_sw;
shows us the correct partition, ubifsmount data
gives us the correct volume name and loadaddr gives us a location with enough space to safely mount the file in fw/0/
. The image can then be mounted using ubifs_genload 0x83000000 fw/0/
.
The output will be something like Loading file 'fw/0/xyz.img' to addr 0x83000000 with size 7755148 (0x0076558c)...
.
Identify the Correct Memory Device, Option 2
Start by running mtdparts
and list the available partition names.
device nand0 <ifx_nand>, # parts = 6
#: name size offset mask_flags
0: bootstrap 0x80000 0x0 0
1: bootloader 0x100000 0x80000 0
2: reserved_1 0x80000 0x180000 0
3: reserved_2 0x80000 0x200000 0
4: system_sw 0x7d00000 0x280000 0
5: bbt 0x80000 0x7f80000 0
Mount system_sw using ubi part system_sw
now ubi part
shows us Device 0: nand0, partition system_sw
.
Next we run ubi info layout
to get the volume name
UBI: volume information dump:
UBI: vol_id 0
UBI: reserved_pebs 33
UBI: alignment 1
UBI: data_pad 0
UBI: vol_type 4
UBI: name_len 8
UBI: usable_leb_size 129024
UBI: used_ebs 33
UBI: used_bytes 4194304
UBI: last_eb_bytes 65536
UBI: corrupted 0
UBI: upd_marker 0
UBI: name reserved
UBI: volume information dump:
UBI: vol_id 1
UBI: reserved_pebs 943
UBI: alignment 1
UBI: data_pad 0
UBI: vol_type 3
UBI: name_len 4
UBI: usable_leb_size 129024
UBI: used_ebs 943
UBI: used_bytes 121669632
UBI: last_eb_bytes 129024
UBI: corrupted 0
UBI: upd_marker 0
UBI: name data
UBI: volume information dump:
UBI: vol_id 2147479551
UBI: reserved_pebs 2
UBI: alignment 1
UBI: data_pad 0
UBI: vol_type 3
UBI: name_len 13
UBI: usable_leb_size 129024
UBI: used_ebs 2
UBI: used_bytes 258048
UBI: last_eb_bytes 2
UBI: corrupted 0
UBI: upd_marker 0
UBI: name layout volume
Yet again data
is the result. We can now utilize ubifsls
:
<DIR> 288 Fri Apr 17 08:32:35 2020 fw
<DIR> 376 Mon Nov 06 10:09:51 2017 production
<DIR> 160 Fri Apr 17 08:32:35 2020 log
<DIR> 160 Fri Apr 17 08:32:35 2020 run
<DIR> 160 Fri Apr 17 08:31:05 2020 config
Dump Memory
Having the offset (0x83000000
) and the length (7755148
) we can print all memory with md 0x83000000 7755148
. This will have to be recorded using the terminal emulator.
This will give us an ugly hex editor style string, which we can easily clean using some python:
d = open('dump','r')
lines = []
for l in d.readlines():
a = l.split(' ')
a = a[1]+a[2]+a[3]+a[4]
lines.append(a)
res = open('result.txt','wb')
for l in lines:
x=bytes.fromhex(l)
res.write(x)
d.close()
res.close()
Finally we have a binary file with what ever is booted by the device!
From there binwalk -e -M
did it’s magic nicely
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 Flattened device tree, size: 7755148 bytes, version: 17
280 0x118 LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 11377688 bytes
2636142 0x28396E HPACK archive data
7732804 0x75FE44 Flattened device tree, size: 10570 bytes, version: 17
7743576 0x762858 Flattened device tree, size: 10578 bytes, version: 17