Back to reports

A Staging C2 That Introduces Itself: Unauthenticated /health on a Custom Flask Panel at 67.215.232.25

PublishedApril 9, 2026

A Staging C2 That Introduces Itself: Unauthenticated /health on a Custom Flask Panel at 67.215.232.25

TL;DR

On April 9, 2026, we followed a lead from @1ZRR4H into a custom Python/Flask command-and-control server at 67.215.232.25 — a HostPapa/ColoCrossing VPS in Los Angeles. The panel listens on two ports (8080 for the operator interface, 5000 for what appears to be the agent listener) and exposes an unauthenticated /health endpoint that politely self-reports the C2's operational state: active agent count, pending command count, completed command count, and status.

At the time of investigation the box is idleactive_servers: 0, pending_commands: 0, completed_commands: 0 — which is the kind of thing only a C2 would feel compelled to tell you. It's fresh infrastructure with zero prior threat intelligence coverage across VirusTotal, OTX, URLhaus, ThreatFox, and AbuseIPDB, and the earliest Shodan surface dates only to March 4, 2026, which makes it a prime candidate for pre-deployment monitoring rather than post-mortem reporting.

What this report adds to the public record:

  • A first-look snapshot of 67.215.232.25 while it's still in staging: SSH fingerprint, the exact /health JSON schema, the auth rejection semantics on the protected endpoints, and the two-port architecture
  • A detection-ready fingerprint for this panel style: HTTP responses from non-standard ports containing all of active_servers, pending_commands, completed_commands, status, healthy on the same JSON body
  • An SSH host-key pivot point unique to this IP for defenders who want to correlate

Hat tip to @1ZRR4H for the lead. If you've already published reporting on this panel style, this IP, or the SSH host key below, please reply or DM — we'll update and credit.


The Target

FieldValue
IP67.215.232.25
ASNAS36352 (HostPapa / AS-COLOCROSSING)
LocationLos Angeles, CA, US
OSUbuntu Linux
Reverse DNSNone
Allocated2025-01-30 (HostPapa /24 block via ARIN)
First Shodan observation2026-03-04 (SSH) / 2026-03-28 (port 8080) / 2026-04-02 (port 5000)
Prior threat intel presenceNone

The /24 block was allocated about 14 months ago; the box itself was provisioned around early March 2026, and the second Flask listener on port 5000 was added only a week before our investigation on April 2. Everything about the deployment timeline says staging.

Open Ports

