Scapy扫描局域网

Scapy是一个强大的交互式数据包处理程序(使用python编写)。它能够伪造或者解码大量的网络协议数据包,能够发送、捕捉、匹配请求和回复包等等。

Scapy起源于Linux,但在windows上也可以安装,具体步骤见下面链接:

https://www.cnblogs.com/qingkongwuyun/p/8508733.html

但是Scapy学习资料比较少,涉及的网络协议比较复杂,所以不太好学。我们首先来看一个简单的例子:

# -*- coding: utf-8 -*-
from scapy.all import srp, Ether, ARP

arp_request=Ether(dst='FF:FF:FF:FF:FF:FF')/ARP(pdst='192.168.1.232')
arp_request.show()

先来看看ARP函数结构:

>>> ls(ARP)
hwtype     : XShortField          = (1)
ptype      : XShortEnumField      = (2048)
hwlen      : ByteField            = (6) 
plen       : ByteField            = (4)
op         : ShortEnumField       = (1) 取值为1或者2,代表ARP请求或者响应包。{"who-has":1, "is-at":2}

hwsrc      : ARPSourceMACField    = (None) 发送方Mac地址。
psrc       : SourceIPField        = (None) 发送方IP地址。
hwdst      : MACField             = ('00:00:00:00:00:00') 目标Mac地址。
pdst       : IPField              = ('0.0.0.0') 目标IP地址。

Ether函数:

>>> ls(Ether)
dst        : DestMACField         = (None) 目的MAC
src        : SourceMACField       = (None) 源MAC
type       : XShortEnumField      = (36864)
这个op选项很重要,1为ARP请求,2为ARP应答。
构造一个以太网数据包通常需要指定目标和源MAC地址,如果不指定,
默认发出的就是广播包ff:ff:ff:ff:ff:ff,即向同一网段内的所有主机发出询问

关于Ether协议,上面的三个属性只代表Ether的头部,完整的Ether由以下几部分组成:

FCS(Frame Check Sequence)表示尾帧,用来检查帧在传输的过程中是否损坏。类型(type)表示后面的数据是属于哪种类型的数据,例如Type为0x0800时为IP协议包,Type为8060时,后面为ARP协议包,RARP为8035,IPv6为86DD等。

Ether本身不是个完整的东西,它只是传递其它协议数据的中转站。

关于ARP的op值,我们举个例子:

arp_frame = Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(op=1, pdst="10.0.0.3")
resp,unans = srp(arp_frame)
#可以看出,op=1时,构造一个ARP请求,既然是请求,就需要应答,所以srp函数接受应答的数据。
....
packet = scapy.ARP(op=2, pdst=dest_ip, hwdst=dest_mac, psrc=source_ip, hwsrc=source_mac) 
scapy.send(packet, count=4, verbose=False) 
#此时op=2,表示告知对方某某事物,不需要回答,所以采用send函数就可以了

 

上面的程序构建了一个Ether()/ARP()数据包。‘/’符号被重载为“叠加”,即在Ether数据包上面再叠加一层ARP数据。运行结果如下:

从上面的图可以看出,[ARP]后面的东西就是ARP()数据包叠加的相关数据参数。

关于以太网的数据格式及传输,可参考下面文章:

http://www.cnblogs.com/qishui/p/5437301.html

下面回到正题,扫描局域网上存活的主机及MAC地址,先贴代码:

# -*- coding: utf-8 -*-
from scapy.all import srp, Ether, ARP

IpScan = '192.168.0.0/24'
try:
    #使用Ether()/ARP()构造ARP包
    packet = Ether(dst="FF:FF:FF:FF:FF:FF")/ARP(pdst=IpScan)
    #srp():发送与接收ARP包,返回一个元组。元组的第一个元素就是收到的数据包,第二个指未收到的包
    ans,_ = srp(packet, timeout=2)
except Exception as e:
    print(e)
else:
    #解析获取的包的信息,得到局域网中存活的主机的IP地址和MAC地址
    for _, rcv in ans:
#        ListMACAddr = rcv.sprintf("%Ether.src%---%ARP.psrc%")
#        print(ListMACAddr)
        print(rcv[ARP].psrc,'----',rcv.src)

 

上面代码中的rcv变量,存放的就是类似于Ether()/ARP()构造的数据包,可以依据前面列出的相关属性进行访问。

其实还有个极简单的方式扫描局域网,那就是arping()方法,如下:

一步到位,真强!

参考文章:

https://zhuanlan.zhihu.com/p/34843290

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值