1,ping程序原理:
ping向目标发送一个ICMP回声消息请求并报告是否收到回声。网络上 的机器都有唯一确定的 IP 地址,我们给目标 IP
地址发送一个数据包, 对方就要返回一个同样大小的数据包, 根据返回的数据包我们可以确定目标主机的存在。
例如在windows下自带的ping程序为例,进行抓包分析:
ping 192.168.219.101
icmp_echo_request:
type:8 code:0是echo_request
icmp_echo_reply:
type:0 code:0是echo_reply
2,程序实现
#!/usr/bin/python3.4
# _*_ coding=utf-8 _*_
#抑制scapy导入所出现的报错信息
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
#导入相应的包
from scapy.all import *
from random import randint
def ping_once(host):
#随机产生一个1-65535的IP的id位
ip_id=randint(1,65535)
#随机产生一个1-65535的icmp的id位
icmp_id=randint(1,65535)
#随机产生一个1-65535的icmp的序列号
icmp_seq=randint(1,65535)
#铸造数据包
packet=IP(dst=host,ttl=64,id=ip_id)/ICMP(id=icmp_id,seq=icmp_seq)/b'rootkit'
#发送数据包
ping=sr1(packet,timeout=2,verbose=False)
#如果收到回复则代表ping成功,成功就以退出码3退出(便于后续用来判断此进程是否成功)
if ping:
os._exit(3)
if __name__ == '__main__':
ping_once(sys.argv[1])
3,实现ping扫描
#!/usr/bin/python3.4
# _*_ coding=utf-8 _*_
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
import ipaddress
import time
import multiprocessing
from random import randint
from scapy.all import *
#实现ping扫描的函数
def ping_once(host):
ip_id=randint(1,65535)
icmp_id=randint(1,65535)
icmp_seq=randint(1,65535)
packet=IP(dst=host,ttl=64,id=ip_id)/ICMP(id=icmp_id,seq=icmp_seq)/b'rootkit'
ping=sr1(packet,timeout=2,verbose=False)
if ping:
os._exit(3)
#使用多进程连续调用ping_once函数,实现ping_scan
def ping_scan(network):
#此模块可以将一个网络转换成一个个ip地址
net=ipaddress.ip_network(network)
ip_processes={}
for ip in net:
#读取网络中的每一个IP地址,使用str将其转换成字符串
ip_addr=str(ip)
#开启多进程,使用ping_once这个函数扫描ip_addr这个地址
ping=multiprocessing.Process(target=ping_once,args=(ip_addr,))
#开启这个进程
ping.start()
#产生ip与进程对应的字典
ip_processes[ip_addr]=ping
ip_list=[]
for ip,process in ip_addresses.items():
if process.exitcode==3:
ip_list.append(ip)
else:
process.terminate()
return sorted(ip_list)
if __name__ == '__main__':
import time
t1=time.time()
active_ip=ping_scan(sys/argv[1])
print("活动IP地址如下:")
for ip in active_ip:
print(ip)
t2=time.time()
print(t2-t1)