Chinaunix首页 | 论坛 | 博客
  • 博客访问: 438715
  • 博文数量: 78
  • 博客积分: 2030
  • 博客等级: 大尉
  • 技术积分: 1002
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-28 15:25
文章分类

全部博文(78)

文章存档

2012年(1)

2011年(1)

2010年(4)

2009年(12)

2008年(60)

我的朋友

分类: LINUX

2008-10-28 16:42:22

TCP scan的程序段出自西北亿痕的blog
http://oss.lzu.edu.cn/blog/blog.php?do_showone/tid_1217.html

udp端口扫描的原理是发送0字节的udp数据包即这个包只有udp报头,如果主机的
端口关闭那么会收到ICMP端口不可达的回应。
这个程序发送要发出去一个udp包,接收的话要分析icmp报文中的内容来判断,这个程序在创建套接口时要使用原始套接字,并且要使用icmp协议,不能使用udp协议,因为接收回来的数据icmp封在udp前面,如果是udp的话,就没有办法获取icmp报文啦!

这个程序有一点奇怪,按理说去掉setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));这句话后,IP报头可以由系统自动填写,但是试验证明不行,但是ping程序又是可以的。很奇怪。

/******************************************************************************/
/** **/
/** MODULE USED **/
/** **/
/******************************************************************************/
#include <stdio.h> /*printf*/
#include <stdlib.h> /*aoti*/
#include <unistd.h> /*gethostname,close*/
#include <sys/types.h>
#include <sys/socket.h> /*socket,setsockopt,connect*/
#include <strings.h> /*bzero*/
#include <errno.h>
#include <fcntl.h>
#include <sys/select.h> /*select*/
#include <sys/time.h> /*time*/
#include <sys/types.h>
#include <sys/signal.h>
#include <fcntl.h> /*fcntl*/
#include <netdb.h> /*struct hostent*/
#include <netinet/in.h> /*inet_addr*/
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
/******************************************************************************/
/** **/
/** DEFINITIONS AND MACROS **/
/** **/
/******************************************************************************/
#define LOCALPORT 32776
#define UDP_LEN 8
#define UDP_CKSUM 0xe887
#define DESTI_UNREACH_ICMP 3
#define PORT_UNREACH_ICMP 3
#define PORT_CLOSED -1
#define PORT_OPENED 0
#define ENABLE_DEBUG
/*debug macro*/
#ifdef ENABLE_DEBUG
int Debug= 0;
#else
#define Debug 0
#endif
#define DDBG(fmts) if(Debug)printf(fmts)
#define DBG(fmts,args) if(Debug)printf(fmts,args)
#define DBG2(fmts,arg1,arg2) if(Debug)printf(fmts,arg1,arg2)

