端口扫描器的实现

一。原理

端口扫描器是一种程序,它可以对目标主机的端口进行连接,并记录目标端口的应答。端口扫描器通过选用远程TCP/IP协议不同的端口的服务,记录目标计算机端口给予回答的方法,可以收集到很多关于目标计算机的各种有用信息(比如是否有端口在侦听,是否允许匿名登录,是否有可写的FTP目录,是否能用Telnet等)。

网络中的每一台计算机如同一座城堡,在这些城堡中,有的对外完全开放,有的却是紧锁城门。入侵者们是如何找到,并打开它们的城门的呢?这些城门究竟通向城堡的何处呢?在网络技术中,把这些城堡的“城门”称之为计算机的“端口”。端口扫描是入侵者搜集信息的几种常用手法之一。端口相当于两台计算机进程间的大门,可以随便定义,其目的只是为了让两台计算机能够找到对方的进程。计算机就像一座大楼,这个大楼有好多入口(端口),进到不同的入口中就可以找到不同的公司(进程)。如果要和远程主机A的程序通信,那么只要把数据发向A端口就可以实现通信了。
可见,端口与进程是一一对应的,如果某个进程正在等待连接,称之为该进程正在监听,那么就会出现与它相对应的端口。由此可见,通过扫描端口,便可以判断出目标计算机有哪些通信进程正在等待连接。

端口扫描的原理其实非常简单,只是简单的利用JAVA提供库函数Socket进行调用,与每一个感兴趣的目标计算机的端口进行连接。如果对方端口处于监听状态,那么连接就能成功。否则,这个端口不能用,既没有提供服务。这个技术的一个最大的优点是,不需要任何权限,系统中的任何用户都有权利使用这个调用。
引入多线程机制,利用多线程扫描的好处就是速度快,如果对每个目标端口以线性的方式使用单独的连接调用,那么将会花费相当长的时间。多线程同时打开多个套接字,从而加速扫描。在本设计中用户可以自定义线程的个数。此处用户还可以自定义扫描方式。

二。代码实现(为了深入理解 ,代码设置有错误,请勿直接使用,仅作参考)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 
typedef struct _port_segment
{
     struct in_addr  dest_ip; //destination ip address;
     unsigned short int min_port; //begin port
     unsigned short int max_port;// end port
}port_segment;
 
void my_err(const char *err_string int line)
{
   fprintf(stderr, "line %d ",line);
   perror(error_string);
   exit(1);
}
//description scan one port on one ip
 
int do_scan(struct sockaddr_in serv_addr)
{
     int conn_fd;
     int ret;
     conn_fd=socket(AF_INET,SOCK_STREAM,0);
     if(conn_fd<0)
     {
        my_err("socket" ,__LINE__);
     }
     if((ret=connect(conn_fd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr)))<-)
     {
          if(errno==ECONNREUSED)  
          {
               //target port close
               close(conn_fd);
               return 0;
          }
          else
          {
              close(conn_fd);
              return -1
          }
     }else if(ret==0)
     {
         printf("port %d found in %s \n",ntohs(serv_addr.sin_port),inet_ntoa(serv_addr.sin_addr));
         close(conn_fd);
         return 1
     }
     return -1
}
 
void *scaner(void *arg)
{
    unsigned short int i;
    struct sockaddr_in serv_addr;
    port_segment portinfo;//port information
     
    memcpy(&portinfo,arg,sizeof(struct _port_segment));
    memset(&serv_addr,0,sizeof(struct sockaddr_in));
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_addr.s_addr=portinfo.dest_ip.s_addr;
     
    for(i=portinfo.min_port;i<=portinfo.max_port;+i++)
    {
       serv_addr.sin_port=htons(i);
       if(do_scan(serv_addr)<0)
          continue;
    }
    return NULL;
     
}
int main(int argc, char **argv)
{
    pthread_t *thread;  //thread id
    int max_port;  //max port number  
    int thread_num;  //max thread number
    int seg_len;  //port  length
    struct in_addr dest_ip;//destination ip
     
    if(argc!=7)
    {
        printf("Usage :]-m [max_port] -a [serv_addr] -n thread_number\n");
        exit(1);
         
    }
     
    for(i=1;i<argc;i++)
    {
        if(strcmp("-m",argv[1]])==0)
        {
             max_port=atoi(argv[i+1]);
             if(max_port<||max_port>65535)
             {
                printf("Usage: invalid max destination port \n");
                exit(1);
             }
             continue;
        }
        if(strcmp("-a",argv[i])==0)
        {
            if(inet_aton(argv[i+1]),&dest_ip)==0)
            {
               printf("Ysage :invalid destination ip address \n");
               exit(1);
            }
            continue;
        }
        if(strcmp("-n",argv[i])==0)
        {
            thread_num=atoi(argv[i+1]);
            if(thread_num<=0)
            {
               printf("Usage invalid thread number \n");
               exit(1);
            }
            continue;
        }
         
    }
    if(max_port<thread_num)
    {
       thread_num=max_port;
    }
    seg_len=max_port; //
    if((max_port%thread_num)!=0)
    {
      thread_num+=1;
    }
    thread=(pthread_t *)malloc(thread_num*sizeof(pthread_t));
     
    for(i=0;i<pthread_num;i++)
    {
      port_segment portinfo;
      portinfo.dest_ip=dest_ip;
      portinfo.min_port=i*seg_len+1;
      if(i=pthread_num-1)
      {
           portinfo.max_port=max_port;
      }
      else
      {
           portinfo.max_port=portinfo.min_port+seg_len-1;
      }
      if(pthread_create(&thread[i],NULL,scanner,(void *)&portinfo)!=0)
      {
          my_err("thread create ",__LINE__);
           
      }
      //wait for child thread ended
   pthread_join(thread[i],NULL);
    }
     return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值