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