While studying the Linux kernel, I just found out that, by default, an executable has an 'executable' stack area. I naturally thought the only (necessary) executable area is the text section. Is there any historical reason related to this, or any practical usage?
DESCRIPTION top. execstack is a program which sets, clears, or queries executable stack flag of ELF binaries and shared libraries. Linux has in the past allowed execution of instructions on the stack and there are lots of binaries and shared libraries assuming this behaviour.
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. But this technique is not really worthy against return to lib attacks, although they do not need executable stacks.
Executable stack is necessary in some cases such as GCC trampoline for nested functions. A trampoline is a small piece of code that is created at run time when the address of a nested function is taken. It normally resides on the stack, in the stack frame of the containing function.
Non-executable stack. Buffer overflow exploits often put some code in a program's data area or stack, and then jump to it. If all writable addresses are non-executable, such an attack is prevented.
Executable stack is necessary in some cases such as GCC trampoline for nested functions.
A trampoline is a small piece of code that is created at run time when the address of a nested function is taken. It normally resides on the stack, in the stack frame of the containing function. These macros tell GCC how to generate code to allocate and initialize a trampoline.
In most distros because of attack risks and use of stack to execute a shellcode this functionality is disables, although you can compile a code with -z execstack
to enable it. It's also possible to use a program called execstack
to enable or disable this feature after compiling the program. To make this clear I wrote a simple program to execute exit
syscall with the exit code of 32. If this feature is enabled the code works, otherwise it gives segmentation fault.
#include <stdlib.h>
#include <unistd.h>
char shellCode[] = "\xb8\x01\x00\x00\x00" // mov $0x1,%eax
"\xbb\x20\x00\x00\x00" // mov $0x20,%ebx
"\xcd\x80"; // int $0x80
int main(){
int *ret;
ret = (int*) &ret + 2;
*ret = (int) shellCode;
return 5;
}
In this code ret
is pointing to it's address plus 2. As we know in IA32 systems pointer size is 4bytes and at the beginning of each function there is a push ebp
after compilation. So in order to reach return address of main
we need to add 2*stack_chunk_size
and by setting each chunk 4byte at compile time this works perfectly.
Compile the code like this to test:
gcc -mpreferred-stack-boundary=2 -z execstack -o testShellCode testShellCode.c
-mpreferred-stack-boundary=2
is to align stack in 4 bytes chunks and -z execstack
is to compile using executable stack.
This simple code can give some insight into the reason why there is such a thing as executable stack protection.
Look up the following links for more information on nested functions and execstack
command:
Trampolines
execstack
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