前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Python】使用scapy模块编写ARP欺骗脚本

【Python】使用scapy模块编写ARP欺骗脚本

作者头像
一名白帽的成长史
发布2019-10-08 15:38:48
5.2K1
发布2019-10-08 15:38:48
举报
Hello,各位小伙伴们周末好~

今天复习自己公众号写的文章,小编发现脚本模块现在只挂着两篇文章...

赶紧写起来!!!(公众号逼我学习系列~)

最近决定发奋图强,写多篇python脚本相关的东西

今天我们先来写一个简单的ARP欺骗脚本练练手吧~

Part.1

认识scapy工具

scapy基本用法

我们编写ARP欺骗脚本时需要用到scapy模块,利用该模块我们根据自己的需要定义一系列的报文,并通过scapy发送出去,最后再接收回应。

scapy除了可以作为Python库被调用之外,也可以作为单独的工具使用,我们先来学习一下这个工具是怎么构造报文的。

在kali中输入scapy我们就可以打开这个软件:

通过自带的ARP()方法,构造一个arp报文kpt,使用show()方法可以查看报文的详细内容:

上面的每一个字段都对应了ARP头的相应字段:

我们可以自定义任意字段,例如修改目的IP为192.168.211.151:

注意:以上所有参数均为字符型,赋值需要用单引号引起来。其中源IP/MAC默认值为Kali的IP和MAC地址。

使用sr1方法可以进行发包 :

(send receive ,1代表只接收第一个回复包,只输入sr代表接收所有回复包)

使用wireshark抓到发送的报文:

我们还可以将sr1的结果赋值给一个变量:

通过变量来查看收到的应答报文会更加清晰:

//其中Padding为报文长度不够时的填充部分

报文的构造规则

来看看我们刚刚抓到的报文,二层帧头部分默认为一个广播包:

那是因为我们构造arp请求时,只配置了ARP()的内容,而没有指定帧的部分。

但是arp报文也是有二层的报头,因此系统为我们加上了默认帧头:

现在来构造一个完整的ARP报文,和TCP报文:

注意:上图每一层必须按照TCP/IP协议簇顺序从外往内构造。构造好的TCP报文内容如下:

此时就可以自定义任意字段的内容啦~~

报文的发包方式

我们来尝试构造一个ARP应答报文。

首先定义一个arp报文,这次带上二层帧头:

//二层帧头源MAC默认为本机的mac,目的默认为网关的mac

我们现在给192.168.211.1发送一个应答包:

(1)修改二层帧头 目的mac为211.1的mac地址;

(2)arp头中,op代表报文类型,1为请求包,2为响应包,修改为2;最后再修改arp头部的目的MAC/IP地址为211.1的地址:

查看修改后的报文:

报文就构造好了,就可以发包了~

但是注意!!指定了Ether头部后使用sr1(pkt)方式系统是不会发包:

//输入sr1(pkt),查看wireshark什么都抓不到

需要使用srp1(pkt)方法,根据二层帧头来发包。

但这里发送的是个应答包,目标主机不会回复报文,因此我们使用sendp(pkt)方式,根据二层发包,但不接收响应包,wireshark抓包如下:

四种发包方式用法:

(1)只发不收

  • send(),在第三层发包,不关心第二层的封装,第二层采用默认值;
  • sendp(),根据第二层发包,需要手动指定第二层如何封装。

(2)发包且收包

  • sr()和sr1()都是在第三层发包,sr1表示只接收第一个回复。
  • srp()和srp1()都是根据第二层发包,srp1表示只接收第一个回复。

还可以在发包的同时构造报文,效果和上面相同:

超时时间

使用sr1等方法,如果目标地址不响应我们发送的报文,系统会一直等待:

//只能通过Ctrl+c停止

我们可以设置一个超时时间,系统在超时时间后就会停止等待了:

以上就是scapy的基本用法了~

Part.2

编写ARP欺骗脚本

构造ARP欺骗包

实验拓扑如下:

我们先用scapy发送一个arp欺骗包,欺骗主机A kali才是网关。

先查看一下主机A的arp表:

发送ARP欺骗包:

//源IP修改为网关IP,源MAC默认为kali的MAC,目的IP修改为主机A的IP。

再次查看主机A的arp表项,欺骗成功:

ARP欺骗一次后,主机A会短暂断网,直到重新学到网关的真实IP:

但是,欺骗后也留下了痕迹,网关MAC和Kali MAC相同:

为什么会出现这种情况呢?通过wireshark抓包发现kali在发送欺骗包时,先会自己发送一个arp报文去问谁是192.168.211.151,再发送欺骗包:

造成该现象的原因是没有自定义二次帧头,kali会先发送了广播报文去问谁是192.168.211.151。

我们清空主机A的arp表项,再来实验一次。

重新发送arp报文,加上一个帧头(可以是广播):

Wireshark抓包,本次直接发送欺骗包了:

查看主机A的arp表项,不再留下痕迹,成功欺骗:

接下来,我们就按照这个思路来编写脚本吧~

Python脚本

基本代码:

  • from scapy.all import * 用于引入scapy模块
  • 定义arpspoof()函数用于接收欺骗主机IP(target)与冒充主机IP(ip)
  • main()函数定义target与ip变量,并传入arpspoof函数

我们先清一下主机A的ARP表项,清除后如下:

执行我们编写的脚本:

查看主机A的ARP表项,无痕迹成功欺骗:

脚本优化

首先对arpspoof函数进行优化,加入try/except语句进行异常处理。

用法:程序执行时,如果try子句中没有异常发生,那么except子句在try语句执行之后被忽略;如果try子句中有异常发生,那么该部分的其他语句将被忽略,直接跳到except部分,执行其后面的子句。

代码优化如下:

接着是main函数部分,我们使用sys.argv[]方式,允许脚本从外部传入target与ip的值:

关于sys.argv的说明:sys.argv是一个变量,专门用来向Python解释器传递参数,类似于Shell脚本编程中的位置变量。

sys.argv[0]存放脚本的名字,所以传递的第一个参数target存放在sys.argv[1]中,ip存放在sys.argv[2]。因此如果len(sys.argv)!=3,就报错退出。

再来我们通过str()函数将变量转换为字符串格式,并通过strip()祛除空格。

main()函数的第二部分,我们写入一个循环:

每0.5秒发送一次报文,达到持续攻击的目的。

KeyboardInterrupt用于接收键盘指令,当我们输入Ctrl+c时,结束循环。

接下来我们测试一下脚本,什么都不输入:

传入target与ip的值,持续欺骗直到输入Ctrl+c:

查看主机A的arp表项,网关为kali的MAC:

执行一次,我们通过wireshark抓包看看:

//可以看到持续不断地发送ARP欺骗报文。

其实arp欺骗我们不仅需要欺骗主机A,同时还要冒充主机A去欺骗网关。这里我们可以同时执行两个脚本,输入时将target与ip调换即可。

当然也可以修改脚本,在脚本中再发送target与ip调换的包,这里就不演示啦~

当达成ARP欺骗后,主机A的报文都会发到kali这里来,kali抓到包后并不会转发出去,会导致主机A断网,被用户发现。

因此需要开启kali的报文转发功能:

开启后,网络就不会中断了。

最后附上全部代码

Part.3

结语

好啦,这就是今天的全部内容了,小伙伴们都学会了吗?

Peace!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一名白帽的成长史 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档