/******************************************************************************/
/** **/
/** LOCAL FUNCTIONS **/
/** **/
/******************************************************************************/
static int sendUdp(int sockfd,struct sockaddr_in *addr)
{
    char buffer[100];
    struct ip *ip;
    struct udphdr *udp;
    struct icmp *icmp;
    int head_len;
    fd_set fdset;
    int retval;
    int len = 0;
    struct timeval tmout;
 tmout.tv_sec = 2;
 tmout.tv_usec = 0;
  
    head_len = sizeof(struct ip)+sizeof(struct udphdr);
  
    bzero(buffer,100);

    ip=(struct ip *)buffer;
    ip->ip_v = IPVERSION; /** ipversion 4 **/
    ip->ip_hl = sizeof(struct ip) >> 2; /** IP header length **/
    ip->ip_tos = 0; /** service type **/
    ip->ip_len = htons(head_len); /** IP package length **/
    ip->ip_id = 0;
    ip->ip_off = 0;
    ip->ip_ttl = MAXTTL; /** MAX TTL 255 **/
    ip->ip_p = IPPROTO_UDP; /** udp package **/
    ip->ip_sum = 0; /** checksum **/
    ip->ip_dst = addr->sin_addr; /** target address **/
  
    /*fill the udp data*/
    udp=(struct udphdr *)(buffer +sizeof(struct ip));
    udp->source = htons(LOCALPORT);
    udp->dest = addr->sin_port; /** target port **/
    udp->len = htons(UDP_LEN);
    udp->check = htons(UDP_CKSUM);

    sendto(sockfd,buffer,head_len,0,(struct sockaddr *)addr,sizeof(struct sockaddr_in));
    
    FD_ZERO(&fdset);
 FD_SET(sockfd, &fdset);
 
 retval = select(sockfd+1,&fdset,NULL,NULL,&tmout);
 if (retval <= 0){
     DDBG("no reply\n");
     FD_CLR(sockfd,&fdset);
     //DBG("shutdown result %d\n",close(sockfd));

  close(sockfd);
  return PORT_OPENED;
 }

    recvfrom(sockfd,buffer,sizeof(buffer),0,(struct sockaddr *)addr,&len);

   

    icmp = (struct icmp*)(buffer+sizeof(struct ip));

    DBG("icmp %d\n",icmp->icmp_type);
    if(icmp->icmp_type == DESTI_UNREACH_ICMP){
        DDBG("destination unreachable\n");
    }
    if(icmp->icmp_code == PORT_UNREACH_ICMP){
        DDBG("port unreachable\n");
        close(sockfd);
        return PORT_CLOSED;
    }

    close(sockfd);
    
    return 0;
}


int UdpPortScan(char *address,char *port)
{
    int sockfd;
    struct sockaddr_in addr;
    struct hostent *host;
    int n=1;
    int result;


    if(!address||!port){
        DDBG("Wrong args\n");
        return -1;
    }
  
    bzero(&addr,sizeof(struct sockaddr_in));
    addr.sin_family=AF_INET;
    addr.sin_port=htons(atoi(port));
  
    if(inet_aton(address,&addr.sin_addr) == 0){
        host = gethostbyname(address);
        if ( NULL == host){
            DDBG("can't resolv the host\n");
            return -1;
        }
        addr.sin_addr=*(struct in_addr *)(host->h_addr_list[0]);
    }

    sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
    if(sockfd < 0){
        DDBG("can't creat raw icmp socket\n");
        return -1;
    }
  
    setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));

    //setuid(getpid());


    result = sendUdp(sockfd,&addr);
    
    return result;
}


int TcpPortScan(char *host,char *pt)
{
    int sockfd, port, yes, status,result;
    //struct hostent *tgHost;

    struct sockaddr_in srvaddr;
    struct timeval timeout;
    fd_set fd;

    if(!host||!pt){
        return -1;
    }

    port = atoi(pt);

    if ((sockfd = socket( AF_INET,SOCK_STREAM, 0 )) == -1){
        DDBG("create socket error\n");
        return -1;
    }


    bzero(&srvaddr, sizeof(srvaddr));
    srvaddr.sin_family = AF_INET;
    srvaddr.sin_port = htons( port );
    srvaddr.sin_addr.s_addr = inet_addr(host);

    timeout.tv_sec = 2;
    timeout.tv_usec = 0;

    FD_ZERO(&fd);
    FD_SET(sockfd, &fd);

    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *) &yes, sizeof (yes)) < 0) {
        DDBG("setsockopt error\n");
        return -1;
    }
    /*set the socket to non block mode*/
    status = fcntl(sockfd, F_GETFL);
    fcntl(sockfd, F_SETFL, status | O_NONBLOCK);

    if (connect( sockfd, (struct sockaddr *)&srvaddr, sizeof(struct sockaddr)) < 0){
        switch (select(sockfd + 1, &fd, &fd, NULL, &timeout)){
            case -1:
                DDBG("select error\n");
                result = -1;
                break;
            case 0:
                DDBG("connect time out\n");
                result = -1;
                break;
            default:
                //printf("%s %d opened\n", host, port);

                result = 0;
        }
    }

    FD_CLR(sockfd, &fd);
    close(sockfd);
    return result;
        
}

