如何使用python3模拟icmp发包

  • 模拟icmp协议快速探测内网机器
    • ICMP 包原理
    • 简单的创建icmp包信息
    • 创建raw socket 发送数据包
    • 接收数据包,以及解包
    • 完整的一次发包以及解析
    • 如何获取ttl值
  • 模拟icmp批量探测内网存活机器

模拟icmp协议快速探测内网机器

如果给定一个b段,如何快速检测出网段中的存活机器,我们肯定会想到ping命令,但有些机器可能开启防火墙策略,但是一个网段内,网关一般是可以被ping通的,所以icmp协议针对探测存活网段,缩小目标很重要。本文章主要讲解如何使用python3 raw socket 完成icmp协议探测

ICMP 包原理

我们要模拟ICMP发包,首先要了解其结构,一个ICMP报文包括IP报头(至少20字节)、ICMP报头(至少8字节)和ICMP报文(属于ICMP报文的数据部分),数据内容没有限制,我们本次不需要模拟IP头部信息,只要模拟ICMP头部和报文就可以, 通过wireshark抓包如下:

以上是通过ping baidu.com 抓包获取的,左边为请求的request包,右边回应的reply包,我们本次主要是模拟发送request包,以下为icmp request 包结构分析:

1.Type(类型):可以看到request中的type值为8,而reply中的type为0,下面表格中将对应Type的内容。

类型 含义
0 回送应答
3 目标不可达
4 原点抑制
5 重定向或改变路由
8 回送请求
9 路由器公告
10 路由器请求
11 超时
17 地址子网请求
18 地址子网应答

2.Code(代码) :占一字节,标识对应ICMP报文的代码。它与类型字段一起共同标识了ICMP报文的详细类型;
3. Checksum(校验和): 对包括ICMP报文数据部分在内的整个ICMP数据报的校验和;
4. Identifier: 为进程号,回送响应消息与回送消息中identifier保持一致,随机即可;
5. Sequence Number:序列号,由主机设定,一般设为由0递增的序列,回送响应消息与回送消息中Sequence Number保持,随机即可;

简单的创建icmp包信息

header = struct.pack('bbHHh', 8, 0, 0, 12345, 0)  # 创建头部
data = struct.pack('d', time.time())  # 创建data数据 时间戳随机

icmp 需要校验和

def inCksum(packet):if len(packet) & 1:packet = packet + '\0'words = array.array('h', packet)sum = 0for word in words:sum += (word & 0xffff)sum = (sum >> 16) + (sum & 0xffff)sum = sum + (sum >> 16)return (~sum) & 0xffff

创建一个完整的icmp包

header = struct.pack('bbHHh', 8, 0, 0, 12345, 0)  # 创建头部
data = struct.pack('d', time.time())  # 创建data数据 时间戳随机
packet = header + data
chkSum = inCksum(packet)
header = struct.pack('bbHHh', 8, 0, chkSum, 12345, 0)
icmp_data = header + data

创建raw socket 发送数据包

Sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname("icmp"))
Sock.sendto(icmp_data , (ip, 0))

接收数据包,以及解包

recv_packet, addr = Sock.recvfrom(1024)
type, code, checksum, packet_ID, sequence = struct.unpack("bbHHh", recv_packet[20:28])  # 前20个字节为ip头部信息,后8位为icmp头部信息

完整的一次发包以及解析

import array
import socket
import struct
import timedef inCksum(packet):if len(packet) & 1:packet = packet + '\0'words = array.array('h', packet)sum = 0for word in words:sum += (word & 0xffff)sum = (sum >> 16) + (sum & 0xffff)sum = sum + (sum >> 16)return (~sum) & 0xffffheader = struct.pack('bbHHh', 8, 0, 0, 12345, 0)  # 创建头部
data = struct.pack('d', time.time())  # 创建data数据 时间戳随机
packet = header + data
chkSum = inCksum(packet)
header = struct.pack('bbHHh', 8, 0, chkSum, 12345, 0)
icmp_data = header + dataSock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname("icmp"))
Sock.sendto(icmp_data , ("172.16.0.254", 0))recv_packet, addr = Sock.recvfrom(1024)
type, code, checksum, packet_ID, sequence = struct.unpack("bbHHh", recv_packet[20:28])  # 前20个字节为ip头部信息,后8位为icmp头部信息print("头部信息:", type, code, checksum, packet_ID, sequence)

