【待做】【攻防技术系列+网络协议】ICMP协议

news/2024/9/8 12:25:52/文章来源:https://www.cnblogs.com/o-O-oO/p/18327369

ICMP协议简介

ICMP(Internet Control Message Protocol)因特网控制报文协议。它是IPv4协议族中的一个子协议,用于IP主机、路由器之间传递控制消息。控制消息是在网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然不传输用户数据,但是对于用户数据的传递起着重要的作用。

ICMP协议与ARP协议不同,ICMP靠IP协议来完成任务,所以ICMP报文中要封装IP头部。它与传输层协议(如TCP和UDP)的目的不同,一般不用来在端系统之间传送数据,不被用户网络程序直接使用,除了像Ping和 Tracert 这样的诊断程序。

下面是ICMP协议被使用的一个实例:

1、ICMP 可以指示网络出错的原因
2、ICMP 协议自身不能解决网络出错,只是指示错误

【ICMP 报头格式】:

ICMP报文包含在IP数据报中,IP报头在ICMP报文的最前面。一个ICMP报文包括IP报头(至少20字节)、ICMP报头(至少八字节)和ICMP报文(属于ICMP报文的数据部分)。当IP报头中的协议字段值为1时,就说明这是一个ICMP报文。ICMP报头如下图所示。

【ICMP 报文类型】:


不同报文类型由报文中的类型字段和代码字段来共同决定。图中的最后两列表明 I C M P报文是查询报文还是差错报文。

当发送一份ICMP差错报文时,报文始终包含IP的首部和产生ICMP差错报文的IP数据报的前8个字节。这样,接收ICMP差错报文的模块就会把它与某个特定协议(根据IP数据报首部中的协议字段来判断)和用户进程(根据包含在IP报前8个字节中的TCP或UDP报文首部中的TCP或UDP端口号来判断)联系起来。

ICMP报告无法传送的数据报的错误,并帮助对这些错误进行疑难解答。例如,如果IPv4不能将数据报传送到目标主机,则路由器上的或目标主机上的ICMP会向主机发送一条“无法到达目标”消息。

下表为最常见的ICMP消息。

其中无法到达目标消息中可以细分为以下几项:

ICMP协议只是试图报告错误,并对特定的情况提供反馈,但最终并没有使IPv4成为一个可靠的协议。ICMP消息是以未确认的IPv4数据报传送的,它们自己也不可靠。

【ICMP差错报文demo1】:

访问一个网络中不存在的路由

在路由器R1上Ping 172.16.32.1,由于路由器R1上存在着去往172.16.32.0 子网的静态路由,所以Ping数据包会被发送到路由器R2上,而在R2上没有去往172.16.32.0的子网路由条目,所以R2路由器就会发送ICMP的差错报文告诉路由器R1。R1的路由解析从R2路由器返回的响应报文,即可知道不可达的原因。在R1路由器上的Ping测试的结构如下图。

通过Wireshark抓取到的报文如下:

可以看到172.16.12.2给172.16.12.1发送了ICMP的差错报文。报文的类型值为3,代码值为1,表示为主机不可达,也就是,路由器R2告诉路由器R1主机不可达。

【ICMP差错报文demo2】:

访问一个路由存在但IP规则被禁止

同样在路由器R1上Ping 172.16.32.1,请求数据包到达路由器R2后,R2路由器存在去往172.16.32.0子网的路由,但IP的访问规则限制了对172.16.32.0子网的访问。在路由器R1上Ping测试结果及Wireshark抓包如下图。


可以看到172.16.12.2给172.16.12.1发送了ICMP的差错报文。报文的类型值为3,代码值为13,表示通信被过滤掉了。

【ICMP差错报文demo3】:

传输超过接口的MTU值的数据

路由器R1和路由器R2上都存在着去往172.16.23.0子网的路由条目。在路由器R1上Ping路由器R3的Fa 0/0 接口的IP地址172.16.23.1,Ping带的数据1200个字节且不允许分包处理。如下图所示。

由于路由器R2的接口Fa 0/0 被设置最大允许的MTU值为1000,所以ICMP的Ping的1200字节无法被直接转发,需要被分包。但Ping请求的报文中却不允许分包的情况。此时,就会由路由器R2发送ICMP的差错报文给路由器R1。Wireshark抓取的报文帧如下图所示。

详细查看ICMP的差错报文帧如下图

此时,ICMP的差错报文的报文类型值为3,代码值为4,表示为需要进行分片,但设置了不分片的比特位DF,也就是,路由器R2告诉路由器R1需要分片但设置了不分片的位而出错。

【ICMP差错报文demo4】:

UDP协议端口不可达

