GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration

GHSA-4595-RVPX-4Q34

Vulnerability from github – Published: 2026-09-15 20:47 – Updated: 2026-09-15 20:47
VLAI
Summary
emp3r0r has an unauthenticated HTTP Polling DoS
Details

Summary

The http_poll C2 transport accepts attacker-controlled HTTP polling sessions before CBOR MsgAuth authentication is completed. A remote unauthenticated attacker can create arbitrary polling sessions and send request bodies that are forwarded into the C2 dispatch path. This can consume server resources and trigger pre-auth C2 processing.

Details

The plain HTTP C2 server starts the HTTP polling listener and forwards requests into HandleHTTPServerSession:

// core/internal/cc/server/c2_http_server.go
mux.HandleFunc(c2Path, func(w http.ResponseWriter, req *http.Request) {
    stream, err := transport.HandleHTTPServerSession(w, req, &live.RuntimeConfig.MalleableC2)
    ...
    if stream != nil {
        go cborStreamAccept(transport.NewStreamTransport(stream, req.RemoteAddr))
    }
})

The HTTP polling handler accepts an attacker-supplied sessionID and init=1 cookie, then creates and stores a server-side stream before authentication:

// core/internal/transport/c2channel_http.go
if isInit {
    stream = newHTTPServerStream(sessionID)
    w.WriteHeader(http.StatusOK)
    return stream, nil
}

POST bodies for that unauthenticated session are read and queued before CBOR authentication rejects them:

// core/internal/transport/c2channel_http.go
case http.MethodPost:
    data, err := io.ReadAll(req.Body)
    if err == nil && len(data) > 0 {
        select {
        case stream.readCh <- data:
            w.WriteHeader(http.StatusOK)
        ...
        }
    }

Authentication only happens later in the C2 dispatch layer:

// core/internal/cc/server/dispatcher.go
secureConn := transport.NewSecureConn(t)
...
n, err := secureConn.Read(authFrame)

PoC

  1. Start the C2 server in a lab environment with the HTTP polling transport exposed, for example with --http-port 12345.
  2. Send an unauthenticated HTTP POST to the default polling path /api/v1/telemetry with a random sessionID cookie and the init=1 cookie value.
  3. Send a second unauthenticated HTTP POST to /api/v1/telemetry using the same sessionID, with a request body containing repeated A bytes.
  4. Observe that both unauthenticated requests return HTTP 200.
  5. Observe the C2 server log showing attacker-controlled bytes reaching the encrypted C2 frame parser, for example: read: invalid encrypted chunk length: 1094795585.
  6. 1094795585 is 0x41414141, which corresponds to AAAA, confirming unauthenticated request body data reached cborProtocolDispatch before CBOR MsgAuth authentication.
  7. Repeat the request sequence concurrently to increase server resource usage and log volume.

Impact

  • Remote unauthenticated attackers can create arbitrary HTTP polling sessions.
  • Attacker-controlled request bodies reach pre-auth C2 dispatch handling.
  • Repeated requests can consume server memory, goroutines, request handling capacity, and log volume.
  • C2 service availability and operator reliability may be degraded under sustained traffic.

Remediation

  • Require authentication before creating long-lived HTTP polling sessions.
  • Do not forward request bodies into the C2 stream before validation.
  • Add strict request body limits.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/jm33-m0/emp3r0r/core"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.0.0-20260531142011-aed3d81641ab"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-61554"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-15T20:47:17Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Summary\nThe `http_poll` C2 transport accepts attacker-controlled HTTP polling sessions before CBOR `MsgAuth` authentication is completed. A remote unauthenticated attacker can create arbitrary polling sessions and send request bodies that are forwarded into the C2 dispatch path. This can consume server resources and trigger pre-auth C2 processing.\n\n### Details\nThe plain HTTP C2 server starts the HTTP polling listener and forwards requests into `HandleHTTPServerSession`:\n```go\n// core/internal/cc/server/c2_http_server.go\nmux.HandleFunc(c2Path, func(w http.ResponseWriter, req *http.Request) {\n    stream, err := transport.HandleHTTPServerSession(w, req, \u0026live.RuntimeConfig.MalleableC2)\n    ...\n    if stream != nil {\n        go cborStreamAccept(transport.NewStreamTransport(stream, req.RemoteAddr))\n    }\n})\n```\nThe HTTP polling handler accepts an attacker-supplied `sessionID` and `init=1` cookie, then creates and stores a server-side stream before authentication:\n\n```go\n// core/internal/transport/c2channel_http.go\nif isInit {\n    stream = newHTTPServerStream(sessionID)\n    w.WriteHeader(http.StatusOK)\n    return stream, nil\n}\n```\nPOST bodies for that unauthenticated session are read and queued before CBOR authentication rejects them:\n```go\n// core/internal/transport/c2channel_http.go\ncase http.MethodPost:\n    data, err := io.ReadAll(req.Body)\n    if err == nil \u0026\u0026 len(data) \u003e 0 {\n        select {\n        case stream.readCh \u003c- data:\n            w.WriteHeader(http.StatusOK)\n        ...\n        }\n    }\n```\nAuthentication only happens later in the C2 dispatch layer:\n```go\n// core/internal/cc/server/dispatcher.go\nsecureConn := transport.NewSecureConn(t)\n...\nn, err := secureConn.Read(authFrame)\n```\n\n### PoC\n1. Start the C2 server in a lab environment with the HTTP polling transport exposed, for example with `--http-port 12345`.\n2. Send an unauthenticated HTTP POST to the default polling path `/api/v1/telemetry` with a random `sessionID` cookie and the `init=1` cookie value.\n3. Send a second unauthenticated HTTP POST to `/api/v1/telemetry` using the same `sessionID`, with a request body containing repeated `A` bytes.\n4. Observe that both unauthenticated requests return HTTP `200`.\n5. Observe the C2 server log showing attacker-controlled bytes reaching the encrypted C2 frame parser, for example: `read: invalid encrypted chunk length: 1094795585`.\n6. `1094795585` is `0x41414141`, which corresponds to `AAAA`, confirming unauthenticated request body data reached `cborProtocolDispatch` before CBOR `MsgAuth` authentication.\n7. Repeat the request sequence concurrently to increase server resource usage and log volume.\n\n### Impact\n- Remote unauthenticated attackers can create arbitrary HTTP polling sessions.\n- Attacker-controlled request bodies reach pre-auth C2 dispatch handling.\n- Repeated requests can consume server memory, goroutines, request handling capacity, and log volume.\n- C2 service availability and operator reliability may be degraded under sustained traffic.\n\n### Remediation\n- Require authentication before creating long-lived HTTP polling sessions.\n- Do not forward request bodies into the C2 stream before validation.\n- Add strict request body limits.",
  "id": "GHSA-4595-rvpx-4q34",
  "modified": "2026-09-15T20:47:17Z",
  "published": "2026-09-15T20:47:17Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/jm33-m0/emp3r0r/security/advisories/GHSA-4595-rvpx-4q34"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/jm33-m0/emp3r0r"
    },
    {
      "type": "WEB",
      "url": "https://github.com/jm33-m0/emp3r0r/releases/tag/v4.2.5"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "emp3r0r has an unauthenticated HTTP Polling DoS"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…