I read a book about buffer overflow, and it suggest the next to deal with:
Making the stack (and heap) non-executable provides a high degree of protection against many types of buffer overflow attacks for existing programs.
But I don't understand how we can do it - where the execute would take place, if not on the heap or on the stack?
If we mark the stack and heap segement as non executable,1.No code will execute.
Non-executable stack (NX) is a virtual memory protection mechanism to block shell code injection from executing on the stack by restricting a particular memory and implementing the NX bit.
By setting the NX bit, parts of the stack can be designated as non-executable which would mean that in order to execute shellcode from the stack an attacker must either find a way to disable the execution protection from memory or find a way to put her/his shellcode payload in a non-protected region of memory.
Heap allocations made by calling the malloc and HeapAlloc functions are non-executable. Applications cannot run code from the default process heap or the stack.
If we mark the stack and heap segement as non executable, 1.No code will execute. 2.return-oriented programming will also not be able to exploit it. 3.we can prevent overflow code execution. 4.All of the above. See what the community says and unlock a badge.
But some unix variants make the heap space non-executable, so as to make exploits of some security vulnerabilities such as buffer overflows more difficult (then even if you can inject code into a program, you might not be able to branch to it). (See the linked article for a discussion of unix variants and their configuration.)
1 In a stack, the allocation and deallocation are automatically done by whereas, in heap, it needs to be done by the programmer manually. 2 Handling of Heap frame is costlier than the handling of the stack frame. 3 Memory shortage problem is more likely to happen in stack whereas the main issue in heap memory is fragmentation. Più articoli...
Note that the name heap has nothing to do with heap data structure. It is called heap because it is a pile of memory space available to programmers to allocated and de-allocate. If a programmer does not handle this memory well, memory leak can happen in the program.
If I understand your question correctly, none of the other answers address it. The answer is that execution occurs in the code section, which is neither stack nor heap. In a typical paged memory system, the code from a program file (e.g., a .exe in Windows) is loaded into executable but read-only pages. Additional writable (and executable) pages are allocated to the process for the stack and heap. The suggestion here is that the operating system and hardware should cooperate to mark those pages writable but not executable (rgngl's answer explains how to do that in Windows).
Even with non-executable heap and stack, exploits are still possible that use the return-oriented programming mentioned in Alexey Frunze's answer, but there are protection techniques that stymie even those, such as stack-smashing protection and address space layout randomization -- see http://en.wikipedia.org/wiki/Return-to-libc_attack#Protection_from_return-to-libc_attacks
There's what's called "return-oriented programming" (AKA ROP) type of exploits.
The attacker finds how to make his evil code out of different pieces of the program that's being exploited.
He finds usable byte sequences (instructions) before the return instruction byte(s) that can do useful operations on registers or memory like move a value to a location, add values, compare values, etc etc. Those are micro subroutines that the exploit gets built of.
Then by exploiting a code bug the attacker forces the program to start executing the chain of those micro subroutines that does all the evil work.
So, now good code turns into evil code. Nothing's executed on the stack or in the heap.
It's also noteworthy that on CPUs where instructions span multiple bytes and are of variable length, even the immediate instruction operands (IOW, numerical constants) that are part of instructions can become code, and so the chances of finding usable byte sequences are higher there than on "simpler" CPUs.
It's also often possible to construct malicious code that will change memory protection and the exploit will no longer be constrained by the existing application's code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With