• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • hacker成長的代碼之路:掃描(2)

    發表于:2007-07-04來源:作者:點擊數: 標簽:
    作者:kf_701 寫作時間:2005/4 Email:kf_701@21cn.com 轉載請保留原作者信息,謝謝。 要求的專業知識: 一: 精通OSI參考模型,精通 網絡 五層:物理層,數據鏈路層, 網絡 層,傳輸層,應用層。 精通每一層的協議,數據報格式。精通 網絡 拓撲結構,第一層
    作者:kf_701 寫作時間:2005/4 Email:kf_701@21cn.com
    轉載請保留原作者信息,謝謝。

    要求的專業知識
        一:    精通OSI參考模型,精通網絡五層:物理層,數據鏈路層,網絡層,傳輸層,應用層。
            精通每一層的協議,數據報格式。精通網絡拓撲結構,第一層,第二層,第三層的網
            絡互聯,數據的轉發和路由等。
        二:    精通C語言程序設計,UNIX/LINUX程序設計,網絡程序設計。熟悉UNIX/LINUX系
            統操作,熟悉著名服務的基本配置,特性及使用的端口號。熟悉經典網絡命令的使用,
            如:netstat,ping,traceroute,netcat,arp等。
        三:    精通標準SQL語言,熟悉流行的數據庫使用,如:Oracle,Mysql等。掌握數據庫與
            WEB語言的結合使用。

      有的時候可能要確定一個局域網內有多少臺機器是開機的,那么就要依次掃描這個網段內的所有IP。通
    常的端口掃描或漏洞掃描的前提是目標主機是開機的,否則所有的掃描都是白費時間。最簡單的辦法是先
    ping一下目標主機。大部分的掃描軟件都會在掃描開始前進行和ping類似的測試。

      我們要成為真正的黑客,所以我們不會滿足于使用別人的程序,我們要理解這里面全部的網絡原理,我
    們要寫自己的程序。

      其實這樣的程序并不難,我們只要向目標主機發送一個ICMP ECHO請求報文,如果目標主機回應了一
    個ICMP ECHOREPLY報文,則目標主機一定是開機的。那么我們就可以進行后面的掃描工作了。

      ICMP是第三層(網絡層)的協議,雖然它和IP協議都在網絡層,但ICMP數據報依然使用IP報頭封裝
    其報文內容。ICMP ECHO的類型值是8(ICMP_ECHO),代碼值是0。我們用程序來完成一個簡單的ping。
    讀到這里,我假想你是完全知道ICMP報文的格式的,如果你不知道,那么請你離開,去打點基礎再來閱
    讀,否則純屬浪費時間。

      先建一個原始socket,再自已構造一個ICMP報文,通過這個原始socket把ICMP報文發送出去,然后
    用這個原始socket接收目標主機的回應ICMP,收到回應,那么進行后面的掃描吧。要說明的是系統內核
    會把收到的所有ICMP消息給每個ICMP原始socket復制一份,也就是說我們程序里創建的ICMP RAW
    socket會收到所有的ICMP消息,但我們只想等待我們程序里指定的目標主機的ICMP ECHOREPLY消息,
    較好的辦法是使用ICMP ECHO報頭的標識字段,在構造ICMP請求報文的時候,把標識字段(icmp_id)設
    為進程號(process id)。然后檢查收到的每個ICMP消息的標識字段,和process id相同的則是我們
    等待的報文。

      raw socket只有superuser可以創建,務必在superuser權限下運行。下面是一段簡單的代碼,不
    過也是完整呈現了ping程序。

      send_icmp()構造ICMP報頭并使用raw socket發送。main循環接收ICMP消息,交給proc_icmp
    判斷處理。代碼是linux系統上測試通過。

      本程序只對一個IP地址進行,如果要對一段IP進行測試,簡單修改程序即可??蓪l送放在單獨的進程
    里(使用fork()),send_icmp里做成循環,每次重新初始化struct sockaddr_in。那么對接收到的數據
    進行分析的proc_icmp()將多一道對IP報頭ip->src字段的判斷。具體的修改,留給讀者自己完成。

         1  /*
         2     A simply ping program for unix
         3     Copyright (C) 2005  by kf_701
         4
         5     This program is free software; you can redistribute it and/or modify
         6     it under the terms of the GNU General Public License as published by
         7     the Free Software Foundation; either version 2 of the License, or
         8     (at your option) any later version.
         9
        10     This program is distributed in the hope that it will be useful,
        11     but WITHOUT ANY WARRANTY; without even the implied warranty of
        12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        13     GNU General Public License for more details.
        14
        15     You should have received a copy of the GNU General Public License
        16     along with this program; if not, write to the Free Software
        17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        18
        19     The author can be reached as follows:
        20          E_mail:         kf_701@21cn.com
        21          Address:        hefei of china
        22          Phone:          0551-2150103
        23  */
        24
        25  #include <netinet/ip.h>
        26  #include <stdio.h>
        27  #include <netinet/ip_icmp.h>
        28  #include <netinet/in_systm.h>
        29  #include <netdb.h>
        30  #include <sys/types.h>
        31  #include <sys/socket.h>
        32  #include <netinet/in.h>
        33  #include <arpa/inet.h>
        34  #include <unistd.h>
        35  #include <sys/time.h>
        36  #include <errno.h>
        37  #include <signal.h>
        38  #include <string.h>
        39  #include <stdlib.h>
        40
        41  #define BUFSIZE         1024
        42
        43          /* global vars */
        44  char recvbuf[BUFSIZE];
        45  char sendbuf[BUFSIZE];
        46  int datalen = 56;       /* bytes of data,following ICMP header*/
        47  pid_t pid;              /* the pid use as icmp_id*/
        48  unsigned short seqno;           /* icmp_seq number*/
        49  int timeerr;            /* test gettimeofday if error*/
        50  int sockfd = -1;
        51  struct sockaddr_in destaddr;
        52  socklen_t len = sizeof(struct sockaddr);
        53
        54          /* function prototypes */
        55  static unsigned short check_sum(unsigned short *,int);
        56  static void send_icmp(void);
        57  static void proc_icmp(char *,ssize_t,struct timeval *);
        58  static void tv_sub(struct timeval *,struct timeval *);
        59  static void sig_alrm(int);
        60  static void sig_int(int);
        61
        62  int
        63  main(int argc,char **argv)
        64  {
        65          int size = 60*1024;     /* set SO_RCVBUF */
        66          struct timeval timeval; /* recvfrom time */
        67          struct hostent *host;
        68
        69          if(argc != 2)
        70                  puts("-----usage:ping host------"),exit(1);
        71
        72          bzero(&destaddr,sizeof(destaddr));
        73          destaddr.sin_family = AF_INET;
        74          if(inet_aton(argv[1],&destaddr.sin_addr) == 0){
        75                  host = gethostbyname(argv[1]);
        76                  if(host == NULL){
        77                          fprintf(stderr,"Hostname Error: %s \n",hstrerror(h_errno));
        78                          exit(1);
        79                  }
        80                  destaddr.sin_addr = *(struct in_addr *)(host->h_addr_list[0]);
        81          }
        82          /*struct addrinfo hints,*res;
        83          hints.ai_flags = AI_CANONNAME;
        84          hints.ai_family = AF_INET;
        85          hints.ai_socktype = 0;
        86          if(getaddrinfo(argv[1],NULL,&hints,&res) != 0)
        87                  perror("getaddrinfo error"),exit(1);*/
        88
        89          sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
        90          if(sockfd == -1)
        91                  perror("socket error"),exit(1);
        92          setuid(getuid());       /* not need super permission any more*/
        93          setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,&size,sizeof(size));
        94
        95          signal(SIGINT,sig_int);
        96          signal(SIGALRM,sig_alrm);
        97          pid = getpid();
        98          printf("------------ping %s 56 bytes packet------------\n",argv[1]);
        99          sig_alrm(SIGALRM);      /* send first packet*/
       100
       101          while(1){               /* receive packet */
       102                  int n = -1;
       103                  n = recvfrom(sockfd,recvbuf,sizeof(recvbuf),0,(struct sockaddr *)NULL,NULL);
       104                  if(n < 0){
       105                          if(errno == EINTR)
       106                                  continue;
       107                          else
       108                                  perror("recvfrom error"),exit(1);
       109                  }
       110                  /*printf("received : ");*/
       111                  if(gettimeofday(&timeval,NULL) == -1)
       112                          perror("gettimeofday error"),timeerr++;
       113                  proc_icmp(recvbuf,n,&timeval);
       114          }
       115  }
       116
       117  static void
       118  send_icmp(void)
       119  {
       120          int len;
       121          struct icmp *icmp;
       122
       123          icmp = (struct icmp *)sendbuf;
       124          icmp->icmp_type = ICMP_ECHO;
       125          icmp->icmp_code = 0;
       126          icmp->icmp_id = pid;
       127          icmp->icmp_seq = seqno;
       128          if(gettimeofday((struct timeval *)icmp->icmp_data,NULL) == -1)
       129                  puts("set icmp_data error"),timeerr++;
       130          len = 8 + datalen;
       131          icmp->icmp_cksum = 0;
       132          icmp->icmp_cksum = check_sum((u_short *)icmp,len);
       133          if(sendto(sockfd,sendbuf,len,0,(struct sockaddr *)&destaddr,len) == -1)
       134                  perror("sendto error"),exit(1);
       135          printf("send one packet and wait for answer ......\n");
       136          fflush(NULL);
       137  }
       138
       139  static void
       140  sig_alrm(int signo)
       141  {
       142          send_icmp();
       143          seqno = seqno + 1;
       144          alarm(1);
       145          return;
       146  }
       147
       148  static void
       149  proc_icmp(char *ptr,ssize_t len,struct timeval *tvrecv)
       150  {
       151          int iphdlen,icmplen;
       152          struct ip *ip;
       153          struct icmp *icmp;
       154          struct timeval *tvsend;
       155          double rtt;
       156
       157          ip = (struct ip *)ptr;                  /* start of IP header   */
       158          iphdlen = ip->ip_hl<<2;                 /* length of IP header  */
       159          icmp = (struct icmp *)(ptr+iphdlen);    /* start of ICMP header */
       160          if( (icmplen = len - iphdlen) < 8){     /* test icmp header len */
       161                  puts("icmplen error");
       162                  return;
       163          }
       164          if((icmp->icmp_type == ICMP_ECHOREPLY)&&(icmp->icmp_id == pid)){
       165                  printf("*receive: icmp_seq=%d ",icmp->icmp_seq);
       166                  if(icmplen < 16)
       167                          puts("icmplen < 16"),exit(1);
       168                  tvsend = (struct timeval *)icmp->icmp_data;
       169                  if(!timeerr){
       170                          tv_sub(tvrecv,tvsend);
       171                          rtt = tvrecv->tv_sec*1000.0 + tvrecv->tv_usec/1000.0;
       172                          printf(" rtt=%.3f ms\n",rtt);
       173                  }
       174          }
       175          return;
       176  }
       177
       178  static void
       179  tv_sub(struct timeval *out,struct timeval *in)
       180  {
       181          if( (out->tv_usec -= in->tv_usec) < 0 ){
       182                  --out->tv_sec;
       183                  out->tv_usec += 1000000;
       184          }
       185          out->tv_sec -= in->tv_sec;
       186  }
       187
       188  static void sig_int(int sig)
       189  {
       190          printf("-------------------------------------------------------\n");
       191          exit(0);
       192  }
       193
       194  static unsigned short
       195  check_sum(unsigned short *addr,int len)
       196  {
       197          register int nleft = len;
       198          register int sum = 0;
       199          register short *w = addr;
       200          short answer = 0;
       201
       202          while(nleft>1)
       203          {
       204                  sum += *w++;
       205                  nleft -= 2;
       206          }
       207          if(nleft ==1)
       208          {
       209                  *(unsigned char *)(&answer) = *(unsigned char *)w;
       210
       211                  sum += answer;
       212          }
       213          sum = (sum>>16)+(sum&0xffff);
       214          sum += (sum>>16);
       215          answer = ~sum;
       216          return(answer);
       217  }



    check_sum函數是大家都使用的函數,這里就不作詳細介紹了。作用是計算校驗和。
    看完后,你是否覺得原來是如些簡單的事情呢,有問題請給我mail,謝謝。
    ******待續******

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>