一、Android内核简介
- EL0层:普通Application、TA (Trusted Application)
- EL1层:Linux内核 (Guest OS)、TEE内核 (Trusted OS)
- EL2层:Hypervisor (No Hypervisor in Secure World)
- EL3层:Secure Monitor
- 不同的EL对应不同的权限,不同的寄存器,高权限的行为在低EL上是不能执行的。
- 常见安全问题:低权限攻击高权限、非安全侧攻击安全侧
二、内核内存
- 单个进程角度:低地址为user内存,高地址(TASK_SIZE以上)为kernel内存
- 系统角度:内核地址是共享的,各个进程地址隔离
三、内核接口
- EL0调用EL1方法:通过中断指令,内核进入中断向量表,再通过系统调用号进入各类系统调用
- ARM中的指令:svc
- libc.so里面所有系统调用都会用到DO_CALL这个宏,包括但不限于:open, read, write, fork, ioctl等。
- 虚拟文件系统(VFS):所有的驱动程序都是通过文件进行调用的
四、识别攻击面
- 入口:/dev、/proc等驱动,系统调用
- 内存操作函数:put_user, get_user, copy_to_user, clear_user, copy_from_user, strncpy_from_user
- 驱动:经常用到的比如字符设备驱动、网络设备驱动以及NetLink等
- 重要结构体:file_operations
- read/write函数:内核VFS框架里,count是被校验过的
- ioctl:arg是一个指针,没有标准的类型,VFS框架无法校验,如何使用全部取决于开发人员
- mmap:内核驱动需实现xxxx_mmap,最终调用到remap_pfn_range
五、内核缓解机制
- KASLR:内核地址随机化
- NX:数据区不可执行
- 栈Cookie:返回地址之前的随机数,覆盖返回地址之前会先覆盖Cookie
- SELinux:基于策略的保护方式
- PXN:内核态不能执行用户态地址的代码
- PAN:内核态不能访问用户态地址数据
- CFI:控制流完整性,只有特定流才能调用