⚠️ 默认使用的 shellcode 是 FreeBSD/x86-64 - execve - 28 bytes from Gitsnik,请将其替换为您自己的 shellcode 以启动 ⚠️
ping 工具用于向主机或网关请求 ICMP ECHO_RESPONSE,它通过 ICMP 协议的强制 ECHO_REQUEST 数据报,使用 IPv4 目标(IPv4 主机或 IPv4 多播组)进行调用。ECHO_REQUEST 数据报由一个 IP 头部和一个 ICMP 头部组成,后面跟着一个 "struct timeval" 以及若干 "填充" 字节以填充数据包。
根据 FreeBSD 项目的安全公告,ping 工具从网络中获取原始 IP 数据包,并在 pr_pack() 函数中处理响应。在响应处理过程中,ping 会重构 IP 头部、ICMP 头部,如果存在,还会重构一个 "引用数据包",该数据包表示导致 ICMP 错误的原始数据包。引用数据包也包含 IP 头部和 ICMP 头部。
pr_pack() 函数将接收到的 IP 和 ICMP 头部复制到栈缓冲区中以供进一步处理。然而,它未能考虑到在响应或引用数据包中,IP 头部之后可能存在 IP 选项头部。当存在 IP 选项时,pr_pack() 会使目标缓冲区溢出最多 40 字节。
ping 工具运行在用户空间,当调用 ping 命令时,会执行位于 /sbin/ping 的二进制文件。该工具的源代码可在 FreeBSD 源代码中公开获取。易受攻击的函数 pr_pack() 将 ICMP 数据包响应信息以字符串格式输出到 stdout,例如 "64 bytes from 1.3.3.7: icmp_seq=1 ttl=55 time=13.7 ms."
✔️ 如上图所示,ICMP 数据包(包括请求和响应)包含 IP 头部及可选的 Options 字段。在恶意攻击中,这些 IP 选项被启用并填充非零字节。✔️
如果 ICMP 数据包在前往目标主机的途中被恶意构造或故意篡改,并且原始 echo 请求中启用了 IP 选项,则 pr_pack() 函数无法在栈上分配足够的空间来容纳 IP 选项的存在,从而导致栈溢出。
🤝 在这些错误情况下,来自目标主机的响应也可能在数据部分包含一个 "引用数据包",用于标识导致 ICMP 错误的特定数据包。当引用数据包包含 ICMP 头部时,pr_pack() 函数会发生栈溢出。🤝