Consider the following vulnerable code / program:
#include <string.h> int main(int argc, char *argv[]) { char buf[16]; strcpy(buf, argv[1]); return 0; }
In IA-32 (x86, 32-bit) running Linux with NX and ASLR support, I would use this using the GOT-overrite method, which essentially involves the following steps:
- Overflow buffer before rip
- Overwrite RIP with
strcpy@plt - Use a clean gadget from
.text , for example. pop edi ; pop ebp ; ret pop edi ; pop ebp ; ret , as the return address for strcpy - Enter arguments for
strcpy : &bss address as the destination and one byte /bin/sh with .text - Repeat steps 2-4 until
/bin/sh is completely written to &bss - Overwrite the GOT record of
strcpy with system (using the offset, knowledge of the version of Libc used is required - let it be ignored here) - Write
strcpy@plt &bss stack, followed by a 4-byte snippet, and finally the address &bss , which points to /bin/sh - Profit
I want to use this on x86-64 with the same mitigation measures enabled. But it is more complicated than expected. Mainly for the following reasons:
- x86-64 case-based conditional agreement : function arguments are passed using registers, not the stack. Therefore, some additional ROP gadgets are required to transfer arguments from the stack to the appropriate register. This is a small issue, but it is also affected by the following issue:
64-bit return address . RIP on x86-64 points to .text , which is not even 32-bit. Therefore, NULL bytes must be written to the stack for a chain of function calls. In principle, you can write as many NULL bytes as needed using the second calls to strcpy and using the NULL-terminating strcpy always character. But you can only call strcpy once, only by overwriting the least significant RIP bytes.
|0x00000000| (most significant bytes) |0x00deadbe| <- RIP (least significant bytes) |0x41414141| |0x41414141| <- SFP | ... |
These are the main problems that I encountered when using the x86-64 program with support for NX and ASLR. Are there any methods that solve these problems? Or does x86-64 really prevent a shell exploit exploit?
source share