Visit our newest sister site!
Hundreds of free aircraft flight manuals
Civilian • Historical • Military • Declassified • FREE!


TUCoPS :: Hacking Techniques :: pscan1.c

PScan Port Scanner




/*  
 *  pscan, by module (jayenz|jay`) <modu1e@excite.com>
 *  class c threaded, non-blocking custom scanner
 *
 *  goals: make a 100% original, easy on the cpu, fast, 
 *  customizable scanner that would not require root privs.
 *
 *  gcc -o pscan pscan.c -lpthread
 *  compile with -DDEBUG for more detail
 *
 *  change timeout to your liking.  took <5 secs for a class 
 *  c scan on a 28.8 modem.
 * 
 *  i.e: ./pscan 192.168.1 21 Version wu-2.4.2-academ[BETA-18] 
 *  to scan 192.168.1.x for wu-ftpd beta 18 on port 21
 *  
 *  i.e ./pscan 192.168.1 110 QPOP 
 *  to scan 192.168.1.x for QPOP (any version) on port 110
 *
 *  greets: x1m, horizon, duke, bind, creeps, segv, j1mmy, xdr,
 *  CITS, vac.
 *  thnx avian! 
 *
 */ 

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pthread.h>
#include <errno.h>
#include <fcntl.h>

#define MAXHOST 254
#define TIMEOUT 10   

char hosts[MAXHOST][32];
int sockfd[254];
struct servent *sv;

struct c_info
{
    char *hostname;
    char *str;
    u_short port;
    int ret;
};

void start_up(char *, char *, u_short);
void parse_ips(char *);
void scan_host(struct c_info *);        
     
main(int argc, char **argv)
{
    char *class_c, str[256];
    u_short port;
    int i, z;

    if(argc < 4)
    {
        (void)fprintf(stderr,"usage: %s <class_c> <port> <args...>\n",
                      argv[0]);
        exit(-1);
    }

    {
      char str_args[argc-3][128];

      setvbuf(stdout, NULL, _IONBF, 0);

      class_c = argv[1];
      port    = ((u_short)atoi(argv[2]));    

      for(i=0; i<((sizeof(str_args))/(sizeof(str_args[i]))); i++) 
        strcpy(str_args[i],argv[3 +i]);      

      bzero(&sockfd,sizeof(sockfd));
      bzero(&str,sizeof(str)); 
      strcat(str,str_args[0]);   
      z = i;

      for(i=1; i<z; i++)
      {
        strcat(str, " ");
        strcat(str, str_args[i]);
      }

      start_up(class_c, str, port);
    }
}
 
