嵌入式设备固件提取与漏洞挖掘
前言
一些基础, 有需要, 总结一下.
又因为 “大流行” , 所以拖了许久.
root的shell获取
有root权限就可以为所欲为所欲为所欲为了, 比如说gdbserver写进去直接调试
uboot命令行
其中如成功进入uboot命令行, 那既可以尝试修改kernel的cmdline, 使之成功进入命令行
使用uboot中的printenv来查看env的值, 使用setenv/saveenv来保存env, 使用env来临时设置env, 最后使用run来启动指定的内容
比如这里有提示cmdline如下
其中一般变量bootargs中存在此字符串 且此变量在其他env中存在. 那么修改此env为/bin/bash后进行一个saveenv后, 直接重启就可获得交互式shell了
固件重打包
大概率是squashfs的只读, 也有JFFS2的可读可写;
修改主要盯得是开机的文件, 即/etc/init.d中的文件与关联文件; 直接加一句/bin/bash去启动shell即可, 同时直接改passwd也是蛮不错的选择.
squashfs
对于squashfs, 他是一个只读的文件系统; 如果将其raw给dump下来之后, 可以直接使用squashfs-tools套件中的相关命令来打包解包即可
如下
1 | root@debian1:~/work/rootfs# mksquashfs squashfs-root/ packed_root_xz.sqsh -comp xz |
这里的comp为squashfs的压缩格式, 理论上与原来保持一致即可
JFFS2
对于JFFS2, 他是一个可读可写的文件系统; 如果将其raw给dump下来之后, 需要先模拟为mtd后, 再对mtd进行挂载
简单来说就是划了一块内存 然后直接挂载
1 | umount /dev/mtdblock0 |
这里需要对mtd进行一些设置, 比如说块大小之类的; 这是将文件直接dd到模拟出来的mtd中, 如果想要直接在文件中修改的话需要将文件变为lo的设备, 需要使用losetup命令
1 | modprobe loop |
就是先losetup再block2mtd然后mtdblock再mount就行了
总之, 这个jffs2比较复杂, 且进了shell后这里面的文件也可以在线修改, 所以可以搞但是没必要离线改了
其他方法
比如说ttl上直接爆破弱口令, 直接进行adb连接, 进行命令注入反弹shell等等
提取固件
观察是否有网络/USB/TTL接口等可以交互的
通过命令行获取
如果能够获取到交互式命令行, 直接使用dd对mount的设备进行一个物理读取.
一般情况下直接进行一个设备到文件的复制即可
1 | dd if=/dev/<dev> of=/mnt/<file> |
如果没有usb设备可以使用nc通过网络读取, 如读取/dev/mtdblock4, 那么使用如下命令即可
1 | dd if=/dev/<dev> | nc <host> <port> |
结果如下
当然也可以用cat代替dd 用/dev/tcp代替nc等等
通过uboot获取
如果能够进入uboot的交互模式, 那么其中有一些命令非常有用, 可直接导出相关的内容
首先查看命令 发现如下命令很有用
那么其中part命令可以查看分区
查看完成之后, 可以根据信息, 直接通过extfatdownloadxxx命令刷入tf卡中的固件
通过存储
其中fatls可以查看相关的文件
其中extfatdownloadrootfs可以直接下载存储介质中的文件到flash中
同时现代的板子上大部分可以进行在线烧录, 在uboot中找到相关的命令即可. 如rkusb
等
通过网络获取
其中命令bootp看起来可以直接从网络启动
有的也有tftp命令可以直接下发上传
通过内存获取
通过printenv后, 可以发现有时候kernel加载方式如下
1 | read_kernel=sf probe 0:0 ${sf_hz} 0; sf read ${loadaddr} ${kernel_offset} ${kernel_size} |
即使用sf模块将存储中的值读取到指定内存中, 则可以直接使用如下命令获取指定存储的二进制raw文件
1 | sf read ${loadaddr} <rawoffset> <rawsize> |
如上命令的读取结果如下
物理方式
直接读取出物理存储.
当然这个物理存储层到逻辑存储层存在对应的转换; 这个就看具体的实现了, 有的会加密, 有的会有相应的转换表.
但是整体的思路中, 系统最终还是需要读取的, 所以这个玩意的读取方式肯定在uboot或linux的内核驱动中.
直接读取存储芯片
存储芯片吹下来, 上相关硬件去读取.
类似于直接读linux下的/etc/mtd1
其中nand通常由(Data+OOB)/Page/Block/Chip
其中Chip指代每一个nand存储芯片, 其由若干个Block构成; 其中Block由若干个Page构成; 而Page由主数据存储及辅助数据存储(Out-Of-Band, OOB)构成.
其中主数据存储即我们储存数据的地方; 而辅助数据存储一般储存辅助数据, 用于主数据存储的辅助, 如ECC纠错/元信息等.
比如该芯片的存储信息如下
按照文档 他有4352(=4096+256) bytes/pages * 64 pages/block * 2048 blocks = 544MB
那么直接读取后按照对应的文档对数据进行还原即可.
一般主数据存储即我们需要的数据存储
在线读取
直接接spi等协议所需要的线到对应的触点上, 然后读取即可. 不需要接VCC供电.
漏洞挖掘
简单来说, 即找输入点, 看能与什么交互
比如说能插存储卡, 能插USB, 能联网, 能连蓝牙; 找到这些入口点后, 根据固件内的程序进行分析.
查看网络通信, 进行中间人; 构造包测试远端服务是否有问题.