WHY does this shellcode program launch a segmentation warning?

advertisements

This question is an exact duplicate of:

  • WHY does this assembly code issue segmentation fault warning?

The code of the c program is shown below, and what it is supposed to do is running the opcode in a char array, which in turn would spawn a shell.

/* call_shellcode.c */
/*A program that creates a file containing code for launching shell*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
const char code[] =
"\x31\xc0" /* Line 1: xorl %eax,%eax */
"\x50" /* Line 2: pushl %eax */
"\x68""//sh" /* Line 3: pushl $0x68732f2f */
"\x68""/bin" /* Line 4: pushl $0x6e69622f */
"\x89\xe3" /* Line 5: movl %esp,%ebx */
"\x50" /* Line 6: pushl %eax */
"\x53" /* Line 7: pushl %ebx */
"\x89\xe1" /* Line 8: movl %esp,%ecx */
"\x99" /* Line 9: cdq */
"\xb0\x0b" /* Line 10: movb $0x0b,%al */
"\xcd\x80" /* Line 11: int $0x80 */
;
int main(int argc, char **argv)
{
char buf[sizeof(code)];
strcpy(buf, code);
((void(*)( ))buf)( );
}

The shellcode(the opcode contained in the char array) itself runs perfectly when written in assembly and compiled by assembler, and I got the opcode from disassembling the executable file compiled by assembler.

WHY is it not working when it's put inside this C program?


Your assembly code is called as a function. Your compiler will most likely generate a call instruction to call the function. Thus the return address will be on the stack. Since your assembly doesn't contain a ret instruction to pop this off and return back to the caller, after the last instruction in your assembly code, your program will try to execute whatever is located right after it. This is what is causing the segmentation fault. Add a ret instruction at the end of the assembly to solve it.

EDIT: After inspecting your assembly a little more thoroughly. You seem to use string literals within your assembly as well. But since you're already executing the program (no assembler will look at it no more), these will not be converted to addresses of a string. So replace the /bin and /sh in your assembly with the addresses of the actual string.