(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);
}