在路由器R1上通过TFTP协议传输文件到路由器R3上。

TFTP协议是基于UDP的传输协议进行传输,而在路由器R3上没有开启TFTP协议,所以路由器R3向路由器R2发送ICMP的差错报文,差错报文的内容是指示R3的TFTP协议的端口不可达。R2接收到这个差错报文后,又将此报文转发给了路由器R1。通过Wireshark抓包获取的报文帧如下图所示。

双击ICMP的差错报文,可以看到此报文帧的详细信息如下:

从上图可以看到ICMP的差错报文的类型值为3,代码值为3,指示为端口不可达。对于采用UDP传输协议传输的应用层协议,到对端端口没有开启时,都会以ICMP的差错报文来告知请求端。在ICMP的报文消息的数据部分封装有请求时的IP报文头和UDP的报文头。对于请求方通过IP的报文头和UDP报文头的组合就可以确认是到目的的那个协议请求的端口不可达。

【ICMP差错报文demo5】:

ICMP TTL超时

在路由器R1上Ping 1.1.1.1 如下图所示:

ICMP的请求报文被发送到路由器R2上,R2再把ICMP请求报文转发给路由器R3,路由器R3再把ICMP请求转发给路由器R2,此时形成了路由环路,ICMP的请求报文在路由器R2和路由器R3之间来回转发。但每次经过一次路由器,ICMP请求报文帧的TTL字段值就会减1,直到TTL字段的值减为0时,路由器就会发送ICMP的差错报文用来指示TTL超时。

如下图所示。

双击上图中的ICMP差错报文,报文的详细内容如下图。

从上图可以看到ICMP的差错报文的类型值为11,代码值为0,指示报文的生命周期为0。

Ping 命令介绍

Ping命令用于进行通信的主机或路由器之间,判断所发送的数据包是否已经成功到达对端的一种消息。可以向对端主机发送请求的消息(ICMP Echo Request Message,类型8),也可以接收对端主机发回来的回显应答消息(ICMP Echo Reply Message,类型0)。网络上最常用的Ping命令,就是利用这个消息实现的。Echo Request 与 Echo Reply为经典的查询报文!

【Python 实现ICMP协议】:

Python先安装Scapy模块,然后利用Scapy提供函数功能来实现ICMP请求报文帧的铸造。
Scapy 铸造ICMP请求数据包的方法:
pkt = Ether()/IP()/ICMP()/”Hello”
pkt.show()可以查看铸造的包的信息:

铸造好的ICMP请求包可以通过sendp()函数或send()函数发送。sendp()函数在第二层次上发送数据包,需要给定正确的网卡接口;send()函数在第三层次上发送数据包,根据本地的路由表来进行路由发送。

下面我们通过sendp()函数来发送一个构造好的ICMP回显请求报文,其中ICMP()括号中不添加任何参数,默认情况下为 type字段的值为8,code字段的值为0, 也就是回显请求报文。在第二层次上发送要指定网卡接口, 这里使用ens37(因为测试使用的是CentOS7的操作系统)。成功发送一个数据包。如果想要循环发送,可以使用loop选项。

sendp(Ether()/IP(dst="192.168.10.101")/ICMP()/"hello", iface="ens37“, loop=1)
代码执行并同时进行Wireshark抓包,可以抓取到报文如下图。

如果在网络上连接有192.168.10.101的设备的话,192.168.10.101的设备会对此ICMP回显请求进行应答。回显应答的报文帧结构如下图所示。

如果希望不仅能够发送ICMP 回显请求报文,还需要对ICMP回显应答的报文帧进行接收的话,则可以使用Scapy模块中的sr()函数来执行(此时sr()为三层发送接收函数,而srp()函数为二层发送接收函数)。这里我们使用三层的发送接收函,代码执行发送接收(三层发送就无需添加Ether()参数),如下图。

成功发送了一个数据包,接收到了4个数据包,其中1个为答复包。这是我要集中注意的地方。将收到的数据赋值给自定义的变量,并查看。
ans为应答包的接收变量;unans为未应答的接收变量。
ans[0]中包括了请求包和应答包。其中ans[0][1]为应答包

使用sr1()函数发送及返回的响应包的数据的效果如下图。

Python 使用 Scapy 实现ICMP扫描指定主机的存活状态

Python 代码如下:

Python 使用 Scapy 实现ICMP扫描指定网段存活的主机

Python 代码如下:

通过Python对ICMP协议的编程实现,更加深了对ICMP协议的理解和认识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/772732.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C141 线段树分治+线性基 P3733 [HAOI2017] 八纵八横

视频链接:C141 线段树分治+线性基 P3733 [HAOI2017] 八纵八横_哔哩哔哩_bilibili P3733 [HAOI2017] 八纵八横 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)// 线段树分治+线性基 O(q*logq*logL*logL) #include <iostream> #include <cstring> #include <a…

