ARPSpoofing、arp欺骗性攻击、arpspoof源码分析

ARPSpoofing

什么是ARP协议
  • 一台主机和另一台主机通信,要知道目标的IP地址,但是在局域网传输的网卡却不能直接识别IP地址,所以用APR解析协议将IP地址解析成MAC地址。ARP协议的基本功能就是通过目标设备的IP地址,来查询设备的MAC地址。
  • 在局域网的任意一台主机中,都有一个ARP缓存表,里面保存本机已知的此局域网中各主机和路由器的IP地址和MAC地址的对照表关系。ARP缓存表的生命周期是有时限的(一般不超过20min)。
  • 以下是IPv4在ARP包上的结构:

    1

    包含的信息有:类型、长度、操作、发送方地址、目标地址。

什么是ARP欺骗攻击
  • 基于如下原则:
    任何主机均能发送伪造包给局域网中的另一主机;
    任一主机相信它们接受到的所有包;
    当一个新的响应包到达时,它甚至在没有请求包被发送的情况下覆盖掉旧的记录。
  • 举个例子:
  • 假设局域网中有4台主机,由于ARP欺骗攻击建立在局域网主机间相互信任的基础上,当A发广播询问:我想知道IP192.168.0.3的硬件地址是多少?
  • 此时B当然会回话:我是IP192.168.0.3,我的硬件地址是mac-b。可是此时IP地址是192.168.0.4的C也非法回了:我是IP192.168.0.3我的硬件地址是mac-c,并且,这种回应是大量的。
  • 所以A就会误信192.168.0.3的硬件地址是mac-c,并且动态更新缓存表。这样,主机C就劫持了主机A发送给主机B的数据,这就是ARP欺骗的过程。
  • 假设C直接冒充网关,此时主机C会不断地发送ARP欺骗广播,大声说:我的IP是192.168.0.1,我的硬件地址是mac-c,此时局域网内所有的主机都被欺骗,更改自己的缓存表,此时C将会监听到整个局域网发给互联网的数据报。
ARP欺骗的常用工具:arpspoof
  • Ubuntu环境下对源码进行编译及分析:
  • 下载dsniff源码 sudo apt-get source dsniff
  • 下载安装编译所需依赖项libnet1、libpcap等:
sudo apt-get install libnet1
sudo apt-get install libpcap-dev
sudo apt-get install libnet1-dev
  • 提取dsniff源码目录下的arp.c, arp.h, arpspoof.c三个文件,将其合并为一个arpspoof.c文件,想办法gcc/clang编译成功。

  • 将其合并成一个arpspoof.c稍作修改并添加注释如下:

/*
 * arpspoof.c
 *
 * Redirect packets from a target host (or from all hosts) intended for
 * another host on the LAN to ourselves.
 * 
 * Copyright (c) 1999 Dug Song <dugsong@monkey.org>
 *
 * $Id: arpspoof.c,v 1.5 2001/03/15 08:32:58 dugsong Exp $
 *
 * Improved 2011 by Stefan Tomanek <stefa@pico.ruhr.de>
 */

//#include "config.h"

#include <sys/types.h>              //基本系统数据类型
/*包含caddr_t clock_t comp_t dev_t fd_set fpos_t gid_t 
ino_t off_t mode_t pid_t ptrdiff_t rlim_t size_t ssize_t
time_t uid_t wchar_t*/
#include <sys/param.h>
#include <sys/socket.h>             //与套接字相关的函数声明和结构体定义
/*SOCKET_STREAM:流式套接字 SOCKET_DGRAM:数据报式套接字 SOCKET_RAW:原始套接字
创建套接字:socket() 绑定本机端口:bind() 建立连接:connect(),accept() 
倾听端口:listen() 数据传输:send(),recv() 输入/输出多路复用:select()
关闭套接字:closesocket() */

/*通过使用#ifdef指示符,我们可以区隔一些与特定头文件、程序库
和其他文件版本有关的代码,提高程序的通用性。*/
#ifdef BSD
#include <sys/sysctl.h>             //sysctl函数头文件
#include <net/if_dl.h>
#include <net/route.h>
#ifdef __FreeBSD__  /* XXX */
#define ether_addr_octet octet      //网络字节地址定义
#endif
#else /* !BSD */
#include <sys/ioctl.h>      //I/O控制操作相关的函数声明,如ioctl()
#ifndef __linux__
#include <sys/sockio.h>
#endif
#endif /* !BSD */
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>             //端口宏定义,著名ip(loopback),结构sockaddr_in..
/*网络字节转换(ntoh,hton...),用途广泛。*/
#include <netinet/if_ether.h>       //ether_arp的数据结构

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> //提供对POSIX操作系统API的访问功能的头文件的名称。
#include <string.h>

//#include "config.h"

//#include <sys/types.h>
//#include <sys/param.h>
//#include <netinet/in.h>

//#include <stdio.h>
//#include <string.h>
#include <signal.h> //C标准函数库中的信号处理部分,定义了程序执行时如何处理不同的信号。
#include <err.h>
#include <libnet.h> //libnet 是一个小型的接口函数库,主要用 C 语言写成,提供了低层网络数据包的构造、处理和发送功能。
#include <pcap.h>   //这个抓包库给抓包系统提供了一个高层次的接口。所有网络上的数据包,通过这种机制,都是可以捕获的。

#ifndef _ARP_H_
#define _ARP_H_

#include <net/ethernet.h>   //包括几个以太网的数据结构,ether_addr(mac帧结构),
/*ether_header(以太帧的头部)*/

/*声明了查找arp缓存表的函数*/
int arp_cache_lookup(in_addr_t ip, struct ether_addr *ether, const char* linf);

#endif

//#include "arp.h"
//#include "version.h"

#ifdef BSD      //BSD系统中的arp_cache_lookup函数实现
/*ip为查找IP值 */
int
arp_cache_lookup(in_addr_t ip, struct ether_addr *ether, const char* linf)
{
    int mib[6];
    size_t len;                 //长度
    char *buf, *next, *end;     //缓存、下一个、最后一个
    struct rt_msghdr *rtm;      //rt_msghdr结构
    struct sockaddr_inarp *sin; //sockaddr_in 是internet环境下套接字的地址形式
    struct sockaddr_dl *sdl;

    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 
  • 5
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值