Social Icons

twitterfacebookgoogle plusrss feedemail

3/31/2013

抓取網路ARP封包

點圖可放大
前面幾篇文章談到過Sock_RAW用法ARP介紹以及攻擊防禦方法,在這邊我們要先學習如何抓取封包資訊,這樣我們才能夠去更改封包欄位資訊~!
以下系列文章只用於學術學習,請不要拿來攻擊別人電腦

完整程式碼會在教完作業後發佈上來,這邊稍為介紹一下怎麼抓ARP封包
記得使用root權限執行!
一、步驟:
1.假設自己IP為192.168.1.131
2.假設arp請求發起方的IP為192.168.1.254
3.在自己電腦中開啟程式
4.觀察程式的輸出
二、arp封包的格式

請至此觀看詳細欄位格式:http://www.ipv6.com/articles/general/Address-Resolution-Protocol.htm

三、示範影片

 建議切換至720P全螢幕觀賞
  
四、程式碼


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
#include "debug.h"




/*arp_packet*/
struct arp_packet
{
     //各項欄位資訊查詢man Page
    //Header 
    //Dest mac
    unsigned char mac_target[ETH_ALEN];
    //Source mac
    unsigned char mac_source[ETH_ALEN];
    //Ethertype 
    unsigned short ethertype;

    //ARP Frame
    // 乙太網類型值0x1
    unsigned short hw_type;
    //proto - IP協議(0x0800)
    unsigned short proto_type;
    //MAC地址長度
    unsigned char mac_addr_len;
    //IP地址長度
    unsigned char ip_addr_len;
    //操作碼 - 0x1表示ARP請求包,0x2表示應答包
    unsigned short operation_code;
    //發送方mac
    unsigned char mac_sender[ETH_ALEN];
    //發送方ip
    unsigned char ip_sender[4];
    //接收方mac
    unsigned char mac_receiver[ETH_ALEN];
    //接收方ip
    unsigned char ip_receiver[4];
    //填充數據
    unsigned char padding[18];//暫時用不到
};


#ifdef DEBUG
#define Debug_printf(format, args...) printf("[%s:%d] "format, __FILE__, __LINE__, ##args)
#else
#define Debug_printf(args...)
#endif

int main()
{
    int sfd;
    struct sockaddr_ll my_etheraddr;
    struct arp_packet rcvbuff;
    //socket: only catch ARP packets
    sfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
    if(-1 == sfd)
    {
        Debug_printf("socket error");
    }

    memset(&my_etheraddr, 0, sizeof(my_etheraddr));
    my_etheraddr.sll_family = PF_PACKET;
    my_etheraddr.sll_protocol = htons(ETH_P_ARP);
    my_etheraddr.sll_ifindex = IFF_BROADCAST;

    //bind
    if(-1 == bind(sfd, (struct sockaddr *)&my_etheraddr, sizeof(my_etheraddr))){
        Debug_printf("bind error");
    }

    while(1)
    {
        //recv
        if(-1 == recv(sfd, &rcvbuff, sizeof(rcvbuff), 0)){
            Debug_printf("recv error");
            continue;
        }

        print_packet(rcvbuff);
    }

    return 0;
}

//參考man page 或者封包格式欄位
void print_packet(struct arp_packet ap)
{
    printf("\n-----------------arp package begin--------------------------\n");
    int i ;
    printf(" mac_target = ");
    for( i = 0; i < ETH_ALEN; i++)
        printf(i > 0 ? ":0x%.2x" : "0x%.2x", ap.mac_target[i]);
    printf("\n mac_source = ");
    for( i = 0; i < ETH_ALEN; i++)
        printf(i > 0 ? ":0x%.2x" : "0x%.2x", ap.mac_source[i]);
    printf("\n ethertype = 0x%x", ntohs(ap.ethertype));
    printf("\n hw_type = 0x%x", ntohs(ap.hw_type));
    printf("\n proto_type = 0x%x", ntohs(ap.proto_type));
    printf("\n mac_addr_len = 0x%x", ap.mac_addr_len);
    printf("\n ip_addr_len = 0x%x", ap.ip_addr_len);
    printf("\n operation_code = 0x%x", ntohs(ap.operation_code));
    printf("\n mac_sender = ");
    for(i = 0; i < ETH_ALEN; i++)
        printf(i > 0 ? ":0x%.2x" : "0x%.2x", ap.mac_sender[i]);
    printf("\n ip_sender = %s", inet_ntoa(*(struct in_addr*)(ap.ip_sender)));
    printf("\n mac_receiver = ");
    for( i = 0; i < ETH_ALEN; i++)
        printf(i > 0 ? ":0x%.2x" : "0x%.2x", ap.mac_receiver[i]);
    printf("\n ip_receiver = %s", inet_ntoa(*(struct in_addr*)(ap.ip_receiver)));

    printf("\n-----------------arp package end----------------------------\n");
}

程式碼載點
RAR: 載點1 載點2
Zip: 載點1 載點2

沒有留言:

張貼留言

俗話說
凡走過必留下痕跡,凡住過必留下鄰居
凡爬過必留下樓梯,凡來過必留下IP
看過文章之後歡迎留下您寶貴的意見喔!

 
 
无觅相关文章插件,迅速提升网站流量