Skip to content

Conversation

@tomsonpl
Copy link
Contributor

@tomsonpl tomsonpl commented Nov 6, 2025

Core Forensic Artifacts Coverage

# Artifact OS Query File Description
1 Services Win suspicious_services 003 Detect suspicious services running from user-writable directories or with generic names commonly used by malware
1a Services Mac suspicious_launchd_macos 043 Detect suspicious launch daemons and agents on macOS, excluding system paths but flagging user-writable directories
1b Services Linux suspicious_systemd_linux 044 Detect suspicious systemd units on Linux, excluding system paths but flagging user-writable directories and unusual locations

Queries by Platform

🪟 Windows - Suspicious Services

Description

Detects suspicious Windows services with comprehensive risk scoring (0-100). Identifies services in user-writable directories, unsigned/untrusted binaries, ServiceDLL hijacking, failure command persistence, and privilege escalation patterns.

Query returned No results, not sure if my query is wrong (should not be ;) ) , or I just do not have suspicious services running on my VM :P Can somebody help validate this?

Platform

windows

Interval

3600 seconds (1 hour)

SQL Query

SELECT
  s.name,
  s.display_name,
  s.status,
  s.start_type,
  s.path,
  s.user_account,
  r1.data AS service_dll,
  r2.data AS failure_command,
  h.sha256,
  h.md5,
  a.subject_name AS cert_subject,
  a.issuer_name AS cert_issuer,
  a.result AS signature_status,
  h_dll.sha256 AS servicedll_sha256,
  h_dll.md5 AS servicedll_md5,
  a_dll.subject_name AS servicedll_cert_subject,
  a_dll.result AS servicedll_signature_status,
  r_service_key.mtime AS service_registry_mtime,
  CAST((strftime('%s', 'now') - r_service_key.mtime) / 86400 AS INTEGER) AS days_since_creation,
  (
    (CASE
      WHEN s.path LIKE '%\\Temp\\%' THEN 40
      WHEN s.path LIKE '%\\Users\\%\\AppData\\Local\\Temp\\%' THEN 40
      WHEN s.path LIKE '%\\Users\\%\\Downloads\\%' THEN 35
      WHEN s.path LIKE '%\\AppData\\Local\\%' THEN 35
      WHEN s.path LIKE '%\\AppData\\Roaming\\%' THEN 30
      WHEN s.path LIKE '%\\Users\\%\\Documents\\%' THEN 30
      WHEN s.path LIKE '%\\Users\\Public\\%' THEN 25
      WHEN s.path LIKE '%\\ProgramData\\%' AND s.path NOT LIKE '%\\ProgramData\\Microsoft\\%' THEN 20
      ELSE 5
    END) +
    (CASE
      WHEN a.result IS NULL OR a.result = '' THEN 25
      WHEN a.result != 'trusted' THEN 25
      WHEN a.subject_name NOT LIKE '%Microsoft%' AND a.subject_name NOT LIKE '%Windows%' THEN 15
      ELSE 0
    END) +
    (CASE
      WHEN s.user_account IN ('LocalSystem', 'NT AUTHORITY\\SYSTEM', 'SYSTEM') AND
           (s.path LIKE '%\\Temp\\%' OR s.path LIKE '%\\AppData\\%' OR s.path LIKE '%\\Users\\%') THEN 20
      WHEN s.user_account IN ('LocalSystem', 'NT AUTHORITY\\SYSTEM', 'SYSTEM') THEN 10
      WHEN s.user_account LIKE '%Administrator%' THEN 5
      ELSE 0
    END) +
    (CASE
      WHEN LOWER(s.name) IN ('service', 'svc', 'system', 'update', 'windows', 'microsoft', 'security', 'monitor', 'agent', 'helper') THEN 10
      WHEN LENGTH(s.name) <= 5 THEN 8
      WHEN s.display_name = s.name OR s.display_name IS NULL THEN 5
      ELSE 0
    END) +
    (CASE
      WHEN r1.data IS NOT NULL AND r1.data != '' AND h_dll.sha256 IS NULL THEN 5
      WHEN r1.data LIKE '%\\Temp\\%' OR r1.data LIKE '%\\AppData\\%' THEN 5
      WHEN a_dll.result IS NOT NULL AND a_dll.result != 'trusted' THEN 5
      ELSE 0
    END)
  ) AS risk_score,
  (CASE
    WHEN (
      (CASE
        WHEN s.path LIKE '%\\Temp\\%' THEN 40
        WHEN s.path LIKE '%\\Users\\%\\AppData\\Local\\Temp\\%' THEN 40
        WHEN s.path LIKE '%\\Users\\%\\Downloads\\%' THEN 35
        WHEN s.path LIKE '%\\AppData\\Local\\%' THEN 35
        WHEN s.path LIKE '%\\AppData\\Roaming\\%' THEN 30
        WHEN s.path LIKE '%\\Users\\%\\Documents\\%' THEN 30
        WHEN s.path LIKE '%\\Users\\Public\\%' THEN 25
        WHEN s.path LIKE '%\\ProgramData\\%' AND s.path NOT LIKE '%\\ProgramData\\Microsoft\\%' THEN 20
        ELSE 5
      END) +
      (CASE
        WHEN a.result IS NULL OR a.result = '' THEN 25
        WHEN a.result != 'trusted' THEN 25
        WHEN a.subject_name NOT LIKE '%Microsoft%' AND a.subject_name NOT LIKE '%Windows%' THEN 15
        ELSE 0
      END) +
      (CASE
        WHEN s.user_account IN ('LocalSystem', 'NT AUTHORITY\\SYSTEM', 'SYSTEM') AND
             (s.path LIKE '%\\Temp\\%' OR s.path LIKE '%\\AppData\\%' OR s.path LIKE '%\\Users\\%') THEN 20
        WHEN s.user_account IN ('LocalSystem', 'NT AUTHORITY\\SYSTEM', 'SYSTEM') THEN 10
        WHEN s.user_account LIKE '%Administrator%' THEN 5
        ELSE 0
      END) +
      (CASE
        WHEN LOWER(s.name) IN ('service', 'svc', 'system', 'update', 'windows', 'microsoft', 'security', 'monitor', 'agent', 'helper') THEN 10
        WHEN LENGTH(s.name) <= 5 THEN 8
        WHEN s.display_name = s.name OR s.display_name IS NULL THEN 5
        ELSE 0
      END) +
      (CASE
        WHEN r1.data IS NOT NULL AND r1.data != '' AND h_dll.sha256 IS NULL THEN 5
        WHEN r1.data LIKE '%\\Temp\\%' OR r1.data LIKE '%\\AppData\\%' THEN 5
        WHEN a_dll.result IS NOT NULL AND a_dll.result != 'trusted' THEN 5
        ELSE 0
      END)
    ) >= 70 THEN 'CRITICAL'
    WHEN (
      (CASE
        WHEN s.path LIKE '%\\Temp\\%' THEN 40
        WHEN s.path LIKE '%\\Users\\%\\AppData\\Local\\Temp\\%' THEN 40
        WHEN s.path LIKE '%\\Users\\%\\Downloads\\%' THEN 35
        WHEN s.path LIKE '%\\AppData\\Local\\%' THEN 35
        WHEN s.path LIKE '%\\AppData\\Roaming\\%' THEN 30
        WHEN s.path LIKE '%\\Users\\%\\Documents\\%' THEN 30
        WHEN s.path LIKE '%\\Users\\Public\\%' THEN 25
        WHEN s.path LIKE '%\\ProgramData\\%' AND s.path NOT LIKE '%\\ProgramData\\Microsoft\\%' THEN 20
        ELSE 5
      END) +
      (CASE
        WHEN a.result IS NULL OR a.result = '' THEN 25
        WHEN a.result != 'trusted' THEN 25
        WHEN a.subject_name NOT LIKE '%Microsoft%' AND a.subject_name NOT LIKE '%Windows%' THEN 15
        ELSE 0
      END) +
      (CASE
        WHEN s.user_account IN ('LocalSystem', 'NT AUTHORITY\\SYSTEM', 'SYSTEM') AND
             (s.path LIKE '%\\Temp\\%' OR s.path LIKE '%\\AppData\\%' OR s.path LIKE '%\\Users\\%') THEN 20
        WHEN s.user_account IN ('LocalSystem', 'NT AUTHORITY\\SYSTEM', 'SYSTEM') THEN 10
        WHEN s.user_account LIKE '%Administrator%' THEN 5
        ELSE 0
      END) +
      (CASE
        WHEN LOWER(s.name) IN ('service', 'svc', 'system', 'update', 'windows', 'microsoft', 'security', 'monitor', 'agent', 'helper') THEN 10
        WHEN LENGTH(s.name) <= 5 THEN 8
        WHEN s.display_name = s.name OR s.display_name IS NULL THEN 5
        ELSE 0
      END) +
      (CASE
        WHEN r1.data IS NOT NULL AND r1.data != '' AND h_dll.sha256 IS NULL THEN 5
        WHEN r1.data LIKE '%\\Temp\\%' OR r1.data LIKE '%\\AppData\\%' THEN 5
        WHEN a_dll.result IS NOT NULL AND a_dll.result != 'trusted' THEN 5
        ELSE 0
      END)
    ) >= 50 THEN 'HIGH'
    WHEN (
      (CASE
        WHEN s.path LIKE '%\\Temp\\%' THEN 40
        WHEN s.path LIKE '%\\Users\\%\\AppData\\Local\\Temp\\%' THEN 40
        WHEN s.path LIKE '%\\Users\\%\\Downloads\\%' THEN 35
        WHEN s.path LIKE '%\\AppData\\Local\\%' THEN 35
        WHEN s.path LIKE '%\\AppData\\Roaming\\%' THEN 30
        WHEN s.path LIKE '%\\Users\\%\\Documents\\%' THEN 30
        WHEN s.path LIKE '%\\Users\\Public\\%' THEN 25
        WHEN s.path LIKE '%\\ProgramData\\%' AND s.path NOT LIKE '%\\ProgramData\\Microsoft\\%' THEN 20
        ELSE 5
      END) +
      (CASE
        WHEN a.result IS NULL OR a.result = '' THEN 25
        WHEN a.result != 'trusted' THEN 25
        WHEN a.subject_name NOT LIKE '%Microsoft%' AND a.subject_name NOT LIKE '%Windows%' THEN 15
        ELSE 0
      END) +
      (CASE
        WHEN s.user_account IN ('LocalSystem', 'NT AUTHORITY\\SYSTEM', 'SYSTEM') AND
             (s.path LIKE '%\\Temp\\%' OR s.path LIKE '%\\AppData\\%' OR s.path LIKE '%\\Users\\%') THEN 20
        WHEN s.user_account IN ('LocalSystem', 'NT AUTHORITY\\SYSTEM', 'SYSTEM') THEN 10
        WHEN s.user_account LIKE '%Administrator%' THEN 5
        ELSE 0
      END) +
      (CASE
        WHEN LOWER(s.name) IN ('service', 'svc', 'system', 'update', 'windows', 'microsoft', 'security', 'monitor', 'agent', 'helper') THEN 10
        WHEN LENGTH(s.name) <= 5 THEN 8
        WHEN s.display_name = s.name OR s.display_name IS NULL THEN 5
        ELSE 0
      END) +
      (CASE
        WHEN r1.data IS NOT NULL AND r1.data != '' AND h_dll.sha256 IS NULL THEN 5
        WHEN r1.data LIKE '%\\Temp\\%' OR r1.data LIKE '%\\AppData\\%' THEN 5
        WHEN a_dll.result IS NOT NULL AND a_dll.result != 'trusted' THEN 5
        ELSE 0
      END)
    ) >= 30 THEN 'MEDIUM'
    ELSE 'LOW'
  END) AS risk_level
