# SPDX-License-Identifier: GPL-3.0-or-later """ld_preload — userland rootkit / library-injection indicators. Two signatures: * ``/etc/ld.so.preload`` non-empty: injects into *every* dynamically-linked process — the classic system-wide rootkit hook. * a process whose ``LD_PRELOAD`` points into a writable/temp dir — per-process function hooking (hiding files/procs, stealing credentials). """ from __future__ import annotations from collections.abc import Iterator from pathlib import Path from ..alert import Alert, Severity from ..config import Config from ..system import SystemState _SUSPICIOUS_PREFIXES = ("/tmp/", "/dev/shm/", "/var/tmp/", "/run/user/", "./") def detect(state: SystemState, cfg: Config) -> Iterator[Alert]: preload = Path("/etc/ld.so.preload") try: contents = preload.read_text().strip() if preload.is_file() else "" except OSError: contents = "" if contents: yield Alert( severity=Severity.CRITICAL, signature="ld_preload", key="ldp:global", detail=f"/etc/ld.so.preload is non-empty: [{contents.replace(chr(10), ' ')}]", ) for proc in state.processes: pre = proc.environ.get("LD_PRELOAD", "") if not pre: continue if pre.startswith(_SUSPICIOUS_PREFIXES): yield Alert( severity=Severity.CRITICAL, signature="ld_preload", key=f"ldp:{proc.pid}", detail=f"pid={proc.pid} comm={proc.comm} LD_PRELOAD=[{pre}]", pids=(proc.pid,), )