平死了! FreeBSD 修复了网络工具 PlatoBlockchain 数据智能中的严重错误。 垂直搜索。 人工智能。

平的死! FreeBSD 修复了网络工具中的 crashtastic 错误

任何计算机用户了解的第一个低级网络工具之一是令人尊敬的 ping 效用。

该命令以任何涉及潜艇的老式战争电影场景中的同名音效命名,是雷达水下版本 SONAR 的隐喻回声(看看我们在那里做了什么?)。

你发出一个 ping(更像是一个 doinnnng 噪音,在 现实) 进入海水深处,通过测量其怪异的回声返回给你需要多长时间,并通过估计周围海洋中的声速,你可以计算出到产生回声的物体的距离。

有趣的是,鉴于您可能听说过缩写 TCP/IP 用作为互联网提供动力的协议胶水的通用描述, ping 技术上根本不使用 TCP/IP。

实际上,TCP/IP 是 互联网协议上的传输控制协议, 并且指的是一种相当高级的机制,用于通过互联网发送数据,网络本身会加入很多“它真的工作正常吗?”的问题。 为你努力。

例如,在 TCP 连接中,您发送的任何数据块都保证要么完好无损地到达另一端,要么导致错误,因此您知道它们没有成功。

此外,即使不同的数据块最终在互联网上采用不同的路由(例如由于负载平衡、临时中断或其他可恢复的错误),即使某些数据块比其他数据块需要更长的时间到达,TCP 数据也会被正确缓冲向上并在另一端以正确的顺序呈现。

平是不同的

ping 但是,命令通常用于验证您感兴趣的计算机是否在线,特别是如果它不接受您期望的那种高级 TCP 连接,例如接收电子邮件或允许 SSH 登录。

这可以快速帮助您确定中断是否可能是由于网络或服务器本身出现故障,或者是由于该服务器上运行的个别服务未能正确启动。

其结果是, ping 使用比 TCP 低得多的协议。

事实上, ping 甚至不使用 TCP 更随意的表亲 UDP,简称 用户数据报协议,这是一种传输数据块的方式,既快速又简单,但通常被称为发送和希望(或者,如果你是一个愤世嫉俗的人,则称为喷雾和祈祷)。

UDP 本身不会通知您数据是否到达另一端,即使它完好无损地到达,UDP 也不会跟踪您的数据包最初发送的顺序,因此它无法重新排列它们另一端,如果他们不按顺序到达那里。

Ping, 就其价值而言,使用非常低级别的协议,专为故障排除和网络重新配置目的而设计,称为 ICMP,或 因特网控制消息协议.

通常在操作系统内核中正确处理,因此即使没有更高级别的网络软件正确启动,ICMP/IP 数据包也几乎可以肯定通过,ICMP 特别包括两种特殊消息类型:

  • 键入 0x08。 正式称为 ICMP Echo, 这个 某种数据包 通常称为 Echo Request。 这是什么 ping 程序发出以探测网络上的活动计算机。
  • 键入 0x00。 正式称为 ICMP Echo Reply, 这个数据包类型是 正是它所说的. 一台活动的、在线的、未配置为阻止 ICMP Echo 流量的计算机应该将这种数据包直接发送回请求它的计算机。

喜欢此页 :

$ ping -c 3 -p 4E414B45445345435552495459 nakedsecurity.sophos.com 模式:0x4e414b45445345435552495459 PING news-sophos.go-vip.net (192.0.66.227) 56(84) 字节数据。 来自 64 (192.0.66.227) 的 192.0.66.227 个字节:icmp_seq=1 ttl=53 time=84.0 ms 来自 64 (192.0.66.227) 的 192.0.66.227 个字节:icmp_seq=2 ttl=53 time=85.1 ms 来自 64 的 192.0.66.227 个字节(192.0.66.227): icmp_seq=3 ttl=53 time=84.8 ms --- news-sophos.go-vip.net ping 统计 --- 发送了 3 个数据包,接收了 3 个数据包,0% 数据包丢失,时间 2004ms rtt min/平均/最大/mdev = 84.025/84.644/85.062/0.446 毫秒

看一个 ping 在稍微低一点的操作中,我们将使用您可以在文章末尾找到的 Lua 代码来构建我们自己的 ICMP Echo 数据包,并读取返回的回复(如果有):

$ sudo luax ping.lua nakedsecurity.sophos.com 发送 ICMP ECHO 请求到 192.0.66.227 --> 00000000 08 00 03 02 bb 5a 6f 1d 50 69 6e 67 52 65 71 75 |.....Zo.PingRequ| 00000010 65 73 74 4d 65 73 73 61 67 65 20 42 42 35 41 36 |estMessage BB5A6| 00000020 46 31 44 |F1D | 回来了--> 00000000 45 00 00 37 f6 af 00 00 35 01 94 7f c0 00 42 e3 |E..7..5.....B.| 00000010 XX XX XX XX 00 00 0b 02 bb 5a 6f 1d 50 69 6e 67 |.........Zo.Ping| 00000020 52 65 71 75 65 73 74 4d 65 73 73 61 67 65 20 42 |RequestMessage B| 00000030 42 35 41 36 46 31 44 |B5A6F1D |

顺便说一下,我们需要使用 sudo 上面以超级用户权限运行我们的脚本,因为我们创建了所谓的 原始 IP 套接字 – 一种可以制作成我们喜欢的任何底层格式的格式,包括 TCP、UDP 以及此处需要的 ICMP。

在许多 Linux/Unix 系统上, ping 您的发行版提供的命令在没有明确授予 root 权限的情况下工作,通常是因为它安装有特殊的安全功能,或者它的 setuid 标志集,这意味着它开始时在与运行它的用户不同的用户帐户下运行。

