babyarm 复现
1 | timeout --foreground 60 qemu-system-aarch64 \ |
- 没有给定
nokaslr
,默认开启地址随机化
1 | !/bin/sh |
- dmesg_restrict
- kptr_restrict
- perf_event_paranoid
漏洞分析
IDA 分析内核模块发现就只有 device_write
和 device_read
有用,但这两个函数都很乱
再加上对 ARM 架构不熟悉,逆向的过程花费了我不少时间,下面是我的思考过程:
函数 device_write
:
1 | __int64 v21; // [xsp+B8h] [xbp+B8h] |
- 从位置上开看 v21 应该是 canary
- 那前面的
_ReadStatusReg(ARM64_SYSREG(3, 0, 4, 1, 0))
就是用来生成 canary 的
然后就到了我感觉最抽象的一段代码:
1 | if ( (*(_DWORD *)(StatusReg + 0x2C) & 0x200000) != 0 |
demo_buf
的范围远比tmp
大,因此有栈溢出
这段代码有很多未命名变量,宏定义,还有很多 if-else 语句,但我们可以从后向前分析:
- 为了不让程序返回错误码 0xFFFFFFFFFFFFFFEALL,以上各个 if-else 语句都只能按照 “△” 标注的路线回溯
- 直到第一个 if 执行:
1 | if ( (*(_DWORD *)(StatusReg + 0x2C) & 0x200000) != 0 |
感觉程序在检查一些环境,没有实质性的操作,写一个 test.c 进行调试:
1 |
|
- 可以通过
/sys/module/demo/sections/.text
获取模块.text
基地址
1 | /home/pwn # cat /sys/module/demo/sections/.text |
1 | ► 0xffffbe24d4559090 bl #0xffffbe24da88b200 <0xffffbe24da88b200> |
- 其实到
_arch_copy_from_user(demo_buf, v13, len)
执行之前的操作都没有什么影响,可以直接忽略
函数 device_read
:
1 | canary = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 0, 4, 1, 0)) + 0x480); |
- 由于 tmp 和 canary 靠得很近,这里可以把 canary 拷贝到 demo_buf 中
入侵思路
栈溢出和泄露 canary 都很简单,关键是怎么提取并且回到用户态
程序开了 smep 因此只能写 ROP,第一个 gadget 需要完成栈迁移的工作
常规获取 gadget 的工具 ropper/ROPgadget 不能使用:
1 | filebytes.binary.BinaryError: Bad architecture |
1 | [Error] PE.getArch() - Bad Arch |
- 这就需要手动找 Gadget 了
内核里有个好用的 gadget:
1 | .text:0000000000016950 00 00 80 52 MOV W0, #0 |
这里有一个小坑需要注意:ARM 的 ret 指令和 x86 的有很大不同
- 执行 ret 之后,会把 LR 寄存器里的值赋值给 PC(注意,不是栈)
因此构造 ROP 链时的核心就是通过栈来控制 LR(X30) 寄存器:
- 控制 X19 为
prepare_kernel_cred+4
- 控制 X30 为
commit_creds+4
- 执行 ret 时就可以执行
commit_creds(prepare_kernel_cred(0))
后续需要考虑返回用户态的问题:
ARM64使用 SVC
指令进入内核态,使用 ERET
指令返回用户态,ARM 在进入内核态之前会保存用户态所有寄存器状态,在返回时恢复
其中比较重要的寄存器有 SP_EL0、ELR_EL1、SPSR_EL1:
- SP_EL0:保存用户态的栈指针
- ELR_EL1:保存要返回的用户态 PC 指针
- SPSR_EL1:保存 0x80001000
可以用下面这个 gadget 来填充上述数据:
1 | .text:0000000000011FE4 17 41 18 D5 MSR #0, c4, c1, #0, X23 /* msr sp_el0, x23 */ |
最后需要注意:不能执行 system("/bin/sh")
,会触发缺页机制
完整 exp 如下:
1 |
|
小结:
第一次打 ARM 的内核题目,调试很久找不到 gadget,最后的 gadget 还是抄的别人的
太菜了,现在找 gadget 还很迷茫,以后有经验了再总结吧