← All hunts high TLP:CLEAR Part 2 of 2

DPRK CurlRAT and HAProxy Ted Interception

An adversary has compromised the edge load balancer by installing a custom HAProxy filter and a Curl-based RAT to intercept web traffic and execute remote commands.

Based on research by Rapid7 2026-09-28 10 steps · 4 queries T1041 T1056.001 T1059.004 T1195.002

Brief

Rapid7 recently detailed DPRK APT activity targeting South Korean organizations using the Ted backdoor and CurlRAT in DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors. These tools allow adversaries to intercept web traffic at the load balancer and establish remote access to internal systems. This hunt provides a structured way to identify these artifacts across Linux-based edge infrastructure.

Scoping the Environment

The first phase identifies Linux hosts running HAProxy 2.8.12. This specific version serves as the foundation for the Ted backdoor plugin. Because the backdoor relies on a custom filter compiled for this version, isolating these hosts narrows the hunt surface to systems that meet the technical requirements for the observed toolkit. If an environment uses different versions or does not run HAProxy, the probability of this specific campaign being present is low.

Parallel Investigation of C2 and Artifacts

Once the hunt identifies relevant hosts, it initiates three parallel queries to gather evidence from network and host activity. The first query searches for HTTP requests to known CurlRAT command-and-control domains, such as img.darklights.store. This activity indicates that the RAT is active and attempting to retrieve instructions or post stolen data.

Simultaneously, the hunt monitors the network behavior of the HAProxy process. A second query looks for the proxy process or its children initiating outbound connections to public IP addresses. Legitimate load balancers typically communicate with internal backends or specific management IPs; direct outbound connections to the public internet suggest C2 traffic or exfiltration.

Finally, the hunt baselines file activity for the proxy process. The third query flags rare file writes by HAProxy to system library directories like /usr/lib/ or variable directories like /var/lib/. The Ted backdoor framework often places malicious filters or encrypted log files in these locations to remain persistent and hide collected credentials.

Synthesis and Triage

An analyst evaluates the combined results of the scoping and investigation phases. A host showing the target HAProxy version alongside suspicious network connections or unusual file modifications receives a malicious verdict. This correlation is essential because the individual behaviors—such as an outbound connection or a file write—might appear benign in isolation but become high-confidence indicators when occurring together on a critical edge appliance.

Blind Spots and Limitations

This hunt relies on host and network logs. If edge proxies do not log custom HTTP headers, the hunt cannot confirm the presence of the 'User-token' header unique to CurlRAT, which increases the risk of false positives from shared infrastructure. Furthermore, if the adversary loads the Ted backdoor filter directly into memory without leaving a persistent binary on disk, standard file audit logs will not capture the installation. In such cases, memory forensics or binary integrity monitoring for load balancer executables is required to confirm the compromise.

Running the Hunt

This hunt is a hunt.md playbook that imports into Huntbase or any hunt.md-aware runtime. It uses a funnel approach, starting with software inventory scoping before moving into behavioral analysis. Practitioners should run the scoping query first to identify the relevant edge footprint before executing the parallel investigation steps.

In this series

