ARM64 内核研究 (一)
2022-11-25
| 2023-9-7
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
Sep 7, 2023 11:52 AM
本篇将实现一个劫持内核内BL指令跳转到自身模块函数执行的简单inline hook。

ARM64 指令基础

BL 指令

跳转到相对于PC的指定地址,并将下一条指令地址存入LR寄存器。
跳转范围:±128MB

指令格式

地址编码

imm26 负数使用补码表示
正数和0的补码就是该数字本身再补上符号位0。负数的补码则是将其对应正数按位取反再加1。
可能有人会有疑惑,明明立即数只有26位,跳转范围应该是±32MB才对,为什么会是±128MB呢?
因为arm64指令长度都是4字节,所以编码地址的时候除了4,比如跳转 0x4,imm26 是 1

简单例子

使用keystone生成机器码

以上代码输出: 0b10010100000000000000000000000001

模拟运行一下试试吧

输出如下
[0x00000000] nop [0x00000004] movz x0, #0x1 [0x00000008] b #0xc [0x00000014] add x0, x0, #1 [0x00000018] add x0, x0, #1

相关内核基础

内核分段及权限设定

一、分了哪些段

见 arch/arm64/kernel/vmlinux.lds.S
  • _text → _etext 之间是代码段
  • __start_rodata → __end_rodata 之间是只读数据段
  • __init_begin → __init_end 之间是内核初始化相关的段,包括代码和数据
  • _data → _end 之间是可读可写的数据段

二、各个段的权限设定

见 arch/arm64/mm/mmu.c 的 map_kernel 函数

三、结论

  • 代码段:_text → _etext
    • rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
      可读特权模式可执行,rodata_enabled为假时可写
  • 只读数据段
    • PAGE_KERNEL 可读可写不可执行
  • 初始化代码段:
    • rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC; 可读特权模式可执行,rodata_enabled为假时可写
  • 初始化数据段:
    • PAGE_KERNEL 可读可写不可执行
  • 数据段:
    • PAGE_KERNEL 可读可写不可执行

寻找对应符号地址

开了KASLR怎么办?摆!

方法一:kallsyms文件

解除内核符号限制
部分设备需要 echo 1 才行
获取符号地址

方法二:kprobe大法 (*推荐)

上代码:
底层原理:
使用 kallsyms_lookup_name 解析符号地址
需高版本内核!

方法三:kallsyms_lookup_name函数

如果该函数导出,可直接使用该函数定位,但是大部分内核中该函数并未导出。

方法四:奇门遁甲

  1. 将内核丢进IDA分析,依靠字符串和源码慢慢寻找位置
  1. 特征码定位
    1. 通过一些特征汇编代码定位
  1. 根据导出函数,结合偏移辅助定位
    1. 比如 &printk - offsetof(printk) + offsetof(foo)

让我们开始吧

绕过内核只读限制

方法一

修改内核,将 rodata_enabled 改为 0
优点:简单方便,快捷高效
缺点:安全性降低
评价:开发机要什么安全,方便就完了!

方法二

修改pte,给权限加上可写
详见下面代码

开始写hook咯

目标:__arm64_sys_faccessat 的 BL do_faccessat
目的:/memfd: 今天必须给我存在
代码:
问题:
加载成功后没多久就寄掉了,日志中没有原因,就戛然而止,但是还是成功打印了hijack success!

更好的方法

使用kprobe对内核进行hook,更方便,而且问题也更少
特别注意:
kprobes回调函数的运行期间关闭了抢占,同时也可能关闭中断。因此不论在何种情况下,在回调函数中不能调用会放弃CPU的函数(如信号量、mutex锁等),否则会领取死机重启大礼包。
下期预告:
基于 DirtyPipe漏洞 实现一个简单的 kernel root
 
  • Kernel
  • Hook
  • ARM64 内核研究 (二)Android 内存执行ELF研究
    • Giscus
    目录