FROM services s
LEFT JOIN registry r1 ON r1.path = 'HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\' || s.name || '\\Parameters' AND r1.name = 'ServiceDll'
LEFT JOIN registry r2 ON r2.path = 'HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\' || s.name AND r2.name = 'FailureCommand'
LEFT JOIN hash h ON h.path = s.path
LEFT JOIN authenticode a ON a.path = s.path
LEFT JOIN hash h_dll ON h_dll.path = r1.data
LEFT JOIN authenticode a_dll ON a_dll.path = r1.data
LEFT JOIN registry r_service_key ON r_service_key.path = 'HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\' || s.name
WHERE
  s.start_type IN ('AUTO_START', 'DEMAND_START', 'BOOT_START', 'SYSTEM_START')
  AND (
    s.path LIKE '%\\Temp\\%'
    OR s.path LIKE '%\\Users\\%\\AppData\\%'
    OR s.path LIKE '%\\Users\\%\\Documents\\%'
    OR s.path LIKE '%\\Users\\%\\Downloads\\%'
    OR s.path LIKE '%\\Users\\Public\\%'
    OR (s.path LIKE '%\\ProgramData\\%' AND s.path NOT LIKE '%\\ProgramData\\Microsoft\\%')
    OR (r1.data IS NOT NULL AND r1.data != '' AND r1.data NOT LIKE 'C:\\Windows\\System32\\%' AND r1.data NOT LIKE 'C:\\Windows\\SysWOW64\\%')
    OR (r2.data IS NOT NULL AND r2.data != '')
    OR (a.result IS NOT NULL AND a.result != 'trusted')
  )
  AND s.path NOT LIKE 'C:\\Windows\\System32\\%'
  AND s.path NOT LIKE 'C:\\Windows\\SysWOW64\\%'
  AND s.name NOT IN ('wuauserv', 'BITS', 'TrustedInstaller', 'WinDefend', 'Spooler')
