要求
内网主机存活检测脚本实现
a.安装scapy 模块
b.构造数据包
c.接收返回包
d.判断主机是否在线
f.批量扫描网段
思考
在编写代码之前,我们还需要考虑以下问题
IP地址工作在IP层,ICMP,还有ARP协议也存在IP信息
先使用 ping 命令进行IP探测,但是此扫描方式存在Bug,一旦防火墙禁止ICMP,那么扫描结果失效
import socket,time,threading,os
from scapy.layers.inet import TCP, IP
from scapy.layers.l2 import ARP
from scapy.sendrecv import sr1
#配置日志记录的级别为ERROR
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
def ping_ip():
for i in range(1,255):
ip = f'192.168.21.{i}'
# output = os.popen(f'ping -n 1 -w 100 {ip}').read()
# if 'TTL=' in output:
# print(f"{ip} online")
output = os.popen(f'ping -n 1 -w 100 {ip} | findstr TTL=').read()
if len(output) > 0:
print(f"{ip} online")
# 如何使用别的方式,让防火墙不存在封锁的行为?了解一下ARP协议
def scapy_ip(start):
for i in range(start,start+20):
ip = f'10.9.46.{i}'
try:
pkg = ARP(psrc='10.9.46.120',pdst=ip)
reply = sr1(pkg,timeout=2,verbose=False)
print(reply[ARP].hwsrc)
print(f"{ip} 在线")
except:
pass
if __name__ == '__main__':
#ping_ip() #ping 命令进行IP探测
#scapy_ip() #ARP协议 IP扫描
for i in range(1,255,20):
threading.Thread(target=scapy_ip,args=(i,)).start()
ICMP扫描方式运行结果图
ARP扫描方式运行结果图
部分代码解释
output = os.popen(f'ping -n 1 -w 100 {ip} | findstr TTL=').read()
代码使用了os
模块的popen
函数来执行命令,并通过管道将ping
命令的输出传递给findstr
命令进行过滤。-n 1
参数表示只发送1个ICMP回显请求,-w 100
参数表示等待100毫秒后超时。findstr TTL=
用于过滤出包含"TTL="的行,以确定目标主机是否在线。
通过read()
方法,你获取了命令的输出并将其赋值给了output
变量。现在,output
将包含符合过滤条件的命令输出。
如果目标主机在线,output
将是非空的。
pkg = ARP(psrc='10.9.46.1',pdst=ip)
reply = sr1(pkg,timeout=2,verbose=False)
print(reply[ARP].hwsrc)
首先,pkg = ARP(psrc='10.9.46.1', pdst=ip)
创建了一个ARP包,其中psrc
字段设置为你的源IP地址(在这种情况下是'10.9.46.1'
,通常是你的本地网关),pdst
字段则设置为目标IP地址(在这种情况下是变量ip
的值)。
接下来,reply = sr1(pkg, timeout=2, verbose=False)
发送了该ARP包并等待回复。sr1()
函数将发送ARP包并阻塞等待回复,然后返回第一个回复的数据包。如果在超时时间(2秒)内没有收到回复,它将返回None
。
最后,print(reply[ARP].hwsrc)
打印了回复数据包中的源MAC地址。reply[ARP]
将返回ARP数据包对象, .hwsrc
属性将返回源MAC地址。