i have this function:
char code[] = \"\\xeb\\x19\\x31\\xc0\\x31\\xdb\\x31\\xd2\\x31\\xc9\\xb0\\x04\\xb3\\x01\\x59\\xb2\\x05\\xcd\\x80\\x31\\xc0\\xb0\\x01\\x3
Your code
variable is an array that's part of your program's initialized data (.data
) segment. When your program is loaded by the OS, the loader reads and executes the load commands from your executable file. One of those commands is "load the following data (a segment named .data
) into memory".
Ordinarily, the .data
segment is loaded as a non-executable segment, meaning that the memory there cannot be executed. Therefore, if you try to execute code from there by jumping to it, like you did, then it will crash with a segmentation fault.
There are a couple of ways to work around this. You can tell the linker to make the .data
segment executable (not a good idea). You can tell the compiler to put the code
variable into the .text
segment instead (the segment used for all of your program's regular code). You can tell the compiler and linker to make a new executable segment and put code
into that. All of these are tricky.
The best solution, is to specifically allocate your own executable memory at runtime and copy the shellcode into that. That completely avoids any potential compiler/linker issues, although it does add a small runtime penalty. But some OSes don't allow memory to be both writable and executable at the same time; so you'd first have to make it writable, copy the shellcode in, and then make it executable.
The way you control memory permissions at runtime is with the mprotect(2) call. So here's a good way to do it:
#include <string.h>
#include <sys/mman.h>
char shellcode[] = "\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x05\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f";
// Error checking omitted for expository purposes
int main(int argc, char **argv)
{
// Allocate some read-write memory
void *mem = mmap(0, sizeof(shellcode), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
// Copy the shellcode into the new memory
memcpy(mem, shellcode, sizeof(shellcode));
// Make the memory read-execute
mprotect(mem, sizeof(shellcode), PROT_READ|PROT_EXEC);
// Call the shellcode
int (*func)();
func = (int (*)())mem;
(int)(*func)();
// Now, if we managed to return here, it would be prudent to clean up the memory:
munmap(mem, sizeof(shellcode));
return 0;
}
By default gcc will compile applications as having nonexecutable stacks. What you're seeing is a segmentation violation because your stack is marked nonexecutable but you're trying to execute code on the stack. You can verify by running your application in gdb and checking where it dies, for instance:
=> 0x601060 : jmp 0x60107b
This is the entry point of your shellcode. To make it so it doesn't segfault, you can disable exectstack by doing the following:
gcc -z execstack source.c