ORDER BY risk_score DESC
LIMIT 200;

Key Detection Capabilities

  • User-writable directory execution (Temp, AppData, Downloads)
  • Unsigned or untrusted code signatures
  • ServiceDLL hijacking attempts
  • Privilege escalation (SYSTEM account with suspicious paths)
  • Generic service name masquerading
🍎 macOS - Suspicious Launch Daemons/Agents

Description

Detects suspicious launchd persistence on macOS with multi-factor risk scoring. Monitors all standard LaunchAgents/LaunchDaemons locations, analyzes program paths, detects label masquerading, and prioritizes high-risk entries.

Screenshot 2025-11-06 at 15 26 42

Platform

darwin (macOS)

Interval

3600 seconds (1 hour)

SQL Query

WITH launchd_base AS (
  SELECT
    l.name,
    l.label,
    l.path,
    -- Extract executable from program_arguments (NO l.program column exists!)
    CASE
      WHEN l.program_arguments LIKE '<%' THEN
        -- Handle XML array format: <string>/path/to/exe</string>
        RTRIM(LTRIM(SUBSTR(l.program_arguments, INSTR(l.program_arguments, '<string>') + 8, INSTR(l.program_arguments, '</string>') - INSTR(l.program_arguments, '<string>') - 8)))
      WHEN l.program_arguments != '' THEN
        -- Use program_arguments as-is (might be a simple string or first element)
        l.program_arguments
      ELSE NULL
    END AS program,
    l.program_arguments,
    l.run_at_load,
    l.keep_alive,
    -- Infer username from plist location (NO l.username column exists!)
    CASE
      WHEN l.path LIKE '/Library/LaunchDaemons/%' THEN 'root'
      WHEN l.path LIKE '/Users/%/Library/LaunchAgents/%' THEN
        -- Extract username from path: /Users/USERNAME/Library/LaunchAgents/...
        SUBSTR(l.path, 8, INSTR(SUBSTR(l.path, 8), '/') - 1)
      WHEN l.path LIKE '/Users/%/Library/LaunchDaemons/%' THEN
        -- Extract username from path: /Users/USERNAME/Library/LaunchDaemons/...
        SUBSTR(l.path, 8, INSTR(SUBSTR(l.path, 8), '/') - 1)
      WHEN l.path LIKE '/Library/LaunchAgents/%' THEN 'system'
      ELSE NULL
    END AS username,
    l.disabled,
    f.ctime AS file_created,
    f.mtime AS file_modified,
    CAST((strftime('%s', 'now') - COALESCE(f.ctime, strftime('%s', 'now'))) / 86400 AS INTEGER) AS age_days,
    -- Program risk category (use program_arguments directly)
    CASE
      WHEN l.program_arguments LIKE '/tmp/%' OR l.program_arguments LIKE '/var/tmp/%' THEN 'TEMP_EXECUTION'
      WHEN l.program_arguments LIKE '/Users/%/Downloads/%' OR l.program_arguments LIKE '/Users/%/Desktop/%' THEN 'USER_DOWNLOAD'
      WHEN l.program_arguments LIKE '/dev/shm/%' THEN 'SHARED_MEMORY'
      WHEN l.program_arguments LIKE '/Users/%/.%' OR l.program_arguments LIKE '%/.hidden/%' THEN 'HIDDEN_PROGRAM'
      WHEN l.program_arguments NOT LIKE '/usr/%' AND l.program_arguments NOT LIKE '/bin/%' AND l.program_arguments NOT LIKE '/sbin/%' AND l.program_arguments NOT LIKE '/Applications/%.app/%' AND l.program_arguments NOT LIKE '/System/%' THEN 'NON_STANDARD_LOCATION'
      WHEN l.program_arguments LIKE '/usr/bin/python%' OR l.program_arguments LIKE '/bin/sh' OR l.program_arguments LIKE '/bin/bash' OR l.program_arguments LIKE '/usr/bin/perl%' OR l.program_arguments LIKE '/usr/bin/ruby%' THEN 'INTERPRETER'
      WHEN l.program_arguments LIKE '/Applications/%.app/%' THEN 'APPLICATION'
      ELSE 'SYSTEM_BINARY'
    END AS program_risk_category,
    CASE
      WHEN l.path LIKE '/Library/LaunchDaemons/%' THEN 'ROOT_DAEMON'
      WHEN l.path LIKE '/Library/LaunchAgents/%' THEN 'SYSTEM_AGENT'
      WHEN l.path LIKE '/Users/%/Library/LaunchAgents/%' THEN 'USER_AGENT'
      WHEN l.path LIKE '/Users/%/Library/LaunchDaemons/%' THEN 'USER_DAEMON'
      WHEN l.path LIKE '/tmp/%' OR l.path LIKE '/var/tmp/%' THEN 'TEMP_PLIST'
      WHEN l.path LIKE '/Users/%/Downloads/%' THEN 'DOWNLOADS'
      WHEN l.path LIKE '/Users/%/Desktop/%' THEN 'DESKTOP'
      ELSE 'OTHER'
    END AS plist_location_type
  FROM launchd l
  LEFT JOIN file f ON f.path = l.path
  WHERE (
    l.path LIKE '/Library/LaunchAgents/%'
    OR l.path LIKE '/Library/LaunchDaemons/%'
    OR l.path LIKE '/Users/%/Library/LaunchAgents/%'
    OR l.path LIKE '/Users/%/Library/LaunchDaemons/%'
    OR l.path LIKE '/tmp/%'
    OR l.path LIKE '/var/tmp/%'
    OR l.path LIKE '/Users/%/Downloads/%'
    OR l.path LIKE '/Users/%/Desktop/%'
  )
  AND l.path NOT LIKE '/System/Library/%'
  AND l.path NOT LIKE '/Library/Apple/%'
  AND l.path NOT LIKE '/Applications/Xcode.app/%'
),
scored_launchd AS (
  SELECT
    *,
    (
      CASE
        WHEN path LIKE '/Library/LaunchDaemons/%' THEN 30
        WHEN path LIKE '/tmp/%' OR path LIKE '/var/tmp/%' THEN 30
        WHEN path LIKE '/Users/%/Library/LaunchAgents/%' THEN 25
        WHEN path LIKE '/Users/%/Library/LaunchDaemons/%' THEN 25
        WHEN path LIKE '/Users/%/Downloads/%' OR path LIKE '/Users/%/Desktop/%' THEN 20
        WHEN path LIKE '/Library/LaunchAgents/%' THEN 20
        ELSE 0
      END +
      CASE
        WHEN program_risk_category IN ('TEMP_EXECUTION', 'SHARED_MEMORY') THEN 30
        WHEN program_risk_category IN ('USER_DOWNLOAD', 'HIDDEN_PROGRAM') THEN 25
        WHEN program_risk_category = 'NON_STANDARD_LOCATION' THEN 20
        WHEN program_risk_category = 'INTERPRETER' THEN 15
        ELSE 0
      END +
      CASE
        WHEN label LIKE 'com.apple.%' AND path NOT LIKE '/System/Library/%' AND path NOT LIKE '/Library/Apple/%' THEN 20
        WHEN label LIKE 'com.google.%' AND program NOT LIKE '/Applications/Google%' AND program NOT LIKE '/Library/Google/%' THEN 20
        WHEN label LIKE '%malware%' OR label LIKE '%trojan%' OR label LIKE '%backdoor%' OR label LIKE '%virus%' THEN 20
        WHEN label LIKE '%update%' OR label LIKE '%check%' OR label LIKE '%sync%' OR label LIKE '%agent%' THEN 15
        WHEN label NOT LIKE '%.%' THEN 10
        ELSE 0
      END +
      CASE
        WHEN run_at_load = 1 AND keep_alive = 1 THEN 20
        WHEN keep_alive = 1 THEN 15
        WHEN run_at_load = 1 THEN 10
        ELSE 0
      END
    ) AS risk_score
  FROM launchd_base
)
SELECT
  name,
  label,
  path,
  program,
  program_arguments,
  run_at_load,
  keep_alive,
  username,
  disabled,
  datetime(file_created, 'unixepoch', 'localtime') AS created_time,
  datetime(file_modified, 'unixepoch', 'localtime') AS modified_time,
  age_days,
  plist_location_type,
  program_risk_category,
  risk_score,
  CASE
    WHEN risk_score >= 70 THEN 'CRITICAL'
    WHEN risk_score >= 50 THEN 'HIGH'
    WHEN risk_score >= 30 THEN 'MEDIUM'
    ELSE 'LOW'
  END AS risk_level