精心设计 ping 当然,一旦打开了所需的原始套接字,程序就会自动放弃它们的额外特权。

为了简洁起见,我们从示例脚本中省略了这个特权删除代码。 您可以使用 posix.unistd.setpid() 在创建套接字之后但在发送或接收任何数据之前切换到非特权帐户的功能。

检查回复

正如您可能在我们上面的脚本的数据转储中认识到的那样,我们用来从响应服务器读回数据的网络套接字函数不仅包括 ICMP Echo Reply 数据,还包括低级 IP(互联网协议标头)在底层数据包中。

我们没有尝试解析或以其他方式处理这些数据,但是 FreeBSD ping 程序需要这样做才能理解回复,包括理解返回的任何错误消息。

如果 ping 以某种方式被拒绝,Echo Reply 通常不仅包括它自己的 IP 标头(如上所示),还包括 IP 标头的参考副本和出现在原始出站请求中的 ICMP 数据。

IPv4 数据包标头通常看起来很像您在上面看到的,其中 IP 标头以 45 00 00 37... 并继续总共 20 个字节,直到并包括显示为的字节 ...XX XX XX XX,这是我笔记本电脑的 IP 地址。

喜欢此页 :

00000000 45 00 00 37 f6 af 00 00 35 01 94 7f c0 00 42 e3 |E..7..5.....B.| 00000010 XX XX XX XX |.... | IP 版本和报头长度:0x45(4 = IPv4,5 = 32 个 20 位字,即 0 字节 服务类型和拥塞数据:00x0 数据包总长度:0037x55(十进制 6) 序列信息:F00 AF 00 0 Time-to -live(左跳数):35x53(十进制 0) 协议类型:01x0 (ICMP) 校验和:947x38015F(十进制 0) 发送计算机的 IP 号:C00 42 3 E192.0.66.227 (XNUMX = nakedsecurity.sophos.com) 收件人的 IP(我的笔记本电脑):XX XX XX XX(删除 = 我自己的 IP 号码)

FreeBSD的 ping 程序员,似乎,假设这种类型的头确实总是恰好 20 个字节长,基于第一个字节中的头长度值 0x45, 表示 IPv4 (0x4?) 与一个 5-DWORD (0x?5) 或 20 字节的标头。

只需担心 20 个字节,程序员就可以在堆栈上分配固定大小的缓冲区,他们可以在其中保留回复中 IP 标头的副本,以及原始请求中的任何嵌入式 IP 标头,如果有错误情况需要处理的话.

你可以猜到这是怎么回事。

IPv4 标头中的第一个字节可以合法地具有来自 0x45 (最小标头大小为 5 个 DWORD,或 20 个字节,如图所示)最多 0x4F (表示 15 个 DWORD,因为 0xF 是十进制的 15,或总共 60 个字节的标头数据),因此巧妙地允许可选的额外 40 个字节的标头数据。

那些罕见但合法的额外标头字节可用于具有奇怪名称的各种时髦和不寻常的“功能”,例如 选择性定向广播, 实验流量控制上行组播数据包 – 我们听说过但从未有意使用过,甚至从未见过的东西。

当心网络犯罪分子对您进行测试

可以想象,鉴于这些额外的字段几乎从未使用过,您可能永远不会看到 IPv4 数据包除了 0x45 一开始,总共有 20 个字节的标头数据,除非你遇到了一群准备好让你接受测试的网络犯罪分子。

遗憾的是,没有什么可以阻止攻击者装配一台服务器来猜测您是否在使用 FreeBSD,并故意生成超大的 ICMP/IP 回声回复数据包以引发 堆栈缓冲区溢出 在你的 ping 程序。

如果您检查他们的服务器是否处于活动状态(您甚至可能这样做,或者特别是,如果您认为它可疑!),您可能会成为诱杀回复的目标。

充其量,你的 ping 程序会崩溃; 然而,在最坏的情况下,正如 FreeBSD 安全公告慷慨承认的那样, “恶意主机可能会在 ping 中触发远程代码执行。”

幸运的是,作为 FreeBSD 的作者, 指出, “[t]he ping 进程在所有受影响的 FreeBSD 版本上以功能模式沙箱运行,因此在可能发生错误时它与系统其余部分交互的方式受到很大限制。”

换句话说,您肯定需要打补丁,但风险可以认为是适度的。

值得注意的是, ping 程序不仅被锁定在沙箱中,而且在到达错误代码时也不会以 root 身份运行,正如安全公告中所确认的那样: “什么时候 ping 运行时,它会创建完成其工作所需的原始套接字,然后撤销其提升的特权。”

如上所述,仅需要超级用户权限才能从操作系统获取原始 IP 套接字,而不需要使用 sendto()recvfrom() 之后在该套接字上运行。

此错误已被赋予官方标识符 CVE-2022-23093; 它记录在安全咨询中 FreeBSD-SA-22:15.ping.

怎么办呢?

  • 如果您是 FreeBSD 用户, 只需将受影响的版本(FreeBSD 12 和 FreeBSD 13)更新到最新版本,该错误已修复。
  • 如果你是一名网络程序员, 始终确保您已经考虑了可能指示异常大小变化的数据包标头。 您自己从未见过任何变化的事实并不能阻止您明天面对一个不同寻常但完全合法的数据包。
  • 如果您是网络管理员, 考虑阻止 IP 标头大小不为 4 字节的 IPv20 数据包。 如果您确实需要允许某些软件产品使用不寻常的 IPv4 标头选项,请考虑记录这些不寻常的数据包以了解原因。

外面小心点!


演示 Ping 流量的示例代码


时间戳记:

更多来自 裸体安全