static void usage(char *argv0)
{
 fprintf(stderr,
 "Usage: %s [-d] [-u] [-t] [-h target ip] [-p target port] \n",argv0);
}


int main(int argc,char *argv[])
{
    int c;
    int flagUdp = 0;
    int flagTcp = 0;
    char host[20] = {0};
    char port[10] = {0};

    if (argc < 4){
        usage(argv[0]);
        DBG("argc %d\n",argc);
        exit(-1);
    }

    if (argc > 1){
  for (;;){
   c = getopt( argc, argv, "dtuh:p:");
   if (c == EOF)
    break;
   switch (c){
#ifdef ENABLE_DEBUG
    case 'd':
     ++Debug;
     break;
#endif
    case 't':
     flagTcp = 1;
     break;

    case 'u':
     flagUdp = 1;
     break;

    case 'h':
     strcpy(host,optarg);
     DBG("host %s\n",host);
     break;

                case 'p':
                    strcpy(port,optarg);
                    DBG("port %s\n",port);
                    break;
    default:
     usage(argv[0]);
     exit(1);
   }
  }
 }

    if (!flagTcp&&!flagUdp){
 printf("Processing TCP port Scaning\n");
 flagTcp = 1;
    }

    if (flagTcp == 1){
 printf("Processing TCP port Scaning\n");
        if (!TcpPortScan(host, port)){
            printf("ip %s tcp port %s is opened\n",host,port);
        } else{
            printf("ip %s tcp port %s is closed\n",host,port);
        }
    }

    if (flagUdp == 1){
 printf("Processing UDP port Scaning\n");
        if (!UdpPortScan(host, port)){
            printf("ip %s udp port %s is opened\n",host,port);
        } else{
            printf("ip %s udp port %s is closed\n",host,port);
        }
    }

    return 0;
}

测试用的shell脚本

 

#!/bin/bash

#scan.sh scan the target host's port


for host in 192.168.2.20 192.168.2.188 202.117.1.5 202.117.1.6 \
            202.117.1.7 202.117.1.8 202.117.1.9 202.117.1.10
do
    for port in 4569 21 25 80
        do
        if [ ".$1" = ".tcp" ]; then
            #echo "--------beginning the tcp port scanning-------"

            ./portscan -t -h $host -p $port
        else
            #echo "--------beginning the udp port scanning-------"

            ./portscan -u -h $host -p $port
        fi
        done
done


上面的updscan有问题 重新贴一个新的

/******************************************************************************/
/** **/
/** MODULE USED **/
/** **/
/******************************************************************************/
#include <stdio.h> /*printf*/
#include <stdlib.h> /*aoti*/
#include <unistd.h> /*gethostname,close*/
#include <sys/types.h>
#include <sys/socket.h> /*socket,setsockopt,connect*/
#include <strings.h> /*bzero*/
#include <errno.h>
#include <fcntl.h>
#include <sys/select.h> /*select*/
#include <sys/time.h> /*time*/
#include <sys/types.h>
#include <sys/signal.h>
#include <fcntl.h> /*fcntl*/
#include <netdb.h> /*struct hostent*/
#include <netinet/in.h> /*inet_addr*/
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
/******************************************************************************/
/** **/
/** DEFINITIONS AND MACROS **/
/** **/
/******************************************************************************/
#define LOCALPORT 32776
#define UDP_LEN 8
#define UDP_CKSUM 0xe887
#define DESTI_UNREACH_ICMP 3
#define PORT_UNREACH_ICMP 3
#define PORT_CLOSED -1
#define PORT_OPENED 0
#define DEV_NAME "eth1"

#define ENABLE_DEBUG
/*debug macro*/
#ifdef ENABLE_DEBUG
int Debug= 1;
#else
#define Debug 0
#endif
#define DBG(fmts,args...) if(Debug)printf(fmts,##args)

struct pseudo_hdr{
 struct in_addr src;
 struct in_addr dst;
 uint8_t mbz;
 uint8_t proto;
 uint16_t len;
}__attribute__((__packed__));