Steps

  1. Find HAProxy 2.8.12 Instances

    Query · scoping

    Identify Linux hosts running the specific load balancer version used as the base for the Ted backdoor plugin.

    reads hb_software_inventorysql
    SELECT DISTINCT device_hostname, package_name, package_version FROM hb_software_inventory WHERE LOWER(package_name) = 'haproxy' AND package_version = '2.8.12'

    What a hit looks like. A list of hostnames running HAProxy 2.8.12. Absence of results reduces the probability of this specific toolkit being present.

  2. CurlRAT Domain Traffic

    Query · detection candidate

    Detect communication with hardcoded CurlRAT domains associated with APT37.

    reads hb_http_activitysql
    SELECT device_hostname, url_hostname, url_path, src_endpoint_ip, time FROM hb_http_activity WHERE instr(',' || '{{c2_domains}}' || ',', ',' || LOWER(url_hostname) || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')

    What a hit looks like. HTTP requests to malicious domains from the scoped proxies. Silence only proves these specific domains were not used.

  3. Outbound HAProxy Sockets

    Query · enrichment

    Identify HAProxy or its children initiating outbound connections to non-internal addresses.

    reads hb_network_connectionsql
    SELECT device_hostname, process_name, dst_endpoint_ip, dst_endpoint_port, time FROM hb_network_connection WHERE LOWER(process_name) LIKE '%haproxy%' AND direction = 'outbound' AND dst_endpoint_ip NOT LIKE '10.%' AND dst_endpoint_ip NOT LIKE '192.168.%' AND dst_endpoint_ip NOT LIKE '172.%' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')

    What a hit looks like. Outbound connections from a load balancer process to the public internet, suggesting C2 or exfiltration.

  4. Rare File Writes by HAProxy

    Query · baseline

    Identify rare file modifications by the haproxy process in system directories like /usr/lib or /var/lib.

    reads hb_file_activitysql
    SELECT LOWER(file_path) AS path, device_hostname, process_name, COUNT(*) AS touches, MIN(time) AS first_seen FROM hb_file_activity WHERE LOWER(process_name) LIKE '%haproxy%' AND (LOWER(file_path) LIKE '/usr/lib/%' OR LOWER(file_path) LIKE '/var/lib/%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY 1, 2, 3 HAVING COUNT(DISTINCT device_hostname) <= 3

    What a hit looks like. Unique files in system libraries or variable directories touched by the proxy process on a small number of hosts.

  5. Synthesize Compromise Evidence

    Agent triage

    Evaluate whether the software version, network behavior, and file artifacts together indicate a host compromise.

  6. Route on Verdict

    Decision

    Initiate containment if the agent confirms malicious activity.

  7. Isolate Compromised Host

    Response action

    Contain the threat and prevent further traffic interception.

  8. Forensic Review

    Analyst task

    Confirm the presence of the Ted backdoor filter and investigate for credential harvesting.

  9. Final Reporting

    Analyst task

    Document the hunt outcome and findings.

Coverage

Scenario coverage

StageCoveredHow, or why not
CurlRAT Command and Control
T1041 · T1059.004
Yes http-c2-traffic, outbound-socket-behavior
HAProxy Traffic Interception
T1195.002 · T1056.001
Yes scoping-haproxy-version, rare-haproxy-files
Exploitation of Edge Applications
T1190
Out of scope Belongs to another part of the 'DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors' series.
Trojanized SSHD Keylogger
T1056.001 · T1195.002
Out of scope Belongs to another part of the 'DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors' series.
Daemon Replacement via Stager
T1195.002 · T1059.004
Out of scope Belongs to another part of the 'DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors' series.

Blind spots

  • Needs hb_http_activity with custom header logging. Legitimate traffic to the same infrastructure could trigger false positives without the unique header verification. It would answer Whether the HTTP request carries the 'User-token' header used by CurlRAT. Remediation: Enable logging for the User-token header on edge proxies.
  • Needs Kernel-level module monitoring or memory forensics. A trojanized HAProxy using internal APIs may not leave standard disk-based artifacts beyond the initial binary replacement. It would answer Whether the Ted backdoor filter is hooked into the HAProxy memory pool. Remediation: Implement binary integrity monitoring for load balancer executables.

Parameters & data

Parameters

ParameterTypeDefaultWhat it is
c2_domainslist[domain]img.darklights.store, img.monderhouse.spaceDomains used by CurlRAT for command and control.
lookback_daysnumber14The number of days to look back for activity.
scope_hostslist[host]—The hostnames identified in the scoping step; leave empty to hunt across the entire estate.

Telemetry

SourceCategoryTelemetry
Endpoint telemetry (hb_ surfaces)endpointendpoint
Network telemetrynetworknetwork
Web server / proxy logssiemnetwork

Source

Download hunt.md Definition (JSON) An open hunt.md file; it runs anywhere that reads the format.
---
analysis: This is a hunt because it correlates the presence of a specific software
  version with behavioral network patterns and rare file system modifications by the
  proxy process. A single rule misses the context of the load balancer's persistent
  backdoor capabilities.
blind_spots:
- id: no-header-logging
  question: Whether the HTTP request carries the 'User-token' header used by CurlRAT
  remediation: Enable logging for the User-token header on edge proxies.
  requires: hb_http_activity with custom header logging
  risk: Legitimate traffic to the same infrastructure could trigger false positives
    without the unique header verification.
  stage: curl-rat-c2
- id: memory-filter-hooks
  question: Whether the Ted backdoor filter is hooked into the HAProxy memory pool
  remediation: Implement binary integrity monitoring for load balancer executables.
  requires: Kernel-level module monitoring or memory forensics
  risk: A trojanized HAProxy using internal APIs may not leave standard disk-based
    artifacts beyond the initial binary replacement.
  stage: ted-backdoor-interception
coverage:
- stage: curl-rat-c2
  status: covered
  steps:
  - http-c2-traffic
  - outbound-socket-behavior
- stage: ted-backdoor-interception
  status: covered
  steps:
  - scoping-haproxy-version
  - rare-haproxy-files
- reason: 'Belongs to another part of the ''DPRK APTs: Ted backdoor and curlRAT target
    South Korean media and automotive sectors'' series.'
  stage: initial-access-exploit
  status: out_of_scope
- reason: 'Belongs to another part of the ''DPRK APTs: Ted backdoor and curlRAT target
    South Korean media and automotive sectors'' series.'
  stage: credential-harvesting-sshd
  status: out_of_scope
- reason: 'Belongs to another part of the ''DPRK APTs: Ted backdoor and curlRAT target
    South Korean media and automotive sectors'' series.'
  stage: persistence-stager-binary-replacement
  status: out_of_scope
guardrails:
  claims: no_unsupported
  evidence: citation_required
  missing_data: not_benign
  telemetry: untrusted
hunt:
  applicability: campaign-specific
  handoff: keep-as-periodic-hunt
  justification: The Ted backdoor enables covert interception of all web traffic and
    session cookies handled by the load balancer. A negative result over the estate
    confirms this specific long-term espionage framework is not currently active.
  methodology: model-assisted
  trigger: intel-report
hypothesis: An adversary has compromised the edge load balancer by installing a custom
  HAProxy filter and a Curl-based RAT to intercept web traffic and execute remote
  commands.
labels:
- hunt
- attack.t1041
- attack.t1056.001
- attack.t1059.004
- attack.t1195.002
name: DPRK CurlRAT and HAProxy Ted Interception
parameters:
  c2_domains:
    default:
    - img.darklights.store
    - img.monderhouse.space
    description: Domains used by CurlRAT for command and control.
    from:
      kind: article
      observed: '2026-09-04'
      ref: rapid7-dprk-apts-ted-backdoor
    type: list[domain]
  lookback_days:
    default: '14'
    description: The number of days to look back for activity.
    type: number
  scope_hosts:
    default: []
    description: The hostnames identified in the scoping step; leave empty to hunt
      across the entire estate.
    type: list[host]
provenance:
  authors:
  - name: Huntbase hunt generation
    org: huntbase.io
  generated:
    by: huntbase-hunt-generation
    from: https://www.rapid7.com/blog/post/tr-dprk-apts-ted-backdoor-curlrat-target-south-korean-media-automotive-sectors
    gates:
    - dry-run
    - lint
    model: hb_google/gemini-3-flash-preview
rationale: Start the hunt on edge servers and load balancers. Focus on systems serving
  automotive or media-related groupware portals.
references:
- name: "Rapid7 \u2014 DPRK APTs: Ted backdoor and curlRAT target South Korean media\
    \ and automotive sectors"
  url: https://www.rapid7.com/blog/post/tr-dprk-apts-ted-backdoor-curlrat-target-south-korean-media-automotive-sectors
related:
- hunt: sshd-keylogger-integrity
  reason: The SSH keylogger component requires specific integrity checks on sshd binaries
    and its encrypted log file, which is a separate host-integrity hunt.
  relation: out-of-scope-alternative
- hunt: linux-system-daemon-trojanization-credential-harvesting
  relation: follows
scenario:
  stages:
  - name: Exploitation of Edge Applications
    observables:
    - External ports 80, 443, 25
    - Groupware login portal
    - Mail server access
    slug: initial-access-exploit
    tactic: initial-access
    techniques:
    - T1190
  - name: Trojanized SSHD Keylogger
    observables:
    - Trojanized /usr/sbin/sshd
    - Encrypted log file /var/lib/sshd/c8c68e629bba773a10ac80012d10bf19
    - Hardcoded master passwords in userauth_passwd()
    slug: credential-harvesting-sshd
    tactic: credential-access
    techniques:
    - T1056.001
    - T1195.002
  - name: Daemon Replacement via Stager
    observables:
    - Stager file /tmp/jasper-log
    - Replacement of /usr/sbin/crond
    - Timestomping crond to match /usr/bin/ssh creation date
    - Trojanized versions of agetty, atd, and polkitd
    - Filtering /root/.bash_history and /var/log/messages
    slug: persistence-stager-binary-replacement
    tactic: persistence
    techniques:
    - T1195.002
    - T1059.004
  - name: CurlRAT Command and Control
    observables:
    - HTTP POST to img.darklights.store
    - HTTP POST to img.monderhouse.space
    - User-token header containing MD5 victim ID
    - Directory /var/lib/snapd/ containing files g580, g105
    - Configuration file /tmp/nimon.unix-docbase.8564479396043450766-db6fb4443bc
    slug: curl-rat-c2
    tactic: c2
    techniques:
    - T1041
    - T1059.004
  - name: HAProxy Traffic Interception
    observables:
    - HAProxy version 2.8.12
    - Custom HAProxy filter plugin 'ted backdoor'
    - File /usr/lib/libvirtlog.so.0
    - Watchdog thread monitoring /var/run/haproxy.pid
    - Cookie stealing and script injection into web traffic
    slug: ted-backdoor-interception
    tactic: collection
    techniques:
    - T1195.002
    - T1056.001
  summary: DPRK-linked actors (likely Kimsuky or APT37) deployed a sophisticated Linux
    toolkit targeting South Korean media and automotive sectors for long-term espionage.
    The campaign features the 'TED backdoor,' a custom HAProxy filter for traffic
    interception and script injection, and 'CurlRAT,' which is embedded in trojanized
    system daemons like crond and sshd to facilitate credential harvesting and remote
    command execution.
series:
  index: 2
  slug: dprk-apts-ted-backdoor-and-curlrat-target-south-korean-media-and-automotive-sectors
  title: 'DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive
    sectors'
  total: 2
severity: high
targets:
  analyst:
    name: Tier-2 analyst
    role: analyst
  endpoint:
    category: endpoint
    name: Endpoint telemetry (hb_ surfaces)
    telemetry:
    - endpoint
  hunter:
    agent: true
    name: Hunt agent
  network:
    category: network
    name: Network telemetry
    telemetry:
    - network
  web:
    category: siem
    name: Web server / proxy logs
    telemetry:
    - network
tlp: clear
type: investigation
---


# DPRK CurlRAT and HAProxy Ted Interception

This hunt identifies Linux systems running the specific HAProxy version targeted by the Ted backdoor framework and searches for associated command-and-control activity. It focuses on the South Korean media and automotive sector campaign, looking for rare file writes by the haproxy process and HTTP traffic to known malicious domains. The flow uses a funnel approach to scope the environment before corroborating network and host indicators.

## scoping-haproxy-version
<!-- Find HAProxy 2.8.12 Instances -->
Identify Linux hosts running the specific load balancer version used as the base for the Ted backdoor plugin.

```sqlite target=endpoint role=scoping
~~~yaml
expected: A list of hostnames running HAProxy 2.8.12. Absence of results reduces the
  probability of this specific toolkit being present.
reads:
- device_hostname
- package_name
- package_version
silence: not_evidence_of_absence
source: hb_software_inventory
verified: dry-run
verified_at: '2026-09-28'
~~~
SELECT DISTINCT device_hostname, package_name, package_version FROM hb_software_inventory WHERE LOWER(package_name) = 'haproxy' AND package_version = '2.8.12'
```

## investigation-fanout
<!-- Parallel Investigation of C2 and Artifacts -->
parallel:
- → http-c2-traffic
- → outbound-socket-behavior
- → rare-haproxy-files
join: → agent-triage

## http-c2-traffic
<!-- CurlRAT Domain Traffic -->
Detect communication with hardcoded CurlRAT domains associated with APT37.

```sqlite target=web role=detection-candidate params=(c2_domains=c2_domains, scope_hosts=scope_hosts, lookback_days=lookback_days)
~~~yaml
expected: HTTP requests to malicious domains from the scoped proxies. Silence only
  proves these specific domains were not used.
reads:
- device_hostname
- url_hostname
- url_path
- src_endpoint_ip
- time
silence: not_evidence_of_absence
source: hb_http_activity
verified: dry-run
verified_at: '2026-09-28'
~~~
SELECT device_hostname, url_hostname, url_path, src_endpoint_ip, time FROM hb_http_activity WHERE instr(',' || '{{c2_domains}}' || ',', ',' || LOWER(url_hostname) || ',') > 0 AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')
```

## outbound-socket-behavior
<!-- Outbound HAProxy Sockets -->
Identify HAProxy or its children initiating outbound connections to non-internal addresses.

```sqlite target=network role=enrichment params=(scope_hosts=scope_hosts, lookback_days=lookback_days)
~~~yaml
expected: Outbound connections from a load balancer process to the public internet,
  suggesting C2 or exfiltration.
reads:
- device_hostname
- process_name
- dst_endpoint_ip
- dst_endpoint_port
- time
silence: not_evidence_of_absence
source: hb_network_connection
verified: dry-run
verified_at: '2026-09-28'
~~~
SELECT device_hostname, process_name, dst_endpoint_ip, dst_endpoint_port, time FROM hb_network_connection WHERE LOWER(process_name) LIKE '%haproxy%' AND direction = 'outbound' AND dst_endpoint_ip NOT LIKE '10.%' AND dst_endpoint_ip NOT LIKE '192.168.%' AND dst_endpoint_ip NOT LIKE '172.%' AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')
```

## rare-haproxy-files
<!-- Rare File Writes by HAProxy -->
Identify rare file modifications by the haproxy process in system directories like /usr/lib or /var/lib.

```sqlite target=endpoint role=baseline params=(scope_hosts=scope_hosts, lookback_days=lookback_days)
~~~yaml
baseline:
  compare: first_seen
  window: '{{lookback_days}}d'
expected: Unique files in system libraries or variable directories touched by the
  proxy process on a small number of hosts.
prevalence:
  by: device_hostname
  key:
  - path
  rare_below: 3
reads:
- device_hostname
- file_path
- process_name
- time
silence: not_evidence_of_absence
source: hb_file_activity
verified: dry-run
verified_at: '2026-09-28'
~~~
SELECT LOWER(file_path) AS path, device_hostname, process_name, COUNT(*) AS touches, MIN(time) AS first_seen FROM hb_file_activity WHERE LOWER(process_name) LIKE '%haproxy%' AND (LOWER(file_path) LIKE '/usr/lib/%' OR LOWER(file_path) LIKE '/var/lib/%') AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY 1, 2, 3 HAVING COUNT(DISTINCT device_hostname) <= 3
```

## agent-triage
<!-- Synthesize Compromise Evidence -->
```agent target=hunter
cite: required
context:
- scoping-haproxy-version
- http-c2-traffic
- outbound-socket-behavior
- rare-haproxy-files
max_iterations: 5
objective: Determine if any host shows evidence of HAProxy version 2.8.12 alongside
  malicious network traffic or unusual file modifications by the proxy process.
success_criteria: A verdict of malicious, suspicious, or benign for each host with
  cited data rows.
tools:
- endpoint
- network
- web
```

## route-findings
<!-- Route on Verdict -->
if~: "the agent-triage verdict is malicious for at least one host" (confidence: high, judge=hunter)
then: → isolate-host
indeterminate: → manual-forensics
unavailable: → manual-forensics (blind_spot: no-header-logging)
else: → close-out-report

## isolate-host
<!-- Isolate Compromised Host -->
```action target=endpoint
~~~yaml
approval: required
~~~
Isolate the host immediately. Preserve the HAProxy process memory and examine system library directories for unauthorized files.
```
→ manual-forensics

## manual-forensics
<!-- Forensic Review -->
```manual target=analyst
Manually inspect the HAProxy configuration and binary symbols for custom filters. Use a 1-byte XOR (0x58) to decrypt any files found in /var/lib/snapd. Search for /var/lib/sshd/c8c68e629bba773a10ac80012d10bf19 to confirm credential harvesting.
```
→ close-out-report

## close-out-report
<!-- Final Reporting -->
```manual target=analyst
Summarize the hosts examined, the software versions identified, and any confirmed indicators. Close the hunt.
```
→ end

Run it

Take this hunt into your environment.

Open it in Huntbase to run every step against your own connections, with Scout weighing the evidence and your analysts in command. Or take the open hunt.md file anywhere that reads the format.

Machine-drafted by huntbase-hunt-generation using hb_google/gemini-3-flash-preview, gated by dry-run, lint, then reviewed by a person.