#5855·zeek

Gnutella: Gnutella 有效负载缓冲区未初始化的堆读取导致堆泄漏到脚本区

作者: evantypanski创建于 2026年8月28日更新于 2026年8月28日

This was originally opened as a security issue, but the team decided that it's not relevant from a security context. It is, however, a bug. Its security claims are overblown, but I did not edit most of them. Events are considered locked down in Zeek. Gnutella is also disabled by default. This issue was generated entirely by an LLM. -------------------------------- ## Summary Gnutella_Analyzer::SendEvents() builds a StringVal directly from the fixed-size char payload[1024] member of GnutellaMsgState. That buffer is filled by memcpy from network bytes, is never NUL-terminated, and is never zero-initialized (the class has a user-provided constructor that does not touch the array, so new leaves it indeterminate). p->payload decays to char* and selects the StringVal(std::string_view) constructor, whose implicit string_view(const char*) conversion calls strlen() on the buffer. An attacker who sends a Gnutella binary message header with a zero payload-length field makes strlen() walk the entirely unwritten 1024-byte array (plus padding, terminating at the zero-initialized payload_len member that follows), and the resulting uninitialized heap bytes are delivered to script-land as the payload argument of gnutella_binary_msg — where they may be logged or exported. The same pattern exists for the 23-byte msg buffer in the gnutella_partial_binary_msg path. ## Technical details Sinksrc/analyzer/protocol/gnutella/Gnutella.cc:202-207 (SendEvents): https://GitHub.com/zeek/zeek/blob/62443ad95d88c82ea5957176e113086fc99b5a05/src/analyzer/protocol/gnutella/Gnutella.cc#L202-L207 p->payload is char[1024] (Gnutella.h:32, GNUTELLA_MAX_PAYLOAD = 1024 at Gnutella.h:13); the call selects StringVal(std::string_view) (src/Val.h / Val.cc), which invokes strlen(). A sibling sink is Gnutella.cc:65 (make_intrusive<StringVal>(p->msg), 23-byte msg buffer, gnutella_partial_binary_msg). Why the buffer is uninitialized and unterminated: 1. GnutellaMsgState::GnutellaMsgState() (Gnutella.cc:17-30) initializes the scalar members but never touches payload[] or msg[]. Because the class has a user-provided default constructor, new detail::GnutellaMsgState()