MRCTF2022 IoT题目之Nand有效数据分析(2)
上一节,我们讲述了如何分离Nand的有效数据,最终使用binwalk解出来文件系统:

但实际上还有1个yaffs文件系统没能正确的解出来,这一节我们来具体看看:

使用16进制命令hexdump -C 2E01000.yaffs -n 4096,查看2E010000.yaffs:
00000000 03 00 00 00 01 00 00 00 ff ff 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000100 00 00 00 00 00 00 00 00 00 ff ff ff ed 41 00 00 |.............A..|
00000110 e8 03 00 00 e8 03 00 00 d2 ce e9 5e d0 ce e9 5e |...........^...^|
00000120 d0 ce e9 5e ff ff ff ff ff ff ff ff ff ff ff ff |...^............|
00000130 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
000001c0 ff ff ff ff ff ff ff ff ff ff ff ff 00 00 00 00 |................|
000001d0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00000800 03 00 00 00 01 00 00 00 ff ff 61 70 70 00 00 00 |..........app...|
00000810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000900 00 00 00 00 00 00 00 00 00 ff ff ff ed 41 00 00 |.............A..|
00000910 e8 03 00 00 e8 03 00 00 d2 ce e9 5e d3 ce e9 5e |...........^...^|
00000920 d3 ce e9 5e ff ff ff ff ff ff ff ff ff ff ff ff |...^............|
00000930 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
000009c0 ff ff ff ff ff ff ff ff ff ff ff ff 00 00 00 00 |................|
000009d0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00001000
可以看出yaffs文件系统的有效区间都是正常的,唯一缺少的是备用区间(spare area),而此区间包含着块的一些信息(具体可以查阅之前的文章《YAFF2文件系统》),nand的OOB区包含着备用区间,由于前一节使用脚本手动去除了OOB区,导致yaffs文件系统丢失了备用区间,所以使用binwalk无法解开此文件系统,那么只需要将备用区间恢复即可。
使用binwalk分析最原始的编程器读取的文件S34ML02G200BHI00@BGA63_948.BIN,得到YAFFS文件系统的起始地址0x30E1100(51253504):

使用16进制命令hexdump -C S34ML02G200BHI00@BGA63_948.BIN -s 51253504 -n 4352,查看部分数据:
030e1100 03 00 00 00 01 00 00 00 ff ff 00 00 00 00 00 00 |................|
030e1110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
030e1200 00 00 00 00 00 00 00 00 00 ff ff ff ed 41 00 00 |.............A..|
030e1210 e8 03 00 00 e8 03 00 00 d2 ce e9 5e d0 ce e9 5e |...........^...^|
030e1220 d0 ce e9 5e ff ff ff ff ff ff ff ff ff ff ff ff |...^............|
030e1230 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
030e12c0 ff ff ff ff ff ff ff ff ff ff ff ff 00 00 00 00 |................|
030e12d0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
030e1510 3a f3 35 15 dd 16 c8 bf a8 11 ab 7b 2e 9f ff ff |:.5........{....|
030e1520 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
030e1910 84 a8 a5 1e 40 b5 3d d7 70 04 7a 13 ca 45 00 10 |....@.=.p.z..E..|
030e1920 00 00 01 00 00 00 00 00 00 00 ff ff 00 00 30 00 |..............0.|
030e1930 00 00 05 00 00 00 05 00 00 00 00 00 ff ff ff ff |................|
030e1940 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
030e1980 03 00 00 00 01 00 00 00 ff ff 61 70 70 00 00 00 |..........app...|
030e1990 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
030e1a80 00 00 00 00 00 00 00 00 00 ff ff ff ed 41 00 00 |.............A..|
030e1a90 e8 03 00 00 e8 03 00 00 d2 ce e9 5e d3 ce e9 5e |...........^...^|
030e1aa0 d3 ce e9 5e ff ff ff ff ff ff ff ff ff ff ff ff |...^............|
030e1ab0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
030e1b40 ff ff ff ff ff ff ff ff ff ff ff ff 00 00 00 00 |................|
030e1b50 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
030e1d90 91 91 a2 ff 66 e9 80 95 a3 49 95 cf 5b d8 ff ff |....f....I..[...|
030e1da0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
030e2190 cc 79 0b ee 0c b4 ed b7 8f 1a 18 eb ad 59 00 10 |.y...........Y..|
030e21a0 00 00 02 01 00 00 00 00 00 00 ff ff 00 00 26 00 |..............&.|
030e21b0 00 00 00 00 00 00 ff ff ff ff 00 00 ff ff ff ff |................|
030e21c0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
030e2200
根据上一节的经验,剔除有效数据里面的OOB数据,保留spare area,可以编写代码(python版本):
#!/usr/bin/python3
data = open("S34ML02G200BHI00@BGA63_948.BIN", "rb").read()[0x30E1100:]
print(hex(len(data)))
f = open("rootfs.yaffs", "wb")
p = 0x880
for i in range(len(data)//p):
f.write(data[i*p:i*p+0x410] + data[i*p+0x41E:i*p+0x80E] + data[i*p+0x81E:i*p+0x85E])
f.close()
使用binwalk或yaffshiv来解开yaffs文件系统,命令如下:
| yaffshiv -f rootfs.yaffs -d out |
解开yaffs文件系统如下,最终解出来120个文件夹、1255文件、20个链接文件:
