/* Yet Another Wingate Scanner (YAWS) Version 0.1 (C) 1999 by tempus fugit, tempusf@gmx.net URL: tf.darpa.org You can freely distribute this stuff, but please let the copyright information intact and don't alter the code. Feel free to send my any comments or suggestions Features: - can read the hosts to check from a file - can scan subnets (class b and c) - has an extra flag to prevent intrusion detection systems from being activated - logs the results - logs successes in an extra file - you can enter the number of subprocesses - you can specify a timeout compile with gcc yaws.c -o yaws */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define wgateport 23 void CheckForWingate (char *,int); void init_rand (); void DoLog (char *); void LogSuccess (char *); void usage (); int sock, timeout=5; char *logfile="yaws.log", *suclogfile="yaws.suc", *progname; int main (int argc, char **argv) { static int forked=0; int forks=1, i, pid, dummy, scanned=0, toscan=0, j, k, extra=0, rnumber; char c, network[64]="none", class[]="z", inputfile[64]="", host[100]; FILE *input; typedef char target[100]; target *mytarget; progname=argv[0]; while ((c = getopt (argc, argv, "vef:l:n:c:i:t:s:")) != -1) { switch (c) { case 'f': forks = atoi (optarg); break; case 'e': extra = 1; break; case 'l': logfile = optarg; break; case 'n': strncpy (network, optarg, 64); break; case 'c': strncpy (class, optarg, 1); break; case 'i': strncpy (inputfile, optarg, 64); break; case 't': timeout = atoi (optarg); break; case 's': suclogfile = optarg; break; case 'v': usage (); case '?': usage (); } } if (argc < 2) { fprintf (stderr, "To few argumtens.\n"); usage (); } if (forks < 1) { fprintf (stderr, "To little number of forks.\n"); usage (); } DoLog ("YAWS 1999 by tempus fugit\n\n"); if ((strcmp (network, "none")) && (strcmp (class, "z"))) { if ((!strcmp (class, "b")) && (extra == 0)) { for (j=1; j<255; j++) { for (k=1; k<255; k++) { snprintf (host, 100, "%s.%d.%d", network, j, k); if ((pid = fork ()) == 0) { CheckForWingate (host, wgateport); kill(getpid(),9); } if (pid != 0) { forked++; if (forked >= forks) { wait (&dummy); forked--; } } } } } else if ((!strcmp(class, "c")) && (extra == 0)) { for (j=1; j<255; j++) { snprintf (host, 100, "%s.%d", network, j); if ((pid = fork ()) == 0) { CheckForWingate (host, wgateport); kill(getpid(),9); } if (pid != 0) { forked++; if (forked >= forks) { wait (&dummy); forked--; } } } } else if ((!strcmp(class, "b")) && (extra == 1)) { init_rand(); mytarget = malloc ((254*254) * (sizeof (target))); if (mytarget == NULL) { fprintf (stderr, "Cannot allocate memory.\n"); exit (1); } fprintf (stdout, "I am computing the random IPs, this may take a while.\n"); for (j=1; j<255; j++) { for (k=1; k<255; k++) { marke: rnumber = (int) ((254.0*254.0)*rand()/(RAND_MAX+1.0)); if (strlen ((mytarget+rnumber)) > 1) goto marke; snprintf ((mytarget+rnumber), 100, "%s.%d.%d", network, j, k); } } for (j=0; j<=(254*254); j++) { if ((pid = fork ()) == 0) { CheckForWingate ((mytarget+j), wgateport); kill(getpid(),9); } if (pid != 0) { forked++; if (forked >= forks) { wait (&dummy); forked--; } } } } else if ((!strcmp(class, "c")) && (extra == 1)) { init_rand(); mytarget = malloc ((255) * (sizeof (target))); if (mytarget == NULL) { fprintf (stderr, "Cannot allocate memory.\n"); exit (1); } for (j=1; j<255; j++) { marke2: rnumber = 1+(int) ((254.0)*rand()/(RAND_MAX+1.0)); if (strlen ((mytarget+rnumber)) > 1) goto marke2; snprintf ((mytarget+rnumber), 100, "%s.%d", network, j); } for (j=1; j<255; j++) { if ((pid = fork ()) == 0) { CheckForWingate ((mytarget+j), wgateport); kill(getpid(),9); } if (pid != 0) { forked++; if (forked >= forks) { wait (&dummy); forked--; } } } } else { if ((class != "b") && (class != "c")) { printf ("You entered an unknown class or no network.\n"); return 1; } } for (i=1; i <= forked; i++) wait (&dummy); return 0; } input = fopen (inputfile, "r"); if (input == NULL) { fprintf (stderr, "Cannot open input file.\n"); return 1; } while ((fscanf (input, "%s\n", host)) != EOF) { if ((pid = fork ()) == 0) { CheckForWingate (host, wgateport); kill(getpid(),9); } if (pid != 0) { forked++; if (forked >= forks) { wait (&dummy); forked--; } } } fclose (input); for (i=1; i <= forked; i++) wait (&dummy); } void alarm_handler (int sig) { close (sock); return; } void CheckForWingate (char *host, int port) { int ret, conn, sel; char buffer[128], logmsg[1024]; struct sockaddr_in sin; fd_set fd; struct timeval tv; struct hostent *he; if ((strlen (host)) == 0) exit (1); if (!(sock = socket (AF_INET, SOCK_STREAM, 0))) { fprintf (stderr, "Cannot create a socket.\n"); exit (1); } if (inet_addr (host) == -1) { if ((he=gethostbyname (host)) == NULL) { snprintf (logmsg, 1024, "The host %s cannot be resolved.\n", host); DoLog (logmsg); return; } memcpy (&sin.sin_addr, he->h_addr,he->h_length); } else if ((sin.sin_addr.s_addr = inet_addr (host)) == -1) { snprintf (logmsg, 1024, "IP %s cannot be identified.\n", host); DoLog (logmsg); return; } sin.sin_family = AF_INET; sin.sin_port = htons (port); signal (SIGALRM, alarm_handler); alarm (timeout); conn = connect (sock, (struct sockaddr*)&sin, sizeof (sin)); if (conn < 0) { snprintf (logmsg, 1024, "Cannot connect to host %s on port %d.\n", host, port); DoLog (logmsg); close (sock); return; } FD_ZERO (&fd); FD_SET (sock, &fd); tv.tv_sec = timeout; tv.tv_usec = 0; sel = select (sock+1, &fd, NULL, NULL, &tv); if (sel > 0) { if ((ret = recv (sock, buffer, 128, 0)) > 0) { if (!strcmp (buffer, "WinGate>")) { snprintf (logmsg, 1024, "Host %s is a wingate.\n", host); DoLog (logmsg); LogSuccess (logmsg); } else { snprintf (logmsg, 1024, "Host %s is no wingate.\n", host); DoLog (logmsg); } } } if (!sel) { snprintf (logmsg, 1024, "Host %s time out by search.\n", host); DoLog (logmsg); } if (sel == -1) { fprintf (stderr, "Select Error.\n"); exit (1); } close (sock); return; } void init_rand() { int fd; unsigned n; fd = open("/dev/random", O_RDONLY); read(fd, &n, sizeof(n)); close(fd); srand(n); } void DoLog (char *message) { FILE *file; file = fopen (logfile, "a"); if (file == NULL) { fprintf (stderr, "File Error.\n"); exit (1); } fprintf (file,"%s", message); fclose (file); } void LogSuccess (char *message) { FILE *file; file = fopen (suclogfile, "a"); if (file == NULL) { fprintf (stderr, "File Error.\n"); exit (1); } fprintf (file, "** SUCCESS: ** "); fprintf (file, "%s", message); fclose (file); } void usage () { printf ("[YAWS] Yet Another Wingate Scanner Version 0.1 1999 by tempus fugit\n"); printf ("mail: tempusf@gmx.net\n"); printf ("URL: http://tf.darpa.org\n\n"); printf ("Usage: %s -v -l -f -t -n -c -i -s \n", progname); printf ("\tlogfile: the name of the file where the scanning results are stored.\n"); printf ("\tforks : the number of forks the program is allowed to create.\n"); printf ("\ttimeout: timeout of search-process in seconds.\n"); printf ("\tnetwork: you can enter network that will be checked for wingates.\n"); printf ("\tnetwork: can be or if class is\n"); printf ("\t b or c\n"); printf ("\tinput-file: you can specify an input-file from which the hosts to checked are extraced.\n"); printf ("\tsuccess-logfile: success messages are written in this file.\n"); printf ("\tif you choose an input-file, the network and class options are ignored.\n"); printf ("Example: %s -l mylogs -n 200.10 -c b -s wow\n", progname); exit (0); }