main
py 68 lines 1.8 KB
Raw
1 from datetime import datetime
2 from typing import List
3 from typing import Optional
4
5 from pydantic import BaseModel
6 from pydantic import ConfigDict
7 from pydantic import Field
8
9
10 class VelociraptorAgent(BaseModel):
11 client_id: Optional[str] = Field("n/a", alias="velociraptor_id")
12 client_last_seen: str = Field(..., alias="velociraptor_last_seen")
13 client_version: str = Field(..., alias="velociraptor_agent_version")
14 client_org: str = Field(..., alias="velociraptor_org")
15
16 @property
17 def client_last_seen_as_datetime(self):
18 dt = datetime.strptime(self.client_last_seen, "%Y-%m-%dT%H:%M:%S%z")
19 return dt.replace(tzinfo=None)
20
21 model_config = ConfigDict(populate_by_name=True)
22
23
24 class VelociraptorAgentInformation(BaseModel):
25 version: str
26 name: str
27 build_time: str
28 build_url: str
29
30
31 class VelociraptorOSInfo(BaseModel):
32 system: str
33 hostname: str
34 release: str
35 machine: str
36 fqdn: str
37 mac_addresses: List[str]
38
39
40 class VelociraptorClient(BaseModel):
41 client_id: str
42 agent_information: VelociraptorAgentInformation
43 os_info: VelociraptorOSInfo
44 first_seen_at: int
45 last_seen_at: int
46 last_ip: str
47 last_interrogate_flow_id: str
48 last_interrogate_artifact_name: str
49 labels: List[str]
50 last_hunt_timestamp: int
51 last_event_table_version: int
52 last_label_timestamp: int
53
54
55 class VelociraptorClients(BaseModel):
56 clients: List[VelociraptorClient]
57
58
59 class Organization(BaseModel):
60 Name: str
61 OrgId: str
62 # _client_config is intentionally not parsed: Velociraptor 0.75.6 changed
63 # SELECT * FROM orgs() to return it as a YAML string instead of a structured
64 # object, and nothing in CoPilot reads it. Pydantic 2 ignores the unknown key.
65
66
67 class VelociraptorOrganizations(BaseModel):
68 organizations: List[Organization]