ARM64内核研究(四)
2023-3-29
| 2023-3-29
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
Mar 29, 2023 01:31 AM
针对GKI设备已有更好解决方案:https://github.com/tiann/KernelSU
时隔两年,终于愿意发布:https://github.com/abcz316/SKRoot-linuxKernelRoot
本文主体内容来自2022年2月的个人笔记,可能具体实现步骤有记录不详细的地方,自己稍微研究一下就能解决。

核心原理

通过静态修改内核,将自定义后门逻辑嵌入内核,从而达到提权的目的。
人话:挂个inline hook来提权

优点

高隐蔽性
无需内核源码

缺点

功能单一,无模块系统支持
不支持其他应用的授权
开发困难
直接的汇编操作容易因错误而导致死机

前置知识

IDA分析内核镜像

没符号很难受是吧,提取kallsyms导进去就好了

提取kallsyms

静态提取
动态提取

将kallsyms导入IDA

获取current指针

一行汇编即可

内核分段及权限设定

一、分了哪些段?

  • _text → _etext 之间是代码段
  • __start_rodata → __end_rodata 之间是只读数据段
  • __init_begin → __init_end 之间是内核初始化相关的段,包括代码和数据,这个段的特点是只在内核初始化的时候用,内核初始化完成后就可以释放了。
  • _data → _end 之间是可读可写的数据段

二、各个段的权限设定

arch/arm64/mm/mmu.c 的 map_kernel 函数
PTE_PXN:特权模式下不可执行 PTE_UXN:用户模式下不可执行 PTE_NG:地址翻译是否是全局的,1非全局,0全局
可以通过静态修改 rodata_enabled 为 0 来让syscall table可写
  • 代码段:_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 可读可写不可执行

三、自定义代码添加到哪里

只能塞到代码段里面,不然没执行权限的。

如何生成ShellCode

写到一个函数内,然后编译生成
g++ tmp.cpp -fno-stack-protector -O3 -o tmp
 

实现思路

一、修改SELinux状态

定位 selinux_state

通过函数定位,如:avc_has_perm、avc_has_extended_perms,搜索引用,X0即为对应地址
在内核源码中搜素:&selinux_state查看所有引用

ShellCode

二、给予进程ROOT权限

获取real_cred偏移

exit_creds函数
notion image
在内核代码中搜索 ->real_cred 查找其他调用也可

提权

权限位值1,其他置0即可
权限判断:
cred->uid.val == 0 || cred->uid.val == 2000 || cred->gid.val == 0 || cred->gid.val == 2000

三、绕过SELinux

原理:修改avc_denied函数判断uid=0时直接返回0
缺陷:只能让root为主动方的规则被绕过
 
  • Kernel
  • ChatGPT Plus 开通指南ArchLinux WakeOnLan 配置
    • Giscus
    目录