Add memory obfuscation and ps-hidden process detection
This commit is contained in:
parent
cb334c0c94
commit
893409b549
17 changed files with 353 additions and 26 deletions
|
|
@ -35,6 +35,7 @@ SID_HIDDEN_UDP_PORT = 100031
|
|||
SID_HIDDEN_RAW_SOCKET = 100034
|
||||
SID_RAW_ICMP_SOCKET = 100035
|
||||
SID_HIDDEN_PROTOCOL_SOCKET = 100037
|
||||
SID_PS_HIDDEN_PROCESS = 100038
|
||||
|
||||
IFF_PROMISC = 0x100
|
||||
|
||||
|
|
@ -81,6 +82,11 @@ def find_hidden_pids(proc_pids: set[int], alive_pids: set[int]) -> set[int]:
|
|||
return alive_pids - proc_pids
|
||||
|
||||
|
||||
def find_ps_hidden_pids(proc_pids: set[int], ps_seen: set[int]) -> set[int]:
|
||||
"""PIDs visible in /proc but missing from ps output."""
|
||||
return proc_pids - ps_seen
|
||||
|
||||
|
||||
def find_hidden_modules(proc_modules: set[str], sys_live: set[str]) -> set[str]:
|
||||
"""Modules live in /sys/module but absent from /proc/modules."""
|
||||
return sys_live - proc_modules
|
||||
|
|
@ -159,6 +165,29 @@ def alive_pids(cap: int) -> set[int]:
|
|||
return alive
|
||||
|
||||
|
||||
def ps_pids() -> set[int] | None:
|
||||
try:
|
||||
res = subprocess.run(
|
||||
["ps", "-e", "-o", "pid="],
|
||||
capture_output=True, text=True, timeout=10,
|
||||
)
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
return None
|
||||
if res.returncode != 0:
|
||||
return None
|
||||
out: set[int] = set()
|
||||
for line in res.stdout.splitlines():
|
||||
try:
|
||||
out.add(int(line.strip()))
|
||||
except ValueError:
|
||||
continue
|
||||
return out
|
||||
|
||||
|
||||
def proc_pid_exists(pid: int) -> bool:
|
||||
return os.path.exists(f"/proc/{pid}")
|
||||
|
||||
|
||||
def proc_modules() -> set[str]:
|
||||
out: set[str] = set()
|
||||
try:
|
||||
|
|
@ -393,7 +422,7 @@ def run(cfg: Config, state: SystemState | None = None) -> Iterator[Alert]:
|
|||
pass
|
||||
except OSError:
|
||||
continue
|
||||
if not os.path.exists(f"/proc/{pid}"):
|
||||
if not proc_pid_exists(pid):
|
||||
confirmed.append(pid)
|
||||
if confirmed:
|
||||
yield Alert(
|
||||
|
|
@ -404,6 +433,22 @@ def run(cfg: Config, state: SystemState | None = None) -> Iterator[Alert]:
|
|||
pids=tuple(sorted(confirmed)[:20]),
|
||||
sid=SID_HIDDEN_PROC, classtype="rootkit-hidden-process")
|
||||
|
||||
tool_seen = ps_pids()
|
||||
if tool_seen is not None:
|
||||
missing_from_ps = []
|
||||
for pid in sorted(find_ps_hidden_pids(visible, tool_seen)):
|
||||
if proc_pid_exists(pid):
|
||||
missing_from_ps.append(pid)
|
||||
if missing_from_ps:
|
||||
yield Alert(
|
||||
severity=Severity.HIGH, signature="rootkit_ps_hidden_process",
|
||||
key=f"rk:pshidproc:{min(missing_from_ps)}",
|
||||
detail=("process(es) visible in /proc but missing from ps output "
|
||||
"(process tool may be hooked): "
|
||||
+ ", ".join(map(str, missing_from_ps[:20]))),
|
||||
pids=tuple(missing_from_ps[:20]),
|
||||
sid=SID_PS_HIDDEN_PROCESS, classtype="rootkit-hidden-process")
|
||||
|
||||
proc_mods = proc_modules()
|
||||
sys_mods = sys_live_modules()
|
||||
hidden_mods = find_hidden_modules(proc_mods, sys_mods)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue