{
  "hunt": {
    "meta": {
      "tlp": "clear",
      "hunt": {
        "handoff": "keep-as-periodic-hunt",
        "trigger": "intel-report",
        "methodology": "model-assisted",
        "applicability": "campaign-specific",
        "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."
      },
      "name": "DPRK CurlRAT and HAProxy Ted Interception",
      "type": "investigation",
      "labels": [
        "hunt",
        "attack.t1041",
        "attack.t1056.001",
        "attack.t1059.004",
        "attack.t1195.002"
      ],
      "series": {
        "slug": "dprk-apts-ted-backdoor-and-curlrat-target-south-korean-media-and-automotive-sectors",
        "index": 2,
        "title": "DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors",
        "total": 2
      },
      "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"
        }
      ],
      "targets": {
        "web": {
          "name": "Web server / proxy logs",
          "category": "siem",
          "telemetry": [
            "network"
          ]
        },
        "hunter": {
          "name": "Hunt agent",
          "agent": true
        },
        "analyst": {
          "name": "Tier-2 analyst",
          "role": "analyst"
        },
        "network": {
          "name": "Network telemetry",
          "category": "network",
          "telemetry": [
            "network"
          ]
        },
        "endpoint": {
          "name": "Endpoint telemetry (hb_ surfaces)",
          "category": "endpoint",
          "telemetry": [
            "endpoint"
          ]
        }
      },
      "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.",
      "coverage": [
        {
          "stage": "curl-rat-c2",
          "steps": [
            "http-c2-traffic",
            "outbound-socket-behavior"
          ],
          "status": "covered"
        },
        {
          "stage": "ted-backdoor-interception",
          "steps": [
            "scoping-haproxy-version",
            "rare-haproxy-files"
          ],
          "status": "covered"
        },
        {
          "stage": "initial-access-exploit",
          "reason": "Belongs to another part of the 'DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors' series.",
          "status": "out_of_scope"
        },
        {
          "stage": "credential-harvesting-sshd",
          "reason": "Belongs to another part of the 'DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors' series.",
          "status": "out_of_scope"
        },
        {
          "stage": "persistence-stager-binary-replacement",
          "reason": "Belongs to another part of the 'DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors' series.",
          "status": "out_of_scope"
        }
      ],
      "scenario": {
        "stages": [
          {
            "name": "Exploitation of Edge Applications",
            "slug": "initial-access-exploit",
            "tactic": "initial-access",
            "techniques": [
              "T1190"
            ],
            "observables": [
              "External ports 80, 443, 25",
              "Groupware login portal",
              "Mail server access"
            ]
          },
          {
            "name": "Trojanized SSHD Keylogger",
            "slug": "credential-harvesting-sshd",
            "tactic": "credential-access",
            "techniques": [
              "T1056.001",
              "T1195.002"
            ],
            "observables": [
              "Trojanized /usr/sbin/sshd",
              "Encrypted log file /var/lib/sshd/c8c68e629bba773a10ac80012d10bf19",
              "Hardcoded master passwords in userauth_passwd()"
            ]
          },
          {
            "name": "Daemon Replacement via Stager",
            "slug": "persistence-stager-binary-replacement",
            "tactic": "persistence",
            "techniques": [
              "T1195.002",
              "T1059.004"
            ],
            "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"
            ]
          },
          {
            "name": "CurlRAT Command and Control",
            "slug": "curl-rat-c2",
            "tactic": "c2",
            "techniques": [
              "T1041",
              "T1059.004"
            ],
            "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"
            ]
          },
          {
            "name": "HAProxy Traffic Interception",
            "slug": "ted-backdoor-interception",
            "tactic": "collection",
            "techniques": [
              "T1195.002",
              "T1056.001"
            ],
            "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"
            ]
          }
        ],
        "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."
      },
      "severity": "high",
      "rationale": "Start the hunt on edge servers and load balancers. Focus on systems serving automotive or media-related groupware portals.",
      "guardrails": {
        "claims": "no_unsupported",
        "evidence": "citation_required",
        "telemetry": "untrusted",
        "missing_data": "not_benign"
      },
      "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.",
      "parameters": {
        "c2_domains": {
          "from": {
            "ref": "rapid7-dprk-apts-ted-backdoor",
            "kind": "article",
            "observed": "2026-09-04"
          },
          "type": "list[domain]",
          "default": [
            "img.darklights.store",
            "img.monderhouse.space"
          ],
          "description": "Domains used by CurlRAT for command and control."
        },
        "scope_hosts": {
          "type": "list[host]",
          "default": [],
          "description": "The hostnames identified in the scoping step; leave empty to hunt across the entire estate."
        },
        "lookback_days": {
          "type": "number",
          "default": "14",
          "description": "The number of days to look back for activity."
        }
      },
      "provenance": {
        "authors": [
          {
            "org": "huntbase.io",
            "name": "Huntbase hunt generation"
          }
        ],
        "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"
        }
      },
      "references": [
        {
          "url": "https://www.rapid7.com/blog/post/tr-dprk-apts-ted-backdoor-curlrat-target-south-korean-media-automotive-sectors",
          "name": "Rapid7 \u2014 DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors"
        }
      ],
      "blind_spots": [
        {
          "id": "no-header-logging",
          "risk": "Legitimate traffic to the same infrastructure could trigger false positives without the unique header verification.",
          "stage": "curl-rat-c2",
          "question": "Whether the HTTP request carries the 'User-token' header used by CurlRAT",
          "requires": "hb_http_activity with custom header logging",
          "remediation": "Enable logging for the User-token header on edge proxies."
        },
        {
          "id": "memory-filter-hooks",
          "risk": "A trojanized HAProxy using internal APIs may not leave standard disk-based artifacts beyond the initial binary replacement.",
          "stage": "ted-backdoor-interception",
          "question": "Whether the Ted backdoor filter is hooked into the HAProxy memory pool",
          "requires": "Kernel-level module monitoring or memory forensics",
          "remediation": "Implement binary integrity monitoring for load balancer executables."
        }
      ]
    },
    "name": "DPRK CurlRAT and HAProxy Ted Interception",
    "description": "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."
  },
  "nodes": [
    {
      "id": "hypothesis",
      "type": "hypothesis",
      "label": "Hypothesis",
      "config": {
        "tags": [],
        "series": {
          "slug": "dprk-apts-ted-backdoor-and-curlrat-target-south-korean-media-and-automotive-sectors",
          "index": 2,
          "title": "DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors",
          "total": 2
        },
        "coverage": [
          {
            "stage": "curl-rat-c2",
            "steps": [
              "http-c2-traffic",
              "outbound-socket-behavior"
            ],
            "status": "covered"
          },
          {
            "stage": "ted-backdoor-interception",
            "steps": [
              "scoping-haproxy-version",
              "rare-haproxy-files"
            ],
            "status": "covered"
          },
          {
            "stage": "initial-access-exploit",
            "reason": "Belongs to another part of the 'DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors' series.",
            "status": "out_of_scope"
          },
          {
            "stage": "credential-harvesting-sshd",
            "reason": "Belongs to another part of the 'DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors' series.",
            "status": "out_of_scope"
          },
          {
            "stage": "persistence-stager-binary-replacement",
            "reason": "Belongs to another part of the 'DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors' series.",
            "status": "out_of_scope"
          }
        ],
        "rationale": "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.",
        "blind_spots": [
          {
            "id": "no-header-logging",
            "risk": "Legitimate traffic to the same infrastructure could trigger false positives without the unique header verification.",
            "stage": "curl-rat-c2",
            "question": "Whether the HTTP request carries the 'User-token' header used by CurlRAT",
            "requires": "hb_http_activity with custom header logging",
            "remediation": "Enable logging for the User-token header on edge proxies."
          },
          {
            "id": "memory-filter-hooks",
            "risk": "A trojanized HAProxy using internal APIs may not leave standard disk-based artifacts beyond the initial binary replacement.",
            "stage": "ted-backdoor-interception",
            "question": "Whether the Ted backdoor filter is hooked into the HAProxy memory pool",
            "requires": "Kernel-level module monitoring or memory forensics",
            "remediation": "Implement binary integrity monitoring for load balancer executables."
          }
        ],
        "scoping_notes": "Start the hunt on edge servers and load balancers. Focus on systems serving automotive or media-related groupware portals.",
        "beyond_detection": "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."
      }
    },
    {
      "id": "scoping-haproxy-version",
      "type": "query",
      "label": "Find HAProxy 2.8.12 Instances",
      "config": {
        "dsl": "sqlite",
        "role": "scoping",
        "source": "endpoint",
        "content": "SELECT DISTINCT device_hostname, package_name, package_version FROM hb_software_inventory WHERE LOWER(package_name) = 'haproxy' AND package_version = '2.8.12'",
        "surface": "hb_software_inventory",
        "description": "Identify Linux hosts running the specific load balancer version used as the base for the Ted backdoor plugin.",
        "expected_signal": "A list of hostnames running HAProxy 2.8.12. Absence of results reduces the probability of this specific toolkit being present."
      },
      "parents": [
        {
          "id": "hypothesis"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "scoping",
        "label": "Find HAProxy 2.8.12 Instances",
        "reads": [
          "device_hostname",
          "package_name",
          "package_version"
        ],
        "source": "hb_software_inventory",
        "target": "endpoint",
        "content": "SELECT DISTINCT device_hostname, package_name, package_version FROM hb_software_inventory WHERE LOWER(package_name) = 'haproxy' AND package_version = '2.8.12'",
        "silence": "not_evidence_of_absence",
        "expected": "A list of hostnames running HAProxy 2.8.12. Absence of results reduces the probability of this specific toolkit being present.",
        "verified": "dry-run",
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "http-c2-traffic",
      "type": "query",
      "label": "CurlRAT Domain Traffic",
      "config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "source": "web",
        "content": "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')",
        "surface": "hb_http_activity",
        "description": "Detect communication with hardcoded CurlRAT domains associated with APT37.",
        "expected_signal": "HTTP requests to malicious domains from the scoped proxies. Silence only proves these specific domains were not used."
      },
      "parents": [
        {
          "id": "scoping-haproxy-version"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "detection-candidate",
        "label": "CurlRAT Domain Traffic",
        "reads": [
          "device_hostname",
          "url_hostname",
          "url_path",
          "src_endpoint_ip",
          "time"
        ],
        "source": "hb_http_activity",
        "target": "web",
        "content": "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')",
        "silence": "not_evidence_of_absence",
        "expected": "HTTP requests to malicious domains from the scoped proxies. Silence only proves these specific domains were not used.",
        "verified": "dry-run",
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "outbound-socket-behavior",
      "type": "query",
      "label": "Outbound HAProxy Sockets",
      "config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "source": "network",
        "content": "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')",
        "surface": "hb_network_connection",
        "description": "Identify HAProxy or its children initiating outbound connections to non-internal addresses.",
        "expected_signal": "Outbound connections from a load balancer process to the public internet, suggesting C2 or exfiltration."
      },
      "parents": [
        {
          "id": "scoping-haproxy-version"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "label": "Outbound HAProxy Sockets",
        "reads": [
          "device_hostname",
          "process_name",
          "dst_endpoint_ip",
          "dst_endpoint_port",
          "time"
        ],
        "source": "hb_network_connection",
        "target": "network",
        "content": "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')",
        "silence": "not_evidence_of_absence",
        "expected": "Outbound connections from a load balancer process to the public internet, suggesting C2 or exfiltration.",
        "verified": "dry-run",
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "rare-haproxy-files",
      "type": "query",
      "label": "Rare File Writes by HAProxy",
      "config": {
        "dsl": "sqlite",
        "role": "baseline",
        "source": "endpoint",
        "content": "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",
        "surface": "hb_file_activity",
        "description": "Identify rare file modifications by the haproxy process in system directories like /usr/lib or /var/lib.",
        "expected_signal": "Unique files in system libraries or variable directories touched by the proxy process on a small number of hosts."
      },
      "parents": [
        {
          "id": "scoping-haproxy-version"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "baseline",
        "label": "Rare File Writes by HAProxy",
        "reads": [
          "device_hostname",
          "file_path",
          "process_name",
          "time"
        ],
        "source": "hb_file_activity",
        "target": "endpoint",
        "content": "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",
        "silence": "not_evidence_of_absence",
        "baseline": {
          "window": "{{lookback_days}}d",
          "compare": "first_seen"
        },
        "expected": "Unique files in system libraries or variable directories touched by the proxy process on a small number of hosts.",
        "verified": "dry-run",
        "prevalence": {
          "by": "device_hostname",
          "key": [
            "path"
          ],
          "rare_below": 3
        },
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "agent-triage",
      "type": "analytic",
      "label": "Synthesize Compromise Evidence",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint",
          "network",
          "web"
        ],
        "context": [
          "scoping-haproxy-version",
          "http-c2-traffic",
          "outbound-socket-behavior",
          "rare-haproxy-files"
        ],
        "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.",
        "description": "Evaluate whether the software version, network behavior, and file artifacts together indicate a host compromise.",
        "max_iterations": 5,
        "expected_signal": "A high-confidence verdict on whether a host is running the backdoored HAProxy or CurlRAT.",
        "success_criteria": "A verdict of malicious, suspicious, or benign for each host with cited data rows."
      },
      "parents": [
        {
          "id": "http-c2-traffic",
          "kind": "merge"
        },
        {
          "id": "outbound-socket-behavior",
          "kind": "merge"
        },
        {
          "id": "rare-haproxy-files",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "route-findings",
      "type": "checkpoint",
      "label": "Route on Verdict",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the agent-triage verdict is malicious for at least one host",
        "condition": "the agent-triage verdict is malicious for at least one host",
        "blind_spot": "no-header-logging",
        "confidence": "high",
        "description": "Initiate containment if the agent confirms malicious activity.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "agent-triage"
        }
      ]
    },
    {
      "id": "isolate-host",
      "type": "action",
      "label": "Isolate Compromised Host",
      "config": {
        "target": "endpoint",
        "description": "Contain the threat and prevent further traffic interception.",
        "instructions": "Isolate the host immediately. Preserve the HAProxy process memory and examine system library directories for unauthorized files.",
        "action_approval": "required"
      },
      "parents": [
        {
          "id": "route-findings",
          "branch": "on_supports"
        }
      ]
    },
    {
      "id": "manual-forensics",
      "type": "task",
      "label": "Forensic Review",
      "config": {
        "assignee": "analyst",
        "description": "Confirm the presence of the Ted backdoor filter and investigate for credential harvesting.",
        "instructions": "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."
      },
      "parents": [
        {
          "id": "route-findings",
          "branch": "default"
        },
        {
          "id": "route-findings",
          "branch": "on_unavailable"
        },
        {
          "id": "isolate-host"
        }
      ]
    },
    {
      "id": "close-out-report",
      "type": "task",
      "label": "Final Reporting",
      "config": {
        "assignee": "analyst",
        "description": "Document the hunt outcome and findings.",
        "instructions": "Summarize the hosts examined, the software versions identified, and any confirmed indicators. Close the hunt."
      },
      "parents": [
        {
          "id": "route-findings",
          "branch": "on_refutes"
        },
        {
          "id": "manual-forensics"
        }
      ]
    }
  ]
}