2dcf47985e
feat: add HASSHServer and TCP/IP stack fingerprinting to DECNET-PROBER
...
Extends the prober with two new active probe types alongside JARM:
- HASSHServer: SSH server fingerprinting via KEX_INIT algorithm ordering
(MD5 hash of kex;enc_s2c;mac_s2c;comp_s2c, pure stdlib)
- TCP/IP stack: OS/tool fingerprinting via SYN-ACK analysis using scapy
(TTL, window size, DF bit, MSS, TCP options ordering, SHA256 hash)
Worker probe cycle now runs three phases per IP with independent
per-type port tracking. Ingester extracts bounties for all three
fingerprint types.
2026-04-14 12:53:55 -04:00
ce2699455b
feat: DECNET-PROBER standalone JARM fingerprinting service
...
Add active TLS probing via JARM to identify C2 frameworks (Cobalt Strike,
Sliver, Metasploit) by their TLS server implementation quirks. Runs as a
detached host-level process — no container dependency.
- decnet/prober/jarm.py: pure-stdlib JARM implementation (10 crafted probes)
- decnet/prober/worker.py: standalone async worker with RFC 5424 + JSON output
- CLI: `decnet probe --targets ip:port` and `--probe-targets` on deploy
- Ingester: JARM bounty extraction (fingerprint type)
- 68 new tests covering JARM logic and bounty extraction
2026-04-14 12:14:32 -04:00
7ecb126c8e
fix: cap commands endpoint limit to 200
...
Requests with limit > 200 get a 422, and the frontend responds
accordingly.
2026-04-14 01:46:37 -04:00
f3bb0b31ae
feat: paginated commands endpoint for attacker profiles
...
New GET /attackers/{uuid}/commands?limit=&offset=&service= endpoint
serves commands with server-side pagination and optional service filter.
AttackerDetail frontend fetches commands from this endpoint with
page controls. Service badge filter now drives both the API query
and the local fingerprint filter.
2026-04-14 01:45:19 -04:00
24e0d98425
feat: add service filter to attacker profiles
...
API now accepts ?service=https to filter attackers by targeted service.
Service badges are clickable in both the attacker list and detail views,
navigating to a filtered view. Active filter shows as a dismissable tag.
2026-04-14 01:35:12 -04:00
ea340065c6
feat: JA4/JA4S/JA4L fingerprints, TLS session resumption, certificate extraction
...
Extend the passive TLS sniffer with next-gen attacker fingerprinting:
- JA4 (ClientHello) and JA4S (ServerHello) computation with
supported_versions, signature_algorithms, and ALPN parsing
- JA4L latency measurement via TCP SYN→SYN-ACK RTT tracking
- TLS session resumption detection (session tickets, PSK, 0-RTT early data)
- Certificate extraction for TLS ≤1.2 with minimal DER/ASN.1 parser
(subject CN, issuer, SANs, validity period, self-signed flag)
- Ingester bounty extraction for all new fingerprint types
- 116 tests covering all new functionality (1255 total passing)
2026-04-13 23:20:37 -04:00
a022b4fed6
feat: attacker profiles — UUID model, API routes, list/detail frontend
...
Migrate Attacker model from IP-based to UUID-based primary key with
auto-migration for old schema. Add GET /attackers (paginated, search,
sort) and GET /attackers/{uuid} API routes. Rewrite Attackers.tsx as
a card grid with full threat info and create AttackerDetail.tsx as a
dedicated detail page with back navigation, stats, commands table,
and fingerprints.
2026-04-13 22:35:13 -04:00
3dc5b509f6
feat: Phase 1 — JA3/JA3S sniffer, Attacker model, profile worker
...
Add passive TLS fingerprinting via a sniffer container on the MACVLAN
interface, plus the Attacker table and periodic rebuild worker that
correlates per-IP profiles from Log + Bounty + CorrelationEngine.
- templates/sniffer/: Scapy sniffer with pure-Python TLS parser;
emits tls_client_hello / tls_session RFC 5424 lines with ja3, ja3s,
sni, alpn, raw_ciphers, raw_extensions; GREASE filtered per RFC 8701
- decnet/services/sniffer.py: service plugin (no ports, NET_RAW/NET_ADMIN)
- decnet/web/db/models.py: Attacker SQLModel table + AttackersResponse
- decnet/web/db/repository.py: 5 new abstract methods
- decnet/web/db/sqlite/repository.py: implement all 5 (upsert, pagination,
sort by recent/active/traversals, bounty grouping)
- decnet/web/attacker_worker.py: 30s periodic rebuild via CorrelationEngine;
extracts commands from log fields, merges fingerprint bounties
- decnet/web/api.py: wire attacker_profile_worker into lifespan
- decnet/web/ingester.py: extract JA3 bounty (fingerprint_type=ja3)
- development/DEVELOPMENT.md: full attacker intelligence collection roadmap
- pyproject.toml: scapy>=2.6.1 added to dev deps
- tests: test_sniffer_ja3.py (40+ vectors), test_attacker_worker.py,
test_base_repo.py / test_web_api.py updated for new surface
2026-04-13 20:22:08 -04:00
c9be447a38
fix: set busy_timeout and WAL pragmas on every async SQLite connection
2026-04-13 19:17:53 -04:00
57d395d6d7
fix: auth redirect, SSE reconnect, stats polling removal, active decky count, schemathesis health check
CI / Lint (ruff) (push) Successful in 18s
CI / SAST (bandit) (push) Successful in 19s
CI / Dependency audit (pip-audit) (push) Failing after 27s
CI / Test (Standard) (3.11) (push) Has been skipped
CI / Test (Standard) (3.12) (push) Has been skipped
CI / Test (Live) (3.11) (push) Has been skipped
CI / Test (Fuzz) (3.11) (push) Has been skipped
CI / Merge dev → testing (push) Has been skipped
CI / Prepare Merge to Main (push) Has been skipped
CI / Finalize Merge to Main (push) Has been skipped
2026-04-13 18:33:32 -04:00
435c004760
feat: extract HTTP User-Agent and VNC client version as fingerprint bounties
CI / Lint (ruff) (push) Successful in 11s
CI / SAST (bandit) (push) Successful in 14s
CI / Dependency audit (pip-audit) (push) Successful in 24s
CI / Test (Standard) (3.11) (push) Successful in 2m2s
CI / Test (Standard) (3.12) (push) Successful in 2m5s
CI / Test (Live) (3.11) (push) Successful in 56s
CI / Test (Fuzz) (3.11) (push) Failing after 6m25s
CI / Merge dev → testing (push) Has been skipped
CI / Prepare Merge to Main (push) Has been skipped
CI / Finalize Merge to Main (push) Has been skipped
2026-04-13 08:14:38 -04:00
3d01ca2c2a
fix: resolve ruff lint errors (unused import, E402 import order)
CI / Lint (ruff) (push) Successful in 12s
CI / SAST (bandit) (push) Successful in 14s
CI / Dependency audit (pip-audit) (push) Successful in 27s
CI / Test (Standard) (3.11) (push) Successful in 2m7s
CI / Test (Standard) (3.12) (push) Successful in 2m8s
CI / Test (Live) (3.11) (push) Successful in 58s
CI / Merge dev → testing (push) Has been cancelled
CI / Prepare Merge to Main (push) Has been cancelled
CI / Finalize Merge to Main (push) Has been cancelled
CI / Test (Fuzz) (3.11) (push) Has been cancelled
2026-04-13 07:58:13 -04:00
035499f255
feat: add component-aware RFC 5424 application logging system
...
- Modify Rfc5424Formatter to read decnet_component from LogRecord
and use it as RFC 5424 APP-NAME field (falls back to 'decnet')
- Add get_logger(component) factory in decnet/logging/__init__.py
with _ComponentFilter that injects decnet_component on each record
- Wire all five layers to their component tag:
cli -> 'cli', engine -> 'engine', api -> 'api' (api.py, ingester,
routers), mutator -> 'mutator', collector -> 'collector'
- Add structured INFO/DEBUG/WARNING/ERROR log calls throughout each
layer per the defined vocabulary; DEBUG calls are suppressed unless
DECNET_DEVELOPER=true
- Add tests/test_logging.py covering factory, filter, formatter
component-awareness, fallback behaviour, and level gating
2026-04-13 07:39:01 -04:00
f2cc585d72
fix: align tests with model validation and API error reporting
2026-04-13 01:43:52 -04:00
03f5a7826f
Fix: resolved sqlite concurrency errors (table users already exists) by moving DDL to explicit async initialize() and implementing lazy singleton dependency.
2026-04-12 08:01:21 -04:00
b2e4706a14
Refactor: implemented Repository Factory and Async Mutator Engine. Decoupled storage logic and enforced Dependency Injection across CLI and Web API. Updated documentation.
CI / Lint (ruff) (push) Successful in 12s
CI / SAST (bandit) (push) Successful in 13s
CI / Dependency audit (pip-audit) (push) Successful in 22s
CI / Test (Standard) (3.11) (push) Failing after 54s
CI / Test (Standard) (3.12) (push) Successful in 1m35s
CI / Test (Live) (3.11) (push) Has been skipped
CI / Test (Fuzz) (3.11) (push) Has been skipped
CI / Merge dev → testing (push) Has been skipped
CI / Prepare Merge to Main (push) Has been skipped
CI / Finalize Merge to Main (push) Has been skipped
2026-04-12 07:48:17 -04:00
f78104e1c8
fix: resolve all ruff lint errors and SQLite UNIQUE constraint issue
...
Ruff fixes (20 errors → 0):
- F401: Remove unused imports (DeckyConfig, random_hostname, IniConfig,
COMPOSE_FILE, sys, patch) across cli.py, mutator/engine.py,
templates/ftp, templates/rdp, test_mysql.py, test_postgres.py
- F541: Remove extraneous f-prefixes on strings with no placeholders
in templates/imap, test_ftp_live, test_http_live
- E741: Rename ambiguous variable 'l' to descriptive names (line, entry,
part) across conftest.py, test_ftp_live, test_http_live,
test_mongodb_live, test_pop3, test_ssh
SQLite fix:
- Change _initialize_sync() admin seeding from SELECT-then-INSERT to
INSERT OR IGNORE, preventing IntegrityError when admin user already
exists from a previous run
2026-04-12 02:17:50 -04:00
c384a3103a
refactor: separate engine, collector, mutator, and fleet into independent subpackages
...
- decnet/engine/ — container lifecycle (deploy, teardown, status); _kill_api removed
- decnet/collector/ — Docker log streaming (moved from web/collector.py)
- decnet/mutator/ — mutation engine (no longer imports from cli or duplicates deployer code)
- decnet/fleet.py — shared decky-building logic extracted from cli.py
Cross-contamination eliminated:
- web router no longer imports from decnet.cli
- mutator no longer imports from decnet.cli
- cli no longer imports from decnet.web
- _kill_api() moved to cli (process management, not engine concern)
- _compose_with_retry duplicate removed from mutator
2026-04-12 00:26:22 -04:00
babad5ce65
refactor(collector): use state file for container detection, drop label heuristics
...
_load_service_container_names() reads decnet-state.json and builds the
exact set of expected container names ({decky}-{service}). is_service_container()
and is_service_event() do a direct set lookup — no regex, no label
inspection, no heuristics.
2026-04-11 03:58:52 -04:00
7abae5571a
fix(collector): fix container detection and auto-start on deploy
...
Two bugs caused the log file to never be written:
1. is_service_container() used regex '^decky-\d+-\w' which only matched
the old decky-01-smtp naming style. Actual containers are named
omega-decky-smtp, relay-decky-smtp, etc. Fixed by using Docker Compose
labels instead: com.docker.compose.project=decnet + non-empty
depends_on discriminates service containers from base (sleep infinity)
containers reliably regardless of decky naming convention.
Added is_service_event() for the Docker events path.
2. The collector was only started when --api was used. Added a 'collect'
CLI subcommand (decnet collect --log-file <path>) and wired it into
deploy as an auto-started background process when --api is not in use.
Default log path: /var/log/decnet/decnet.log
2026-04-11 03:56:53 -04:00
08242a4d84
Implement ICS/SCADA and IMAP Bait features
2026-04-10 01:50:08 -04:00
25ba3fb56a
feat: replace bind-mount log pipeline with Docker log streaming
...
Services now print RFC 5424 to stdout; Docker captures via json-file driver.
A new host-side collector (decnet.web.collector) streams docker logs from all
running decky service containers and writes RFC 5424 + parsed JSON to the host
log file. The existing ingester continues to tail the .json file unchanged.
rsyslog can consume the .log file independently — no DECNET involvement needed.
Removes: bind-mount volume injection, _LOG_NETWORK bridge, log_target config
field and --log-target CLI flag, TCP syslog forwarding from service templates.
2026-04-10 00:14:14 -04:00
14f7a535db
fix: use model_dump(mode='json') to serialize datetime fields; fixes SSE stream silently dying post-ORM migration
2026-04-09 19:29:27 -04:00
cea6279a08
fix: add Last-Event-ID to CORS allow_headers to unblock SSE reconnects
2026-04-09 19:26:24 -04:00
6b8392102e
fix: emit stats/histogram snapshot on SSE connect; remove polling api.get('/stats') from Dashboard
2026-04-09 19:23:24 -04:00
d2a569496d
fix: add get_stream_user dependency for SSE endpoint; allow query-string token for EventSource
2026-04-09 19:20:38 -04:00
016115a523
fix: clear all addressable technical debt (DEBT-005 through DEBT-025)
...
Security:
- DEBT-008: remove query-string token auth; header-only Bearer now enforced
- DEBT-013: add regex constraint ^[a-z0-9\-]{1,64}$ on decky_name path param
- DEBT-015: stop leaking raw exception detail to API clients; log server-side
- DEBT-016: validate search (max_length=512) and datetime params with regex
Reliability:
- DEBT-014: wrap SSE event_generator in try/except; yield error frame on failure
- DEBT-017: emit log.warning/error on DB init retry; silent failures now visible
Observability / Docs:
- DEBT-020: add 401/422 response declarations to all route decorators
Infrastructure:
- DEBT-018: add HEALTHCHECK to all 24 template Dockerfiles
- DEBT-019: add USER decnet + setcap cap_net_bind_service to all 24 Dockerfiles
- DEBT-024: bump Redis template version 7.0.12 → 7.2.7
Config:
- DEBT-012: validate DECNET_API_PORT and DECNET_WEB_PORT range (1-65535)
Code quality:
- DEBT-010: delete 22 duplicate decnet_logging.py copies; deployer injects canonical
- DEBT-022: closed as false positive (print only in module docstring)
- DEBT-009: closed as false positive (templates already use structured syslog_line)
Build:
- DEBT-025: generate requirements.lock via pip freeze
Testing:
- DEBT-005/006/007: comprehensive test suite added across tests/api/
- conftest: in-memory SQLite + StaticPool + monkeypatched session_factory
- fuzz mark added; default run excludes fuzz; -n logical parallelism
DEBT.md updated: 23/25 items closed; DEBT-011 (Alembic) and DEBT-023 (digest pinning) remain
2026-04-09 19:02:51 -04:00
0166d0d559
fix: clean up db layer — model_dump, timezone-aware timestamps, unified histogram, async load_state
2026-04-09 18:46:35 -04:00
de84cc664f
refactor: migrate database to SQLModel and implement modular DB structure
2026-04-09 16:43:30 -04:00
b6b046c90b
fix: harden startup security — require strong secrets, restrict CORS
...
- decnet/env.py: DECNET_JWT_SECRET and DECNET_ADMIN_PASSWORD are now
required env vars; startup raises ValueError if unset or set to a
known-bad default ("admin", "password", etc.)
- decnet/env.py: add DECNET_CORS_ORIGINS (comma-separated, defaults to
http://localhost:8080 ) replacing the previous allow_origins=["*"]
- decnet/web/api.py: use DECNET_CORS_ORIGINS and tighten allow_methods
and allow_headers to explicit lists
- tests/conftest.py: set required env vars at module level so test
collection works without real credentials
- tests/test_web_api.py, test_web_api_fuzz.py: use DECNET_ADMIN_PASSWORD
from env instead of hardcoded "admin"
Closes DEBT-001, DEBT-002, DEBT-004
2026-04-09 12:13:22 -04:00
29a2cf2738
refactor: modularize API routes into separate files and clean up dependencies
2026-04-09 11:58:57 -04:00
551664bc43
fix: stabilize test suite by ensuring proper test DB isolation and initialization
2026-04-09 02:31:14 -04:00
a3b92d4dd6
docs: tag API endpoints for better organization
2026-04-09 01:58:54 -04:00
30edf9a55d
feat: add DECNET_DEVELOPER toggle for API documentation
2026-04-09 01:55:31 -04:00
69626d705d
feat: implement Bounty Vault for captured credentials and artifacts
2026-04-09 01:52:50 -04:00
0f86f883fe
fix: resolve remaining bandit warnings and stabilize lifespan
2026-04-09 01:35:08 -04:00
13f3d15a36
fix: stabilize tests with synchronous DB init and handle Bandit security findings
2026-04-09 01:33:15 -04:00
8c7ec2953e
fix: handle bcrypt 72-byte limit and increase JWT secret length
2026-04-09 01:11:32 -04:00
6c2478ede3
fix: restore missing API endpoints, fix chart rendering, and update date filter formatting
2026-04-08 21:25:59 -04:00
532a4e2dc5
fix: resolve SSE CORS issues and fix date filter format mismatch
2026-04-08 21:15:26 -04:00
ec503b9ec6
feat: implement advanced live logs with KQL search, histogram, and live/historical modes
2026-04-08 21:01:05 -04:00
32b06afef6
feat: add .env based configuration for API, Web, and Auth options
2026-04-08 01:27:11 -04:00
31e0c5151b
fix: ensure API-deployed deckies inherit the correct log ingestion path
2026-04-08 01:09:48 -04:00
cc3d434c02
feat: add server-side validation for web-based INI deployments
2026-04-08 01:04:59 -04:00
168ecf14ab
feat: add API-only mode and web-based INI deployment
2026-04-08 00:56:25 -04:00
c544964f57
feat: migrate dashboard live logs to Server-Sent Events (SSE)
2026-04-08 00:30:31 -04:00
18de381a43
feat: implement dynamic decky mutation and fix dot-separated INI sections
2026-04-08 00:16:57 -04:00
a9c7ddec2b
fix: enforce absolute paths for state and database files
2026-04-07 23:21:16 -04:00
eb4be44c9a
feat: add dedicated Decoy Fleet inventory page and API
2026-04-07 23:15:20 -04:00
ba2faba5d5
chore: enforce strict typing and internal naming conventions across web components
2026-04-07 19:56:15 -04:00