When the prober observes a NEW hash for an (attacker_uuid, port, probe_type) triple it has seen before — VPS rotation, SSH server rebuild, TLS cert swap — emit a derived attacker.fingerprint_rotated event carrying both old and new hash. Detection is a small library (decnet.correlation.fingerprint_rotation) called inline from the prober at each of the three emit sites (JARM/HASSH/TCPFP). No new daemon. New AttackerFingerprintState table holds per-triple last-hash state; Attacker.rotation_count and Attacker.last_rotation_at are stamped on every diff. Library is sync, fully unit-tested via injected publish_fn / syslog_fn callbacks.
388 lines
8.2 KiB
Python
388 lines
8.2 KiB
Python
"""
|
|
Database tables (SQLModel) and HTTP request/response shapes (Pydantic).
|
|
|
|
Split into topical modules for readability, but every symbol is re-exported
|
|
from this package so ``from decnet.web.db.models import X`` keeps working
|
|
everywhere — no importer needs to know which submodule a class lives in.
|
|
"""
|
|
from ._base import (
|
|
NullableDatetime,
|
|
NullableString,
|
|
_BIG_TEXT,
|
|
_normalize_null,
|
|
)
|
|
from .common import (
|
|
MessageResponse,
|
|
)
|
|
from .canary import (
|
|
CanaryBlob,
|
|
CanaryBlobResponse,
|
|
CanaryBlobsResponse,
|
|
CanaryKind,
|
|
CanaryState,
|
|
CanaryToken,
|
|
CanaryTokenCreateRequest,
|
|
CanaryTokenResponse,
|
|
CanaryTokensResponse,
|
|
CanaryTrigger,
|
|
CanaryTriggerResponse,
|
|
CanaryTriggersResponse,
|
|
)
|
|
from .auth import (
|
|
AdminConfigResponse,
|
|
ChangePasswordRequest,
|
|
ConfigResponse,
|
|
CreateUserRequest,
|
|
DeploymentLimitRequest,
|
|
GlobalMutationIntervalRequest,
|
|
LoginRequest,
|
|
ResetUserPasswordRequest,
|
|
Token,
|
|
UpdateUserRoleRequest,
|
|
User,
|
|
UserResponse,
|
|
)
|
|
from .attackers import (
|
|
Attacker,
|
|
AttackerBehavior,
|
|
AttackerFingerprintState,
|
|
AttackerIdentity,
|
|
AttackersResponse,
|
|
SessionProfile,
|
|
SmtpTarget,
|
|
)
|
|
from .attacker_intel import (
|
|
AttackerIntel,
|
|
)
|
|
from .campaigns import (
|
|
Campaign,
|
|
CampaignsResponse,
|
|
)
|
|
from .deploy import (
|
|
DeployIniRequest,
|
|
DeployResponse,
|
|
MutateIntervalRequest,
|
|
PurgeResponse,
|
|
)
|
|
from .decky import (
|
|
DeckyFileDeleteRequest,
|
|
DeckyFileDropRequest,
|
|
DeckyServiceAddRequest,
|
|
DeckyServiceConfigRequest,
|
|
DeckyServiceConfigResponse,
|
|
DeckyServicesResponse,
|
|
ServiceConfigFieldDTO,
|
|
ServiceSchemaResponse,
|
|
)
|
|
from .fleet import (
|
|
LOCAL_HOST_SENTINEL,
|
|
FleetDecky,
|
|
)
|
|
from .health import (
|
|
ComponentHealth,
|
|
HealthResponse,
|
|
)
|
|
from .orchestrator import (
|
|
OrchestratorEmail,
|
|
OrchestratorEmailsResponse,
|
|
OrchestratorEvent,
|
|
OrchestratorEventsResponse,
|
|
)
|
|
from .realism import (
|
|
RealismConfig,
|
|
SyntheticFile,
|
|
SyntheticFilesResponse,
|
|
)
|
|
from .logs import (
|
|
Bounty,
|
|
BountyResponse,
|
|
Credential,
|
|
CredentialReuse,
|
|
CredentialReuseResponse,
|
|
CredentialsResponse,
|
|
Log,
|
|
LogsResponse,
|
|
State,
|
|
StatsResponse,
|
|
)
|
|
from .swarm import (
|
|
DeckyShard,
|
|
DeckyShardView,
|
|
SwarmCheckResponse,
|
|
SwarmDeployRequest,
|
|
SwarmDeployResponse,
|
|
SwarmEnrolledBundle,
|
|
SwarmEnrollRequest,
|
|
SwarmHost,
|
|
SwarmHostHealth,
|
|
SwarmHostResult,
|
|
SwarmHostView,
|
|
SwarmTeardownRequest,
|
|
SwarmUpdaterBundle,
|
|
)
|
|
from .topology import (
|
|
LAN,
|
|
ArchetypeCatalogResponse,
|
|
ArchetypeEntry,
|
|
DeckyCreateRequest,
|
|
DeckyRow,
|
|
DeckyUpdateRequest,
|
|
DeployAcceptedResponse,
|
|
EdgeCreateRequest,
|
|
EdgeRow,
|
|
LANCreateRequest,
|
|
LANRow,
|
|
LANUpdateRequest,
|
|
MutationEnqueueRequest,
|
|
MutationEnqueueResponse,
|
|
MutationRow,
|
|
NextIPResponse,
|
|
NextSubnetResponse,
|
|
NotEditableResponse,
|
|
ReapReportResponse,
|
|
ServiceCatalogResponse,
|
|
Topology,
|
|
TopologyDecky,
|
|
TopologyDetail,
|
|
TopologyEdge,
|
|
TopologyGenerateRequest,
|
|
TopologyListResponse,
|
|
TopologyMutation,
|
|
TopologyStatusEvent,
|
|
TopologyStatusEventRow,
|
|
TopologySummary,
|
|
ValidationErrorResponse,
|
|
ValidationIssueResponse,
|
|
VersionConflictResponse,
|
|
)
|
|
from .updater import (
|
|
HostReleaseInfo,
|
|
HostReleasesResponse,
|
|
PushUpdateRequest,
|
|
PushUpdateResponse,
|
|
PushUpdateResult,
|
|
RollbackRequest,
|
|
RollbackResponse,
|
|
)
|
|
from .webhooks import (
|
|
SimpleEvent,
|
|
WebhookCreateRequest,
|
|
WebhookCreateResponse,
|
|
WebhookResponse,
|
|
WebhookSubscription,
|
|
WebhookTestResponse,
|
|
WebhookUpdateRequest,
|
|
)
|
|
from .workers import (
|
|
StartAllResponse,
|
|
StartFailure,
|
|
WorkerControlResponse,
|
|
WorkersResponse,
|
|
WorkerStatus,
|
|
)
|
|
from .tarpit import (
|
|
TarpitEnableRequest,
|
|
TarpitRule,
|
|
TarpitRuleResponse,
|
|
TarpitStatusResponse,
|
|
)
|
|
from .ttp import (
|
|
CampaignTechniqueRow,
|
|
CanaryFingerprintEvidence,
|
|
CommandEvidence,
|
|
EmailEvidence,
|
|
IdentityTechniqueRow,
|
|
IntelEvidence,
|
|
NavigatorLayer,
|
|
NavigatorTechnique,
|
|
RuleCatalogueRow,
|
|
RuleStateRequest,
|
|
RuleStateResponse,
|
|
TTPRule,
|
|
TTPRuleState,
|
|
TTPTag,
|
|
TTPTagDetailRow,
|
|
TechniqueRollupRow,
|
|
compute_tag_uuid,
|
|
)
|
|
|
|
__all__ = [
|
|
# _base
|
|
"NullableDatetime",
|
|
"NullableString",
|
|
"_BIG_TEXT",
|
|
"_normalize_null",
|
|
# common
|
|
"MessageResponse",
|
|
# canary
|
|
"CanaryBlob",
|
|
"CanaryBlobResponse",
|
|
"CanaryBlobsResponse",
|
|
"CanaryKind",
|
|
"CanaryState",
|
|
"CanaryToken",
|
|
"CanaryTokenCreateRequest",
|
|
"CanaryTokenResponse",
|
|
"CanaryTokensResponse",
|
|
"CanaryTrigger",
|
|
"CanaryTriggerResponse",
|
|
"CanaryTriggersResponse",
|
|
# auth
|
|
"AdminConfigResponse",
|
|
"ChangePasswordRequest",
|
|
"ConfigResponse",
|
|
"CreateUserRequest",
|
|
"DeploymentLimitRequest",
|
|
"GlobalMutationIntervalRequest",
|
|
"LoginRequest",
|
|
"ResetUserPasswordRequest",
|
|
"Token",
|
|
"UpdateUserRoleRequest",
|
|
"User",
|
|
"UserResponse",
|
|
# attackers
|
|
"Attacker",
|
|
"AttackerBehavior",
|
|
"AttackerFingerprintState",
|
|
"AttackerIdentity",
|
|
"AttackerIntel",
|
|
"AttackersResponse",
|
|
"SessionProfile",
|
|
"SmtpTarget",
|
|
# campaigns
|
|
"Campaign",
|
|
"CampaignsResponse",
|
|
# deploy
|
|
"DeployIniRequest",
|
|
"DeployResponse",
|
|
"MutateIntervalRequest",
|
|
"PurgeResponse",
|
|
# fleet
|
|
"LOCAL_HOST_SENTINEL",
|
|
"DeckyFileDeleteRequest",
|
|
"DeckyFileDropRequest",
|
|
"DeckyServiceAddRequest",
|
|
"DeckyServiceConfigRequest",
|
|
"DeckyServiceConfigResponse",
|
|
"DeckyServicesResponse",
|
|
"FleetDecky",
|
|
"ServiceConfigFieldDTO",
|
|
"ServiceSchemaResponse",
|
|
# health
|
|
"ComponentHealth",
|
|
"HealthResponse",
|
|
# orchestrator
|
|
"OrchestratorEmail",
|
|
"OrchestratorEmailsResponse",
|
|
"OrchestratorEvent",
|
|
"OrchestratorEventsResponse",
|
|
# realism
|
|
"RealismConfig",
|
|
"SyntheticFile",
|
|
"SyntheticFilesResponse",
|
|
# logs
|
|
"Bounty",
|
|
"BountyResponse",
|
|
"Credential",
|
|
"CredentialReuse",
|
|
"CredentialReuseResponse",
|
|
"CredentialsResponse",
|
|
"Log",
|
|
"LogsResponse",
|
|
"State",
|
|
"StatsResponse",
|
|
# swarm
|
|
"DeckyShard",
|
|
"DeckyShardView",
|
|
"SwarmCheckResponse",
|
|
"SwarmDeployRequest",
|
|
"SwarmDeployResponse",
|
|
"SwarmEnrolledBundle",
|
|
"SwarmEnrollRequest",
|
|
"SwarmHost",
|
|
"SwarmHostHealth",
|
|
"SwarmHostResult",
|
|
"SwarmHostView",
|
|
"SwarmTeardownRequest",
|
|
"SwarmUpdaterBundle",
|
|
# topology
|
|
"LAN",
|
|
"ArchetypeCatalogResponse",
|
|
"ArchetypeEntry",
|
|
"DeckyCreateRequest",
|
|
"DeckyRow",
|
|
"DeckyUpdateRequest",
|
|
"DeployAcceptedResponse",
|
|
"EdgeCreateRequest",
|
|
"EdgeRow",
|
|
"LANCreateRequest",
|
|
"LANRow",
|
|
"LANUpdateRequest",
|
|
"MutationEnqueueRequest",
|
|
"MutationEnqueueResponse",
|
|
"MutationRow",
|
|
"NextIPResponse",
|
|
"NextSubnetResponse",
|
|
"NotEditableResponse",
|
|
"ReapReportResponse",
|
|
"ServiceCatalogResponse",
|
|
"Topology",
|
|
"TopologyDecky",
|
|
"TopologyDetail",
|
|
"TopologyEdge",
|
|
"TopologyGenerateRequest",
|
|
"TopologyListResponse",
|
|
"TopologyMutation",
|
|
"TopologyStatusEvent",
|
|
"TopologyStatusEventRow",
|
|
"TopologySummary",
|
|
"ValidationErrorResponse",
|
|
"ValidationIssueResponse",
|
|
"VersionConflictResponse",
|
|
# updater
|
|
"HostReleaseInfo",
|
|
"HostReleasesResponse",
|
|
"PushUpdateRequest",
|
|
"PushUpdateResponse",
|
|
"PushUpdateResult",
|
|
"RollbackRequest",
|
|
"RollbackResponse",
|
|
# webhooks
|
|
"SimpleEvent",
|
|
"WebhookCreateRequest",
|
|
"WebhookCreateResponse",
|
|
"WebhookResponse",
|
|
"WebhookSubscription",
|
|
"WebhookTestResponse",
|
|
"WebhookUpdateRequest",
|
|
# workers
|
|
"StartAllResponse",
|
|
"StartFailure",
|
|
"WorkerControlResponse",
|
|
"WorkersResponse",
|
|
"WorkerStatus",
|
|
# tarpit
|
|
"TarpitEnableRequest",
|
|
"TarpitRule",
|
|
"TarpitRuleResponse",
|
|
"TarpitStatusResponse",
|
|
# ttp
|
|
"CampaignTechniqueRow",
|
|
"CanaryFingerprintEvidence",
|
|
"CommandEvidence",
|
|
"EmailEvidence",
|
|
"IdentityTechniqueRow",
|
|
"TTPTagDetailRow",
|
|
"IntelEvidence",
|
|
"NavigatorLayer",
|
|
"NavigatorTechnique",
|
|
"RuleCatalogueRow",
|
|
"RuleStateRequest",
|
|
"RuleStateResponse",
|
|
"TTPRule",
|
|
"TTPRuleState",
|
|
"TTPTag",
|
|
"TechniqueRollupRow",
|
|
"compute_tag_uuid",
|
|
]
|