UAF + fork后修改struct cred

<aside> ⚠️ 适用: <4.5

</aside>

进程fork/clone会调用**kernel_clone** (老版本为 _do_fork),接着 **copy_process →** **copy_creds →** **prepare_creds** ,内部会调用kmem_cache_alloc分配新的cred结构,若我们有UAF,则可按以下步骤利用:

  1. kmalloc分配一个和cred大小相同的块
  2. 释放该块
  3. fork,此时新进程通过**prepare_creds** 很有可能使用我们刚释放的块
  4. 利用UAF修改cred,完成提权,fork出的进程权限提升。

修改时主要需要让euid和egid为0,可直接将 offsetof(struct cred, securebits) 前的部分全部置零(root uid = gid = 0)

例题:ctf-challenges/pwn/kernel/CISCN2017-babydriver at master · ctf-wiki/ctf-challenges (github.com)

返回用户态

我们在控制完内核执行流完成提权后,通常还要考虑如何回到用户态

返回用户态的方法可以参考内核处理syscall的流程:entry_64.S

对于我们攻击者,sysret和iret都可以使用,我们只需要布置好栈帧/控制好寄存器值后,控制执行流至swapgs_restore_regs_and_return_to_usermode / **syscall_return_via_sysret** 的 POP_REGS 后即可,该段汇编会帮我们还原CR3并swapgs。

对于ROP,sysret要更复杂一些,因为需要控制寄存器,而iret只需要在栈上构造即可。

tty_struct

<aside> ⚠️ 对于≥4.7需要确保/dev/pts被挂载

</aside>