Build1 publisher3 min readPublished
A backdoor built as an HAProxy filter suppresses the log lines that would show it
Rapid7's account puts the ted backdoor inside HAProxy 2.8.12 as an internal filter, matching requests by IP, URL and User-Agent and reducing the same counters an operator would use to triage it. Root was already held.
The Engineer · Build desk

What happened
- Rapid7, in an account summarised on dev.to and dated 2026-09-04, describes an actor deploying the ted backdoor and curlRAT against South Korean sectors, with the incident rated High severity.
- The same component reduced HAProxy's counters and stopped specific C2 requests from reaching backend servers, so those requests never appeared in the servers' records.
- Remediation in the report is to preserve memory and disk, rebuild the suspected compromised server, then rotate SSH keys, passwords and certificates.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint Once the proxy's own logs and counters are tampered with, they carry no weight in triage, so an off-host record has to already exist when the investigation starts rather than being stood up during it.
- decision With no patch to apply, the decision moves to rebuilding a load balancer and rotating every credential it touched, scheduled against traffic you cannot simply drop.
- exposure The blast radius reaches past the host to the site's visitors, whose cookies and sessions are collectable and whose responses can be replaced while the service keeps answering normally.
- cost Hash-and-signature comparison only pays off if a known-good baseline exists for however your HAProxy was built, which is expenditure in the build pipeline months before anyone needs it.
A filter in HAProxy is code running inside the proxy process on the HTTP analysis path, which is also the process that writes the access log line and updates the stats counters [24]. That adjacency is the trick. Rapid7's account, summarised on dev.to, has ted matching on IPs, URLs, Referrers and User-Agents, replacing only the traffic it wants, and hiding the activity from logs and counters [4]. Specific C2 requests were also kept from reaching backend servers, so they left no record there either [5]. The load balancer is the one host many teams monitor by asking it how it is doing.
The version number in the write-up simply marks where the backdoor was found; it does not describe a vulnerability in HAProxy 2.8.12 itself. Rapid7 says no specific initial access vector was confirmed and that the actor was operating with root or elevated privileges on an internet-facing Linux server [6]; the groupware portal exploitation shown in the analysis diagram is an assumption [7]. Upgrading past 2.8.12 leaves the compromise untouched. What the report asks for instead is preserving memory and disk, rebuilding the server, then rotating SSH keys, passwords and certificates [13].
Host tooling still works here, but only under conditions. The endpoint checks listed are a specific path, /var/lib/sshd/c8c68e629bba773a10ac80012d10bf19, the replaced crond, timestomped files, and a comparison of HAProxy binaries and memory against known baselines, with an explicit warning not to rely on file names alone [16]. Hash, signature and package-metadata comparison is extended to OpenSSH and cron as well [14]. Whether that comparison is available to you is a property of your build pipeline. A distro package has a signature to verify. A locally patched HAProxy has whatever hash you recorded at build time, and if nobody recorded it, this detection does not transfer.
The network indicators want the same reading. curlRAT's default interval is 12 hours, with a 30-second fast mode [18]. That is two callbacks a day at the default [19] against 2,880 in fast mode [20], a factor of 1,440 [21], and the report warns against judging traffic malicious on an interval match alone [18]. Two outbound HTTPS requests a day from a proxy host sit inside normal behaviour. The more usable artefact is the upstream request for /favorite_list_2x_m500_ico.jpg, which the report notes the compromised HAProxy and its backends may fail to capture [17].
That is the prerequisite the whole investigation rests on: a record the compromised host cannot edit, such as a network TAP or an upstream proxy [15]. Local HAProxy logs and counters were tampered with in this case, so the usual metrics carry no weight [22]. Meanwhile the service keeps answering normally, and only targeted users see replaced responses or a watering hole [11]. Attribution is medium confidence [2] and the entry point is unconfirmed [6], so it's the placement that holds up as the durable finding, while attribution stays soft. Anything with a plugin interface on the request path can host a filter, and the proxy tier is where the plaintext is.
What to watch
- Whether Rapid7 or another vendor publishes a ted sample hash or a filter-level check that does not depend on a locally recorded baseline.
- Whether the medium-confidence DPRK attribution firms up, or the groupware portal entry point moves from assumption to confirmed vector.
- Whether any HAProxy distribution ships a runtime way to enumerate loaded filters and diff them against the configuration on disk.