void start_up(char *class_c, char *str, u_short port)
{
    int i, s, res, fd_amnt, j=0;
    char buff[100];
    pthread_t p_thread[MAXHOST];
    struct c_info scanme[MAXHOST];

    parse_ips(class_c); 

    bzero(scanme, sizeof(scanme)); 
    if((sv=getservbyport(htons(port),"tcp")) == NULL)
    {
        fprintf(stderr,"cant find %d in /etc/services\n", port);
        exit(-1);
    }
    for(i=0; i<5;i++)
    {
        if(i==1) continue;
        close(i);
    }

    printf("Beginning scan of %s.x [%s]\n", class_c, sv->s_name);
    printf("when you've had enough of the scanning, hit ^C\n\n");
   
    fd_amnt = (getdtablesize()-1);
    printf("using fd_amnt: %d\n", fd_amnt);

    for(i=0; i<((sizeof(hosts))/(sizeof(hosts[i]))); i++)       
    {
        for(s=0; s<fd_amnt && i<MAXHOST; s++,i++) 
        {
           scanme[i].port = port;
           scanme[i].hostname = hosts[i];
           scanme[i].str = str;
                
           res=pthread_create(&p_thread[i],NULL,(void *)&scan_host,
               (struct c_info *)&scanme[i]);     

           if(res == EAGAIN)
           {
               (void)printf("pth_crt, ran out of resources at %d\n
                            iteration",i);
               exit(0);
           }  
           usleep(1000);
        }

       /*  now that one segment of the threads have been 
        *  deployed, lets wait for those that have not returned
        */  
        sleep(1);
        for(s=0; s<fd_amnt && j<MAXHOST; s++,j++)
        {
            pthread_join(p_thread[j], NULL);       
        }  
    }                     
    printf("\nFIN\n");
}

void parse_ips(char *class_c)
{
    int i;

    for(i=0; i<((sizeof(hosts))/(sizeof(hosts[i]))); i++)
      sprintf(hosts[i],"%s.%d", class_c, i+1); 
}


void scan_host(struct c_info *scanme)
{
    int *fd,i,l,c,err,r,flgs;
    fd_set rd, wr;
    char *ret;
    char buff[2048];
    struct c_info *scanme_ptr;
    struct sockaddr_in sa;
    struct timeval tv;
  
    scanme_ptr = (struct c_info *) scanme;
  
    for(i=0;i<MAXHOST;i++)
    {
        if(!sockfd[i])
        {
          fd=&sockfd[i];
          break;
        }
    } 
    
    if((*fd=socket(AF_INET,SOCK_STREAM,IPPROTO_IP))==(-1))
    {
        perror("\nsocket");
        exit(-1);
    }

    bzero(&sa, sizeof(sa));
    bzero(&tv, sizeof(tv));

    sa.sin_port   = htons(scanme_ptr->port);
    sa.sin_family = AF_INET;   
    tv.tv_sec     = TIMEOUT;
    tv.tv_usec    = 0;
   
    if(!inet_aton(scanme_ptr->hostname,&sa.sin_addr))
    {   
        fprintf(stderr,"inet_aton error\n");
        pthread_exit(0);
    }     

    flgs=fcntl(*fd,F_GETFL, 0);

    if((fcntl(*fd,F_SETFL,O_NONBLOCK))==(-1))
    {
        fprintf(stderr,"fcntl error\n");
        pthread_exit(0);
    }

    if((c=connect(*fd, (struct sockaddr *)&sa, sizeof(sa)))==(-1))
    {
        if(errno != EINPROGRESS)
        {
            close(*fd);
        //    printf("connect didnt have EINPROGRESS"); 
            #ifdef DEBUG
            printf(".");
            #endif
            pthread_exit(0);
        }
    }

    l= sizeof(err);
  
    FD_SET(*fd,&wr);
    if((c=select(*fd+1,NULL,&wr,NULL, &tv))==(0))     
    {
          close(*fd);                 /* timeout */
     //   printf("select for wr on connect() timeout");
          #ifdef DEBUG
          printf(".");
          #endif
          pthread_exit(0);
    }
    else if(c == (-1)) /* redundant */
    {
        close(*fd);    /* for some generic select() error */
    //  printf("generic select error for connect() wr");
        #ifdef DEBUG
        printf(".");
        #endif
        pthread_exit(0);
    }
 
    getsockopt(*fd,SOL_SOCKET,SO_ERROR,&err,&l);

//    printf("sockopt: %d on %s\n",err,scanme_ptr->hostname);
   
    /* lets see what we have to work with now */
    if(err == ECONNREFUSED)
    {     
        close(*fd);                
    //  printf("connection refused at %s\n",scanme_ptr->hostname);
        #ifdef DEBUG
        printf(".");
        #endif
        pthread_exit(0);
    }
    else if(err == EHOSTUNREACH)
    {
        close(*fd);                              
   //   printf("host unreachable at %s",scanme_ptr->hostname);
        #ifdef DEBUG
        printf(".");
        #endif
        pthread_exit(0);
    } 
  
    bzero(&buff, sizeof(buff));

    if((r=recv(*fd,buff,sizeof(buff)-1,0))!=(-1)) 
    {
        close(*fd);
        printf(".");
    //  printf("recv not at -1");
        pthread_exit(0);   
    }
    if(errno != EWOULDBLOCK)
    {                 
        close(*fd);  /* timed out! */
        #ifdef DEBUG
        printf(".");
        #endif
    //  printf("recv errno not ewouldblock");
        pthread_exit(0);
    }
    
    FD_SET(*fd, &rd);

    if((c=select(*fd+1,&rd,NULL,NULL, &tv))==(0))
    {
        close(*fd);
        #ifdef DEBUG
        printf(".");
        #endif
     // printf("select returned 0, timeout for recv rd");
        pthread_exit(0);
    }
    else if(c == (-1))
    {
        close(*fd);
        #ifdef DEBUG
        printf(".");
        #endif
     // printf("geenric select error for recv rd");
        pthread_exit(0);
    }
    else
    {
        if((fcntl(*fd,F_SETFL,flgs))==(-1))
        {
            #ifdef DEBUG
            printf(".");
       //   printf("fcntl error\n");
            #endif
            pthread_exit(0);
        }
        /* no more non-blocking */
        
        if((r=recv(*fd,buff,sizeof(buff)-1,0))!=(-1))
        {
            if((char *)strstr(buff, scanme_ptr->str) != (char *)NULL)
            {
                printf("[%s] has [%d]:%s\n",scanme_ptr->hostname,
                scanme_ptr->port, scanme_ptr->str);
                pthread_exit(0);
            }
            else
            {
                printf("[%s] has [%d] open but no match\n",
                 scanme_ptr->hostname, scanme_ptr->port);
                pthread_exit(0);
            }
        }
 
        pthread_exit(0);
    }
}


TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2014 AOH