以下为 wireshark抓包结果:

如何获取ttl值

ttl值在回报的ip头部信息中, 占1个字节位置

ttl = struct.unpack("!BBHHHBBHII", recv_packet[:20])[5]

模拟icmp批量探测内网存活机器

不多说了,直接上代码

import socket
import struct
import time
import array
import random
import threadingclass IcmpScan:def __init__(self, ip_list, timeout=3):self.ips = ip_listself.__data = struct.pack('d', time.time())  # 需要发送的数据self.__id = random.randint(1000, 65535)self.timeout = timeoutself.socket = self.rawSocketself.finished = False@propertydef rawSocket(self):try:Sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname("icmp"))Sock.settimeout(self.timeout)except:Sock = self.rawSocketreturn Sockdef inCksum(self, packet):if len(packet) & 1:packet = packet + '\0'words = array.array('h', packet)sum = 0for word in words:sum += (word & 0xffff)sum = (sum >> 16) + (sum & 0xffff)sum = sum + (sum >> 16)return (~sum) & 0xffffdef create_packet(self):header = struct.pack('bbHHh', 8, 0, 0, self.__id, 0)packet = header + self.__datachkSum = self.inCksum(packet)header = struct.pack('bbHHh', 8, 0, chkSum, self.__id, 0)return header + self.__datadef recv_packet(self):while 1:try:recv_packet, addr = self.socket.recvfrom(1024)type, code, checksum, packet_ID, sequence = struct.unpack("bbHHh", recv_packet[20:28])if packet_ID == self.__id:ttl = struct.unpack("!BBHHHBBHII", recv_packet[:20])[5]print(f"检测到存活设备: {addr[0]}  ttl: {ttl}")except:if self.finished:breakdef start(self):random.shuffle(self.ips)  # 乱序一下地址packet = self.create_packet()time_space = 1 / 1000t = threading.Thread(target=self.recv_packet,)t.start()for i, ip in enumerate(self.ips):try:self.socket.sendto(packet, (ip, 0))time.sleep(time_space)except socket.timeout:breakexcept:passself.finished = Truetime.sleep(self.timeout + 1)self.socket.close()t.join()if __name__ == '__main__':ip_list = ['172.16.0.' + str(i) for i in range(1, 255)]icmp_scan = IcmpScan(ip_list)icmp_scan.start()

结果如下:

检测到存活设备: 172.16.0.28  ttl: 128
检测到存活设备: 172.16.0.44  ttl: 64
检测到存活设备: 172.16.0.47  ttl: 64
检测到存活设备: 172.16.0.64  ttl: 64
检测到存活设备: 172.16.0.5  ttl: 64
检测到存活设备: 172.16.0.55  ttl: 128
检测到存活设备: 172.16.0.38  ttl: 64
检测到存活设备: 172.16.0.7  ttl: 128
检测到存活设备: 172.16.0.25  ttl: 64
检测到存活设备: 172.16.0.12  ttl: 64
检测到存活设备: 172.16.0.56  ttl: 128
检测到存活设备: 172.16.0.10  ttl: 64
检测到存活设备: 172.16.0.13  ttl: 64
检测到存活设备: 172.16.0.54  ttl: 128
检测到存活设备: 172.16.0.254  ttl: 255
检测到存活设备: 172.16.0.42  ttl: 64
检测到存活设备: 172.16.0.24  ttl: 64
检测到存活设备: 172.16.0.8  ttl: 64
检测到存活设备: 172.16.0.15  ttl: 64

