Exploiting a string-based overflow on x86-64 with

2019-04-07 20:01发布

问题:

Consider the following vulnerable code/program:

#include <string.h>

int main(int argc, char *argv[]) {
    char buf[16];
    strcpy(buf, argv[1]);

    return 0;
}

On IA-32 (x86, 32-bit) running Linux with NX and ASLR enabled, I would exploit this using GOT-overwrite technique, which essentially includes the following steps:

  1. Overflow buffer till RIP
  2. Overwrite RIP with the address of strcpy@plt
  3. Use a clean gadget from .text, e.g. pop edi ; pop ebp ; ret, as return address for strcpy
  4. Write arguments for strcpy: &bss-address as destination and one byte of /bin/sh using .text
  5. Repeat steps 2-4 until /bin/sh is completely written to &bss
  6. Overwrite GOT-entry of strcpy with system (using offset, requires knowledge about the used version of Libc - let's ignore this here)
  7. Write strcpy@plt on the stack, followed by some 4-byte chunk and finally address of &bss which points to /bin/sh
  8. Profit

I want to exploit this on x86-64 with the same mitigation measures enabled. But this is more difficult as imagined. Basically for the following reasons:

  1. x86-64 register-based calling convention: Function arguments are passed using registers, not the stack. Therefore some additional ROP-gadgets are required to transfer the arguments from the stack into the appropriate register. This is a minor problem, but is also affected by the following problem:
  2. 64-bit return address: The RIP in x86-64 points to .text which is not even 32-bit long. Therefore NULL-bytes must be written on the stack to chain function calls. Basically one can write as much NULL-bytes as desired using chained calls to strcpy and taking advantage of the NULL-terminating character strcpy always writes. But one may only call strcpy once by only overwriting the least significant bytes of the RIP.

    |0x00000000|        (most significant bytes)
    |0x00deadbe| <- RIP (least significant bytes)
    |0x41414141|
    |0x41414141| <- SFP
    |   ...    | 
    

These are the major problems I got with exploiting the program on x86-64 with NX and ASLR enabled. Are there any techniques which solve these problems? Or does x86-64 really prevent a working, shell-opening exploit?

回答1:

x86-64 does not prevent these type of exploits. See this tutorial.