{
  "hunt": {
    "meta": {
      "tlp": "clear",
      "hunt": {
        "handoff": "keep-as-periodic-hunt",
        "trigger": "intel-report",
        "methodology": "model-assisted",
        "applicability": "campaign-specific",
        "justification": "DPRK APTs use deeply integrated trojanized system binaries that are invisible to standard monitoring; a proactive baseline of system daemon hashes is required to detect these modifications."
      },
      "name": "Linux System Daemon Trojanization and Credential Harvesting",
      "type": "investigation",
      "labels": [
        "hunt",
        "attack.t1056.001",
        "attack.t1195.002",
        "attack.t1059.004",
        "attack.t1190"
      ],
      "series": {
        "slug": "dprk-apts-ted-backdoor-and-curlrat-target-south-korean-media-and-automotive-sectors",
        "index": 1,
        "title": "DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors",
        "total": 2
      },
      "related": [
        {
          "hunt": "curl-rat-c2-behavior",
          "reason": "If a trojanized daemon is found, the next hunt investigates its specific network communication patterns.",
          "relation": "follows"
        }
      ],
      "targets": {
        "hunter": {
          "name": "Hunt agent",
          "agent": true
        },
        "analyst": {
          "name": "Tier-2 analyst",
          "role": "analyst"
        },
        "endpoint": {
          "name": "Endpoint telemetry (hb_ surfaces)",
          "category": "endpoint",
          "telemetry": [
            "endpoint"
          ]
        }
      },
      "analysis": "A rule firing on every sshd modification causes excessive false positives during legitimate updates. This hunt uses a gated flow to only run expensive fleet-wide stack-counts when specific toolkit artifacts are found, then correlates rarity with vulnerability context.",
      "coverage": [
        {
          "stage": "initial-access-exploit",
          "steps": [
            "vulnerable-edge-apps"
          ],
          "status": "covered"
        },
        {
          "stage": "credential-harvesting-sshd",
          "steps": [
            "lead-file-discovery"
          ],
          "status": "covered"
        },
        {
          "stage": "persistence-stager-binary-replacement",
          "steps": [
            "rare-daemon-hashes"
          ],
          "status": "covered"
        },
        {
          "stage": "curl-rat-c2",
          "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": "ted-backdoor-interception",
          "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": "Focus on Linux servers running HAProxy or edge mail servers (Postfix, Exim). Start with a 14-day window for file activity but extend to 90 days for process hash baseline if results are inconclusive.",
      "guardrails": {
        "claims": "no_unsupported",
        "evidence": "citation_required",
        "telemetry": "untrusted",
        "missing_data": "not_benign"
      },
      "hypothesis": "An adversary has established long-term persistence and credential harvesting by replacing legitimate Linux system daemons with trojanized versions that log passwords and monitor process health.",
      "parameters": {
        "scope_hosts": {
          "from": {
            "ref": "analyst-scoping",
            "kind": "manual",
            "observed": "2026-09-04"
          },
          "type": "list[host]",
          "default": [],
          "description": "Hosts identified in the lead query; leave empty to scan the full estate."
        },
        "daemon_paths": {
          "from": {
            "ref": "rapid7-dprk-ted",
            "kind": "article",
            "observed": "2026-09-04"
          },
          "type": "list[path]",
          "default": [
            "/usr/sbin/sshd",
            "/usr/sbin/crond",
            "/usr/sbin/agetty",
            "/usr/sbin/atd",
            "/usr/sbin/polkitd",
            "/usr/sbin/haproxy"
          ],
          "description": "System binaries targeted for replacement or backdoor insertion."
        },
        "lookback_days": {
          "from": {
            "ref": "standard-retention",
            "kind": "manual",
            "observed": "2026-09-04"
          },
          "type": "number",
          "default": "14",
          "description": "Days of history to examine."
        },
        "toolkit_files": {
          "from": {
            "ref": "rapid7-dprk-ted",
            "kind": "article",
            "observed": "2026-09-04"
          },
          "type": "list[path]",
          "default": [
            "/var/lib/sshd/c8c68e629bba773a10ac80012d10bf19",
            "/tmp/jasper-log",
            "/var/lib/snapd/g580",
            "/var/lib/snapd/g105",
            "/usr/lib/libvirtlog.so.0"
          ],
          "description": "Hidden log and configuration files associated with the SSH keylogger and CurlRAT."
        }
      },
      "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": "pre-existing-compromise",
          "risk": "A host compromised months ago will not show file-activity rows for the initial replacement, making the hunt dependent on hash rarity.",
          "stage": "persistence-stager-binary-replacement",
          "question": "Was the trojanized crond dropped before the telemetry retention window?",
          "requires": "long-term file creation telemetry"
        },
        {
          "id": "unhashed-executables",
          "risk": "If hashes are not captured for standard system daemons, the stack-counting step cannot identify trojanized outliers.",
          "stage": "persistence-stager-binary-replacement",
          "question": "Does the agent hash every execution of system daemons?",
          "requires": "hb_process_activity with SHA256"
        }
      ]
    },
    "name": "Linux System Daemon Trojanization and Credential Harvesting",
    "description": "This hunt targets the endpoint artifacts of the Ted and CurlRAT toolkit used against South Korean automotive and media sectors. It focuses on identifying trojanized system binaries like sshd and crond by first searching for known hidden log and configuration files. If these leads are found, the hunt expands to stack-count binary hashes across the estate to identify outliers and correlates these with high-severity vulnerabilities in edge-facing applications."
  },
  "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": 1,
          "title": "DPRK APTs: Ted backdoor and curlRAT target South Korean media and automotive sectors",
          "total": 2
        },
        "coverage": [
          {
            "stage": "initial-access-exploit",
            "steps": [
              "vulnerable-edge-apps"
            ],
            "status": "covered"
          },
          {
            "stage": "credential-harvesting-sshd",
            "steps": [
              "lead-file-discovery"
            ],
            "status": "covered"
          },
          {
            "stage": "persistence-stager-binary-replacement",
            "steps": [
              "rare-daemon-hashes"
            ],
            "status": "covered"
          },
          {
            "stage": "curl-rat-c2",
            "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": "ted-backdoor-interception",
            "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 established long-term persistence and credential harvesting by replacing legitimate Linux system daemons with trojanized versions that log passwords and monitor process health.",
        "blind_spots": [
          {
            "id": "pre-existing-compromise",
            "risk": "A host compromised months ago will not show file-activity rows for the initial replacement, making the hunt dependent on hash rarity.",
            "stage": "persistence-stager-binary-replacement",
            "question": "Was the trojanized crond dropped before the telemetry retention window?",
            "requires": "long-term file creation telemetry"
          },
          {
            "id": "unhashed-executables",
            "risk": "If hashes are not captured for standard system daemons, the stack-counting step cannot identify trojanized outliers.",
            "stage": "persistence-stager-binary-replacement",
            "question": "Does the agent hash every execution of system daemons?",
            "requires": "hb_process_activity with SHA256"
          }
        ],
        "scoping_notes": "Focus on Linux servers running HAProxy or edge mail servers (Postfix, Exim). Start with a 14-day window for file activity but extend to 90 days for process hash baseline if results are inconclusive.",
        "beyond_detection": "A rule firing on every sshd modification causes excessive false positives during legitimate updates. This hunt uses a gated flow to only run expensive fleet-wide stack-counts when specific toolkit artifacts are found, then correlates rarity with vulnerability context."
      }
    },
    {
      "id": "lead-file-discovery",
      "type": "query",
      "label": "Lead discovery: Known toolkit artifacts",
      "config": {
        "dsl": "sqlite",
        "role": "scoping",
        "source": "endpoint",
        "content": "SELECT device_hostname, file_path, activity_name, time FROM hb_file_activity WHERE (instr(',' || '{{toolkit_files}}' || ',', ',' || LOWER(file_path) || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "surface": "hb_file_activity",
        "description": "Find hosts where specific encrypted log paths or stager configuration files have been touched.",
        "expected_signal": "Any row naming a toolkit path on a host. Silence proves these specific IOCs are absent but does not rule out the campaign."
      },
      "parents": [
        {
          "id": "hypothesis"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "scoping",
        "label": "Lead discovery: Known toolkit artifacts",
        "reads": [
          "activity_name",
          "device_hostname",
          "file_path",
          "time"
        ],
        "source": "hb_file_activity",
        "target": "endpoint",
        "content": "SELECT device_hostname, file_path, activity_name, time FROM hb_file_activity WHERE (instr(',' || '{{toolkit_files}}' || ',', ',' || LOWER(file_path) || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days')",
        "silence": "not_evidence_of_absence",
        "expected": "Any row naming a toolkit path on a host. Silence proves these specific IOCs are absent but does not rule out the campaign.",
        "verified": "dry-run",
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "agent-gate-read",
      "type": "analytic",
      "label": "Evaluate lead findings",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint"
        ],
        "context": [
          "lead-file-discovery"
        ],
        "objective": "Determine if any host shows activity matching the specific file artifacts of the Ted and CurlRAT toolkit.",
        "description": "Decide if the lead file activity matches the reported toolkit behavior enough to warrant expansion.",
        "max_iterations": 3,
        "expected_signal": "A recommendation to proceed or close based on the specificity of the file path matches.",
        "success_criteria": "A verdict citing specific hosts and paths."
      },
      "parents": [
        {
          "id": "lead-file-discovery"
        }
      ]
    },
    {
      "id": "gate-decision",
      "type": "checkpoint",
      "label": "Gate: Proceed to expansion",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the agent-gate-read verdict is malicious because at least one host shows a reported toolkit artifact",
        "condition": "the agent-gate-read verdict is malicious because at least one host shows a reported toolkit artifact",
        "blind_spot": "pre-existing-compromise",
        "confidence": "high",
        "description": "Restrict expensive fleet-wide stack-counting to when a lead indicator is confirmed.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "agent-gate-read"
        }
      ]
    },
    {
      "id": "rare-daemon-hashes",
      "type": "query",
      "label": "Stack-count daemon hashes",
      "config": {
        "dsl": "sqlite",
        "role": "baseline",
        "source": "endpoint",
        "content": "SELECT process_hash_sha256, process_path, COUNT(DISTINCT device_hostname) AS host_count, MIN(time) AS first_seen FROM hb_process_activity WHERE (instr(',' || '{{daemon_paths}}' || ',', ',' || LOWER(process_path) || ',') > 0) AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY process_hash_sha256, process_path HAVING host_count <= 2",
        "surface": "hb_process_activity",
        "description": "Find system daemons with rare binary hashes that differ from the fleet baseline.",
        "expected_signal": "A rare SHA256 for a standard path like /usr/sbin/crond on a small number of hosts."
      },
      "parents": [
        {
          "id": "gate-decision",
          "branch": "on_supports"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "baseline",
        "label": "Stack-count daemon hashes",
        "reads": [
          "device_hostname",
          "process_hash_sha256",
          "process_path",
          "time"
        ],
        "source": "hb_process_activity",
        "target": "endpoint",
        "content": "SELECT process_hash_sha256, process_path, COUNT(DISTINCT device_hostname) AS host_count, MIN(time) AS first_seen FROM hb_process_activity WHERE (instr(',' || '{{daemon_paths}}' || ',', ',' || LOWER(process_path) || ',') > 0) AND ('{{scope_hosts}}' = '' OR instr(',' || '{{scope_hosts}}' || ',', ',' || device_hostname || ',') > 0) AND time >= datetime('now', '-{{lookback_days}} days') GROUP BY process_hash_sha256, process_path HAVING host_count <= 2",
        "silence": "not_evidence_of_absence",
        "baseline": {
          "window": "{{lookback_days}}d",
          "compare": "first_seen"
        },
        "expected": "A rare SHA256 for a standard path like /usr/sbin/crond on a small number of hosts.",
        "verified": "dry-run",
        "prevalence": {
          "by": "device_hostname",
          "key": [
            "process_hash_sha256"
          ],
          "rare_below": 3
        },
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "vulnerable-edge-apps",
      "type": "query",
      "label": "Check for edge vulnerabilities",
      "config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "source": "endpoint",
        "content": "SELECT device_uid, affected_package_name, affected_package_version, severity_id, cve_uid FROM hb_vulnerability_finding WHERE severity_id >= 4 AND (LOWER(affected_package_name) LIKE '%haproxy%' OR LOWER(affected_package_name) LIKE '%sshd%' OR LOWER(affected_package_name) LIKE '%at%' OR LOWER(affected_package_name) LIKE '%cron%' OR LOWER(affected_package_name) LIKE '%polkit%')",
        "surface": "hb_vulnerability_finding",
        "description": "Identify if the suspected hosts run unpatched edge applications that match the reported entry vectors.",
        "expected_signal": "High-severity vulnerabilities on edge servers that validate the initial compromise hypothesis."
      },
      "parents": [
        {
          "id": "gate-decision",
          "branch": "on_supports"
        }
      ],
      "primitive_config": {
        "dsl": "sqlite",
        "role": "enrichment",
        "label": "Check for edge vulnerabilities",
        "reads": [
          "affected_package_name",
          "affected_package_version",
          "cve_uid",
          "device_uid",
          "severity_id"
        ],
        "source": "hb_vulnerability_finding",
        "target": "endpoint",
        "content": "SELECT device_uid, affected_package_name, affected_package_version, severity_id, cve_uid FROM hb_vulnerability_finding WHERE severity_id >= 4 AND (LOWER(affected_package_name) LIKE '%haproxy%' OR LOWER(affected_package_name) LIKE '%sshd%' OR LOWER(affected_package_name) LIKE '%at%' OR LOWER(affected_package_name) LIKE '%cron%' OR LOWER(affected_package_name) LIKE '%polkit%')",
        "silence": "not_evidence_of_absence",
        "expected": "High-severity vulnerabilities on edge servers that validate the initial compromise hypothesis.",
        "verified": "dry-run",
        "verified_at": "2026-09-28"
      }
    },
    {
      "id": "agent-final-triage",
      "type": "analytic",
      "label": "Final triage of compromise",
      "config": {
        "cite": "required",
        "tools": [
          "endpoint"
        ],
        "context": [
          "agent-gate-read",
          "rare-daemon-hashes",
          "vulnerable-edge-apps"
        ],
        "objective": "Determine if the host is compromised by correlating toolkit artifacts, rare binary hashes, and edge-facing vulnerabilities.",
        "description": "Correlate artifact findings, rare hashes, and vulnerabilities to confirm a host compromise.",
        "max_iterations": 6,
        "expected_signal": "A detailed verdict confirming which daemons were replaced and identifying the compromised hosts.",
        "success_criteria": "A final verdict citing rows from both lead and expansion steps."
      },
      "parents": [
        {
          "id": "rare-daemon-hashes",
          "kind": "merge"
        },
        {
          "id": "vulnerable-edge-apps",
          "kind": "merge"
        }
      ]
    },
    {
      "id": "route-verdict",
      "type": "checkpoint",
      "label": "Route verdict",
      "config": {
        "fuzzy": true,
        "judge": "hunter",
        "question": "the agent-final-triage verdict is malicious for at least one host",
        "condition": "the agent-final-triage verdict is malicious for at least one host",
        "blind_spot": "unhashed-executables",
        "confidence": "high",
        "description": "Initiate containment for confirmed malicious activity.",
        "checkpoint_type": "mandatory"
      },
      "parents": [
        {
          "id": "agent-final-triage"
        }
      ]
    },
    {
      "id": "isolate-host",
      "type": "action",
      "label": "Isolate host",
      "config": {
        "target": "endpoint",
        "description": "Halt credential harvesting and HAProxy traffic interception.",
        "instructions": "Isolate the compromised host immediately to stop the trojanized system daemons. Collect the suspect binaries for forensic analysis before reimaging.",
        "action_approval": "required"
      },
      "parents": [
        {
          "id": "route-verdict",
          "branch": "on_supports"
        }
      ]
    },
    {
      "id": "forensic-verification",
      "type": "task",
      "label": "Forensic verification",
      "config": {
        "assignee": "analyst",
        "description": "Verify timestomping and log tampering on the suspect host.",
        "instructions": "Inspect the suspect host for timestomping: compare the modification time of /usr/sbin/crond with /usr/bin/ssh. Search for keyword-based line removals in /var/log/secure and .bash_history using strings like 'jasper-log' or 'cron'."
      },
      "parents": [
        {
          "id": "route-verdict",
          "branch": "default"
        },
        {
          "id": "route-verdict",
          "branch": "on_unavailable"
        },
        {
          "id": "isolate-host"
        }
      ]
    },
    {
      "id": "close-out-task",
      "type": "task",
      "label": "Close out hunt",
      "config": {
        "assignee": "analyst",
        "description": "Record final results and decide on follow-on hunts.",
        "instructions": "Document whether malicious artifacts or rare daemon hashes were confirmed. If a compromise was found, move to the CurlRAT C2 behavior hunt."
      },
      "parents": [
        {
          "id": "gate-decision",
          "branch": "default"
        },
        {
          "id": "gate-decision",
          "branch": "on_unavailable"
        },
        {
          "id": "gate-decision",
          "branch": "on_refutes"
        },
        {
          "id": "route-verdict",
          "branch": "on_refutes"
        },
        {
          "id": "forensic-verification"
        }
      ]
    }
  ]
}