Author: geneblue
Blog: https://geneblue.github.io/
系统环境
1 | Nexus 6 MRA58K |
验证漏洞
1 | fastboot oem config fsg-id "a androidboot.bar=1" |
ro.boot.bar
更改为1,说明漏洞存在。
看了其他几款手机,huawei,xiaomi,nubia,neuxs5,vivo, fastboot oem
config
命令都不可用,看来只有摩托罗拉的手机才有这个问题。
逆向 ABOOT
从 bootloader.img 中提取 ABOOT,可以使用 unpack_motoboot 脚本。
参考文章里的 aboot 带了符号表,所以可以很轻松找到
target_get_scratch_address()
函数的返回值。 但我提取出来的
aboot 没有符号表,只有逆向着看了。
先将 ida-mbn-sbl-loader
放入 IDA loader
中,方便 IDA 解析 aboot。
然后下载 LK
代码对照着看。首先需要搜索 target_get_scratch_address()
都在哪些地方被调用了,之后可以试着搜索周边的字符串。
因为这个 aboot 和 Android LK
源码并不是一致的,所以很多字符串并不对应,所以要多尝试着找一些字符串,找了一会儿,找到了
aboot_init()
中调用
target_get_scratch_address()
的位置:
1 |
|
fastboot_init()
中有个 "fastboot_init()\n"
字符串,恰好逆向的 aboot 中也存在, 所以可以很快确定
fastboot_init()
函数,之后就能确定
target_get_scratch_address()
。
有时会找不到字符串引用的位置,主要是 IDA
分析代码时,没有做好交叉引用关系,直接在汇编码中表达成了字符串地址值,可以写个脚本批处理这种情况,临时性的方法,可以先将汇编码导出成
asm
文件,在文件中搜索字符串的地址值,之后就可以确定引用字符串的函数。
1 | signed int target_get_scratch_address() |
伪造 initramfs
对于有的 Moto 设备,在 flash
时需要添加一个padding
做填充,漏洞作者猜测,在 flash
image
后,手机启动过程可能污染了发送的initramfs
,导致initramfs
被破坏。因此,需要将initramfs
放在一个高地址内存处。
padding 32 MB
1 | python -c "print 'A'*(32*1024*1024-1)" > initramfs_padding |
对于 nexus6 设备,不需要加 padding
1 | fastboot oem config fsg-id "a initrd=0x11000000,1125383" |
1125383 为 boot.img-ramdisk.gz
文件大小,刷入原镜像,手机启动成功。
initramfs 镜像是由 cpio 打包,再经 gzip 压缩的一个压缩文件,伪造的方法就是先将 initramfs 镜像使用 gunzip 解压缩,再用 cpio 解包,修改解包出来的文件再打包压缩。相关命令如下:
解压解包:
1 | cp boot.img-ramdisk.gz tmp_ramdisk.gz |
打包压缩:
1 | cd cpio_out |
压缩的 new_ramdisk.cpio.gz
比原镜像文件要大,对应更改
fastboot 参数,刷入手机重启成功。之前,由于 cpio
打包命令错误,导致手机一直在重启状态循环。
gzip 的压缩比是可以更改的,更改 gzip 压缩比,-1 最快,但是压缩比最差,-9 最慢,但是压缩比最好!预设是 -6。
如果要添加 root 权限,我们可以直接向 initramfs 中添加 su 文件,或者 patch adbd,让其降权不成功,直接以 root 权限启动。
添加 su
将su,拷贝到根目录,再重新打包后,启动成功
patch adbd
adbd 是个后台守护进程,由 init 进程启动,启动之初具备 root 权限,init.rc 中有段脚本可以表明。 为了不让 adb shell 以 root 权限执行,adbd 源码中有一段降权代码,将该代码 patch 掉, 在执行 adb shell 时就可以获取 root 权限。
代码位置 syste/core/adb/adb_main.cpp
1 | int adb_main(int is_daemon, int server_port) |
initramfs 中包含的文件都比较重要,能 patch 的目标也是比较多的,如 init.rc,sepolicy,甚至 init 进程,所以这个漏洞的攻击面还是比较广的。
需要注意的问题
伪造是一次性的,伪造成功后,重启手机,手机循环启动,无法进入系统,这是为什么???
这需要重新将 initramfs 恢复到原始内存位置,再重启手机, 参见 【漏洞分析】如何通过内核命令注入绕过Nexus 6的安全启动模式(含演示视频) 物理内存布局。
1 | fastboot oem config fsg-id "a initrd=0x02000000,1125383" |
这样重启时,手机可以重启,没有问题,当我重新向手机刷入 Android7.1(原系统是6.0)时,手机重启时又陷入了无限重启状态。
通过与漏洞作者的沟通,恢复手机原状要执行 fastboot 命令。
1 | fastboot oem config fsg-id "" |
总结
该漏洞只影响 Moto 系列的手机,主要是 bootloader 出的问题,做针对性的攻击是可行,伪造 initramfs 的攻击面比较广。