Replace MIT with the full GNU GPLv3 text, update license metadata in pyproject.toml (+ trove classifiers) and PKGBUILD, and add SPDX-License-Identifier headers to all Python modules and shell scripts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
40 lines
1.3 KiB
Python
40 lines
1.3 KiB
Python
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
"""deleted_exe — a process running from a deleted or memfd-backed binary.
|
|
|
|
Fileless malware unlinks its dropper (or runs straight from ``memfd``) so there
|
|
is nothing on disk to scan. The kernel still labels the ``/proc/<pid>/exe``
|
|
symlink ``(deleted)`` or ``memfd:``. Normal-path deleted exes (a daemon still
|
|
running after a package upgrade) are ignored — only attacker-controlled/fileless
|
|
locations alert.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Iterator
|
|
|
|
from ..alert import Alert, Severity
|
|
from ..config import Config
|
|
from ..system import SystemState
|
|
|
|
_SUSPICIOUS_PREFIXES = ("/tmp/", "/dev/shm/", "/var/tmp/", "/run/")
|
|
|
|
|
|
def _is_fileless(exe: str) -> bool:
|
|
if "memfd:" in exe:
|
|
return True
|
|
if "(deleted)" not in exe:
|
|
return False
|
|
return exe.startswith(_SUSPICIOUS_PREFIXES)
|
|
|
|
|
|
def detect(state: SystemState, cfg: Config) -> Iterator[Alert]:
|
|
for proc in state.processes:
|
|
exe = proc.exe
|
|
if not exe or not _is_fileless(exe):
|
|
continue
|
|
yield Alert(
|
|
severity=Severity.CRITICAL,
|
|
signature="deleted_exe",
|
|
key=f"del:{proc.pid}",
|
|
detail=f"pid={proc.pid} comm={proc.comm} exe=[{exe}]",
|
|
pids=(proc.pid,),
|
|
)
|