On Dec 01, 2022, a stack overflow vulnerability CVE-2022-23093 was found in the FreeBSD operating system (all supported versions) ping utility. The issue is a buffer overflow vulnerability affecting the “pr_pack()” function in ping(8). The flaw can be leveraged to cause a stack overflow, which could lead to a crash or trigger remote code execution in ping.
What is the issue?
The following vulnerability details were published in the FreeBSD security advisory
Ping reads raw IP packets from the network to process responses in the pr_pack() function. As part of processing a response ping has to reconstruct the IP header, the ICMP header and if present a "quoted packet," which represents the packet that generated an ICMP error. The quoted packet again has an IP header and an ICMP header.
The pr_pack() copies received IP and ICMP headers into stack buffers for further processing. In so doing, it fails to take into account the possible presence of IP option headers following the IP header in either the response or the quoted packet. When IP options are present, pr_pack() overflows the destination buffer by up to 40 bytes.
What versions are impacted?
This vulnerability impacts all currently supported versions of FreeBSD.
What can you do to protect yourself?
If you are a FreeBSD customer, we encourage you to take the following steps at the earliest:
Zscaler’s cloud is not at risk
After a thorough investigation, ThreatLabz determined that Zscaler platform service components have not been impacted by this vulnerability. You can read the ThreatLabz trust post here.
Additionally, the Zscaler platform is built on a holistic zero trust architecture that offers defense-in-depth against supply chain and compromised user attacks, mitigating incidents such as this in the following ways:
The ping utility runs in userspace. When a user runs the ping command, it invokes the binary at /sbin/ping. The code is available on the FreeBSD source. The vulnerable function, pr_pack() prints out the ICMP packet response information to stdout, similar to the familiar string:
64 bytes from 220.127.116.11: icmp_seq=1 ttl=57 time=86.4 ms
On the network, the ICMP packet (both request and response) looks like this:
The headers in the diagram above are the IP headers, with an optional Options field. In an attack case, these IP Options are enabled and filled with non-null bytes.
In some cases, for example, if an ICMP packet is malformed or deliberately modified en route to the destination host, and the IP Options are enabled in the original echo request, the vulnerable pr_pack() fails to allocate enough space on the stack to account for the presence of IP Options, instead overflowing the stack.
In these error cases, the response from the destination host may also include a "quoted packet" in the data section (which tracks which packet specifically caused the ICMP error), and the pr_pack() function similarly overflows the stack in the case that the quoted packet has ICMP headers.
The buffer overflow occurs in line 1156 and line 1161 in the pr_pack() function (defined in ping.c) here:
The value of hlen is calculated without checking for the IP options header, assuming the standard IP packet header length of 20 bytes. The memcpy into the icp struct leads to the buffer overflow.