如何使用python3模拟icmp发包相关推荐

  1. 【Jetson Nano】使用python3模拟向阿里云发送数据

    文章目录 使用python3模拟向阿里云发送数据 阿里云准备 1.登入阿里云物联网平台 2.产品创建流程 3.功能自定义 Jetson Nano准备 1.系统准备,首先烧写系统镜像 英伟达官网下载ub ...

  2. Python3实现ICMP远控后门(下)之“Boss”出场

    ICMP后门 前言 第一篇:Python3实现ICMP远控后门(上) 第二篇:Python3实现ICMP远控后门(上)_补充篇 第三篇:Python3实现ICMP远控后门(中)之"嗅探&qu ...

  3. Python3实现ICMP远控后门(上)

    这几天一直在研究远控木马的一些通信协议,比如TCP,UDP,ICMP,DNS,HTTP等等,对于TCP,UDP这两种就不讲解了,因为太常见了. 大家可能对采用ICMP,DNS的木马不是很熟悉,其实这两 ...

  4. python3模拟键盘输入_python 模拟键盘输入

    一.PyUserInput安装 python3.5的PyMouse和PyKeyboard模块都集成到了PyUserInput模块中.在python3.5中,直接安装PyUserInput模块即可 Py ...

  5. Python3模拟登录人人网

    登录人人网urllib2的实现方法早就实现了,但是各种库比较混乱,代码不过pythonic,早就有很多人吐槽.今天咱们用requests库来模拟登录把人人网吧! 第一步 导入模块 #导入需要的模块 i ...

  6. python3模拟键盘输入_Python模拟键盘输入

    使用pynput库达到模拟键盘输入的目的(也可以进行鼠标模拟). 1.安装pynput库 pip install pynput 2.引入键盘所需类 from pynput.keyboard impor ...

  7. python3模拟登陆人人网(requests)

    前言 之前看别人一直模拟登陆人人网,我就想人人网有头有脸的咋那么好模拟登陆进去呢,,今天看了下发现真的超级容易登陆,可能人人太老了也好久不更新了吧.人人网一点防护措施都没有,没有验证码,没有加密,没有 ...

  8. Python模拟ICMP包

    主要使用Scapy来完成 基础环境 VM1(192.168.1.226) | | VM2(192.168.1.125) vm1封装icmp包发给vm2 vm1脚本: #! /usr/bin/env p ...

  9. python3模拟登录_Python3.4模拟登陆例子

    import urllib.request import urllib.parse import http.cookiejar #post的内容 values={ 'logon.x':'linke', ...

最新文章

  1. linux 开启LACP 单端口,linux – 使用FTOS在Force10 S50N上PXE启动LACP主机
  2. Leecode11. 盛最多水的容器——Leecode大厂热题100道系列
  3. java j2se1.5_用J2SE1.5建立多任务的Java应用程序...
  4. 如何制作pem公钥证书和私钥证书
  5. Aptana插件安装到eclipse和myeclipse的详细过程
  6. Composer帮你轻松管理PHP包 autoload
  7. 基于Keras机器学习库的分类预测
  8. 【Shell】获取文件名和扩展名
  9. 在Vue.js中使用Mixin
  10. HTTP2还没用上,HTTP3就出来了
  11. Redis 6.0学习指南
  12. docker pxc mysql_docker安装pxc集群的详细教程
  13. 怎样取消QQ的热键(快捷键)
  14. Linux数据结构之radix-tree
  15. Photoshop中27种图层混合模式原理图文详解
  16. 【数学建模入门】时间序列|山猫数量预测
  17. Redis Java连接使用
  18. OTM区块链应用离我们的生活有多近?
  19. 用API函数使程序标题栏闪烁
  20. Vue计算属性、监视属性

热门文章

  1. 11.4工作总结 系统安装
  2. 几何原本-欧几里得算法(判断两数是否互质+最大公倍数)代码实现
  3. mysql如何让自增id从1开始设置方法(三种方法)
  4. HP打印机将介质装入纸盒1
  5. 单片机LED点阵控制。
  6. UE百度编辑器的使用
  7. Ai challenger 2017 image caption小结
  8. 使用串口过程中遇到的问题总结
  9. 万网服务器如何备份网站数据库,万网主机如何备份数据
  10. 1H412000机电工程专业技术——1H412030焊接技术