固件分析和文件系统提取?

逆向工程 混淆 文件格式 固件 嵌入式
2021-06-26 02:00:57

我正在尝试分析 NAS 设备的固件映像。

我使用了各种工具来帮助分析(binwalk、deezee、signsrch、使用 binwalk AFAIK 的firmware-mod-kit),但到目前为止都没有成功。

例如,binwalk 似乎会生成关于 gzip 压缩数据和 Cisco IOS 实验微码的误报。

Scan Time:     2013-08-27 14:52:15
Signatures:    196
Target File:   firmware.img
MD5 Checksum:  4d34d45db310bf599b62370f92d0a425

DECIMAL         HEX             DESCRIPTION
-------------------------------------------------------------------------------------------------------------------
80558935        0x4CD3B57       gzip compressed data, ASCII, has CRC, last modified: Fri Oct  4 17:37:33 2019
82433954        0x4E9D7A2       Cisco IOS experimental microcode
145038048       0x8A51AE0       gzip compressed data, ASCII, extra field, last modified: Mon May 26 20:11:40 2014  

尝试解压缩数据时,使用 gunzip/gzip 出现以下错误

gzip: 4CD3B57.gz is a multi-part gzip file -- not supported

根据 gzip 常见问题解答 ( http://www.gzip.org/#faq2 ),这是由于不是以二进制模式进行的传输损坏了 gzip 标头。

对我来说,这看起来更像是 binwalk 的误报,主要是因为用于识别 gzip 数据的幻数很容易触发误报并且日期错误。

我还运行了字符串和 hexdump 命令,以便了解文件的内容并尝试识别已知模式,但到目前为止它没有多大帮助(我可能在这里缺乏这种类型的经验)。

唯一的非乱码/可识别字符串位于固件映像的末尾。

00000000  f5 7b 47 03 d5 08 bf 64  ba e9 99 d8 48 cf 81 18  |.{G....d....H...|
00000010  b1 69 1e 2c c2 f3 46 6b  53 2b b7 63 e8 ce 78 c9  |.i.,..FkS+.c..x.|
00000020  87 fd b8 68 41 4d b2 61  71 cb cc 75 eb 8c e0 75  |...hAM.aq..u...u|
00000030  25 d1 ec bd 6d 46 e8 16  37 c6 f5 2e 2a e0 dc 07  |%...mF..7...*...|
00000040  65 b1 ce 7f 20 57 7c d7  cb 1d 91 fc 05 25 ad af  |e... W|......%..|
00000050  58 56 ff 13 4d 03 95 7f  ad 58 0e 84 85 2f 73 5c  |XV..M....X.../s\|
00000060  d9 19 d4 d4 2c 27 be c6  45 f2 9f a4 b1 e1 04 f1  |....,'..E.......|
00000070  c1 28 17 9c e1 f7 9d 2b  63 c3 7d e1 95 56 06 05  |.(.....+c.}..V..|
[...]
09ec9d60  4b 29 75 20 46 6e fb e3  0f 14 d4 93 54 8e 4f bb  |K)u Fn......T.O.|
09ec9d70  4b ab 91 bf e7 8a b9 4e  c8 ff 87 17 93 19 e9 3f  |K......N.......?|
09ec9d80  70 fe a6 9f d3 36 48 83  34 48 83 34 48 83 34 48  |p....6H.4H.4H.4H|
09ec9d90  83 34 48 83 34 48 83 34  48 83 34 48 83 34 48 83  |.4H.4H.4H.4H.4H.|
09ec9da0  34 48 83 34 48 83 34 48  83 34 48 83 34 48 83 34  |4H.4H.4H.4H.4H.4|
09ec9db0  48 83 34 48 83 34 48 83  34 48 83 34 48 83 24 a7  |H.4H.4H.4H.4H.$.|
09ec9dc0  ff 07 e9 0d 37 73 00 20  08 0a 69 63 70 6e 61 73  |....7s. ..icpnas|
09ec9dd0  00 00 10 00 54 53 2d 35  36 39 00 00 00 00 00 00  |....TS-569......|
09ec9de0  00 00 00 00 33 2e 38 2e  33 00 00 00 00 00 00 00  |....3.8.3.......|
09ec9df0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
09ec9e14

这是我第一次进行这种类型的锻炼,我不确定接下来应该做什么。图像似乎以某种方式被混淆了(这可能是一个错误的假设)。

你有什么建议/技巧可以帮助我取得一些进展吗?

4个回答

一段时间以来,我一直在剖析另一种嵌入式设备的固件,想看看是否能找到任何东西。几个小时后,我想通了!有难的方法,也有简单的方法,是我挖了难的路才找到的。这是一篇很长的文章,但我希望它能帮助其他类似的企业。

稍微谷歌一下,我发现http://wiki.qnap.com/wiki/Firmware_Recovery描述了完整的固件恢复方法和同一 wiki 上的另一个页面,用于“手动更新固件”和命令行示例。有几件事突出了......

  • NAS 操作系统有一个用于处理固件更新映像的脚本:

    # /etc/init.d/update.sh /mnt/HDA_ROOT/update/TS-209_2.1.2_build1031.img
    
  • 二进制文件中嵌入了校验和,然后输出中有这一行:

    "Using 120-bit encryption - (QNAPNASVERSION4)"
    

我走了两条路:艰难的道路和非常简单的道路......

艰难的道路(但有有用的提示)

我从固件恢复页面下载了 TS-569 完整系统恢复映像,500MB 花了将近 2 个小时。现在我必须弄清楚我在做什么:

# file F_TS-569_20120628-1.2.2.img
F_TS-569_20120628-1.2.2.img: x86 boot sector; GRand Unified Bootloader, ...

一个完整的磁盘映像,如下所示:

$ fdisk -l F_TS-569_20120628-1.2.2.img
                      Device Boot      Start         End      Blocks   Id  System
F_TS-569_20120628-1.2.2.img1              32        4351        2160   83  Linux
F_TS-569_20120628-1.2.2.img2   *        4352      488959      242304   83  Linux
F_TS-569_20120628-1.2.2.img3          488960      973567      242304   83  Linux
F_TS-569_20120628-1.2.2.img4          973568     1007615       17024    5  Extended
F_TS-569_20120628-1.2.2.img5          973600      990207        8304   83  Linux
F_TS-569_20120628-1.2.2.img6          990240     1007615        8688   83  Linux

分离分区(或者您可以将映像写入备用磁盘):

# dd if=F_TS-569_20120628-1.2.2.img bs=512 of=part1 skip=32 count=2160w
# dd if=F_TS-569_20120628-1.2.2.img bs=512 of=part2 skip=4352 count=242304w
# dd if=F_TS-569_20120628-1.2.2.img bs=512 of=part3 skip=488960 count=242304w
# dd if=F_TS-569_20120628-1.2.2.img bs=512 of=part5 skip=973600 count=8304w
# dd if=F_TS-569_20120628-1.2.2.img bs=512 of=part6 skip=990240 count=8688w  
... which gives  
-rw-r--r-- 1 root   root     2211840 2013-08-30 15:41 part1
-rw-r--r-- 1 root   root   248119296 2013-08-30 15:42 part2
-rw-r--r-- 1 root   root   248119296 2013-08-30 15:42 part3
-rw-r--r-- 1 root   root     8503296 2013-08-30 15:42 part5
-rw-r--r-- 1 root   root     8896512 2013-08-30 15:42 part6

分区3是分区2的镜像,通过md5sum验证。分区 5 和 6 是空的,可能是暂存空间。分区 1 是/boot/grub,其中包含用于启动和硬件配置的模块等。所以让我们看看分区 2,引导分区。

# mkdir /mnt/ts2
# mount -r part2 /mnt/ts2 -o loop
# ls -la /mnt/ts2/boot
-rw-r--r-- 1 root root  3982976 2012-06-27 22:17 bzImage
-rw-r--r-- 1 root root       81 2012-06-27 22:17 bzImage.cksum
-rw-r--r-- 1 root root  8890727 2012-06-27 22:17 initrd.boot
-rw-r--r-- 1 root root       85 2012-06-27 22:17 initrd.boot.cksum
-rw-r--r-- 1 root root 73175040 2012-06-27 22:17 qpkg.tar
-rw-r--r-- 1 root root       83 2012-06-27 22:17 qpkg.tar.cksum
-rw-r--r-- 1 root root 33593992 2012-06-27 22:17 rootfs2.bz
-rw-r--r-- 1 root root       85 2012-06-27 22:17 rootfs2.bz.cksum
-rw-r--r-- 1 root root 31160679 2012-06-27 22:17 rootfs_ext.tgz
-rw-r--r-- 1 root root       87 2012-06-27 22:17 rootfs_ext.tgz.cksum
# file -z /mnt/ts2/boot/initrd.boot
/mnt/ts2/boot/initrd.boot: Linux rev 1.0 ext2 filesystem data, UUID=770ce31c-d03f-484e-81e8-6911340bdcbf (gzip compressed data, from Unix, last modified: Wed Jun 27 22:16:58 2012, max compression)
  • bzImage 是压缩的内核映像
  • initrd 是使操作系统运行的初始 ramdisk 根文件系统
  • qpkg.tar 包含 NAS 的各种软件包
  • rootfs2.bz 是一些 /home、/lib 和 /usr 文件的压缩包
  • rootfs_ext.tgz 是 apache、php5、mysql 的 /opt/source 的另一个 ext2 文件系统的压缩 tarball,似乎是 NVRAM 设置的备份。

所有的魔法都在 initrd 文件系统映像中。仔细观察我们得到:

# gunzip -c /mnt/ts2/boot/initrd.boot >/tmp/initrd.boot.img
# mkdir /mnt/tsinitrd
# mount -r /tmp/initrd.boot.img /mnt/tsinitrd -o loop
# ls -la /mnt/tsinitrd
drwxr-xr-x  2 root root  2048 2012-06-27 22:05 bin
drwxr-xr-x  5 root root 13312 2012-06-27 22:11 dev
drwxr-xr-x 22 root root  2048 2012-06-27 22:15 etc
drwxr-xr-x  3 root root  3072 2012-06-27 22:05 lib
drwxr-xr-x  2 root root  1024 2010-11-03 04:53 lib64
lrwxrwxrwx  1 root root    11 2012-06-27 22:16 linuxrc -> bin/busybox
drwx------  2 root root 12288 2012-06-27 22:16 lost+found
drwxr-xr-x  4 root root  1024 2012-06-27 22:04 mnt
drwxr-sr-x  2 root root  1024 2012-06-27 22:16 opt
lrwxrwxrwx  1 root root    19 2012-06-27 22:16 php.ini -> /etc/config/php.ini
drwxr-sr-x  2 root root  1024 1999-11-02 18:54 proc
lrwxrwxrwx  1 root root    18 2012-06-27 22:16 Qmultimedia -> /share/Qmultimedia
drwxr-xr-x  3 root root  1024 2007-07-18 05:24 root
drwxr-xr-x  2 root root  5120 2012-06-27 22:15 sbin
drwxrwxr-x 29 root root  1024 2006-02-28 00:57 share
drwxrwxrwx  4 root root  1024 2006-02-28 00:57 tmp
drwxrwxrwx  8 root root  1024 2012-06-27 22:15 var

还记得固件恢复页面上突出的两件事吗?更新脚本和加密参考:

# more /mnt/tsinitrd/etc/init.d/update.sh
...
... line 223
    /sbin/PC1 d QNAPNASVERSION4 $path_name ${_tgz};
...

有对似乎是加密密钥和解密器的引用!由于此 NAS 固件映像基于 x86,而我在 x86 VM 中,不妨尝试一下:

# /mnt/tsinitrd/sbin/PC1
Usage: pc1 e|d "key" sourcefile <targetfile>
where: e - encrypt, d - decrypt & "key" is the encryption key.
The length of the key will determine strength of encryption
If no targetfile, output file name is equal to sourfile name
ie: 5 characters is 40-bit encryption.

最后:

# /mnt/tsinitrd/sbin/PC1 d QNAPNASVERSION4 TS-569_20130726-4.0.2.img TS-569_20130726-4.0.2.tgz
Using 120-bit encryption - (QNAPNASVERSION4)
len=1048576
model name = TS-569
version = 4.0.2

# tar -tvf TS-569_20130726-4.0.2.tgz 
-rw-r--r-- root/root       106 2013-07-25 20:49 bios_layout
drwxr-xr-x root/root         0 2013-07-25 20:49 boot/
-rw-r--r-- root/root   4557984 2013-07-25 20:49 bzImage
-rw-r--r-- root/root        69 2013-07-25 20:49 bzImage.cksum
drwxr-xr-x root/root         0 2013-07-25 20:49 config/
-rwxr-xr-x root/root     48408 2013-07-25 20:49 dmidecode
-rwxr-xr-x root/root    356714 2013-07-25 20:49 flashrom
-rw-r--r-- root/root   2097152 2013-07-25 20:49 flashrom.img
-rw-r--r-- root/root        33 2013-07-25 20:49 fw_info
-rw-r--r-- root/root   8480290 2013-07-25 20:49 initrd.boot
-rw-r--r-- root/root        73 2013-07-25 20:49 initrd.boot.cksum
-rwxr-xr-x root/root   1606508 2013-07-25 20:49 libcrypto.so.1.0.0
-rwxr-xr-x root/root    372708 2013-07-25 20:49 libssl.so.1.0.0
-rw-r--r-- root/root  81090560 2013-07-25 20:49 qpkg.tar
-rw-r--r-- root/root        72 2013-07-25 20:49 qpkg.tar.cksum
-rw-r--r-- root/root  41185897 2013-07-25 20:49 rootfs2.bz
-rw-r--r-- root/root        74 2013-07-25 20:49 rootfs2.bz.cksum
-rw-r--r-- root/root  47500086 2013-07-25 20:49 rootfs_ext.tgz
-rw-r--r-- root/root        78 2013-07-25 20:49 rootfs_ext.tgz.cksum
drwxr-xr-x root/root         0 2013-07-25 20:49 update/
-rw-r--r-- root/root       105 2013-07-25 20:49 update_bios.conf
-rwxr-xr-x root/root      3188 2013-07-25 20:49 update_bios.sh
-rwxr-xr-x root/root      6088 2013-07-25 20:49 update_check
-rwxr-xr-x root/root     22041 2013-07-25 20:49 update_img.sh

所有这些都是为了获得一个为我们解密固件映像的可执行文件,一个以纯文本形式为我们提供解密密钥的脚本,以及一种如果我们想要修改某些内容将所有内容重新打包的方法。

......现在是完全不同的东西

非常简单的方法

一旦我走到了“艰难之路”的尽头,我决定在谷歌上搜索加密密钥“QNAPNASVERSION4”。第一个结果是 C 语言中的 PC1 enc/dec 算法,有人已经很友好地修改了它来为我们处理固件格式的细节:http : //www.r00ted.com/downloads/pc1.c

更新:据报道链接已损坏,这是一个转储:http : //pastebin.com/KHbX85nG

# gcc -o pc1 pc1.c
# pc1 d QNAPNASVERSION4 TS-569_20130726-4.0.2.img TS-569_20130726-4.0.2.tgz
# tar -tvf TS-569_20130726-4.0.2.tgz
-rw-r--r-- root/root       106 2013-07-25 20:49 bios_layout
drwxr-xr-x root/root         0 2013-07-25 20:49 boot/
-rw-r--r-- root/root   4557984 2013-07-25 20:49 bzImage
... same result as the hard way

现在您有一个实用程序,可以在您自己的操作系统中轻松解密您的固件文件,而无需物理访问 NAS。

该文件确实看起来加密或混淆。可能可以使用一些密码分析来解决这个问题(34 48 83最后的序列看起来不是随机的),但你最好寻找 UART 或 JTAG 引脚,或者一个正在运行的 telnet 服务器或其他服务可能会给你一条路。

编辑:在NAS下载页面,有名为“Qfix”的较小下载。他们似乎是简单的自解压shell脚本+tar.gz数据。我建议您尝试使用 shell 脚本制作自己的 .qfix,该脚本可以将文件从设备中复制出来,而不是正常行为。

但是,有可能用于完整性检查的文件页脚。“SambaFix”旁边的数字看起来像一些校验和。

我现在知道这是一个较旧的问题,但我只想在讨论中添加一些更新的信息,以供将来寻求答案的人使用。

我也在试验这个。较新版本的 binwalk 具有自动提取功能。只需运行:

binwalk -e ./firmwarefile.bin

它将提取并拆分不同的分区到单独的文件夹中。这是很多,比使用更容易dd,在这里如果你的价值观错了,然后squashfs/ gzip/ ...只会看到它损坏。

此外,获取 Kali 或 Backtrack linux 的副本(Backtrack 现在可能会贬值。我认为 Kali 是首选)它们已binwalk安装或在 apt 包管理器存储库中安装了固件模块工具,以便于安装。

至于重新打包上传固件,我自己还没有做到。使用我正在使用的固件,binwalk也提取带有签名的文件。这包含用于验证设备固件的 MD5 数据。

我找到了几个可以玩固件的工具,但它们都不能用来“玩”我为媒体播放器下载的固件,也许它对你更有用:

http://www.routertech.org/tools/firmware_tool-097b.zip

固件模组套件:http : //code.google.com/p/firmware-mod-kit/downloads/list

我只想弄清楚设备上存储了哪些网页,可以用作 NAS,但我无法访问 Linux 设备。