Can't execute Shellcode --> (Speicherzugrif

2019-02-16 00:37发布

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\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f";

int main(int argc, char **argv)
{
  int (*func)();
  func = (int (*)()) code;
  (int)(*func)();
}

(this code is from: shellcode tutorial)

so i compiled and execute it, but i only get this message: Speicherzugriffsfehler (Speicherabzug geschrieben).

Why i don't get something back, only this error message?

p.s.: my system is an ubuntu x86 pc. the shellcode should work with it. i compiled it with gcc and with gcc-4.5, both same error...

标签: c gcc shellcode
2条回答
Animai°情兽
2楼-- · 2019-02-16 01:15

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

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-02-16 01:17

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;
}
查看更多
登录 后发表回答