/******************************************************************************/
/** **/
/** LOCAL FUNCTIONS **/
/** **/
/******************************************************************************/
static int fetch_ip(struct in_addr *ina)
{
 
 int sockfd;
 struct ifreq ifr;
 
 if (!ina){
  return -1;
 }

 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 if (sockfd < 0){
  perror("SOCK_RAW");
  return -1;
 }
 
 memcpy(ifr.ifr_name, DEV_NAME, IFNAMSIZ);
 if ( ioctl(sockfd, SIOCGIFADDR, &ifr) < 0 ){
   perror("ioctl(SIOCGIFADDR)");
  close(sockfd);
    return -1;
 }

 memcpy(ina, &ifr.ifr_addr.sa_data[2], sizeof(struct in_addr));
 DBG("fetch ip result %s\n", inet_ntoa(*ina));
 return 0;

 
}

unsigned short in_cksum(unsigned short *addr, int len)
{
       int sum=0;
       unsigned short res=0;
       while( len > 1) {
         sum += *addr++;
            len -=2;
       }
       if( len == 1) {
         *((unsigned char *)(&res))=*((unsigned char *)addr);
            sum += res;
       }
       sum = (sum >>16) + (sum & 0xffff);
       sum += (sum >>16) ;
       res = ~sum;
       return res;
}


static int sendUdp(int sockfd, struct sockaddr_in *dest)
{
    char buffer[100];
    struct ip *ip;
    struct udphdr *udp;
    struct icmp *icmp;
    int udphd_len, total_len;
    fd_set fdset;
    int retval;
    int len = 0;
    struct timeval tmout;
  tmout.tv_sec = 5;
  tmout.tv_usec = 0;
 struct pseudo_hdr *pseudo_header;


 udphd_len = sizeof(struct udphdr);
 total_len = udphd_len + sizeof(struct pseudo_hdr);
 pseudo_header = (struct pseudo_hdr *)buffer;
 fetch_ip(&pseudo_header->src);
 memcpy(&pseudo_header->dst, &dest->sin_addr, sizeof(struct in_addr));
 pseudo_header->mbz = 0;
 pseudo_header->proto = IPPROTO_UDP;
 pseudo_header->len = htons(udphd_len);
  
    /*fill the udp data*/
    udp=(struct udphdr *)&buffer[sizeof(struct pseudo_hdr)];
    udp->source = htons(LOCALPORT);
    udp->dest = dest->sin_port; /** target port **/
    udp->len = htons(udphd_len);
    udp->check = 0;

 udp->check = in_cksum((unsigned short *)buffer, total_len);


    retval = sendto(sockfd, &buffer[sizeof(struct pseudo_hdr)], udphd_len, 0,
      (struct sockaddr *)dest, sizeof(struct sockaddr_in));

 if (retval != udphd_len){
  DBG("sendto error with length %d\n", retval);
  return -1;
 }
    
    FD_ZERO(&fdset);
  FD_SET(sockfd, &fdset);
 
  retval = select(sockfd+1, &fdset, NULL, NULL, &tmout);
  if (retval <= 0){
      DBG("select error with return %d\n", retval);
      FD_CLR(sockfd,&fdset);
    close(sockfd);
    return -1;
  }

    recvfrom(sockfd,buffer,sizeof(buffer),0, NULL, 0);

    icmp = (struct icmp*)(buffer+sizeof(struct ip));

    DBG("icmp %d\n",icmp->icmp_type);
    if(icmp->icmp_type == DESTI_UNREACH_ICMP){
        DBG("destination unreachable\n");
    }
    if(icmp->icmp_code == PORT_UNREACH_ICMP){
        DBG("port unreachable\n");
        close(sockfd);
        return PORT_CLOSED;
    }

    close(sockfd);
    
    return 0;
}


