Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stacks are executable even with `noexecstack`

I'm trying to protect my application against buffer overflow exploits. Among other things, I'm using non-executable stacks and link my binaries with the noexecstack flag (by passing -Wl,-z,noexecstack to gcc).

Everything seems fine - readelf confirms that PT_GNU_STACK specifies correct permissions:

$ readelf -l target | grep -A1 GNU_STACK
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     10

So does execstack:

$ execstack -q target
- target

There's only one problem. All my stacks are actually executable:

root@170ubuntu16p04-64smp-1:~# cat /proc/12878/task/*/maps | grep stack
7ffcac654000-7ffcac675000 rwxp 00000000 00:00 0                          [stack]
7fe540e66000-7fe541666000 rwxp 00000000 00:00 0                          [stack]
7fe540665000-7fe540e65000 rwxp 00000000 00:00 0                          [stack]
7fe53b800000-7fe53c000000 rwxp 00000000 00:00 0                          [stack]

I've trapped allocate_stack calls and examined protection flags. In theory, they should be initialized according to PT_GNU_STACK. But in my case, it seems like PT_GNU_STACK was ignored and _dl_stack_flags was initialized with default permissions.

Does anyone know what could have caused this? Everything seems correct, but stacks are still executable.

I'm using gcc 4.8.3 / glibc 2.11.

like image 642
Nikita Kakuev Avatar asked Nov 17 '16 14:11

Nikita Kakuev


People also ask

Is the stack executable?

The stack is, naturally, readable, writeable and executable - not of much use otherwise. As far as I know we use the stack for data and code addresses (functions and their parameters/variable).

Why is stack non-executable?

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.

What does executable stack mean?

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.

How do I make a non-executable stack?

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.


1 Answers

what could have caused this?

In addition to the main executable's PT_GNU_STACK having correct permissions, you also need to have PT_GNU_STACK with correct permissions in every directly-linked shared library.

If any one of these libraries does not have PT_GNU_STACK at all, or has one with executable permissions, it will "poison" all of your stacks with executable permission.

So run

for j in $(ldd target | grep -o '=> .* ' | sed -e 's/=> //' -e '/^ *$/d' ); do
  out=$(readelf -Wl $j | grep STACK)
  [[ -z "$out" ]] &&  echo "missing GNU_STACK in $j"
  echo $out | grep -q RWE && echo "executable GNU_STACK in $j"
done

and you will likely see at least one library with missing or executable stack.

P.S. I see that Olaf has already (partially) suggested this.

like image 108
Employed Russian Avatar answered Sep 28 '22 07:09

Employed Russian