-1

There is something that puzzles me about the behaviour of the following code (SMP Debian 4.19.260-1 (2022-09-29) x86_64 GNU/Linux):

#include <stdio.h>
const char
shellcode[]="\xb8\×01\×00\x00\x00\×48\xbe\×48\×65\×6c\x6c\×6f\×00\×00\×00\×56\×48\x89\xe6\xba\x05\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\x0f\x05";
int main(){
    (*(void (*) ()) shellcode)();
    return 0;
}

When I execute the program by the debugger I see that the code executed after the cast of the array to a function is located where one expects to see it, that is, in the initialized globals area (since it is defined as such). In other words the code is very low in the process address space and definitely not on the stack.

Nevertheless, to actually run the code without receiving a SIGSEGV, one must compile it with the executable stack option -z execstack. How come this happens if the code is NOT on the stack?

Update:

I used these commands:

$ gcc testshellcode.c -o testshellcode
$ ./testshellcode
Segmentation fault

$ gcc -z execstack testshellcode.c -o testshellcode
$ ./testshellcode
Hello

I am using gcc (Debian 8.3.0-6) 8.3.0.

Solution found: The execstack flag makes all the pages in memory executable, not just those of the stack. See:

Why is execstack required to execute code on the heap?

Exactly what cases does the gcc execstack flag allow and how does it enforce it?

diciotto
  • 69
  • 3

1 Answers1

0
  1. The code you pasted is not valid:
 shellcode[]="\xb8\<U+00D7>01\<U+00D7>00...

These are supposed to be \x, not .

  1. On my system, compiling this with gcc t.c -Wl,-z,execstack still crashes. That is because the const char ... is put into .rodata section, which goes into a read-only segment (which isn't executable).

You should a) show the exact compile / link commands you used and b) show the version of the compiler you used for a more thorough answer.

Also take a look at readelf -Wl ./a.out to see what the segment permissions are -- chances are your .rodata ends up in a segment with no execute permissions.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Right from the machine whose specifications I reported above. As you can see the code compile and execute all right (with the Segmentation fault when compiled with a non executable stack) – diciotto Mar 01 '23 at 14:28
  • $ cat testshellcode.c #include const char shellcode[]="\xb8\x01\x00\x00\x00\x48\xbe\x48\x65\x6c\x6c\x6f\x00\x00\x00\x56\x48\x89\xe6\xba\x05\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\x0f\x05\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x44\x00\x00"; int main(){ (*(void (*)()) shellcode)(); return 0; } $ gcc testshellcode.c -o testshellcode $ ./testshellcode Segmentation fault $ gcc -z execstack testshellcode.c -o testshellcode $ ./testshellcode Hello$ – diciotto Mar 01 '23 at 14:29
  • @diciotto Please edit your question with the exact commands (instead of using comments). Also the "machine specification" in the question is meaningless -- it's a kernel version. You can have 10 different versions of GCC running on the _same_ kernel. – Employed Russian Mar 01 '23 at 14:44
  • I tried to format the comment but I didn't succeed and after a while modifications were forbidden. Anyway the compiler is gcc (Debian 8.3.0-6) 8.3.0 – diciotto Mar 01 '23 at 15:47
  • @diciotto You shouldn't put _any_ of this into comments -- you can _edit_ your _question_ with additional info instead. – Employed Russian Mar 01 '23 at 17:31