[FreeBSD] Stack overflow in ping
A pretty straight forward stack-based overflow in ping
on FreeBSD. It is a little interesting though in that there is one caveat this is teh vulnerable code:
static void
pr_pack(char *buf, ssize_t cc, struct sockaddr_in *from, struct timespec *tv)
{
u_char *cp, *dp, l
struct ip ip;
/* ... */
memcpy(&l, buf, sizeof(l));
hlen = (l & 0x0f) << 2;
memcpy(&ip, buf, hlen);
/* ... */
}
This code is processing the IP header of an incoming packet. Thehlen
variable is the length of the complete IP header, and it is based on the lower-nibble of the first byte from the user-controlledbuf
. It then copies the header into the ip
structure on the stack. The problem here is that struct ip
is a “naked ip header.” it does not include space for any of the IP options that could be sent. The packet length hlen
reads however reflects the full size including those optional parts. So if a packet has options, they will be copied onto the stack, beyond the allocated space.
On exploitation there are a couple considerations here:
- As a network-attached program it is most likely going to be compiled with stack canaries so the classic technique would be difficult to pull-off here. However there are a lot of items on the local stack, so there is some potential to corrupt that data.
ping
is a setuid binary, it will run as root, however it is in a capability sandbox, so its root but only withCAP_NET_RAW
. So for a local attacker, it is a minor privilege escalation. Still something to be considered about with access to raw packets they can potentially mess with traffic on the system. For a remote attacker, this code path is in the response to a ping, so the victim would need to ping a malicious machine. Its concievable, but it is definitely an ask.