/*-------------------------------------------------------------------* * SyncDet (c) Jason Hamilton Created: 01.20.98 * * Last updated: 10.20.98 * *-------------------------------------------------------------------* * This little program scans for any type of * DoS that eats up tcp connections, or vhost/clones * * Thanks to Patrick Kane for an overflow bug. * * Syntax: ./syncdet *-------------------------------------------------------------------* */ #define LINUX /* undef this if you are running a bsd box like bsd/os. The linux machine has several things diff from a a bsd machine: 1) netstat path. 2) host format has a :port 3) something else that I can't remember now. If you can't get it working, I recommend undefining this and try just updating the netstat path. */ #ifdef LINUX #define NETSTAT_PATH "/bin/netstat" #else #define NETSTAT_PATH "/usr/sbin/netstat" #endif #include #include #include #include #include #include #include #include #include #define SYN_VERSION "v4.4" void process_log(), write_all(char *ip), add_ip(char *i, char *target), add_domain(char *ip, long num); long process_ip(), check_ip(char *ip), start_time = 0, clones = 0, totals = 0, res = 0, unr = 0; struct domains { char domain[25]; long high; long low; struct domains *nx; } *domainhead = NULL; struct ip_list { char ip[25]; /* full ip */ char ip2[25];/* domain */ char target[30]; long num; long clone; long done; struct ip_list *nx; } *iphead = NULL; long CONN; main(int argc, char **argv) { struct timeval timeout; char ptr[300]; fd_set fdvar; start_time = time(NULL); if (argv[1] == NULL) { printf("\n\nSyntax: %s \n", argv[0]); printf(" Where num_con is the number of connections to alert at.\n\n"); exit(0); } CONN = atoi(argv[1]); snprintf(ptr, sizeof(ptr), "%s -an | grep tcp > netstat.log", NETSTAT_PATH); system(ptr); process_log(); } long process_ip() { struct ip_list *c; char s[300], tmp[25]; long x = 0, vhost = 0, clone = 0, total = 0; c = iphead; printf("--- SyncDet %s VHOST/Clone detector (c) Jason Hamilton ---\n\n", SYN_VERSION); printf(" Listing c-blocks with greater-than %d connections.\n\n", CONN); c = iphead; while (c != NULL) { if (c->num > CONN && c->done == 0) { x++; printf("--- %11s.* -> %-2d matches ------------\n", c->ip2, c->num); write_all(c->ip2); } c = c->nx; } printf("\n"); printf("Total netblocks listed: %d\n", x); printf("Total clones found : %d\n", clones); printf("Total resolved users : %d\n", res); printf("Total unresolved users: %d\n", unr); printf("Total listed users : %d\n", totals); return x; } void write_all(char *ip) { struct ip_list *c; struct domains *d; char addr[5], i_addr[5], *ptr; long toggle = 0, x = 0, high = 0, low = 0; struct hostent *h; char s[300]; d = domainhead; while (d) { if (strcmp(d->domain, ip) == 0) { low = d->low; high = d->high; break; } d = d->nx; } c = iphead; while (c) { if (strcmp(ip, c->ip2) == 0) { c->done = 666; sscanf(c->ip, "%d.%d.%d.%d", &addr[0], &addr[1], &addr[2], &addr[3]); h = gethostbyaddr(addr, 4, AF_INET); if (h == NULL) { toggle = 0; unr++; } else { res++; toggle = 1; } totals++; if (c->clone > 1) { clones += c->clone; printf(" x%-4d %s (%s)\n", c->clone, toggle == 0 ? c->ip : h->h_name, c->target); } else printf(" %s (%s)\n", toggle == 0 ? c->ip : h->h_name, c->target); } c = c->nx; } } void add_domain(char *ip, long numb) { struct domains *n, *c; n = (struct domains *) malloc(sizeof(struct domains)); c = domainhead; while (c) { if (strcmp(c->domain, ip) == 0) { if (numb > c->high) c->high = numb; if (numb < c->low) c->low = numb; return; } c = c->nx; } if (n) { strncpy(n->domain,ip,sizeof(n->domain)); n->low = 0; n->high = 0; if (domainhead == NULL) { domainhead = n; } else { c = domainhead; while (c->nx != NULL) c = c->nx; c->nx = n; } } } void add_ip(char *ip, char *target) { char *ptr, host[100], host2[100], temp[100]; struct ip_list *n, *c; n = (struct ip_list *) malloc(sizeof(struct ip_list)); ptr = strtok(ip, "."); snprintf(host, sizeof(host), "%s", ptr); ptr = strtok(NULL, "."); snprintf(temp, sizeof(temp), "%s.%s", host, ptr); ptr = strtok(NULL, "."); snprintf(host, sizeof(host), "%s.%s", temp, ptr); strncpy(host2,host,sizeof(host2)); #ifdef LINUX ptr = strtok(NULL, ":"); #else ptr = strtok(NULL, "."); #endif add_domain(host2, atoi(ptr)); snprintf(temp, sizeof(temp), "%s.%s", host, ptr); strncpy(host,temp,sizeof(host)); ptr = strtok(NULL, ""); if (n != NULL) { strncpy(n->ip,host,sizeof(n->ip)); strncpy(n->ip2,host2,sizeof(n->ip2)); strncpy(n->target,target,sizeof(n->target)); n->num = 1; n->clone = 1; n->done = 0; if (iphead == NULL) { iphead = n; } else { c = iphead; while (c->nx != NULL) c = c->nx; c->nx = n; } } } long check_ip(char *ip) { char *ptr, host[100], temp[100]; long clone_count = 0; struct ip_list *c; c = iphead; ptr = strtok(ip, "."); strncpy(host,ptr,sizeof(host)); ptr = strtok(NULL, "."); snprintf(temp, sizeof(temp), "%s.%s", host, ptr); ptr = strtok(NULL, "."); snprintf(host, sizeof(host), "%s.%s", temp, ptr); ptr = strtok(NULL, "."); snprintf(temp, sizeof(temp), "%s.%s", host, ptr); ptr = strtok(NULL, ""); while (c != NULL) { if (strcmp(c->ip2, host) == 0) c->num++; if (strcmp(c->ip, temp) == 0) { c->clone++; clone_count = c->clone; } c = c->nx; } return clone_count; } void process_log() { FILE *fp; long i = 0; char b[1000], *dat, s[300], s2[300], *target, *ptr; if ((fp = fopen("netstat.log", "r")) == NULL) { printf("ERROR: Unable to open \"netstat.log\"\n"); exit(0); } while (fgets(b, 1000, fp)) { i++; dat = strtok(b, " "); dat = strtok(NULL, " "); /* recvq */ dat = strtok(NULL, " "); /* sendq */ target = strtok(NULL, " "); /* local computer's port */ dat = strtok(NULL, " "); /* remote machine ip:port */ #ifdef LINUX ptr = strtok(dat, ":"); strncpy(s,ptr,sizeof(s)); strncpy(s2,ptr,sizeof(s2)); #else strncpy(s,dat,sizeof(s)); strncpy(s2,dat,sizeof(s2)); #endif dat = strtok(target, "."); dat = strtok(NULL, "."); dat = strtok(NULL, "."); #ifdef LINUX dat = strtok(NULL, ":"); /* connected port on local */ #else dat = strtok(NULL, "."); /* connected port on local */ #endif target = strtok(NULL, ""); /* connected port on local */ if (strcmp(s2, "*.*") != 0) { if (check_ip(s) < 2) add_ip(s2, target); } } if (process_ip() > 0) { printf("\nProcessed : %d connections... \n", i); printf("Total time Elapsed : %d seconds.\n", time(NULL) - start_time); } }