在第二层主机发现中,除了使用arping命令外,还可以使用Kali下自带的一个工具————netdiscover。
netdiscover是一个专门用于二层主机发现的工具,它有两种扫描方式:主动扫描和被动扫描。其中,主动扫描的原理就是对外发送ARP广播,操作也很简单。例如,我本机的IP所在的网段为192.168.80.0/24,我要扫描我这个网段的存活主机,指令为netdiscover -r 192.168.80.0/24 这里的扫描参数为r。被动扫描的原理是将我们自己机器的网卡设置为混杂模式,接受网络中的ARP广播,被动扫描相比主动扫描的好处是被动扫描可以隐蔽自己。操作指令为netdiscover -p,如下所示:
介绍完工具之后,我们来用python实现一下这个功能,与之前利用python模块subprocess发送arping命令不同是,这次我们使用python下的另外一个模块————scapy。
scapy模块的优势在于可以自由的去构造一系列的报文,并通过scapy发送出去,再接收回应。另外scapy模块对接收到的回应只做解码,而不做解释,它只会如实显示响应的报文,不会去提供分析的结论,至于判断和利用都由我们自己来决定。,并且scapy可以在二、三、四层工作。
先上代码
import os
import time
from scapy.all import *
from threading import Thread
from optparse import OptionParser
def sweep(ip):
try:
pakt=Ether(dst="ff:ff:ff:ff:ff:ff",src="")/ARP(
hwsrc="",psrc="",hwdst="00:00:00:00:00:00",pst=ip
)
#src源mac,hwsrc源mac,psrc写源ip
if result:
time.sleep(0.1)
print ip,'在线'
return
except:
return
def main():
usage="Usage: %prog -f <filename> -i <ip address>"
parser=OptionParser(usage=usage)
parser.add_option("-f","--file",type="string",dest="filename",help=
"specify the IP address file")
parser.add_option("-i","--ip",type="string",dest="address",help=
"specify the IP address")
(options,args)=parser.parse_args()
filename=options.filename
address=options.address
if(filename == None and address == None):
print "请指定IP列表文件或者IP地址"
sys.exit()
if filename:
if not os.path.exists(filename):
print "指定文件不存在,请重新输入"
sys.exit()
f=open(filename,"r")
for i in f.readlines():
ip = i.strip("
")
t=Thread(target=sweep,args=(ip,))
t.start()
if address:
prefix=address.split(".")[0]+"."+address.split(".")[1]+"."+address.split(".")[2]+"."
for i in range(1,255):
ip=prefix+str(i)
t=Thread(target=sweep,args=(ip,))
t.start()
if __name__=='__main__':
main()
代码的一些解释
1.sweep()函数中是这个脚本的主要功能,我们通过scapy构造一个ARP广播包。dst为目的mac地址,这里由于我们要发现主机,所以填写广播地址ff:ff:ff:ff:ff:ff ,src为本机的mac地址,可以不填写。hwsrc同样为本机的mac地址,psrc为本机的ip地址,hwdst为被攻击的mac地址,这里保持默认就好。
2.verbose=0的作用是不反馈各种信息,如果不加这条,会返回很多影响我们判断的信息,建议写上。
3.-f选项是读取文件,-i选项是选择ip地址
4.readlines()方法是一次性把内容都读取到内存中,当文件很大时,可能会导致内存不够用。要读取大文件的话,一般是一行一行的读,
如 f=open('password.txt')
for i in f:
print i.strip()
...