PortServiceVersionRole
22SSHOpenSSH 9.6p1 Ubuntu 3ubuntu13.15Operator access
25SMTPFirewall-filtered
5000HTTPWerkzeug/3.1.6 Python/3.12.3Suspected agent listener (all paths → 404)
8080HTTPWerkzeug/3.1.6 Python/3.12.3Operator panel with /health and /api/*

Two Flask instances on the same box is itself a pattern worth noting — one public-facing on a management port, one on a secondary port that answers nothing on any common path we tested. That's consistent with an operator/agent separation where the agent port expects specific, non-guessable routes (UUIDs, signed tokens in the path, or specific headers before it'll route anything).

Port 8080 — The Management Panel

MethodEndpointResponseAuth?
GET/health200 with JSONNo
POST/api/report401 {"error":"Authentication failed"}Yes
POST/api/heartbeat401 {"error":"Authentication failed"}Yes
GET/api/report405 Method Not Allowed
GET/api/heartbeat405 Method Not Allowed

The /health response (captured 2026-04-09T02:12:45Z)

{
  "active_servers": 0,
  "completed_commands": 0,
  "pending_commands": 0,
  "status": "healthy",
  "timestamp": "2026-04-09T02:12:45.515454"
}

Field by field, this hands defenders the panel's entire tasking model:

  • active_servers — currently-connected implants
  • pending_commands — tasks queued for implants to pull
  • completed_commands — tasks implants have executed and reported back
  • status — panel operational state
  • timestamp — server-side UTC

The natural interpretation of that schema is: operators queue commands via the panel → agents poll /api/heartbeat to pull pending tasks → agents post results back to /api/report. The fact that the POST-only endpoints return 401 on empty bodies and 405 on GETs means the panel is routing correctly and enforcing auth — the operator just forgot to include /health in the auth-required set.

Auth mechanism (what it isn't)

We probed the obvious auth shapes on /api/report to see what the panel expects:

  • Bearer tokens → rejected
  • HTTP Basic → rejected
  • X-API-Key header → rejected
  • Body-embedded server_id / api_key / token / auth_key → rejected

All return {"error":"Authentication failed"}. That leaves a custom scheme — most likely a shared secret embedded in a non-standard JSON field, HMAC over the body, or timing/nonce checks. The panel requires Content-Type: application/json (it returns 415 Unsupported Media Type on form-encoded bodies), which is consistent with a hand-rolled JSON-only API.

Port 5000 — The Quiet One

Port 5000 runs the same Werkzeug/Flask stack but returns 404 on every path we tried — root, /api, /v1, /v2, /beacon, /agent, /gate, /task, /callback, and about a hundred more common C2 routes. Behavior consistent with:

  1. A listener expecting specific, non-guessable endpoint paths (UUID-routed agents, signed paths, etc.)
  2. A listener that requires specific HTTP headers before routing (e.g., X-Implant-Id or a custom auth header)
  3. A backup / secondary channel that isn't fully wired yet

Given the agent tasking model implied by the /health schema, (1) is the most likely reading: the agent probably beacons to a path like /<agent-uuid>/beacon and any other path returns 404 as cover.

This Isn't an Off-the-Shelf Framework

We walked this panel through the usual suspects and it matched none of them:

  • Cobalt Strike — no BEACON patterns, no malleable C2 profile, no team server ports
  • Sliver — no gRPC / mTLS, no implant registration endpoints
  • Havoc — no Demon agent patterns
  • Mythic — no GraphQL API, no Apollo routes
  • Metasploit — no Meterpreter handler signatures, no stage patterns

The Flask + Werkzeug + minimal JSON API stack, the "report/heartbeat" naming, and the lack of any standard framework fingerprint all point to a custom panel — either bespoke to this operator or an early-stage framework that hasn't been publicly released.

Attribution

None — yet. The panel has zero OPSEC tells that I could find:

  • No leaked emails, domains, or associated accounts
  • No identifying strings in the /health body beyond timestamp format
  • No TLS cert (HTTP only across the board)
  • No associated hostnames, domains, or certs in crt.sh or VT passive DNS
  • Infrastructure too new and too clean for confident attribution

Use of HostPapa / ColoCrossing (AS36352) is consistent with low-cost VPS procurement — common across everything from script kiddies to bulletproof hosting resellers. Not a discriminator.

Detection & Hunting

Network

  • Block 67.215.232.25 at the perimeter on all ports.
  • Alert on HTTP responses containing all five fields active_servers, pending_commands, completed_commands, status, healthy in a single JSON body — that exact combination is a tight fingerprint for this panel style. A single grep over web-scanner archives will surface sister boxes if this framework is deployed elsewhere.
  • Alert on HTTP traffic to non-standard ports (5000, 8080) containing JSON payloads with api_key, heartbeat, or report fields in the body.
  • Flag raw-IP HTTP POSTs to /api/heartbeat or /api/report — direct IP comms with no associated hostname is the norm for this deployment pattern.

SSH pivot

The server's SSH host key is unique to this IP in Shodan's index:

Type:        ecdsa-sha2-nistp256
Fingerprint: b9:db:77:d7:f0:2f:98:f3:27:9a:09:e5:dc:0e:63:7f
Public key:  AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDN8gOvi3wu8Z2DMxeldHv3uQj2/JQoFqk7eraXDvzd8+n6NAqpL0dMvDfVwyInizh7g/cLlJMR8HMPev7xvCs8=

If this key turns up on a second IP, that's sister infrastructure.

Monitoring

  • Periodic Shodan polling on this IP — when active_servers climbs above 0 the panel has gone operational and defenders should expect beaconing traffic.
  • Watch the 67.215.232.0/24 subnet for sibling deployments using the same Werkzeug banner.
  • Watch VirusTotal / OTX passively — when samples pointing at this C2 finally surface, they'll reveal the client-side binary format and unlock the auth scheme.

MITRE ATT&CK

TacticTechniqueID
Resource DevelopmentAcquire Infrastructure: VPST1583.003
Resource DevelopmentDevelop Capabilities: MalwareT1587.001
Command and ControlApplication Layer Protocol: Web ProtocolsT1071.001
Command and ControlNon-Standard PortT1571
Command and ControlIngress Tool TransferT1105

IOCs

67.215.232.25                                  Custom Python/Flask C2 (HostPapa LA)
67.215.232.25:8080                             Operator panel (Werkzeug/3.1.6)
67.215.232.25:8080/health                      Unauthenticated status endpoint
67.215.232.25:8080/api/report                  Suspected result posting (auth req)
67.215.232.25:8080/api/heartbeat               Suspected agent beacon (auth req)
67.215.232.25:5000                             Suspected agent listener
b9:db:77:d7:f0:2f:98:f3:27:9a:09:e5:dc:0e:63:7f SSH ecdsa fingerprint

Detection signature (JSON field combination):
  active_servers + pending_commands + completed_commands + status + healthy
  in a single HTTP response body on a non-standard port

Disclosure

  • HostPapa abuse: net-abuse-global@hostpapa.com (+1-905-315-3455)

The box is still idle as of this writing. We're not publishing the panel side — this post is defender-first. If you have reason to believe you have an implant beaconing to 67.215.232.25 on port 5000 or 8080, the SSH host key and the /health schema are your tightest pivots.


GHOST — Breakglass Intelligence "One indicator. Total infrastructure."

Share