from django.db import models from apps.common.models import BaseModel from apps.common.readable_ids import save_with_readable_id def value_labeled(choice_class): for member in choice_class: member._label_ = member.value return choice_class @value_labeled class ArtifactType(models.TextChoices): UNKNOWN = "Unknown" HOSTNAME = "Hostname" IP_ADDRESS = "IP Address" MAC_ADDRESS = "MAC Address" USER_NAME = "User Name" EMAIL_ADDRESS = "Email Address" URL_STRING = "URL String" FILE_NAME = "File Name" HASH = "Hash" PROCESS_NAME = "Process Name" RESOURCE_UID = "Resource UID" PORT = "Port" SUBNET = "Subnet" COMMAND_LINE = "Command Line" COUNTRY = "Country" PROCESS_ID = "Process ID" HTTP_USER_AGENT = "HTTP User-Agent" CWE = "CWE" CVE = "CVE" USER_CREDENTIAL_ID = "User Credential ID" ENDPOINT = "Endpoint" USER = "User" EMAIL = "Email" UNIFORM_RESOURCE_LOCATOR = "Uniform Resource Locator" FILE = "File" PROCESS = "Process" GEO_LOCATION = "Geo Location" CONTAINER = "Container" REGISTRY = "Registry" FINGERPRINT = "Fingerprint" GROUP = "Group" ACCOUNT = "Account" SCRIPT_CONTENT = "Script Content" SERIAL_NUMBER = "Serial Number" RESOURCE = "Resource" MESSAGE = "Message" ADVISORY = "Advisory" FILE_PATH = "File Path" DEVICE = "Device" REGISTRY_PATH = "Registry Path" OTHER = "Other" @value_labeled class ArtifactName(models.TextChoices): UNKNOWN = "Unknown" OTHER = "Other" SOURCE = "Source" DESTINATION = "Destination" CLIENT = "Client" SERVER = "Server" ACTOR = "Actor" TARGET = "Target" AFFECTED = "Affected" RELATED = "Related" OBSERVED = "Observed" REQUEST = "Request" RESPONSE = "Response" SOURCE_IP = "Source IP" DESTINATION_IP = "Destination IP" CLIENT_IP = "Client IP" SERVER_IP = "Server IP" REMOTE_IP = "Remote IP" LOCAL_IP = "Local IP" NAT_IP = "NAT IP" PROXY_IP = "Proxy IP" FORWARDED_IP = "Forwarded IP" DNS_SERVER_IP = "DNS Server IP" DHCP_SERVER_IP = "DHCP Server IP" VPN_IP = "VPN IP" SOURCE_PORT = "Source Port" DESTINATION_PORT = "Destination Port" CLIENT_PORT = "Client Port" SERVER_PORT = "Server Port" SOURCE_MAC = "Source MAC" DESTINATION_MAC = "Destination MAC" DEVICE_MAC = "Device MAC" DOMAIN = "Domain" SOURCE_DOMAIN = "Source Domain" DESTINATION_DOMAIN = "Destination Domain" REQUEST_DOMAIN = "Request Domain" DNS_QUERY_NAME = "DNS Query Name" DNS_ANSWER = "DNS Answer" DNS_RECORD = "DNS Record" URL = "URL" REQUEST_URL = "Request URL" REFERRER_URL = "Referrer URL" REDIRECT_URL = "Redirect URL" LANDING_URL = "Landing URL" PHISHING_URL = "Phishing URL" CALLBACK_URL = "Callback URL" DOWNLOAD_URL = "Download URL" HTTP_METHOD = "HTTP Method" HTTP_USER_AGENT = "HTTP User-Agent" HTTP_HOST = "HTTP Host" HTTP_PATH = "HTTP Path" HTTP_QUERY = "HTTP Query" HTTP_STATUS_CODE = "HTTP Status Code" HTTP_REQUEST_BODY = "HTTP Request Body" HTTP_RESPONSE_BODY = "HTTP Response Body" USER = "User" USER_NAME = "User Name" USER_ID = "User ID" USER_SID = "User SID" USER_UPN = "User UPN" USER_EMAIL = "User Email" SOURCE_USER = "Source User" DESTINATION_USER = "Destination User" ACTOR_USER = "Actor User" TARGET_USER = "Target User" AFFECTED_USER = "Affected User" EXECUTING_USER = "Executing User" LOGON_USER = "Logon User" LOGIN_USER = "Login User" PRINCIPAL_USER = "Principal User" INITIATING_USER = "Initiating User" REQUESTING_USER = "Requesting User" OWNER_USER = "Owner User" ACCOUNT = "Account" ACCOUNT_ID = "Account ID" ACCOUNT_NAME = "Account Name" SERVICE_ACCOUNT = "Service Account" ADMIN_ACCOUNT = "Admin Account" CLOUD_ACCOUNT = "Cloud Account" AWS_ACCOUNT_ID = "AWS Account ID" AZURE_TENANT_ID = "Azure Tenant ID" AZURE_SUBSCRIPTION_ID = "Azure Subscription ID" GCP_PROJECT_ID = "GCP Project ID" CREDENTIAL_ID = "Credential ID" ACCESS_KEY_ID = "Access Key ID" API_KEY_ID = "API Key ID" TOKEN_ID = "Token ID" SESSION_ID = "Session ID" HOST = "Host" HOSTNAME = "Hostname" HOST_ID = "Host ID" SOURCE_HOST = "Source Host" DESTINATION_HOST = "Destination Host" AFFECTED_HOST = "Affected Host" TARGET_HOST = "Target Host" DEVICE = "Device" DEVICE_ID = "Device ID" DEVICE_NAME = "Device Name" ENDPOINT = "Endpoint" ENDPOINT_ID = "Endpoint ID" ASSET_ID = "Asset ID" AGENT_ID = "Agent ID" SENSOR_ID = "Sensor ID" OPERATING_SYSTEM = "Operating System" HOST_OS = "Host OS" HOST_IP = "Host IP" HOST_MAC = "Host MAC" HOST_SERIAL_NUMBER = "Host Serial Number" PROCESS = "Process" PROCESS_NAME = "Process Name" PROCESS_ID = "Process ID" PROCESS_PATH = "Process Path" PROCESS_EXECUTABLE = "Process Executable" PROCESS_COMMAND_LINE = "Process Command Line" PROCESS_HASH = "Process Hash" PARENT_PROCESS = "Parent Process" PARENT_PROCESS_NAME = "Parent Process Name" PARENT_PROCESS_ID = "Parent Process ID" PARENT_PROCESS_PATH = "Parent Process Path" PARENT_PROCESS_COMMAND_LINE = "Parent Process Command Line" PARENT_PROCESS_HASH = "Parent Process Hash" CHILD_PROCESS = "Child Process" CHILD_PROCESS_NAME = "Child Process Name" CHILD_PROCESS_ID = "Child Process ID" CHILD_PROCESS_COMMAND_LINE = "Child Process Command Line" ACTING_PROCESS = "Acting Process" TARGET_PROCESS = "Target Process" INJECTED_PROCESS = "Injected Process" FILE = "File" FILE_NAME = "File Name" FILE_PATH = "File Path" FILE_EXTENSION = "File Extension" FILE_DIRECTORY = "File Directory" FILE_SIZE = "File Size" FILE_HASH = "File Hash" FILE_MD5 = "File MD5" FILE_SHA1 = "File SHA1" FILE_SHA256 = "File SHA256" FILE_SHA512 = "File SHA512" FILE_IMPHASH = "File Imphash" FILE_SIGNATURE = "File Signature" FILE_PUBLISHER = "File Publisher" FILE_OWNER = "File Owner" DOWNLOAD_FILE = "Download File" ATTACHMENT_FILE = "Attachment File" DROPPED_FILE = "Dropped File" TARGET_FILE = "Target File" EMAIL = "Email" SENDER_EMAIL = "Sender Email" RECIPIENT_EMAIL = "Recipient Email" CC_EMAIL = "CC Email" BCC_EMAIL = "BCC Email" REPLY_TO_EMAIL = "Reply-To Email" RETURN_PATH_EMAIL = "Return-Path Email" MAIL_FROM = "Mail From" MAIL_TO = "Mail To" MAIL_SUBJECT = "Mail Subject" MAIL_MESSAGE_ID = "Mail Message ID" MAIL_ATTACHMENT = "Mail Attachment" MAIL_URL = "Mail URL" MAIL_DOMAIN = "Mail Domain" SENDER_DOMAIN = "Sender Domain" RECIPIENT_DOMAIN = "Recipient Domain" CLOUD_RESOURCE = "Cloud Resource" CLOUD_RESOURCE_ID = "Cloud Resource ID" CLOUD_RESOURCE_NAME = "Cloud Resource Name" CLOUD_RESOURCE_ARN = "Cloud Resource ARN" CLOUD_REGION = "Cloud Region" CLOUD_ZONE = "Cloud Zone" CLOUD_SERVICE = "Cloud Service" CLOUD_ROLE = "Cloud Role" CLOUD_POLICY = "Cloud Policy" CLOUD_POLICY_ARN = "Cloud Policy ARN" CLOUD_INSTANCE_ID = "Cloud Instance ID" CLOUD_BUCKET = "Cloud Bucket" CLOUD_STORAGE_OBJECT = "Cloud Storage Object" CLOUD_FUNCTION = "Cloud Function" CLOUD_TRAIL_EVENT_ID = "CloudTrail Event ID" CLOUD_REQUEST_ID = "Cloud Request ID" IAM_USER = "IAM User" IAM_ROLE = "IAM Role" IAM_GROUP = "IAM Group" IAM_POLICY = "IAM Policy" IAM_POLICY_ARN = "IAM Policy ARN" IAM_PERMISSION = "IAM Permission" IAM_ACTION = "IAM Action" IAM_RESOURCE = "IAM Resource" ASSUMED_ROLE = "Assumed Role" ACCESS_KEY = "Access Key" SECRET_KEY_ID = "Secret Key ID" PERMISSION_SET = "Permission Set" REGISTRY_KEY = "Registry Key" REGISTRY_VALUE = "Registry Value" REGISTRY_PATH = "Registry Path" REGISTRY_DATA = "Registry Data" WINDOWS_SERVICE = "Windows Service" SCHEDULED_TASK = "Scheduled Task" WMI_OBJECT = "WMI Object" COM_OBJECT = "COM Object" NAMED_PIPE = "Named Pipe" MUTEX = "Mutex" CONTAINER = "Container" CONTAINER_ID = "Container ID" CONTAINER_NAME = "Container Name" CONTAINER_IMAGE = "Container Image" CONTAINER_IMAGE_ID = "Container Image ID" POD = "Pod" POD_NAME = "Pod Name" NAMESPACE = "Namespace" KUBERNETES_CLUSTER = "Kubernetes Cluster" KUBERNETES_NODE = "Kubernetes Node" KUBERNETES_SERVICE_ACCOUNT = "Kubernetes Service Account" CVE = "CVE" CWE = "CWE" CPE = "CPE" CVSS_SCORE = "CVSS Score" VULNERABLE_PRODUCT = "Vulnerable Product" MALWARE_NAME = "Malware Name" MALWARE_FAMILY = "Malware Family" THREAT_ACTOR = "Threat Actor" THREAT_CAMPAIGN = "Threat Campaign" ATTACK_TECHNIQUE = "Attack Technique" ATTACK_TACTIC = "Attack Tactic" IOC = "IOC" YARA_RULE = "YARA Rule" SIGMA_RULE = "Sigma Rule" @value_labeled class ArtifactRole(models.TextChoices): UNKNOWN = "Unknown" TARGET = "Target" ACTOR = "Actor" AFFECTED = "Affected" RELATED = "Related" OTHER = "Other" class Artifact(BaseModel): artifact_id = models.CharField(max_length=32, unique=True, editable=False, db_index=True, blank=True, default="", help_text="Record ID e.g. artifact_000001 (记录 ID e.g. artifact_000001)") name = models.CharField(max_length=100, choices=ArtifactName, default=ArtifactName.UNKNOWN, blank=True, help_text="Artifact name (实体名称)") type = models.CharField(max_length=50, choices=ArtifactType, default=ArtifactType.UNKNOWN, help_text="Artifact type (实体类型)") role = models.CharField(max_length=20, choices=ArtifactRole, default=ArtifactRole.UNKNOWN, help_text="Artifact role in event (实体在事件中的角色)") value = models.CharField(max_length=500, blank=True, default="", help_text="Artifact value (实体值)") class Meta: db_table = "artifacts" ordering = ["-created_at"] indexes = [ models.Index(fields=["-created_at", "-id"], name="artifact_created_id_idx"), ] def save(self, *args, **kwargs): return save_with_readable_id(self, "artifact_id", "artifact", *args, **kwargs) def __str__(self): return f"{self.type}: {self.value}" if self.value else str(self.id)