int UdpPortScan(char *address,char *port)
{
    int sockfd;
    struct sockaddr_in addr;
    struct hostent *host;
    int n = 1;
    int result;

    if(!address || !port){
        DBG("Wrong args\n");
        return 1;
    }
  
    bzero(&addr,sizeof(struct sockaddr_in));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(port));
  
    host = gethostbyname(address);
    if ( NULL == host){
     DBG("can't resolv the host\n");
        return 1;
    }
  
    addr.sin_addr=*(struct in_addr *)(host->h_addr_list[0]);

    sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
    if(sockfd < 0){
        perror("SOCK_RAW");
        return 1;
    }
  
    //setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));

    //setuid(getpid());


    result = sendUdp(sockfd, &addr);
    
    return result;
}


int TcpPortScan(char *host,char *pt)
{
    int sockfd, port, yes, status,result;
    //struct hostent *tgHost;

    struct sockaddr_in srvaddr;
    struct timeval timeout;
    fd_set fd;

    if (!host || !pt){
        return 1;
    }

    port = atoi(pt);

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0 )) == -1){
        perror("SOCK_STREAM");
        return 1;
    }


    bzero(&srvaddr, sizeof(srvaddr));
    srvaddr.sin_family = AF_INET;
    srvaddr.sin_port = htons(port);
    srvaddr.sin_addr.s_addr = inet_addr(host);

    timeout.tv_sec = 2;
    timeout.tv_usec = 0;

    FD_ZERO(&fd);
    FD_SET(sockfd, &fd);

    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *) &yes, sizeof (yes)) < 0) {
        DBG("setsockopt error\n");
        return 1;
    }
    /*set the socket to non block mode*/
    status = fcntl(sockfd, F_GETFL);
    fcntl(sockfd, F_SETFL, status | O_NONBLOCK);

    if (connect( sockfd, (struct sockaddr *)&srvaddr, sizeof(struct sockaddr)) < 0){
        switch (select(sockfd + 1, &fd, &fd, NULL, &timeout)){
            case -1:
                DBG("select error\n");
                result = -1;
                break;
            case 0:
                DBG("connect time out\n");
                result = -1;
                break;
            default:
                //printf("%s %d opened\n", host, port);

                result = 0;
        }
    }

    FD_CLR(sockfd, &fd);
    close(sockfd);
    return result;
        
}

static void usage(char *argv0)
{
  fprintf(stderr,
   "Usage: %s [-d] [-u] [-t] [-h target ip] [-p target port] \n",argv0);
}


int main(int argc,char *argv[])
{
    int c;
    int flagUdp = 0;
    int flagTcp = 0;
 int ret;
    char host[20] = {0};
    char port[10] = {0};

    if (argc < 4){
        usage(argv[0]);
        DBG("argc %d\n",argc);
        exit(-1);
    }

    if (argc > 1){
    for (;;){
      c = getopt( argc, argv, "dtuh:p:");
      if (c == EOF)
       break;
      switch (c){
#ifdef ENABLE_DEBUG
      case 'd':
        ++Debug;
        break;
#endif
      case 't':
        flagTcp = 1;
        break;

      case 'u':
        flagUdp = 1;
        break;

      case 'h':
        strcpy(host,optarg);
        DBG("host %s\n",host);
        break;

            case 'p':
                strcpy(port,optarg);
                DBG("port %s\n",port);
                break;
      default:
        usage(argv[0]);
        exit(1);
      }
    }
  }

    if (!flagTcp && !flagUdp){
   printf("Processing TCP port Scaning\n");
   flagTcp = 1;
    }

    if (flagTcp == 1){
   printf("Processing TCP port Scaning\n");
  ret = TcpPortScan(host, port);
        if (!ret){
            printf("ip %s tcp port %s is opened\n",host,port);
        } else if(ret == -1){
            printf("ip %s tcp port %s is closed\n",host,port);
        }
    }

    if (flagUdp == 1){
   printf("Processing UDP port Scaning\n");
  ret = UdpPortScan(host, port);
        if (!ret){
            printf("ip %s udp port %s is opened\n",host,port);
        } else if (ret == -1){
            printf("ip %s udp port %s is closed\n",host,port);
  }
    }
    return 0;
}

阅读(1281) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~