SMB2 LZ77 Decompression Bomb (crash/dos)
## Summary SMB2 Compression Transform Header with LZ77 algorithm triggers a decompression loop of **\~4.29 billion iterations** in `tvbuff_lz77.c:do_uncompress()`. The LZ77 decompressor has no output size limit, allowing a 51-byte compressed payload to request unbounded output via a single back-reference with `match_len = 4,294,915,339`. This inevitably results in a complete denial of service (DoS), ultimately causing a full crash. ## Steps to reproduce Run the PCAP - note that Wireshark / TShark may hang during processing: [mega-ultimate-vuln-smb2-lz77-bomb.pcap](/uploads/f3322de75f397a2eaa4433f37f4219dd/mega-ultimate-vuln-smb2-lz77-bomb.pcap) I'm running these type of samples with `timeout --signal=KILL 30 tshark -r ./pcap` ## What is the current bug behavior? ``` dissect_smb2_comp_transform_header() [packet-smb2.c:12467] → tvb_uncompress_lz77(tvb, offset, in_size) [packet-smb2.c:12552] → do_uncompress(tvb, offset, in_size, obuf) [tvbuff_lz77.c:19] ``` **File:** `epan/tvbuff_lz77.c`, function `do_uncompress()` ```c #define MAX_INPUT_SIZE (16*1024*1024) /* 16MB — limits INPUT only */ static bool do_uncompress(tvbuff_t *tvb, int offset, int in_size, wmem_array_t *obuf) { // ... if (!in_size || in_size > MAX_INPUT_SIZE) // ← checks INPUT size return false; // NO CHECK ON OUTPUT SIZE ← the bug while (1) { // ... flag processing ... // Match copy loop — match_len can be up to 2^32 for (i = 0; i < match_len; i++) { // wmem_array_try_index + wmem_array_append_one // Byte-by-byte copy with no output cap } } } ``` The caller (`packet-smb2.c`) checks `orig_size > MAX_UNCOMPRESSED_SIZE` (16MB) before calling the decompressor, but `orig_size` is an attacker-controlled field in the header — **the actual decompressed output size is determined by the LZ77 stream itself**, not by `orig_size`. The decompressor ignores `orig_size` entirely. ## What is the expected correct behavior? (What you should see instead) ## Relevant logs and/or screenshots ``` Ethernet II (14B) → IPv4 (20B) → TCP src:445 dst:4703 (20B) └─ NetBIOS Session Service (4B, length=73) └─ SMB2 Compression Transform Header ProtocolId: 0xfc534d42 OriginalSize: 7,077,952 (6.75 MB) CompressionAlgorithm: LZ77 (0x0002) Flags: 0x4000 (non-chained, non-standard) Offset: 0x00000000 Compressed payload: 51 bytes ``` ## Build information ``` TShark (Wireshark) 4.6.4 (Git commit f7c4a74874d9). Copyright 1998-2026 Gerald Combs <gerald@wireshark.org> and contributors. Licensed under the terms of the GNU General Public License (version 2 or later). This is free software; see the file named COPYING in the distribution. There is NO WARRANTY; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compile-time info: Bit width: 64-bit Compiler: Clang 17.0.0 (clang-1700.6.4.2) GLib: 2.86.4 With: +Gcrypt 1.12.1 +LZ4 1.10.0 +GnuTLS 3.8.12 and PKCS#11 +MaxMind +Kerberos (MIT) +nghttp2 1.68.0 +libpcap +nghttp3 1.15.0 +libsmi 0.5.0 +PCRE2 10.47 2025-10-21 +libxml2 2.9.13 +zlib 1.2.12 +Lua 5.5.0 +Zstandard 1.5.7 Without: -brotli -Snappy -zlib-ng -POSIX capabilities -xxhash Runtime info: OS: macOS 26.3.1, build 25D2128 (Darwin 25.3.0) CPU: Apple M1 Max Memory: 32768 MB of physical memory GLib: 2.88.0 Locale: LC_TYPE=en_US.UTF-8 Plugins: supported, 0 loaded With: +c-ares 1.34.6 +libsmi 0.5.0 +PCRE2 10.47 2025-10-21 +Gcrypt 1.12.1 +LZ4 1.10.0 +zlib 1.2.12 +GnuTLS 3.8.12 +nghttp2 1.68.1 +Zstandard 1.5.7 +libpcap 1.10.1 +nghttp3 1.15.0 ```
issue