FROM scored_launchd
WHERE risk_score >= 30 OR age_days <= 7
ORDER BY risk_score DESC, age_days ASC, label
LIMIT 200;

Key Detection Capabilities

  • Temporary directory persistence (/tmp, /var/tmp)
  • User Downloads/Desktop execution
  • Label masquerading (com.apple., com.google.)
  • Hidden program execution
  • Non-standard binary locations
  • RunAtLoad + KeepAlive persistence patterns
🐧 Linux - Suspicious Systemd Units

Description

Detects suspicious systemd persistence on Linux with multi-factor risk scoring. Monitors /etc/systemd/system/ (80% of malware), user systemd units, runtime units, and temporary locations. Prioritizes socket/timer units and recently created entries.

Screenshot 2025-11-06 at 15 26 29

Platform

linux

Interval

3600 seconds (1 hour)

SQL Query

WITH systemd_base AS (
  SELECT
    su.id,
    su.description,
    su.load_state,
    su.active_state,
    su.sub_state,
    su.fragment_path,
    su.unit_file_state,
    f.ctime,
    f.mtime,
    CASE
      WHEN su.id LIKE '%.socket' THEN 'SOCKET'
      WHEN su.id LIKE '%.timer' THEN 'TIMER'
      WHEN su.id LIKE '%.service' THEN 'SERVICE'
      WHEN su.id LIKE '%.target' THEN 'TARGET'
      WHEN su.id LIKE '%.path' THEN 'PATH'
      ELSE 'OTHER'
    END AS unit_type
  FROM systemd_units su
  LEFT JOIN file f ON f.path = su.fragment_path
  WHERE (
    su.fragment_path LIKE '/etc/systemd/system/%'
    OR su.fragment_path LIKE '/etc/systemd/user/%'
    OR su.fragment_path LIKE '/run/systemd/system/%'
    OR su.fragment_path LIKE '%/.config/systemd/user/%'
    OR su.fragment_path LIKE '/tmp/%'
    OR su.fragment_path LIKE '/var/tmp/%'
  )
  AND su.fragment_path NOT LIKE '/lib/systemd/%'
  AND su.fragment_path NOT LIKE '/usr/lib/systemd/%'
),
systemd_risk AS (
  SELECT
    id,
    description,
    load_state,
    active_state,
    sub_state,
    fragment_path,
    unit_file_state,
    unit_type,
    ctime,
    mtime,
    CASE
      WHEN fragment_path LIKE '/tmp/%' OR fragment_path LIKE '/var/tmp/%' THEN 40
      WHEN fragment_path LIKE '/etc/systemd/system/%' THEN 30
      WHEN fragment_path LIKE '%/.config/systemd/user/%' THEN 25
      WHEN fragment_path LIKE '/run/systemd/system/%' THEN 20
      WHEN fragment_path LIKE '/etc/systemd/user/%' THEN 15
      ELSE 0
    END AS location_risk,
    CASE
      WHEN unit_file_state = 'enabled' AND active_state = 'active' THEN 35
      WHEN unit_file_state = 'enabled' AND active_state = 'inactive' THEN 25
      WHEN unit_file_state = 'static' AND active_state = 'active' THEN 20
      WHEN load_state = 'error' THEN 15
      WHEN load_state = 'masked' THEN 0
      ELSE 10
    END AS state_risk,
    CASE
      WHEN unit_type = 'SOCKET' THEN 25
      WHEN unit_type = 'TIMER' THEN 20
      WHEN unit_type = 'SERVICE' THEN 10
      ELSE 0
    END AS type_risk
  FROM systemd_base
)
SELECT
  id,
  description,
  fragment_path,
  unit_file_state,
  active_state,
  load_state,
  unit_type,
  location_risk,
  state_risk,
  type_risk,
  (location_risk + state_risk + type_risk) AS risk_score,
  CASE
    WHEN (location_risk + state_risk + type_risk) >= 70 THEN 'CRITICAL'
    WHEN (location_risk + state_risk + type_risk) >= 50 THEN 'HIGH'
    WHEN (location_risk + state_risk + type_risk) >= 30 THEN 'MEDIUM'
    ELSE 'LOW'
  END AS risk_level,
  CASE
    WHEN unit_type = 'SOCKET' THEN 'HIGH: Socket unit detected - potential network backdoor listener'
    WHEN unit_type = 'TIMER' THEN 'MEDIUM: Timer unit detected - potential C2 beaconing mechanism'
    WHEN fragment_path LIKE '/tmp/%' OR fragment_path LIKE '/var/tmp/%' THEN 'CRITICAL: Unit file in temporary directory - likely malware persistence'
    WHEN fragment_path LIKE '/etc/systemd/system/%' AND unit_file_state = 'enabled' THEN 'HIGH: Enabled system unit - review configuration for suspicious commands'
    WHEN unit_file_state = 'enabled' AND active_state = 'active' THEN 'MEDIUM: Enabled and active unit - validate legitimacy'
    ELSE 'Review unit configuration and validate against baseline'
  END AS analyst_guidance,
  datetime(ctime, 'unixepoch', 'localtime') AS file_created,
  datetime(mtime, 'unixepoch', 'localtime') AS file_modified,
  CAST((strftime('%s', 'now') - COALESCE(mtime, strftime('%s', 'now'))) / 86400 AS INTEGER) AS age_days
