Hello, I am an Engineering Manager at Facebook with 13+ years in Ad Technology, Natural Language Processing and Data mining. (Learn More)
by Pravin Paratey

Anonymous ftp scanner

Scans for anonymous ftp hosts in an IP range. To compile, gcc fatap.c -o fatap.

/* Pravin Paratey (November 02, 2002)
 * Searches for anonymous ftp servers in the given range
 * Range can be of the form 10.2.0-3.*
 * Wildcards * and range modifier - allowed
**/

#include <sys/socket.h>
#include <sys/types.h>
#include <resolv.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>

#define TIMEOUT 4
#define MAX_THREADS 5
extern int errno;

/* this will handle timeouts */
struct sigaction action;
/* Stores the current ip, stderr and alarm problem had to make it global:( */
char conString[20];

int numThreads; // Stores the number of threads
pthread_cond_t threadFree; // Tells if the no of running threads < MAX_THREADS
pthread_mutex_t threadLock; // Mutex which is locked while changing numThreads


void tryConnect (void *address);
void fillIP (char *string, int array[4]);
void timedOut();

int main(int argc, char *argv[])
{
    int start[4], end[4]; // IP addresses
    char *pStart, *pEnd;
    int count;
    int i,j,k,l;
    char *bigline="-------------------------------------------------------------------";
    pthread_t daThread;


    if (argc < 3) {
        printf ("Usage: %s <start-ip-address> <end-ip-address>\n \
<*ip-address> is of the form x.x.x.x where x is between 0 and 255 both inclusive.\n \
eg. 10.2.1.27\n", argv[0]);
        exit(2);
    }

    printf("%s\n fatap v0.2a - A proggy which scans an ip range for open ftp ports\n\
 By Pravin Paratey (pravin@iitb.ac.in)\n%s\n", bigline, bigline);

    /* Get the start ip address */
    fillIP (argv[1], start);

    /* Get the end ip address */
    fillIP (argv[2], end);

    /* Check if the ranges are correct */
    if (!(start[0] <= end[0] && start[1] <= end[1] &&
        start[2] <= end[2] && start[3] <= end[3])) {
        fprintf(stderr, "%s: Invalid range specified\n", argv[0]);
        exit(2);
    }


    /* Some alarm related stuff */
    action.sa_handler = timedOut;
    action.sa_flags = 0;
    /* Set sigaction for alarm timeout */
    sigaction (SIGALRM, &action, 0);

    /* Initialise threads */
    pthread_mutex_init(&threadLock, NULL);
    pthread_cond_init(&threadFree, NULL);
    numThreads = 0;

    /* Iterate */
    for (i=start[0]; i <= end[0]; i++) {
        for (j=start[1]; j <= end[1]; j++) {
            for (k=start[2]; k <= end[2]; k++) {
                for (l=start[3]; l <= end[3]; l++) {
                    sprintf(conString, "%i.%i.%i.%i",i,j,k,l);
                    if (numThreads > 5) {
                        pthread_cond_wait (&threadFree, &threadLock);
                    }
                    pthread_create(&daThread, NULL, tryConnect, (void*) conString);
                    pthread_mutex_lock(&threadLock);
                    numThreads++;
                    pthread_mutex_unlock(&threadLock);
                    start[3] = start[2] = start[1] = 0;
                }
            }
        }
    }
    pthread_cond_destroy(&threadFree);
    pthread_mutex_destroy(&threadLock);
    return 0;
}

void fillIP (char *string, int array[4])
{
    int count;
    char *pStart, *pEnd;

    count=0;
    pStart = pEnd = string;
    while (*pEnd != 0) {
        if (*pEnd == '.') {
            *pEnd = 0;
            array[count++] = atoi(pStart);
            pStart = pEnd+1;
        }
        *pEnd++;
    }
    array[count] = atoi(pStart);
}

void tryConnect (void *address)
{
    /* Some variables */
    int sock1;
    struct sockaddr_in sa1;
    char inbuf[1000];
    char outbuf[100];
    int retval;

    /* Create socket */
    sock1 = socket (AF_INET, SOCK_STREAM, 0);
    if (sock1 == -1) {
        perror(address);
        exit(1);
    }

    sa1.sin_family = AF_INET;
    sa1.sin_port = htons(21);
    inet_aton (address, &sa1.sin_addr.s_addr);

    /* Set timeout */
    //alarm(TIMEOUT);

    /* Connect to server and see if alive */
    if (connect (sock1,(struct sockaddr *) &sa1, sizeof (sa1)) == -1) {
        if (errno != 4) // 4 - Interrupted system call (return from signal)
            fprintf(stderr, "[%s] %s\n",address, strerror(errno));
    }
    else {
        sprintf(outbuf, "USER anonymous\r\n");
        if(send(sock1, outbuf, sizeof(outbuf), 0) == -1)
            goto CLOSECON;
        retval = recv(sock1, inbuf, 1000, 0);
        if(retval == -1)
            goto CLOSECON;
        if(send(sock1, "\r\n",2,0) == -1)
            goto CLOSECON;
        retval = recv(sock1, inbuf, 1000, 0);
        sprintf(outbuf,"PASS unknown@unknown.com\r\n");
        if(send(sock1, outbuf, sizeof(outbuf), 0) == -1)
            goto CLOSECON;
        retval = recv(sock1, inbuf, 1000, 0);
        if(send(sock1, "\r\n",2,0) == -1)
            goto CLOSECON;
        retval = recv(sock1, inbuf, 1000, 0);

        sscanf(inbuf, "%i %s*",&retval);
        printf("***%i\n",retval);
        if(retval == 230 || retval == 220)
            printf("[%s] Anonymous allowed\n", address);
        else
            printf("[%s] Anonymous NOT allowed\n", address);
        send(sock1, "QUIT\r\n", sizeof("QUIT\r\n"), 0);
        recv(sock1, inbuf, 1000, 0);
    }
    /* Reset alarm */
    //alarm(0);
CLOSECON:
    close(sock1);
    pthread_mutex_lock(&threadLock);
    numThreads--;
    pthread_cond_signal(&threadFree);
    pthread_mutex_unlock(&threadLock);
    pthread_exit(0);
}

void timedOut()
{
    fprintf(stderr,"[%s] Connection timed out\n", conString);
}