scapy_ping扫描

scapy实现ping发包

  1. ping原理:
    Ping发送一个ICMP(Internet Control Messages Protocol)即因特网信报控制协议;回声请求消息给目的地并报告是否收到所希望的ICMPecho (ICMP回声应答)。它是用来检查网络是否通畅或者网络连接速度的命令。
  2. 看一下数据包结构:
    使用wireshark抓包,ping 192.168.254.226,一共发送四个请求包,接收四个响应包
    在这里插入图片描述
    请求包:
    scapy_ping扫描_第1张图片
    响应包:
    scapy_ping扫描_第2张图片
  3. 使用scapy进行自动发包并且获取响应:
    代码如下:
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
from random import randint
def scapy_ping_one(host):
    id_ip=randint(1,65535) #产生随机的IP ID位
    id_ping=randint(1,65535) #产生随机ping ID位
    seq_ping=randint(1,65535) #随机产生ping序列号位
    #构造ping数据包
    packet = IP(dst=host, ttl=64, id=id_ip) / ICMP(id=id_ping, seq=seq_ping) / b'rootkit'
    re = sr1(packet)
    #re.show()    #可打印得到的响应数据
    if re: #如果有响应信息,退出码为3
        os._exit(3)
if __name__=='__main__':
    scapy_ping_one("192.168.254.226")

运行结果:
scapy_ping扫描_第3张图片
ps:运行代码的时候注意,如果电脑有多张网卡记得把多余网卡关掉,因为上面代码没有指定发数据的网卡。
4. 查看一下scapy发包的数据包结构:
一共发送了一个ICMP数据包:
在这里插入图片描述
请求包:
scapy_ping扫描_第4张图片
响应包:
scapy_ping扫描_第5张图片
5. 多线程实现ping扫描:

import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
from random import randint
import ipaddress   #可用于IP地址的计算
import multiprocessing  #用于开启多线程
def scapy_ping_one(host):
    id_ip=randint(1,65535) #产生随机的IP ID位
    id_ping=randint(1,65535) #产生随机ping ID位
    seq_ping=randint(1,65535) #随机产生ping序列号位  ,ICMP的序列号

    #构造ping数据包
    packet = IP(dst=host, ttl=64, id=id_ip) / ICMP(id=id_ping, seq=seq_ping) / b'11111'
    re = sr1(packet)
    #re.show()
    if re: #如果有响应信息,退出码为3
        os._exit(3)

#多线程扫描函数
def scapy_ping_scan(network):
    net=ipaddress.ip_network(network)  #解析IP地址
    ip_process={}  #创建字典用于存储扫描结果
    for ip in net:
        ip=str(ip)  #转换为字符串类型
        print(ip)
        ping_one=multiprocessing.Process(target=scapy_ping_one,args=(ip,))
        ping_one.start()
        time.sleep(3)   #休眠三秒,否则有可能因为进程过快,结果无法获取
        ip_process[ip] = ping_one     #产生IP与进程对应的字典
    ip_list=[]
    for ip,process in ip_process.items():
        if process.exitcode==3:
            ip_list.append(ip)
        else:
            process.terminate()
    return sorted(ip_list)

if __name__=='__main__':
    #scapy_ping_one("192.168.254.226")
    active_ip=scapy_ping_scan("192.168.254.224/29")
    for ip in active_ip:
        print(ip)

ps:其中的坑,休眠三秒,在开启一个新线程进行扫描后休眠,否则测试时无法获取扫描得到的数据。

结果:
scapy_ping扫描_第6张图片

然后查看发包情况,与上面相符,只有三个包获取到了响应包。
scapy_ping扫描_第7张图片

你可能感兴趣的:(scapy)