My (certainly incomplete) understanding of a remote system compromise on the binary code level is roughly:
- A program vulnerability, such as missing input validation, is exploited to insert external shellcode into the target system.
- Program flow is diverted to execute the shellcode, e.g. by overwriting return addresses on the call stack.
- The attacker can now execute arbitrary code on the target system with the privileges of the compromised process.
Let's assume that system level protection mechanisms are in place, in particular:
- All data segments are non-executable
- All code segments are marked as read-only
- Code is built with hardening flags, such as stack protector, input size checking etc.
How is it still possible to obtain control of the target process (via a machine code level attack) under these conditions? How can shellcode be executed when code segments can't be modified and data segments cannot be executed?