将Mathtype添加到WPS中

(1)在顶部菜单栏,工具--加载项--在“模板和加载项”窗口中再点击“添加”(2)找到mathtype安装路径下面的“OfficeSupprot”,这时会看到有“32”和“64”两个文件夹,分别对应WPS软件的系统(任务管理器可以直接查看wps版本)。默认路径为下边这个:(3)如果许多功能不…

BUUCTF 3.warmup_csaw_2016

拿到题目,我们先运行一下我们发现这道题的样子和BUUCTF的rip很像,一样是让我们输入,一样是在输入超长字符串后程序会崩溃,所以我们可以猜测是一道栈溢出的问题,我们来看一下保护机制我们发现依旧是几乎没开保护机制,所以大概率是一道栈溢出的题。 我们看一下IDA我们发现最…

sql注入漏洞复现

and 1=1 正常and 1=2 报错从这就已经说明是sql数字型注入了 上sqlmap验证一下存在布尔盲注,时间盲注...... 我是在漏洞盒子上提交的,能不能通过看运气吧 下面这个漏洞已经是很久之前的了,现在已经是修复了,当时还是太年轻了......当时复现过程没有做好,截图也已经删掉了..…

【PHP系列】phpinfo里面有什么?

一、INFO_GENERAL:一般信息 1.1 版本 1.2 操作系统版本和SAPI 原创 猎豹安全中心 小豹讲安全 2021-05-25 14:30 在PHP中,我们往往通过phpinfo()函数(及可选选项)来检查配置设置和预定义变量,返回结果输出关于PHP的配置信息,其中包含了 PHP 编译选项、启用的扩展、PHP 版本、…

【学习笔记】线段树

本文冲刺 \(3000\) 行中,目前行数:\(2668\) 行。 【0】线段树简介 【0.1】线段树是干什么的 线段树是一种基于分治的树形数据结构,可以处理很多区间问题,值域问题。 【0.2】线段树的形态 线段树作为一棵二叉树,其左子节点维护的是左半区间的信息,右子节点维护的是右半区间…

从零开始的JAVAday22~day28

上周我们学习了如何定义变量,这周我们学习如何给变量起名。 硬性要求: 1.由数字、字母、下划线()和美元符($)组成 2.不能以数字开头 3.不能是关键字 4.区分大小写 软性要求: 小驼峰命名法:存在一个单词时所有字母都小写,存在多个字母时第一个单词小写第二个单词首字母大写…

Git的存储原理

Git提交的只有你的代码吗?底层存储大剖析!目录Git 设计原理Git vs SVNGit 存储模型.git 目录结构Git 基本数据对象Git 包文件Git 引用 Git 设计原理 概括的讲,Git 就是一个基于快照的内容寻址文件系统。 往下慢慢看。 Git vs SVN Git 出现前,主流版本控制系统(SVN...)一般…

运行一个jar包的过程

在Linux运作jar包在Linux系统中,一个Java Archive(JAR)文件是包含Java类文件、相关的元数据和资源(如文本、图片等)的压缩包,通常用于存储Java应用程序或库。要在Linux上运行一个JAR包,你可以按照以下步骤操作: 1、确保Java环境已安装: 在Linux系统中运行JAR文件之前,…

BUUCTF 2.rip

拿到题目首先运行一下我们可以看到在我第一次运行时我们发现他就是将我们输入的重新输出了一遍,我们可以猜测应该是gets函数输入,然后输出,那我们便可以测试第二次,我们输入一个超长字符串,发现程序崩溃了,我们可以猜测应该是程序没有对长度进行检测而导致的栈溢出,那么…

计组笔记第七章——输入输出系统

7.1.1 I/O系统和IO控制方式常见I/O设备: 鼠标、键盘;显示器、打印机;硬盘、光盘。 主机如何与I/0设备进行交互? I/O接口:又称I/O控制器、设备控制器,负责协调主机与外部设备之间的数据传输。 I/O接口与CPU之间靠总线连接,与外设之间靠USB连接线连接。 I/O接口多种多样,…

Raft协议深度解析:RocketMQ中基于DLedger的日志主从复制

本文所涉及的注释源码:bigcoder84/dledgerRaft 协议主要包含两个部分:Leader选举和日志复制。 前面我们在 Raft协议深度解析:RocketMQ中的自动Leader选举与故障转移 一文中已经详细介绍了DLedger如何实现Leader选举的,而本文主要聚焦于Leader选举完成后的日志复制的过程。 …