FROM systemd_risk
WHERE (
  (location_risk + state_risk + type_risk) >= 30
  OR CAST((strftime('%s', 'now') - COALESCE(mtime, strftime('%s', 'now'))) / 86400 AS INTEGER) <= 7
  OR unit_type IN ('SOCKET', 'TIMER')
)
ORDER BY (location_risk + state_risk + type_risk) DESC, CAST((strftime('%s', 'now') - COALESCE(mtime, strftime('%s', 'now'))) / 86400 AS INTEGER) ASC, id
LIMIT 200;

Key Detection Capabilities

  • Socket units (network backdoor listeners)
  • Timer units (C2 beaconing mechanisms)
  • Temporary directory persistence (/tmp, /var/tmp)
  • User systemd units (~/.config/systemd/user/)
  • Enabled and active suspicious units
  • Recently created units (within 7 days)

Risk Score Interpretation

Risk Level Score Range Action Required
CRITICAL 70-100 Immediate investigation required - likely active threat
HIGH 50-69 Review within 24 hours - potential persistence mechanism
MEDIUM 30-49 Weekly review - may be legitimate but unusual
LOW 0-29 Baseline monitoring - context-dependent assessment

@tomsonpl tomsonpl self-assigned this Nov 6, 2025
@tomsonpl tomsonpl added documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. Integration:osquery_manager Osquery Manager labels Nov 6, 2025
@tomsonpl tomsonpl marked this pull request as ready for review November 6, 2025 14:30
@tomsonpl tomsonpl requested a review from a team as a code owner November 6, 2025 14:30
@tomsonpl tomsonpl requested review from joeypoon and parkiino November 6, 2025 14:30
@elasticmachine
Copy link

💚 Build Succeeded

cc @tomsonpl

@tomsonpl tomsonpl closed this Nov 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. Integration:osquery_manager Osquery Manager

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants