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:
- Overflow buffer till RIP
- Overwrite RIP with the address of
strcpy@plt - Use a clean gadget from
.text, e.g.pop edi ; pop ebp ; ret, as return address forstrcpy - Write arguments for
strcpy:&bss-address as destination and one byte of/bin/shusing.text - Repeat steps 2-4 until
/bin/shis completely written to&bss - Overwrite GOT-entry of
strcpywithsystem(using offset, requires knowledge about the used version of Libc - let's ignore this here) - Write
strcpy@plton the stack, followed by some 4-byte chunk and finally address of&bsswhich points to/bin/sh - 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:
- 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:
64-bit return address: The RIP in x86-64 points to
.textwhich 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 tostrcpyand taking advantage of the NULL-terminating characterstrcpyalways writes. But one may only callstrcpyonce 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?