Multithreaded high speed scanner that scans for 6 different daemons, and records the version of every daemon for analysis. Courtesy of Mixter
079ae01a2da00d9398b7999c8fff4885d92b021fc74a2421ed49ce1ef25c600f
/* lscan2.c - 1999 (c) Mixter */
/* compile: gcc -O3 -s -Wall lscan2.c -o lscan */
#define INITIAL_TIMEOUT 5 // how long to wait for a connection
#define WAIT_FORK 550000 // wait 1/2 second between forks
#define BIND "ns.log"
#define POP "pop.log"
#define IMAP "imap.log"
#define RPC "mountd.log"
#define FTP "ftp.log"
#define STATUSLOG "status.log"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#define SSA sizeof(struct sockaddr)
#define SOX socket(AF_INET,SOCK_STREAM,0)
int s1,s2,s3,s4,s5;
int ncon(int tsock, char *ip, int port, int timeout);
void invoke(struct hostent *host, int port); // udp send
void usage(char *name, char *text); // print usage & die
int validip(char *ip); // check and correct ip address
void fchk(FILE *fp); // check a file
void timedout(int sig); // dummy function
int background(); // background a process
void scan0r(char *ip); // log services for one ip
char buf[75]; // read the first 75 chars from a server
int main(int argc,char **argv)
{
FILE *data,*err;
char ip[30];
int pid;
if((argc!=2)) usage(argv[0],"<ipfile>");
fprintf(stderr,"[0;34mlamerz scan 1.0 by [5mMixter[0m\n");
fprintf(stderr,"[0;34mscanning from %s (pid: %d)[0m\n"
,argv[1] ,(pid=background()));
signal(SIGHUP,SIG_IGN);
signal(SIGCHLD,SIG_IGN); // zombies suck
fchk(data=fopen(argv[1],"r"));
fchk(err=fopen(STATUSLOG,"a"));
fprintf(err,"Started new session. File: %s, PID: %d\n",argv[1],pid);
while(!feof(data))
{
fscanf(data,"%s\n",ip);
if(validip(ip)==1)
{
usleep(WAIT_FORK); // wait between fork()'s (1/2 second default)
if ((pid=vfork()) < 0) { perror("fork"); exit(1); }
if (pid==0) // child
{
scan0r(ip); // collect data for this host & save into files
raise(9);
return 0;
}
}
else fprintf(err,"Invalid IP: %s\n",ip);
}
sleep(60); // wait for the last childs
fprintf(err,"Finished session. File: %s\n",argv[1]);
return 0;
}
void scan0r(char *ip)
{
int tout=INITIAL_TIMEOUT,
s1=SOX,s2=SOX,s3=SOX,s4=SOX,s5=SOX,
bind,pop,imap,rpc,ftp;
FILE *f1,*f2,*f3,*f4,*f5;
fchk(f1=fopen(BIND,"a"));
fchk(f2=fopen(POP,"a"));
fchk(f3=fopen(IMAP,"a"));
fchk(f4=fopen(RPC,"a"));
fchk(f5=fopen(FTP,"a"));
rpc=ncon(s4,ip,635,tout); // we check port 635 because 2.2b29
// mountd always binds on that one
if(rpc==-9) return; // host timed out
else if(rpc>=0) fprintf(f4,"%s\n",ip); // log mountd connect
pop=ncon(s2,ip,110,tout);
if(pop==-9) return; // host timed out
else if(pop>=0)
{
bzero(buf,sizeof(buf));
read(s2,buf,sizeof(buf)); // get popper version
fprintf(f2,"%s %s\n",ip,buf); // log popper connect
}
pop=ncon(s2,ip,109,tout);
if(pop==-9) return; // host timed out
else if(pop>=0)
{
bzero(buf,sizeof(buf));
read(s2,buf,sizeof(buf)); // get popper version
fprintf(f2,"%s !POP2! %s\n",ip,buf); // log popper connect
}
imap=ncon(s3,ip,143,tout);
if(imap==-9) return; // host timed out
else if(imap>=0)
{
bzero(buf,sizeof(buf));
read(s3,buf,sizeof(buf)); // get imap version
fprintf(f3,"%s %s\n",ip,buf); // log imap connect
}
bind=ncon(s1,ip,53,tout);
tout -= 2; // wait 2 seconds less
if(bind==-9) return; // host timed out
else if(bind>=0) // log dns connect
fprintf(f1,"%s\n",ip);
ftp=ncon(s5,ip,21,tout);
if(ftp==-9) return; // host timed out
else if(ftp>=0)
{
bzero(buf,sizeof(buf));
read(s5,buf,sizeof(buf)); // get ftp version
fprintf(f5,"%s %s\n",ip,buf); // log ftp connect
}
fclose(f1); fclose(f2); fclose(f3); fclose(f4); fclose(f5);
raise(9);
return;
}
int ncon(int tsock, char *ip, int port, int timeout) {
int probe;
struct sockaddr_in target;
target.sin_family = AF_INET;
target.sin_port = htons(port);
target.sin_addr.s_addr = inet_addr(ip);
bzero(&target.sin_zero,8);
alarm(0); signal(SIGALRM,timedout); alarm(timeout);
probe = connect(tsock, (struct sockaddr *)&target, SSA);
alarm(0);
if(probe < 0) {
close(tsock);
if(errno == EINTR) return -9;
if(errno == ETIMEDOUT) return -9;
}
return probe;
}
void usage(char *name,char *text)
{
printf("usage: %s %s\n",name,text);
exit(EXIT_FAILURE);
}
int validip(char *ip)
{
int a,b,c,d,*x;
sscanf(ip,"%d.%d.%d.%d",&a,&b,&c,&d);
x=&a;
if(*x < 0) return 0; if(*x > 255) return 0;
x=&b;
if(*x < 0) return 0; if(*x > 255) return 0;
x=&c;
if(*x < 0) return 0; if(*x > 255) return 0;
x=&d;
if(*x < 0) return 0; if(*x > 255) return 0;
sprintf(ip,"%d.%d.%d.%d",a,b,c,d); // truncate possible garbage data
return 1;
}
void fchk(FILE *fp)
{
if(fp==NULL)
{
fprintf(stderr,"Error opening file or socket.\n");
exit(EXIT_FAILURE);
}
return;
}
void timedout(int sig)
{
alarm(0);
raise(9);
}
int background()
{
int pid;
signal(SIGCHLD,SIG_IGN);
pid = fork();
if(pid<0) return -1; // fork failed
if(pid>0)
{
sleep(1);
exit(EXIT_SUCCESS); // parent, exit
}
if(pid==0)
{
signal(SIGCHLD,SIG_DFL);
return getpid(); // child, go on
}
return -2; // shouldnt happen
}