• 威尼斯人官网官网

  • 威尼斯人官网官网

  • 威尼斯人官网官网

  • 威尼斯人官网官网

威尼斯人官网官网

作者(zhe)︰追(zhui)影(ying)人  發(fa)布日期︰2020-02-20 07:29:13
Tag標簽︰基(ji)礎  
  • 網絡編(bian)程在網絡安全方面具有舉足輕重(zhong)的作用,如何(he)快捷(jie)高效的監听、分析、構造網絡流量,成為(wei)很(hen)多安全從業者(zhe)需(xu)要(yao)解決的重(zhong)點問題。而winpcap這一免(mian)費開源(yuan)項目(mu)恰(qia)好(hao)可(ke)以為(wei)win32應用程序提供訪問網絡底層的能力,所以其(qi)成為(wei)了相關網絡編(bian)程的首選開發(fa)工具。
    0×01 winpcap是什麼?
    winpcap(windows packet capture)是windows平台下一個(ge)免(mian)費的網絡訪問系統(tong),可(ke)用于windows系統(tong)下的網絡編(bian)程。著(zhu)名的wireshark便是基(ji)于winpcap開發(fa)的,大家在安裝wireshark中可(ke)以看到winpcap驅動(dong)程序的安裝過(guo)程。
    有關winpcap的介(jie)紹網絡上(shang)很(hen)多,百(bai)科里面介(jie)紹的也很(hen)詳(xiang)細,我就不再copy了。需(xu)要(yao)注意的一點是,winpcap並(bing)不是一個(ge)簡單的library,而是一個(ge)針對(dui)Win32平台上(shang)的抓(zhua)包(bao)和網絡分析的一個(ge)架構,它包(bao)括一個(ge)核心態的包(bao)過(guo)濾器,一個(ge)底層的動(dong)態鏈(lian)接庫(packet.dll)和一個(ge)高層的不依賴于系統(tong)的mu)猓pcap.dll)。所以它只能“嗅探(tan)”到物理線(xian)路(lu)上(shang)的數據(ju)包(bao),而不具備攔截的能力,因此不適用于個(ge)人防火(huo)牆等項目(mu)。
    0×02 你需(xu)要(yao)準(zhun)備些(xie)什麼?
    本系列(lie)文章主(zhu)要(yao)帶大家認識和了si)餿綰he)利用winpcap網絡編(bian)程技(ji)術進行網絡的協議分析、流量統(tong)計(ji)及網絡探(tan)測(ce)掃描等,這里我們並(bing)不會去深硬的解讀(du)相關源(yuan)代碼,而是以輕松的方式結合實驗(yan)來對(dui)相關原理進行深入理解。在本系列(lie)文章中,筆shou)嘰蛹虻僥眩 蠣鶻jie)紹winpcap架構原理、相關環境(jing)搭建(jian)及快速編(bian)寫核心代碼。但(dan)是在開始(shi)前,讀(du)者(zhe)需(xu)要(yao)有一些(xie)相關基(ji)礎︰了si)饌縲 橄喙鞀ji)礎知識,掌握(wo)一門(men)winpcap開發(fa)庫支持的編(bian)程語言,自己能動(dong)手實dao)bian)寫一些(xie)例子(zi)。Winpcap提供的mu) fa)接口原生是c語言的,不過(guo)熱心腸的程序猿們已經為(wei)其(qi)他語言的使用提供了封裝,比如java、.net、python,好(hao)像連(lian)易zi)鋂遠加小1鞠盜lie)文章將使用c語言來進行各種實驗(yan),有興(xing)趣的讀(du)者(zhe)可(ke)以將其(qi)轉換成自己熟悉的語言來動(dong)手實dao)br />0×03 你能學(xue)到什麼?
    有關winpcap開發(fa)的文章在網上(shang)很(hen)容(rong)易找到,但(dan)是更多的都是qian)dui)于代碼的講解,筆shou) 詒疚木×肯低tong)性的從原理層面結合各個(ge)應用場景來介(jie)紹相關知識︰
    1.   Winpcap獲取網卡(ka)基(ji)本信息及收(shou)發(fa)數據(ju)包(bao)
    2.   存(cun)活主(zhu)機探(tan)測(ce)
    3.   端(duan)口掃描
    4.   Arp欺騙
    5.   中間人攻擊的簡單實現
    6.    流量統(tong)計(ji)與(yu)分析
    0×04 知識補充(chong)
    進行下面的介(jie)紹前,我們需(xu)要(yao)了si)餳父ge)名詞的關系。
    winpcap(windows packet capture)是windows平台下一個(ge)免(mian)費的網絡訪問系統(tong),可(ke)用于windows系統(tong)下的網絡編(bian)程。linux 平台下對(dui)應的mu) fa)包(bao)是libpcap。
    Wireshark是基(ji)于winpcap處理網絡驅動(dong)層。
    Wpdpack是winpcap的mu) fa)包(bao),提供開發(fa)相關程序的接口。
    0×05 環境(jing)準(zhun)備
    首先(xian)根據(ju)你所選擇(ze)的mu) fa)語言選擇(ze)對(dui)應的編(bian)譯器,筆shou)呤褂語言,利用VS2012進行相關開發(fa)。

     
    安裝好(hao)編(bian)譯器後,進行相關配置。下載wpdpack點擊這里
    初學(xue)者(zhe)可(ke)以選擇(ze)里面的Examples進行編(bian)譯,可(ke)以看到找不到頭文件,及相關庫。
     

     
    這是因為(wei)wpdpack中的相關庫還沒有引入到編(bian)譯環境(jing)中

     
    將wpdpack包(bao)中的Include和lib文件夾中的文件添加到VS的相關目(mu)錄下即(ji)可(ke)編(bian)譯通過(guo)。將編(bian)譯後的程序進行運行則出(chu)現以下錯誤。

     
    這是由于運行時缺乏動(dong)態鏈(lian)接庫導(dao)致,最(zui)簡單的方法是直接下載並(bing)安裝winpcap驅動(dong)程序 下載
    如果你覺得這樣子(zi)很(hen)麻煩,也可(ke)以采用簡易zhui)椒 3絛蛟讜誦惺敝恍xu)要(yao)winpcap在system32下面釋放的wpcap.dll和packet.dll,還有driver下面的npf.sys,所以不需(xu)要(yao)完(wan)整安裝winpcap,而選擇(ze)只復制以上(shang)三(san)個(ge)文件到對(dui)應目(mu)錄中即(ji)可(ke)。
    本節筆shou)囈 捎彌zhu)名的Arpspoof源(yuan)碼進行相關講解,源(yuan)碼下載地址http://www.verysource.com/code/2287464_1/arpspoof.cpp.html
    0×06 枚舉可(ke)用網絡適配器資源(yuan)
    在使用winpcap進行收(shou)發(fa)數據(ju)包(bao)時,需(xu)指(zhi)定對(dui)應的網卡(ka),所以有必要(yao)列(lie)出(chu)計(ji)算機上(shang)所有可(ke)用的網絡適配資源(yuan)。
    列(lie)取網卡(ka)信息的核心代碼︰
    //該函數在Arpspoof程序中,筆shou)囈辛訟xiang)細注釋
    void ListAdapters()
    {
     pcap_if_t *alldevs;//用于存(cun)儲網卡(ka)鏈(lian)表的頭指(zhi)針
     pcap_if_t *d;//用于遍(bian)歷網卡(ka)鏈(lian)表的臨時變(bian)量
        int i = 0;//記錄網卡(ka)個(ge)數
    char errbuf[PCAP_ERRBUF_SIZE];//存(cun)儲錯誤信息
    char szGateIPAddr[16];//網卡(ka)對(dui)應網關地址
    char *p;//網卡(ka)名詞
     char szIPAddr[16];//網卡(ka)對(dui)應IP
     unsigned char ucPhysicalAddr[6];//網卡(ka)對(dui)應的MAC地址
        if (pcap_findalldevs(&alldevs, errbuf) == -1)//獲取網卡(ka)鏈(lian)表
        {
            fprintf(stderr,"Error in pcap_findalldevs: %s ", errbuf);
            return;
        }
        for (d=alldevs; d; d=d->next)//遍(bian)歷網卡(ka)鏈(lian)表
        {
            if (d->addresses != NULL && (p = strchr(d->name, '{')) != NULL

       && Getadapterbyname(p, szIPAddr, ucPhysicalAddr,szGateIPAddr))//獲取網卡(ka)的對(dui)應信息
      {
       for(int j = strlen(d->description) - 1; j > 0; j--)//對(dui)網卡(ka)的描述信息格式化(hua)
       {
        if (d->description[j] == 0x20)
         d->description[j] = '';
        else
         break;
       }
       printf("   %d. %s IP Address. . . . . : %s ", i, d->description, szIPAddr);//格式化(hua)輸出(chu)網卡(ka)信息
       printf(" Physical Address. . : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X ",
        ucPhysicalAddr[0], ucPhysicalAddr[1], ucPhysicalAddr[2],
        ucPhysicalAddr[3], ucPhysicalAddr[4], ucPhysicalAddr[5]);
       printf(" Default Gateway . . : %s ", szGateIPAddr);
       i ++;
      }
        } 
        if (i==0)
        {
            printf(" No interfaces found! Make sure WinPcap is installed. ");
            return;
        }
     
        pcap_freealldevs(alldevs);//釋放網卡(ka)鏈(lian)表
    }
    科普(pu)Tips︰
    “網卡(ka)”是神馬(ma)?
    計(ji)算機與(yu)外界局域(yu)網的連(lian)接是通過(guo)主(zhu)機箱內插入一塊網絡接口板(或者(zhe)是在筆shi)潛鏡縋nao)中插入一塊PCMCIA卡(ka))。網絡接口板又稱為(wei)通信適配器或網絡適配器(network adapter)或網絡接口卡(ka)NIC(Network Interface Card),但(dan)是更多的人願意使用更為(wei)簡單的名稱“網卡(ka)”。
    利用上(shang)面的程序,我們可(ke)以查看計(ji)算機上(shang)可(ke)利用的所有網卡(ka)資源(yuan),以便選擇(ze)相應的網卡(ka)資源(yuan)進行相關操作。為(wei)了便于觀察,我們在VMware虛擬機中進行,首先(xian)在對(dui)應的虛擬機設置中增加硬件選項中添加多塊網卡(ka),然後配置相應的IP,運行程序,可(ke)以得到對(dui)應網卡(ka)的名稱描述、IP地址、MAC地址等。


    0×07 如何(he)構造和發(fa)送數據(ju)包(bao)
    上(shang)一步我們列(lie)出(chu)了所有的mu)ke)用網卡(ka)資源(yuan),在發(fa)送數據(ju)包(bao)前,需(xu)要(yao)打(da)開對(dui)應的網卡(ka)來進行發(fa)送數據(ju)包(bao)的操作。這里使用的函數是pcap_open_live︰
    函數名稱︰pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
    函數功能︰獲得用于捕獲網絡數據(ju)包(bao)的數據(ju)包(bao)捕獲描述字(zi)zheng)br />參數說明︰device參數為(wei)指(zhi)定打(da)開的網絡設備名。snaplen參數定義捕獲數據(ju)的最(zui)大字(zi)節數。promisc指(zhi)定是否將網絡接口置于混雜模式。to_ms參數指(zhi)定超(chao)時時間(毫秒)。ebuf參數則僅在pcap_open_live()函數出(chu)錯返回(hui)NULL時用于傳(chuan)遞錯誤消息。
    返回(hui)值︰打(da)開的網卡(ka)句柄(bing)
    Arpspoof中將網卡(ka)的打(da)開操作進行了如下lu)庾埃 饔檬敝苯郵淙臚ka)序號即(ji)可(ke),程序會對(dui)參數2、3、4進行初始(shi)化(hua)設置︰
    pcap_t* OpenAdapter(int uIndexofAdapter, char szIPSelf[],
         unsigned char ucPhysicalAddr[], char szGateIPAddr[])
    {
     pcap_if_t *alldevs;
     pcap_if_t *d;
     pcap_t *fp = NULL;
        int i = 0;
        char errbuf[PCAP_ERRBUF_SIZE], *p;
        /* 這個(ge)API用來獲得網卡(ka)的列(lie)表 */
        if (pcap_findalldevs(&alldevs, errbuf) == -1)
        {
            fprintf(stderr,"Error in pcap_findalldevs: %s ", errbuf);
            return NULL;
        }
        /* 顯示(shi)列(lie)表的響應字(zi)段的內容(rong) */
        for (d=alldevs; d; d=d->next)
        {       
      if (d->addresses != NULL && (p = strchr(d->name, '{')) != NULL
       && Getadapterbyname(p, szIPSelf, ucPhysicalAddr, szGateIPAddr))
      { 
       if (i == uIndexofAdapter)
       {
        if ((fp = pcap_open_live(d->name, // 設備名稱
         65536,     // portion of the packet to capture.
         // 65536 grants that the whole packet will be captured on all the MACs.
         1,       // 混雜模式
         1, //讀(du)超(chao)時為(wei)1ms,越小越好(hao)
         errbuf     // error buffer
         )) == NULL)
        {
         fprintf(stderr," Unable to open the adapter.
          %s is not supported by WinPcap ", d->name);
         pcap_freealldevs(alldevs);
         return NULL;

     

        }
        else
        {
         // 去掉網卡(ka)注釋右邊的mu)kong)格
         for(int j = strlen(d->description) - 1; j > 0; j--)
         {
          if (d->description[j] == 0x20)
           d->description[j] = '';
          else
           break;
         }
         printf("[*] Bind on %s %s ... ", szIPSelf, d->description);
         return fp;
        }
       }
       i ++;
      }
        }
        if (i==0)
        {
            printf(" No interfaces found! Make sure WinPcap is installed. ");
            return FALSE;
        }
        /* We don't need any more the device list. Free it */
        pcap_freealldevs(alldevs);
     return NULL;
    }
     
    使用範例︰
    pcap_t *adhandle; // 網卡(ka)句柄(bing)
    unsigned char ucSelf[6];
    char szIPSelf[16], szIPGate[16];
    if ((adhandle = OpenAdapter(0, szIPSelf, ucSelf, szIPGate)) == NULL)
    {
     printf("[!] Open adatper error! ");
     return FALSE;
    }
    在獲取到網卡(ka)句柄(bing)並(bing)打(da)開後,發(fa)送數據(ju)包(bao)就很(hen)容(rong)易了
    if(pcap_sendpacket(adhandle, (const unsigned char *) ucFrame,
       ucFrameLen) 0)
    {
     printf("Send Packet Error ");
     return FALSE;
    }
    ucFrame是封裝好(hao)的數據(ju)包(bao),ucFrameLen為(wei)數據(ju)包(bao)的長度。
    下面我們封裝一個(ge)例子(zi),使用上(shang)述代碼發(fa)送ARP請(qing)求(qiu)包(bao),用于查詢某IP對(dui)應的MAC地址。
    ARP協議格式

     
    關鍵代碼
    bool sendARPData(pcap_t *adhandle)
    {
     u_char ucFrame[ARP_LEN];
     // 設置Ethernet頭
     ETHeader eh = { 0 };
     memset(eh.dhost,0xff, 6);//ARP廣(guang)播包(bao)目(mu)的地址為(wei)ffffffffffff
     memcpy(eh.shost, ucSelf, 6);
     eh.type = htons(ETHERTYPE_ARP);//幀(zheng)類(lei)型為(wei)ARP
     memcpy(ucFrame, &eh, sizeof(eh));
     
     // 設置Arp頭
     ARPHeader ah = { 0 };
     ah.hrd = htons(ARPHRD_ETHER);
     ah.eth_type = htons(ETHERTYPE_IP);
     ah.maclen = 6;//硬件地址長度
     ah.iplen = 4;//IP地址長度
     ah.opcode = htons(ARP_REQUEST);//ARP請(qing)求(qiu)包(bao)類(lei)型
     memcpy(ah.smac, ucSelf, 6);
     ah.saddr = inet_addr(szIPSelf); 
     memset(ah.dmac, 0x00, 6);//ARP請(qing)求(qiu)包(bao)中目(mu)的MAC地址均置0
     ah.daddr = inet_addr("192.168.0.2");   //ARP請(qing)求(qiu)的目(mu)的IP地址
     
     memcpy(&ucFrame[sizeof(ETHeader)], &ah, sizeof(ah));
     
     // 發(fa)送ARP數據(ju)包(bao)
     if(pcap_sendpacket(adhandle, (const unsigned char *) ucFrame,ARP_LEN) 0)
     {
      printf("Send Packet Error ");
      return FALSE;
     }
     return TRUE; 
    }
     
    啟動(dong)wireshark進行監听,運行程序,我們可(ke)以看到如下結果,程序發(fa)出(chu)了一個(ge)ARP廣(guang)播包(bao),用于查詢192.168.0.2的主(zhu)機MAC,並(bing)且目(mu)標機在收(shou)到該查詢包(bao)後,進行了回(hui)復,將自己的MAC地址告(gao)訴了查詢發(fa)起的機器。

    0×08 如何(he)監听分析數據(ju)包(bao)
    在監听數據(ju)包(bao)時,使用的關鍵函數為(wei)pcap_loop
    函數名稱︰int pcap_loop(pcap_t * p,int cnt, pcap_handler callback, uchar * user);
    參數說明:
    p 是由pcap_open_live()返回(hui)的所打(da)開的網卡(ka)的指(zhi)針;
    cnt用于設置所捕獲數據(ju)包(bao)的個(ge)數;
    callback 是回(hui)調函數,其(qi)原型為(wei)pcap_callback(u_char* argument,const struct pcap_pkthdr* packet_header,const u_char* packet_content)
    ;user值一般為(wei)NULL
    結合上(shang)面的代碼,我們在獲得並(bing)打(da)開網卡(ka)句柄(bing)adhandle,使用下面的代碼並(bing)可(ke)捕獲數據(ju)包(bao)
     
    //每次捕捉到數據(ju)包(bao)時,pcap都會自動(dong)調用這個(ge)回(hui)調函數
    void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
    {
     struct tm *ltime;
     char timestr[16];
     time_t local_tv_sec;
     //將時間戳轉換成可(ke)識別(bie)的格式
     local_tv_sec = header->ts.tv_sec;
     printf("%d ", local_tv_sec);
     ltime = localtime(&local_tv_sec);
     strftime(timestr, sizeof(timestr), "%H %M %S", ltime);
     printf("%s,%.6d len:%d ", ctime(&local_tv_sec), header->ts.tv_usec, header->len);
    }
     
    pcap_loop(adhandle, 0, packet_handler, NULL);
     
    程序在每一個(ge)數據(ju)包(bao)到來時,都會自動(dong)調用回(hui)調函數packet_handler來對(dui)數據(ju)包(bao)進行處理,其(qi)第三(san)個(ge)參數便是數據(ju)包(bao)內容(rong)。

     


    上(shang)圖(tu)為(wei)運行結果圖(tu),可(ke)以看到每一個(ge)數據(ju)包(bao)的時間戳lie)畔  統(tong)?刃畔 br />值得注意的是,原始(shi)套接字(zi)也可(ke)以完(wan)成數據(ju)包(bao)的發(fa)送和tu) ?鰨 dan)是與(yu)winpcap相比,在監听數據(ju)包(bao)方面是有區別(bie)的,由于winpcap更接近與(yu)底層,所以在混雜模式下,凡是到達網卡(ka)的數據(ju)包(bao)不管目(mu)的地址是否為(wei)自身主(zhu)機,winpcap均能接收(shou)到;而原始(shi)套接字(zi)只能接收(shou)到投duan)透約旱氖ju)包(bao)。
    0×09 總結與(yu)預告(gao)
    本章中我們簡單認識du)inpcap的相關基(ji)礎知識,學(xue)習了發(fa)送數據(ju)包(bao)和接收(shou)數據(ju)包(bao)的方法,其(qi)實不難發(fa)現,發(fa)送和接收(shou)數據(ju)包(bao)的過(guo)程都比較簡單,只需(xu)要(yao)調用相關庫函數即(ji)可(ke),而更多的精力在數據(ju)包(bao)的組織和拆分上(shang),同時在一些(xie)場景中,算法的使用也較為(wei)重(zhong)要(yao)。在接下來的章節中,我們會看到下面的內容(rong)︰
    1.掃描存(cun)活主(zhu)機
    2.Arp欺騙的實現與(yu)應用
    3.端(duan)口掃描
    4.流量監控與(yu)統(tong)計(ji)分析

威尼斯人官网官网

About IT165 -廣(guang)告(gao)服務 -隱私(si)聲明 -版權申(shen)明 -免(mian)責(ze)條款 -網站地圖(tu) -網友(you)投稿 -聯系方式
本站內容(rong)來自于互聯網,僅供用于網絡ke)際躚xue)習,學(xue)習中請(qing)遵循相關法律法規
威尼斯人官网官网 | 下一页