Trickscan is a portscanner and wingate scanner in one.
5b1ff66794d0a711ce45a7f69a3d09d3c5b832489f6950b07413e7725ef1e684
/*
This is just a a/b/c class (or single host) Port and Wingate Scanner.I did
this to learn about sockets and child proccesses, and to just have one
program instead of a portscanner and a wingate scanner. Drop me an email
if you like this program.
-To compile(in unix):
gcc trickscan.c -o trickscan
TODO:
-ping hosts before scanning them, just wastes time if they're down
-add a gui, probly unix with gtk (gotta learn it first)
-port to windows (anyone want to do a win gui?)
For the wingate stuff, I kinda borrowed ideas from misteri0's Gatescan. I
obviusly didn't copy the code, I just didn't know how to go about checking
if a host was a wingate. Aint that what open source is all about?
Anyway, thanks goes out to misteri0.
sharper_image <unixtrip@yahoo.com>
*/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#define CHILDREN 100
#define TIMEOUT 5
#define WINGATE_PORT 23
#define MIN_PORT 1 /*default min and max ports*/
#define MAX_PORT 1080
#define VERSION 1.3
#define DONT_ASK strncpy(host,argv[optind-1],(strlen(argv[optind-1]))+1);
int aflag=0,bflag=0,cflag=0,sflag=0,Wflag=0,Pflag=0,xflag=0,zflag=0;
unsigned int children=0,timeout=0,cur_children=0;
void about(void);
void usage(char *filename);
void scan(char host[], int min_port, int max_port);
void check_port(char host[], int port);
void prep_children(char host[], int port, int flag); /*flag:0=finish up*/
int main(int argc, char **argv) {
int min_port, max_port, junk;
char ch, host[16];
about();
if(argc<3)
usage(argv[0]);
while((ch=getopt(argc, argv, "WPa:b:c:s:x:z:C:T:"))!=-1) {
switch(ch) {
case 'C': children=atoi(optarg); break;
case 'T': timeout=atoi(optarg); break;
case 'a': aflag=1; DONT_ASK ;break;
case 'b': bflag=1; DONT_ASK ;break;
case 'c': cflag=1; DONT_ASK ;break;
case 's': sflag=1; DONT_ASK ;break;
case 'x': xflag=1; min_port=atoi(optarg); break;
case 'z': zflag=1; max_port=atoi(optarg); break;
case 'W': Wflag=1; break;
case 'P': Pflag=1; break;
case '?': { fprintf(stderr, "Error: unrecognized option\n");
exit(1); }
}
}
/*OPTION CHECKING*/
if((junk=(aflag+bflag+cflag+sflag))>1) {
fprintf(stderr, "Error: cannot combine the -a, -b, -c or -s options\n");
exit(1);
}
if(junk<1) {
fprintf(stderr, "Error: specify scanning class (-a, -b, -c or -s)\n");
exit(1);
}
if((junk=(Wflag+Pflag))>1) {
fprintf(stderr, "Error: cannot combine the -W and -P options\n");
exit(1);
}
if(!junk)
Pflag=1;
if(!zflag)
max_port=MAX_PORT;
if(!xflag)
min_port=MIN_PORT;
if(!children)
children=CHILDREN;
if(!timeout)
timeout=TIMEOUT;
/*DONE*/
scan(host, min_port, max_port);
return 1;
}
void scan(char host[], int min_port, int max_port) {
unsigned int ip1, ip2, ip3, ip4;
unsigned int junk;
char host_add[16];
struct hostent *hp;
if(isdigit(host[0]))
strncpy(host_add, host, (strlen(host))+1);
else {
hp=gethostbyname(host);
if(hp==NULL) {
fprintf(stderr, "Error; Cannot Resolve %s\n", host);
return;
}
sprintf(host_add,"%s",inet_ntoa(*((struct in_addr *)hp->h_addr)));
}
if(sflag) {
if(Wflag) {
printf("Scanning %s for a WinGate server\n", host_add);
prep_children(host_add, WINGATE_PORT, 1);
}
if(Pflag) {
printf("Scanning %s: ports %d to %d\n",host_add,min_port,max_port);
for(junk=min_port; junk<=max_port; junk++)
prep_children(host_add, junk, 1);
}
}
if(aflag) {
sscanf(host_add, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
if(Pflag) printf("Scanning %d.*:ports %d to %d\n", ip1, min_port, max_port);
if(Wflag) printf("Scanning %d.* for WinGate servers\n", ip1);
ip2=ip3=ip4=0;
for(ip4=1; ip2<256; ip4++) {
if(ip4==256)
ip4=1; ip3++;
if(ip3==256)
ip4=1; ip3=0; ip2++;
sprintf(host_add, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);
if(Pflag) {
printf("%s:\n", host_add);
for(junk=min_port; junk<=max_port; junk++)
prep_children(host_add, junk, 1);
}
if(Wflag) {
prep_children(host_add, WINGATE_PORT, 1);
}
} /*end of for()*/
} /*end of if(aflag)*/
if(bflag) {
sscanf(host_add, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
if(Pflag) printf("Scanning %d.%d.*: ports %d to %d\n",ip1,ip2,min_port,max_port);
if(Wflag) printf("Scanning %d.%d.* for WinGate servers\n",ip1,ip2);
ip3=ip4=0;
for(ip4=1; ip3<256; ip4++) {
if(ip4==256)
ip4=1; ip3++;
sprintf(host_add, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);
if(Pflag) {
printf("%s:\n", host_add);
for(junk=min_port; junk<=max_port; junk++)
prep_children(host_add, junk, 1);
}
if(Wflag) {
prep_children(host_add, WINGATE_PORT, 1);
}
} /*end of while*/
} /*end of if(bflag)*/
if(cflag) {
sscanf(host_add, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
if(Pflag) printf("Scanning %d.%d.%d.*:ports %d to %d\n",ip1,ip2,ip3,min_port,max_port);
if(Wflag) printf("Scanning %d.%d.%d.* for WinGate servers\n", ip1,ip2,ip3);
for(ip4=1; ip4<255; ip4++) {
sprintf(host_add, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);
if(Pflag) {
printf("%s\n", host_add);
for(junk=min_port; junk<=max_port; junk++)
prep_children(host_add, junk, 1);
}
if(Wflag) {
prep_children(host_add, WINGATE_PORT, 1);
}
} /*end of for*/
} /*end of cflag*/
prep_children("", 0, 0);
return;
} /*End of scan()*/
void prep_children(char host[], int port, int flag) {
int status;
if(!flag) {
for(;cur_children>0;cur_children--)
wait(&status);
return;
}
if(cur_children==children) {
wait(&status);
cur_children--;
}
if(!fork()) check_port(host, port);
cur_children++;
return;
}
void check_port(char host[], int port) {
int s, ret;
char buf[40];
FILE *fp;
struct sockaddr_in remote;
struct servent *service;
remote.sin_family=AF_INET;
remote.sin_port=htons(port);
remote.sin_addr.s_addr=inet_addr(host);
if((s=socket(AF_INET, SOCK_STREAM, 0)) < 0) {
fprintf(stderr, "\nError: Socket Error");
_exit(-1);
}
alarm(timeout); /*kill process after timeout seconds*/
if((connect(s, (struct sockaddr *)&remote, sizeof(remote))) < 0) {
close(s);
_exit(1);
}
if(Pflag) {
service = getservbyport(port, "tcp");
if(service==NULL) {
service = getservbyport(port, "udp");
if(service!=NULL)
printf("\t%s: runnint port %d: %s\n",host,port,service->s_name);
else
printf("\t%s: running port %d; Unknown\n", host, port);
}
else
printf("\t%s: running port %d: %s\n", host, port, service->s_name);
} /*end of if(Sflag)*/
if(Wflag) {
memset(buf, '\0', sizeof(buf));
if((read(s, buf, sizeof(buf))) > 0) {
/*fprintf(stderr,"DEBUG: after first read: %s\n", buf);*/
ret=read(s, buf, sizeof(buf));
/*fprintf(stderr,"DEBUG: after second read: %s\n", buf);*/
if(!(strncmp(buf, "WinGate>", 8))||!(strncmp(buf, "Too m", 5))) {
fprintf(stderr, "\t!Wingate found!: %s\n\a", host);
if((fp=fopen("wingate.list", "a"))==NULL) {
fprintf(stderr, "Error: couldn't open wingate.list\n");
close(s);
_exit(-1);
}
fprintf(fp, "%s port %d\n", host, port);
fclose(fp);
}
}
} /*end of Wflag*/
close(s);
_exit(1);
}
/**************************************************/
void about(void) {
printf("Trickscan v%.1f; A Tricksoft Production\n", VERSION);
printf("\thttp://Tricksoft.cjb.net\n");
printf("By Sharper_Image <unixtrip@yahoo.com>\n\n");
}
void usage(char *filename) {
fprintf(stderr,"Usage: %s [OPTIONS]\n", filename);
fprintf(stderr," OPTIONS:\n");
fprintf(stderr,"\t-W\t = Wingate scanning\n");
fprintf(stderr,"\t-P\t = Port scanning(default)\n");
fprintf(stderr,"\t-a <network> = Entire A-class Domain\n");
fprintf(stderr,"\t-b <network> = Entire B-class Domain\n");
fprintf(stderr,"\t-c <network> = Entire C-class Domain\n");
fprintf(stderr,"\t-s <host> = Single host\n");
fprintf(stderr,"\t-x <PORT> = Lowest Port to scan(Default = %d)\n",MIN_PORT);
fprintf(stderr,"\t-z <PORT> = Highest Port to scan(Default = %d)\n",MAX_PORT);
fprintf(stderr,"\t-C <children>= Number of child procceses(Default = %d)\n", CHILDREN);
fprintf(stderr,"\t-T <timeout> = Timeout(sec) before connection is dropped(Default = %d)\n", TIMEOUT);
fprintf(stderr,"-All found Wingates will go in a file called wingate.list\n");
exit(1);
}