-1

I am trying to learn shell-code and I keep getting a segmentation fault in my Ubuntu box.

/*shellcodetest.c*/ 
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\xe8\xd8\xff\xff\xff"\
        "\x68\x65\x6c\x6c\x6f\xe8\xce\xff\xff\xff\x68\x65\x6c\x6c"\
        "\x6f\xe8\xc4\xff\xff\xff\x68\x65\x6c\x6c\x6f\xe8\xba\xff"\
        "\xff\xff\x68\x65\x6c\x6c\x6f";
int main(int argc, char **argv)
{
    int (*func)();
    func = (int (*)()) code;
    (int)(*func)();
}

I don't understand why this fails. I was thinking maybe a null-pointer. if you have any idea that i can follow up on that would be great.

Dennis Hayden
  • 184
  • 1
  • 5
  • 15

4 Answers4

3

OK, lets examine your code now.

char code[]="\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01"\

The above line creates a global character array called code and has been initialized with a bunch of hex. The memory for char[] will be allocated in data-segment.

int (*func)();

The above line declares a pointer-to-a-function that takes no arguments and returns int. The memory for this will be allocated in stack but this variable is expected to point to a memory location which stores code

func = (int (*)()) code;

The above lines cast the code (global-character-array) and make func (pointer-to-a-function) to point to it! This action is an undefined behavior because a stack variable which is suppose to point to a code-segment is now made to point to data-segment.

Even if the assignment is successful (may be because of miracle) then de-referring them in the next line will definitely not expected to work!

For more information on how variables are allocated in heap, stack and code segment, please refer this

Community
  • 1
  • 1
Sangeeth Saravanaraj
  • 16,027
  • 21
  • 69
  • 98
  • Actually the shellcode will be allocated on the stack, not in the data segment, and the assignment should always work because it's just assigning pointers – Seth Carnegie Jan 03 '12 at 15:39
  • However, the stack might not be executable. The array, being global, might very well not be allocated on the stack though. – nos Jan 03 '12 at 22:22
2

This program invokes loads of undefined behavior, so, per standard, anything can happen. Segmentation fault is perfectly acceptable result for a program like this.

zvrba
  • 24,186
  • 3
  • 55
  • 65
1

You can directly define:

 int (*func)() = (int (*)()) "\xeb\x19\x31\xc0..."

and it'll work.

But it still's being undefined behavior.

Matías Marquez
  • 422
  • 2
  • 13
1

Not an answer but may help. I'm disassembling it on 64-bit Ubuntu. On 32-bit it will be different.

(gdb) disassemble /mr func,0x60108A
Dump of assembler code from 0x601040 to 0x60108a:
0x0000000000601040 <code+0>:     eb 19  jmp    0x60105b <code+27>
0x0000000000601042 <code+2>:     31 c0  xor    %eax,%eax
0x0000000000601044 <code+4>:     31 db  xor    %ebx,%ebx
0x0000000000601046 <code+6>:     31 d2  xor    %edx,%edx
0x0000000000601048 <code+8>:     31 c9  xor    %ecx,%ecx
0x000000000060104a <code+10>:    b0 04  mov    $0x4,%al
0x000000000060104c <code+12>:    b3 01  mov    $0x1,%bl
0x000000000060104e <code+14>:    59 pop    %rcx
0x000000000060104f <code+15>:    b2 05  mov    $0x5,%dl
0x0000000000601051 <code+17>:    cd 80  int    $0x80
0x0000000000601053 <code+19>:    31 c0  xor    %eax,%eax
0x0000000000601055 <code+21>:    b0 01  mov    $0x1,%al
0x0000000000601057 <code+23>:    31 db  xor    %ebx,%ebx
0x0000000000601059 <code+25>:    cd 80  int    $0x80
0x000000000060105b <code+27>:    e8 e2 ff ff ff callq  0x601042 <code+2>
0x0000000000601060 <code+32>:    68 65 6c 6c 6f pushq  $0x6f6c6c65
0x0000000000601065 <code+37>:    e8 d8 ff ff ff callq  0x601042 <code+2>
0x000000000060106a <code+42>:    68 65 6c 6c 6f pushq  $0x6f6c6c65
0x000000000060106f <code+47>:    e8 ce ff ff ff callq  0x601042 <code+2>
0x0000000000601074 <code+52>:    68 65 6c 6c 6f pushq  $0x6f6c6c65
0x0000000000601079 <code+57>:    e8 c4 ff ff ff callq  0x601042 <code+2>
0x000000000060107e <code+62>:    68 65 6c 6c 6f pushq  $0x6f6c6c65
0x0000000000601083 <code+67>:    e8 ba ff ff ff callq  0x601042 <code+2>
0x0000000000601088 <code+72>:    68 65 6c 6c 6f pushq  $0x6f6c6c65

It fails with SIGSEGV on the very first line:

(gdb) display /3i $pc
1: x/3i $pc
=> 0x601040 <code>: jmp    0x60105b <code+27>
0x601042 <code+2>:  xor    %eax,%eax
0x601044 <code+4>:  xor    %ebx,%ebx

May it fail because of jump into the data segment ?

LiMar
  • 2,822
  • 3
  • 22
  • 28