mirror of
https://github.com/FunnyWolf/agentic-soc-platform.git
synced 2026-08-22 13:12:56 +02:00
tmp
This commit is contained in:
+175
-22
@@ -1,3 +1,4 @@
|
||||
import json
|
||||
import random
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
@@ -7,50 +8,202 @@ import settings
|
||||
|
||||
# --- 基础日志生成类 ---
|
||||
class NetworkGenerator:
|
||||
# 常见端口和协议
|
||||
PORTS_CONFIG = [
|
||||
{"port": 443, "proto": "tcp", "action": "allow", "service": "https", "weight": 35},
|
||||
{"port": 80, "proto": "tcp", "action": "allow", "service": "http", "weight": 20},
|
||||
{"port": 22, "proto": "tcp", "action": "deny", "service": "ssh", "weight": 15},
|
||||
{"port": 3389, "proto": "tcp", "action": "allow", "service": "rdp", "weight": 10},
|
||||
{"port": 3306, "proto": "tcp", "action": "allow", "service": "mysql", "weight": 8},
|
||||
{"port": 5432, "proto": "tcp", "action": "allow", "service": "postgresql", "weight": 7},
|
||||
{"port": 6379, "proto": "tcp", "action": "allow", "service": "redis", "weight": 3},
|
||||
{"port": 53, "proto": "udp", "action": "allow", "service": "dns", "weight": 2},
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def generate(cls):
|
||||
patterns = [
|
||||
{"port": 443, "proto": "tcp", "action": "allow", "weight": 90},
|
||||
{"port": 22, "proto": "tcp", "action": "deny", "weight": 10}
|
||||
]
|
||||
p = random.choices(patterns, weights=[x["weight"] for x in patterns])[0]
|
||||
p = random.choices(cls.PORTS_CONFIG, weights=[x["weight"] for x in cls.PORTS_CONFIG])[0]
|
||||
src_ip = random.choice(settings.INTERNAL_IPS)
|
||||
dst_ip = random.choice(settings.EXTERNAL_IPS)
|
||||
|
||||
# 数据字节数
|
||||
bytes_in = random.randint(100, 1000000)
|
||||
bytes_out = random.randint(100, 500000)
|
||||
|
||||
return {
|
||||
"@timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"event.dataset": "network",
|
||||
"source.ip": random.choice(settings.INTERNAL_IPS),
|
||||
"destination.ip": random.choice(settings.EXTERNAL_IPS),
|
||||
"event.module": "firewall",
|
||||
"event.category": "network_traffic",
|
||||
"event.type": "connection",
|
||||
"event.action": p["action"],
|
||||
"event.outcome": "success" if p["action"] == "allow" else "failure",
|
||||
"network.protocol": p["proto"],
|
||||
"network.direction": "egress",
|
||||
"source.ip": src_ip,
|
||||
"source.port": random.randint(49152, 65535),
|
||||
"source.mac": f"{random.randint(0, 255):02x}:{random.randint(0, 255):02x}:{random.randint(0, 255):02x}:{random.randint(0, 255):02x}:{random.randint(0, 255):02x}:{random.randint(0, 255):02x}",
|
||||
"destination.ip": dst_ip,
|
||||
"destination.port": p["port"],
|
||||
"event.action": p["action"]
|
||||
}
|
||||
|
||||
|
||||
class HostGenerator:
|
||||
@classmethod
|
||||
def generate(cls):
|
||||
return {
|
||||
"@timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"event.dataset": "host",
|
||||
"destination.service": p["service"],
|
||||
"network.bytes_in": bytes_in,
|
||||
"network.bytes_out": bytes_out,
|
||||
"network.packets": random.randint(1, 10000),
|
||||
"network.duration": random.randint(100, 3600000), # ms
|
||||
"host.name": random.choice(settings.HOSTS),
|
||||
"host.ip": src_ip,
|
||||
"process.pid": random.randint(100, 65535),
|
||||
"process.name": random.choice(settings.PROCESSES),
|
||||
"user.name": random.choice(settings.USERS),
|
||||
"event.action": random.choice(["process_started", "file_read"]),
|
||||
"user.id": f"{random.randint(1000, 9999)}",
|
||||
"firewall.rule_id": f"FW-{random.randint(10000, 99999)}",
|
||||
"firewall.rule_name": f"rule-{random.choice(['allow', 'deny'])}-traffic",
|
||||
"log.level": "info"
|
||||
}
|
||||
|
||||
|
||||
class HostGenerator:
|
||||
# 常见进程动作
|
||||
PROCESS_ACTIONS = [
|
||||
{"action": "process_created", "weight": 50},
|
||||
{"action": "process_terminated", "weight": 20},
|
||||
{"action": "file_created", "weight": 15},
|
||||
{"action": "file_deleted", "weight": 10},
|
||||
{"action": "network_connection", "weight": 3},
|
||||
{"action": "registry_modified", "weight": 2},
|
||||
]
|
||||
|
||||
FILE_EXTENSIONS = [".exe", ".dll", ".sys", ".log", ".txt", ".dat", ".tmp", ".cmd", ".ps1", ".sh"]
|
||||
|
||||
@classmethod
|
||||
def generate(cls):
|
||||
host_name = random.choice(settings.HOSTS)
|
||||
user_name = random.choice(settings.USERS)
|
||||
action_obj = random.choices(cls.PROCESS_ACTIONS, weights=[x["weight"] for x in cls.PROCESS_ACTIONS])[0]
|
||||
action = action_obj["action"]
|
||||
process_name = random.choice(settings.PROCESSES)
|
||||
|
||||
return {
|
||||
"@timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"event.dataset": "host",
|
||||
"event.module": "endpoint",
|
||||
"event.category": "process" if "process" in action else "file",
|
||||
"event.type": action,
|
||||
"event.action": action,
|
||||
"event.outcome": random.choice(["success", "failure"]),
|
||||
"host.name": host_name,
|
||||
"host.id": str(uuid.uuid4()),
|
||||
"host.os.name": random.choice(["Windows", "Linux", "macOS"]),
|
||||
"host.os.version": random.choice(["10", "11", "20.04", "22.04", "12.0"]),
|
||||
"host.architecture": random.choice(["x86_64", "arm64"]),
|
||||
"user.name": user_name,
|
||||
"user.id": f"S-1-5-21-{random.randint(1000000000, 9999999999)}-{random.randint(1000000000, 9999999999)}-{random.randint(1000000000, 9999999999)}-{random.randint(500, 9999)}",
|
||||
"user.domain": random.choice(["CORP", "LOCAL", "WORKGROUP"]),
|
||||
"process.pid": random.randint(100, 65535),
|
||||
"process.ppid": random.randint(100, 65535),
|
||||
"process.name": process_name,
|
||||
"process.executable": f"/usr/bin/{process_name}" if "." not in process_name else f"C:\\Windows\\System32\\{process_name}",
|
||||
"process.command_line": f"{process_name} {random.choice(['--verbose', '-d', '--config', ''])}",
|
||||
"process.hash.md5": f"{uuid.uuid4().hex[:32]}",
|
||||
"process.hash.sha256": f"{uuid.uuid4().hex}",
|
||||
"process.parent.name": random.choice(["svchost.exe", "bash", "systemd"]),
|
||||
"process.parent.pid": random.randint(100, 1000),
|
||||
"file.name": f"file_{random.randint(1000, 9999)}{random.choice(cls.FILE_EXTENSIONS)}",
|
||||
"file.path": f"/var/log/app.log" if "linux" in random.choice(["windows", "linux"]) else f"C:\\Users\\{user_name}\\Documents\\file.txt",
|
||||
"file.size": random.randint(1024, 10485760), # 1KB to 10MB
|
||||
"file.hash.md5": f"{uuid.uuid4().hex[:32]}",
|
||||
"file.hash.sha256": f"{uuid.uuid4().hex}",
|
||||
"log.level": random.choice(["info", "warning", "error"]),
|
||||
"message": f"Process {process_name} executed by user {user_name}",
|
||||
}
|
||||
|
||||
|
||||
class CloudGenerator:
|
||||
# API 调用风险等级
|
||||
EVENT_RISK_LEVELS = {
|
||||
"RunInstances": "medium",
|
||||
"StopInstances": "low",
|
||||
"TerminateInstances": "high",
|
||||
"ModifyInstanceAttribute": "high",
|
||||
"CreateUser": "medium",
|
||||
"DeleteUser": "high",
|
||||
"CreateAccessKey": "high",
|
||||
"UpdateAssumeRolePolicy": "high",
|
||||
"AttachUserPolicy": "high",
|
||||
"PutObject": "medium",
|
||||
"GetObject": "low",
|
||||
"DeleteBucket": "critical",
|
||||
"ConsoleLogin": "medium",
|
||||
"AssumeRole": "high",
|
||||
"CreateSecurityGroup": "medium",
|
||||
"AuthorizeSecurityGroupIngress": "high",
|
||||
"DeleteFlowLogs": "high",
|
||||
}
|
||||
|
||||
HTTP_STATUS_CODES = [200, 201, 202, 400, 401, 403, 404, 409, 500, 503]
|
||||
|
||||
@classmethod
|
||||
def generate(cls):
|
||||
event_name = random.choice(settings.EVENT_NAMES)
|
||||
risk_level = cls.EVENT_RISK_LEVELS.get(event_name, "medium")
|
||||
status_code = random.choice(cls.HTTP_STATUS_CODES)
|
||||
request_id = str(uuid.uuid4())
|
||||
|
||||
return {
|
||||
"@timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"event.dataset": "aws.cloudtrail",
|
||||
"event.module": "cloudtrail",
|
||||
"event.action": event_name,
|
||||
"event.category": "iam" if "User" in event_name or "Assume" in event_name or "Policy" in event_name else "cloud",
|
||||
"event.outcome": "success" if status_code == 200 else "failure",
|
||||
"event.duration": random.randint(100, 5000), # ms
|
||||
"event.risk_score": 50 if risk_level == "medium" else (20 if risk_level == "low" else (80 if risk_level == "high" else 100)),
|
||||
"cloud.provider": "aws",
|
||||
"cloud.service.name": random.choice(["ec2", "iam", "s3", "lambda", "rds"]),
|
||||
"cloud.region": random.choice(settings.REGIONS),
|
||||
"cloud.account.id": random.choice(settings.AWS_ACCOUNTS),
|
||||
"cloud.account.name": f"prod-{random.choice(['account', 'prod'])}",
|
||||
"user.name": random.choice(settings.IAM_USERS),
|
||||
"event.action": event_name,
|
||||
"user.id": f"AIDAI{uuid.uuid4().hex[:16].upper()}",
|
||||
"user.type": random.choice(["IAMUser", "IAMRole", "AssumedRole", "RootUser"]),
|
||||
"user.access_key_id": f"AKIA{uuid.uuid4().hex[:16].upper()}",
|
||||
"source.ip": random.choice(settings.EXTERNAL_IPS),
|
||||
"user_agent": "aws-cli/2.0.50 Python/3.8.5 Windows/10",
|
||||
"request_id": str(uuid.uuid4()),
|
||||
"event.outcome": "success" if random.random() > 0.1 else "failure"
|
||||
"source.address": random.choice(settings.EXTERNAL_IPS),
|
||||
"source.geo.country_name": random.choice(["United States", "China", "Russia", "India", "Germany"]),
|
||||
"source.geo.country_iso_code": random.choice(["US", "CN", "RU", "IN", "DE"]),
|
||||
"http.request.method": random.choice(["GET", "POST", "PUT", "DELETE", "PATCH"]),
|
||||
"http.response.status_code": status_code,
|
||||
"http.request.body.content": f"EventVersion: 1.0, Parameters: {json.dumps({'Action': event_name})}",
|
||||
"user_agent": random.choice([
|
||||
"aws-cli/2.0.50 Python/3.8.5 Windows/10",
|
||||
"aws-cli/2.13.0 Python/3.11.0 Linux/5.10.0",
|
||||
"Terraform/1.5.0",
|
||||
"AWS-CloudFormation/1.0",
|
||||
"boto3/1.26.0"
|
||||
]),
|
||||
"request_id": request_id,
|
||||
"event_id": str(uuid.uuid4()),
|
||||
"aws_service": random.choice(["cloudtrail", "config", "guardduty", "securityhub"]),
|
||||
"aws_request_id": request_id,
|
||||
"recipient_account_id": random.choice(settings.AWS_ACCOUNTS),
|
||||
"additional_event_data": {
|
||||
"LoginTo": f"https://console.aws.amazon.com/",
|
||||
"MobileVersion": "False",
|
||||
"MFAUsed": random.choice([True, False]),
|
||||
},
|
||||
"request_parameters": {
|
||||
"instanceId": f"i-{uuid.uuid4().hex[:16]}",
|
||||
"userId": f"AIDAI{uuid.uuid4().hex[:16].upper()}",
|
||||
"groupId": f"sg-{uuid.uuid4().hex[:8]}",
|
||||
"bucketName": f"bucket-{random.randint(1000, 9999)}",
|
||||
},
|
||||
"response_elements": {
|
||||
"instanceId": f"i-{uuid.uuid4().hex[:16]}",
|
||||
"reservationSet": f"r-{uuid.uuid4().hex[:8]}",
|
||||
},
|
||||
"error_code": None if status_code == 200 else random.choice(
|
||||
["AccessDenied", "InvalidParameterValue", "UnauthorizedOperation", "InsufficientPermissions"]),
|
||||
"error_message": None if status_code == 200 else "User is not authorized to perform: iam:CreateUser on resource",
|
||||
"read_only": random.choice([True, False]),
|
||||
"log.level": "info" if risk_level == "low" else "warning"
|
||||
}
|
||||
|
||||
+311
-37
@@ -16,35 +16,87 @@ class BruteForceScenario(Scenario):
|
||||
self.target_user = target_user or random.choice(settings.USERS)
|
||||
self.target_host = random.choice(settings.HOSTS)
|
||||
self.attacker_ip = "45.95.11.22" # 模拟黑客常用 IP
|
||||
import uuid
|
||||
self.session_id = str(uuid.uuid4())
|
||||
|
||||
def get_logs(self) -> list:
|
||||
import uuid
|
||||
logs = []
|
||||
# 1. 模拟 5-10 次失败登录
|
||||
fail_count = random.randint(5, 10)
|
||||
for _ in range(fail_count):
|
||||
for attempt in range(fail_count):
|
||||
logs.append({
|
||||
"@timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"event.dataset": "host",
|
||||
"host.name": self.target_host,
|
||||
"user.name": self.target_user,
|
||||
"source.ip": self.attacker_ip,
|
||||
"event.module": "endpoint",
|
||||
"event.category": "authentication",
|
||||
"event.type": "authentication",
|
||||
"event.action": "login_failed",
|
||||
"event.outcome": "failure",
|
||||
"event.reason": "Invalid credentials",
|
||||
"host.name": self.target_host,
|
||||
"host.id": str(uuid.uuid4()),
|
||||
"host.os.name": random.choice(["Windows", "Linux"]),
|
||||
"user.name": self.target_user,
|
||||
"user.id": f"S-1-5-21-{random.randint(100000000, 999999999)}-{random.randint(100000000, 999999999)}-{random.randint(100000000, 999999999)}-1001",
|
||||
"user.domain": random.choice(["CORP", "LOCAL"]),
|
||||
"source.ip": self.attacker_ip,
|
||||
"source.port": random.randint(49152, 65535),
|
||||
"source.geo.country_name": "China",
|
||||
"source.geo.country_iso_code": "CN",
|
||||
"destination.ip": random.choice(settings.INTERNAL_IPS),
|
||||
"destination.port": random.choice([22, 3389, 445]),
|
||||
"process.pid": random.randint(100, 1000),
|
||||
"process.name": random.choice(["sshd", "lsass.exe", "svchost.exe"]),
|
||||
"process.executable": "/usr/sbin/sshd" if "linux" in random.choice(["windows", "linux"]) else "C:\\Windows\\System32\\lsass.exe",
|
||||
"authentication.type": random.choice(["ssh", "rdp", "kerberos", "ntlm"]),
|
||||
"authentication.method": "password",
|
||||
"network.protocol": "tcp",
|
||||
"network.transport": "ssh" if random.random() > 0.5 else "rdp",
|
||||
"error.code": random.choice(["AUTH_FAILED", "INVALID_USER", "INVALID_CREDS"]),
|
||||
"error.message": "Authentication failed: invalid password",
|
||||
"event.duration": random.randint(1000, 5000),
|
||||
"session.id": self.session_id,
|
||||
"log.level": "warning",
|
||||
"message": "Authentication failed"
|
||||
"message": f"Failed login attempt {attempt + 1}/{fail_count} for user {self.target_user}"
|
||||
})
|
||||
|
||||
# 2. 紧接着一次成功登录 (触发告警的关键点)
|
||||
logs.append({
|
||||
"@timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"event.dataset": "host",
|
||||
"host.name": self.target_host,
|
||||
"user.name": self.target_user,
|
||||
"source.ip": self.attacker_ip,
|
||||
"event.module": "endpoint",
|
||||
"event.category": "authentication",
|
||||
"event.type": "authentication",
|
||||
"event.action": "login_success",
|
||||
"event.outcome": "success",
|
||||
"log.level": "info",
|
||||
"message": "User logged in successfully"
|
||||
"event.reason": "Valid credentials",
|
||||
"host.name": self.target_host,
|
||||
"host.id": str(uuid.uuid4()),
|
||||
"host.os.name": random.choice(["Windows", "Linux"]),
|
||||
"user.name": self.target_user,
|
||||
"user.id": f"S-1-5-21-{random.randint(100000000, 999999999)}-{random.randint(100000000, 999999999)}-{random.randint(100000000, 999999999)}-1001",
|
||||
"user.domain": random.choice(["CORP", "LOCAL"]),
|
||||
"user.logon_type": random.choice(["RemoteInteractive", "Network", "Interactive"]),
|
||||
"source.ip": self.attacker_ip,
|
||||
"source.port": random.randint(49152, 65535),
|
||||
"source.geo.country_name": "China",
|
||||
"source.geo.country_iso_code": "CN",
|
||||
"destination.ip": random.choice(settings.INTERNAL_IPS),
|
||||
"destination.port": random.choice([22, 3389, 445]),
|
||||
"process.pid": random.randint(100, 1000),
|
||||
"process.name": random.choice(["sshd", "lsass.exe", "svchost.exe"]),
|
||||
"process.executable": "/usr/sbin/sshd" if "linux" in random.choice(["windows", "linux"]) else "C:\\Windows\\System32\\lsass.exe",
|
||||
"authentication.type": random.choice(["ssh", "rdp", "kerberos", "ntlm"]),
|
||||
"authentication.method": "password",
|
||||
"network.protocol": "tcp",
|
||||
"network.transport": "ssh" if random.random() > 0.5 else "rdp",
|
||||
"session.id": self.session_id,
|
||||
"session.duration": random.randint(300000, 3600000), # ms
|
||||
"event.duration": random.randint(500, 2000),
|
||||
"risk_score": 85,
|
||||
"log.level": "critical",
|
||||
"message": f"Successful login after {fail_count} failed attempts - BRUTE FORCE DETECTED"
|
||||
})
|
||||
return logs
|
||||
|
||||
@@ -52,15 +104,64 @@ class BruteForceScenario(Scenario):
|
||||
class SqlInjectionScenario(Scenario):
|
||||
def get_logs(self) -> list:
|
||||
# 模拟 Web 访问中携带恶意的 SQL 注入载荷
|
||||
payloads = [
|
||||
"id=1' OR '1'='1",
|
||||
"username=admin' --",
|
||||
"id=1; DROP TABLE users;--",
|
||||
"email=' OR 1=1 --",
|
||||
"search=<script>alert('xss')</script>"
|
||||
]
|
||||
payload = random.choice(payloads)
|
||||
|
||||
return [{
|
||||
"@timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"event.dataset": "network",
|
||||
"event.module": "waf",
|
||||
"event.category": "web",
|
||||
"event.type": "attack",
|
||||
"event.action": "web_attack",
|
||||
"event.outcome": "failure",
|
||||
"event.severity": "high",
|
||||
"event.risk_score": 90,
|
||||
"source.ip": random.choice(settings.EXTERNAL_IPS),
|
||||
"source.port": random.randint(49152, 65535),
|
||||
"source.geo.country_name": random.choice(["China", "Russia", "North Korea"]),
|
||||
"source.geo.country_iso_code": random.choice(["CN", "RU", "KP"]),
|
||||
"source.user_agent": random.choice([
|
||||
"Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org)",
|
||||
"sqlmap/1.5.2 (http://sqlmap.org)",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
|
||||
"curl/7.64.1",
|
||||
"python-requests/2.26.0"
|
||||
]),
|
||||
"destination.ip": random.choice(settings.INTERNAL_IPS),
|
||||
"destination.port": random.choice([80, 443, 8080]),
|
||||
"destination.address": f"web-{random.randint(1, 5)}.example.com",
|
||||
"destination.service": "http",
|
||||
"http.request.method": random.choice(["GET", "POST"]),
|
||||
"http.request.header.user-agent": random.choice([
|
||||
"Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org)",
|
||||
"sqlmap/1.5.2",
|
||||
"curl/7.64.1"
|
||||
]),
|
||||
"http.request.body.content": payload,
|
||||
"url.scheme": "https",
|
||||
"url.domain": f"web-{random.randint(1, 5)}.example.com",
|
||||
"url.path": "/api/user",
|
||||
"url.query": "id=1' OR '1'='1",
|
||||
"http.response.status_code": 200,
|
||||
"event.action": "web_access"
|
||||
"url.query": payload,
|
||||
"url.full": f"https://web-{random.randint(1, 5)}.example.com/api/user?{payload}",
|
||||
"http.response.status_code": 403,
|
||||
"http.response.body.content": "Access Denied - SQL Injection Detected",
|
||||
"http.request.body.bytes": len(payload),
|
||||
"http.response.body.bytes": 200,
|
||||
"waf.action": "block",
|
||||
"waf.rule_id": f"WAF-{random.randint(10000, 99999)}",
|
||||
"waf.rule_name": "SQL Injection Detection Rule",
|
||||
"waf.triggered_rules": ["SQL Injection Pattern", "OWASP CRS SQL Injection"],
|
||||
"process.name": random.choice(["nginx", "apache2", "tomcat"]),
|
||||
"host.name": random.choice(settings.HOSTS),
|
||||
"log.level": "critical",
|
||||
"message": f"SQL Injection attack detected: {payload}"
|
||||
}]
|
||||
|
||||
|
||||
@@ -69,46 +170,112 @@ class RansomwareScenario(Scenario):
|
||||
self.target_host = random.choice(settings.HOSTS)
|
||||
self.target_user = random.choice(settings.USERS)
|
||||
self.malware_proc = "decryptor.exe"
|
||||
import uuid
|
||||
self.malware_pid = random.randint(1000, 9999)
|
||||
self.malware_hash = uuid.uuid4().hex
|
||||
|
||||
def get_logs(self) -> list:
|
||||
import uuid
|
||||
logs = []
|
||||
base_path = "C:\\Users\\admin\\Documents\\"
|
||||
base_path = f"C:\\Users\\{self.target_user}\\Documents\\"
|
||||
|
||||
# 1. 模拟删除卷影副本 (Shadow Copy) - 典型的勒索预兆
|
||||
logs.append({
|
||||
"@timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"event.dataset": "host",
|
||||
"event.module": "endpoint",
|
||||
"event.category": "process",
|
||||
"event.type": "process_started",
|
||||
"event.action": "process_started",
|
||||
"event.outcome": "success",
|
||||
"host.name": self.target_host,
|
||||
"host.id": str(uuid.uuid4()),
|
||||
"host.os.name": "Windows",
|
||||
"user.name": self.target_user,
|
||||
"user.id": f"S-1-5-21-{random.randint(100000000, 999999999)}-{random.randint(100000000, 999999999)}-{random.randint(100000000, 999999999)}-1001",
|
||||
"process.pid": random.randint(100, 1000),
|
||||
"process.name": "vssadmin.exe",
|
||||
"process.command_line": "vssadmin.exe delete shadows /all /quiet",
|
||||
"event.action": "process_started",
|
||||
"log.level": "critical"
|
||||
"process.executable": "C:\\Windows\\System32\\vssadmin.exe",
|
||||
"process.hash.md5": uuid.uuid4().hex[:32],
|
||||
"process.hash.sha256": uuid.uuid4().hex,
|
||||
"process.parent.name": random.choice(["cmd.exe", "powershell.exe"]),
|
||||
"process.parent.pid": random.randint(100, 1000),
|
||||
"process.working_directory": "C:\\Windows\\System32",
|
||||
"event.duration": random.randint(100, 5000),
|
||||
"log.level": "critical",
|
||||
"risk_score": 100,
|
||||
"message": "Shadow Copy deletion detected - ransomware indicator"
|
||||
})
|
||||
|
||||
# 2. 批量生成文件重命名日志 (模拟加密过程)
|
||||
extensions = [".docx", ".pdf", ".jpg", ".xlsx"]
|
||||
extensions = [".docx", ".pdf", ".jpg", ".xlsx", ".ppt", ".xls"]
|
||||
for i in range(20):
|
||||
original_file = f"finance_data_{i}{random.choice(extensions)}"
|
||||
encrypted_file = f"{original_file}.encrypted"
|
||||
logs.append({
|
||||
"@timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"event.dataset": "host",
|
||||
"event.module": "endpoint",
|
||||
"event.category": "file",
|
||||
"event.type": "file_renamed",
|
||||
"event.action": "file_renamed",
|
||||
"event.outcome": "success",
|
||||
"host.name": self.target_host,
|
||||
"host.id": str(uuid.uuid4()),
|
||||
"host.os.name": "Windows",
|
||||
"user.name": self.target_user,
|
||||
"user.id": f"S-1-5-21-{random.randint(100000000, 999999999)}-{random.randint(100000000, 999999999)}-{random.randint(100000000, 999999999)}-1001",
|
||||
"file.name": original_file,
|
||||
"file.path": base_path + original_file,
|
||||
"file.target_path": base_path + encrypted_file,
|
||||
"event.action": "file_renamed",
|
||||
"process.name": self.malware_proc
|
||||
"file.size": random.randint(1024, 10485760), # 1KB to 10MB
|
||||
"file.hash.md5": uuid.uuid4().hex[:32],
|
||||
"file.hash.sha256": uuid.uuid4().hex,
|
||||
"file.extension": random.choice(extensions),
|
||||
"process.pid": self.malware_pid,
|
||||
"process.name": self.malware_proc,
|
||||
"process.executable": f"C:\\Users\\{self.target_user}\\AppData\\Roaming\\{self.malware_proc}",
|
||||
"process.hash.md5": self.malware_hash[:32],
|
||||
"process.hash.sha256": self.malware_hash,
|
||||
"process.parent.name": "explorer.exe",
|
||||
"process.parent.pid": random.randint(100, 1000),
|
||||
"log.level": "warning",
|
||||
"risk_score": 95,
|
||||
"message": f"File encrypted by {self.malware_proc}: {original_file}"
|
||||
})
|
||||
|
||||
# 3. 留下勒索说明文件
|
||||
logs.append({
|
||||
"@timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"event.dataset": "host",
|
||||
"host.name": self.target_host,
|
||||
"file.path": base_path + "README_TO_DECRYPT.txt",
|
||||
"event.module": "endpoint",
|
||||
"event.category": "file",
|
||||
"event.type": "file_created",
|
||||
"event.action": "file_created",
|
||||
"log.level": "warning"
|
||||
"event.outcome": "success",
|
||||
"host.name": self.target_host,
|
||||
"host.id": str(uuid.uuid4()),
|
||||
"host.os.name": "Windows",
|
||||
"user.name": self.target_user,
|
||||
"user.id": f"S-1-5-21-{random.randint(100000000, 999999999)}-{random.randint(100000000, 999999999)}-{random.randint(100000000, 999999999)}-1001",
|
||||
"file.name": "README_TO_DECRYPT.txt",
|
||||
"file.path": base_path + "README_TO_DECRYPT.txt",
|
||||
"file.size": random.randint(512, 2048),
|
||||
"file.hash.md5": uuid.uuid4().hex[:32],
|
||||
"file.hash.sha256": uuid.uuid4().hex,
|
||||
"file.content": "Your files have been encrypted. Contact us for decryption key.",
|
||||
"process.pid": self.malware_pid,
|
||||
"process.name": self.malware_proc,
|
||||
"process.executable": f"C:\\Users\\{self.target_user}\\AppData\\Roaming\\{self.malware_proc}",
|
||||
"process.hash.md5": self.malware_hash[:32],
|
||||
"process.hash.sha256": self.malware_hash,
|
||||
"process.parent.name": "explorer.exe",
|
||||
"process.parent.pid": random.randint(100, 1000),
|
||||
"event.duration": random.randint(100, 5000),
|
||||
"log.level": "critical",
|
||||
"risk_score": 100,
|
||||
"message": "Ransomware ransom note created"
|
||||
})
|
||||
return logs
|
||||
|
||||
@@ -119,8 +286,12 @@ class CloudPrivilegeEscalationScenario(Scenario):
|
||||
self.target_account = random.choice(settings.AWS_ACCOUNTS)
|
||||
self.region = random.choice(settings.REGIONS)
|
||||
self.malicious_new_user = "hacker_backdoor_user"
|
||||
import uuid
|
||||
self.request_id_base = str(uuid.uuid4())
|
||||
|
||||
def get_logs(self) -> list:
|
||||
import uuid
|
||||
import json
|
||||
logs = []
|
||||
attacker_ip = "1.2.3.4" # 模拟外部攻击 IP
|
||||
|
||||
@@ -128,39 +299,142 @@ class CloudPrivilegeEscalationScenario(Scenario):
|
||||
logs.append({
|
||||
"@timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"event.dataset": "aws.cloudtrail",
|
||||
"cloud.provider": "aws",
|
||||
"cloud.account.id": self.target_account,
|
||||
"user.name": self.attacker_user,
|
||||
"event.module": "cloudtrail",
|
||||
"event.action": "ListPolicies",
|
||||
"event.category": "iam",
|
||||
"event.type": "api_call",
|
||||
"event.outcome": "success",
|
||||
"event.duration": random.randint(100, 500),
|
||||
"event.risk_score": 30,
|
||||
"cloud.provider": "aws",
|
||||
"cloud.service.name": "iam",
|
||||
"cloud.region": self.region,
|
||||
"cloud.account.id": self.target_account,
|
||||
"cloud.account.name": f"prod-account",
|
||||
"user.name": self.attacker_user,
|
||||
"user.id": f"AIDAI{uuid.uuid4().hex[:16].upper()}",
|
||||
"user.type": "IAMUser",
|
||||
"user.access_key_id": f"AKIA{uuid.uuid4().hex[:16].upper()}",
|
||||
"source.ip": attacker_ip,
|
||||
"event.outcome": "success"
|
||||
"source.address": attacker_ip,
|
||||
"source.geo.country_name": "China",
|
||||
"source.geo.country_iso_code": "CN",
|
||||
"http.request.method": "POST",
|
||||
"http.response.status_code": 200,
|
||||
"http.request.body.content": json.dumps({"Action": "ListPolicies"}),
|
||||
"user_agent": "aws-cli/2.13.0 Python/3.11.0",
|
||||
"request_id": str(uuid.uuid4()),
|
||||
"event_id": str(uuid.uuid4()),
|
||||
"aws_service": "cloudtrail",
|
||||
"aws_request_id": str(uuid.uuid4()),
|
||||
"recipient_account_id": self.target_account,
|
||||
"response_elements": {"policies": []},
|
||||
"error_code": None,
|
||||
"error_message": None,
|
||||
"read_only": True,
|
||||
"log.level": "warning",
|
||||
"message": "IAM ListPolicies API call detected"
|
||||
})
|
||||
|
||||
# 2. 创建新用户 (持久化行为)
|
||||
logs.append({
|
||||
"@timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"event.dataset": "aws.cloudtrail",
|
||||
"cloud.provider": "aws",
|
||||
"cloud.account.id": self.target_account,
|
||||
"user.name": self.attacker_user,
|
||||
"event.module": "cloudtrail",
|
||||
"event.action": "CreateUser",
|
||||
"request_parameters": f"{{\"userName\": \"{self.malicious_new_user}\"}}",
|
||||
"event.category": "iam",
|
||||
"event.type": "api_call",
|
||||
"event.outcome": "success",
|
||||
"event.duration": random.randint(200, 800),
|
||||
"event.risk_score": 75,
|
||||
"cloud.provider": "aws",
|
||||
"cloud.service.name": "iam",
|
||||
"cloud.region": self.region,
|
||||
"cloud.account.id": self.target_account,
|
||||
"cloud.account.name": f"prod-account",
|
||||
"user.name": self.attacker_user,
|
||||
"user.id": f"AIDAI{uuid.uuid4().hex[:16].upper()}",
|
||||
"user.type": "IAMUser",
|
||||
"user.access_key_id": f"AKIA{uuid.uuid4().hex[:16].upper()}",
|
||||
"source.ip": attacker_ip,
|
||||
"event.outcome": "success"
|
||||
"source.address": attacker_ip,
|
||||
"source.geo.country_name": "China",
|
||||
"source.geo.country_iso_code": "CN",
|
||||
"http.request.method": "POST",
|
||||
"http.response.status_code": 200,
|
||||
"http.request.body.content": json.dumps({"Action": "CreateUser", "UserName": self.malicious_new_user}),
|
||||
"user_agent": "aws-cli/2.13.0 Python/3.11.0",
|
||||
"request_id": str(uuid.uuid4()),
|
||||
"event_id": str(uuid.uuid4()),
|
||||
"aws_service": "cloudtrail",
|
||||
"aws_request_id": str(uuid.uuid4()),
|
||||
"recipient_account_id": self.target_account,
|
||||
"request_parameters": {
|
||||
"userName": self.malicious_new_user
|
||||
},
|
||||
"response_elements": {
|
||||
"user": {
|
||||
"path": "/",
|
||||
"userName": self.malicious_new_user,
|
||||
"userId": f"AIDAI{uuid.uuid4().hex[:16].upper()}",
|
||||
"arn": f"arn:aws:iam::{self.target_account}:user/{self.malicious_new_user}",
|
||||
"createDate": datetime.utcnow().isoformat()
|
||||
}
|
||||
},
|
||||
"error_code": None,
|
||||
"error_message": None,
|
||||
"read_only": False,
|
||||
"log.level": "critical",
|
||||
"message": f"New IAM user created: {self.malicious_new_user}"
|
||||
})
|
||||
|
||||
# 3. 附加管理员策略 (提权行为)
|
||||
logs.append({
|
||||
"@timestamp": datetime.utcnow().isoformat() + "Z",
|
||||
"event.dataset": "aws.cloudtrail",
|
||||
"cloud.provider": "aws",
|
||||
"cloud.account.id": self.target_account,
|
||||
"user.name": self.attacker_user,
|
||||
"event.module": "cloudtrail",
|
||||
"event.action": "AttachUserPolicy",
|
||||
"request_parameters": f"{{\"userName\": \"{self.malicious_new_user}\", \"policyArn\": \"arn:aws:iam::aws:policy/AdministratorAccess\"}}",
|
||||
"source.ip": attacker_ip,
|
||||
"event.category": "iam",
|
||||
"event.type": "api_call",
|
||||
"event.outcome": "success",
|
||||
"log.level": "critical"
|
||||
"event.duration": random.randint(150, 600),
|
||||
"event.risk_score": 100,
|
||||
"cloud.provider": "aws",
|
||||
"cloud.service.name": "iam",
|
||||
"cloud.region": self.region,
|
||||
"cloud.account.id": self.target_account,
|
||||
"cloud.account.name": f"prod-account",
|
||||
"user.name": self.attacker_user,
|
||||
"user.id": f"AIDAI{uuid.uuid4().hex[:16].upper()}",
|
||||
"user.type": "IAMUser",
|
||||
"user.access_key_id": f"AKIA{uuid.uuid4().hex[:16].upper()}",
|
||||
"source.ip": attacker_ip,
|
||||
"source.address": attacker_ip,
|
||||
"source.geo.country_name": "China",
|
||||
"source.geo.country_iso_code": "CN",
|
||||
"http.request.method": "POST",
|
||||
"http.response.status_code": 200,
|
||||
"http.request.body.content": json.dumps({
|
||||
"Action": "AttachUserPolicy",
|
||||
"UserName": self.malicious_new_user,
|
||||
"PolicyArn": "arn:aws:iam::aws:policy/AdministratorAccess"
|
||||
}),
|
||||
"user_agent": "aws-cli/2.13.0 Python/3.11.0",
|
||||
"request_id": str(uuid.uuid4()),
|
||||
"event_id": str(uuid.uuid4()),
|
||||
"aws_service": "cloudtrail",
|
||||
"aws_request_id": str(uuid.uuid4()),
|
||||
"recipient_account_id": self.target_account,
|
||||
"request_parameters": {
|
||||
"userName": self.malicious_new_user,
|
||||
"policyArn": "arn:aws:iam::aws:policy/AdministratorAccess"
|
||||
},
|
||||
"response_elements": None,
|
||||
"error_code": None,
|
||||
"error_message": None,
|
||||
"read_only": False,
|
||||
"log.level": "critical",
|
||||
"message": f"Administrator policy attached to user {self.malicious_new_user} - PRIVILEGE ESCALATION DETECTED"
|
||||
})
|
||||
|
||||
return logs
|
||||
|
||||
@@ -1210,6 +1210,257 @@ alert_cloud_config_change = AlertModel(
|
||||
artifacts=[artifact_aws_role, artifact_cloudtrail_event]
|
||||
)
|
||||
|
||||
# === Artifacts and Alerts from SIEM Scenarios ===
|
||||
# Artifact for Brute Force Attack
|
||||
artifact_brute_force_ip = ArtifactModel(
|
||||
name="45.95.11.22",
|
||||
type=ArtifactType.IP_ADDRESS,
|
||||
role=ArtifactRole.ACTOR,
|
||||
value="45.95.11.22",
|
||||
reputation_provider="AbuseIPDB",
|
||||
reputation_score=ArtifactReputationScore.MALICIOUS,
|
||||
enrichments=[enrichment_greynoise_scanner, enrichment_geoip_russia]
|
||||
)
|
||||
|
||||
artifact_target_user_brute = ArtifactModel(
|
||||
name="admin@example.com",
|
||||
type=ArtifactType.EMAIL_ADDRESS,
|
||||
role=ArtifactRole.TARGET,
|
||||
value="admin@example.com",
|
||||
owner="System"
|
||||
)
|
||||
|
||||
artifact_target_host_brute = ArtifactModel(
|
||||
name="srv-web-prod-01",
|
||||
type=ArtifactType.HOSTNAME,
|
||||
role=ArtifactRole.TARGET,
|
||||
value="srv-web-prod-01",
|
||||
owner="Operations"
|
||||
)
|
||||
|
||||
# Alert for Brute Force Attack
|
||||
alert_brute_force_siem = AlertModel(
|
||||
title="Brute Force Attack: Multiple Failed Login Attempts Followed by Success",
|
||||
severity=Severity.CRITICAL,
|
||||
impact=ImpactLevel.HIGH,
|
||||
action=AlertAction.OBSERVED,
|
||||
disposition=Disposition.ALERT,
|
||||
confidence=Confidence.HIGH,
|
||||
uid="ALERT-BRUTE-FORCE-001",
|
||||
labels=["brute-force", "authentication", "ssh", "credential-attack"],
|
||||
desc="External IP 45.95.11.22 (China) made 5-10 failed authentication attempts to user 'admin' on srv-web-prod-01, followed by a successful login. Pattern suggests brute force attack.",
|
||||
first_seen_time=past_1h,
|
||||
last_seen_time=past_1h,
|
||||
rule_id="AUTH-RULE-BF-001",
|
||||
rule_name="Brute Force Attack Detection",
|
||||
correlation_uid="CORR-BRUTE-FORCE-001",
|
||||
count=6,
|
||||
src_url="https://siem.example.com/alerts/ALERT-BRUTE-FORCE-001",
|
||||
source_uid="siem-bf-001",
|
||||
data_sources=["SSH Logs", "Syslog", "SIEM"],
|
||||
analytic_name="Brute Force Detection Engine",
|
||||
analytic_type=AlertAnalyticType.BEHAVIORAL,
|
||||
analytic_state=AlertAnalyticState.ACTIVE,
|
||||
analytic_desc="Detects multiple failed login attempts from same source IP followed by success.",
|
||||
tactic="Credential Access",
|
||||
technique="T1110.001",
|
||||
sub_technique="",
|
||||
mitigation="Account Lockout Policy, Rate Limiting, MFA",
|
||||
product_category=ProductCategory.SIEM,
|
||||
product_vendor="Elasticsearch",
|
||||
product_name="ELK Stack",
|
||||
product_feature="Authentication-Monitoring",
|
||||
policy_name="Access Control Policy",
|
||||
policy_type=AlertPolicyType.ACCESS_CONTROL_POLICY,
|
||||
policy_desc="Detect and prevent brute force attacks.",
|
||||
risk_level=AlertRiskLevel.CRITICAL,
|
||||
risk_details="Successful compromise of admin account could lead to full system control. Account from high-risk geographic location (China).",
|
||||
status=AlertStatus.NEW,
|
||||
status_detail="Immediate investigation required. Account may be compromised.",
|
||||
remediation="1. Immediately force password change for admin account. 2. Review all commands executed by admin since last_seen_time. 3. Block source IP 45.95.11.22 at firewall. 4. Enable MFA for admin account. 5. Review login history for other successful attempts from this IP.",
|
||||
comment="Risk Score: 85/100. Successful login after multiple failures is strong indicator of compromise.",
|
||||
unmapped="",
|
||||
raw_data=json.dumps(
|
||||
{"failed_attempts": 7, "source_ip": "45.95.11.22", "source_country": "CN", "target_user": "admin", "target_host": "srv-web-prod-01", "protocol": "ssh",
|
||||
"port": 22}),
|
||||
summary_ai="Brute force attack successfully compromised admin account on production web server. Attacker origin: China. Immediate containment action required.",
|
||||
case=None,
|
||||
enrichments=[enrichment_greynoise_scanner, enrichment_geoip_russia],
|
||||
artifacts=[artifact_brute_force_ip, artifact_target_user_brute, artifact_target_host_brute]
|
||||
)
|
||||
|
||||
# Artifacts for SQL Injection Attack
|
||||
artifact_malicious_url_sqli = ArtifactModel(
|
||||
name="https://web-3.example.com/api/user?id=1' OR '1'='1",
|
||||
type=ArtifactType.URL_STRING,
|
||||
role=ArtifactRole.RELATED,
|
||||
value="https://web-3.example.com/api/user?id=1' OR '1'='1",
|
||||
reputation_score=ArtifactReputationScore.MALICIOUS
|
||||
)
|
||||
|
||||
artifact_sqlmap_tool = ArtifactModel(
|
||||
name="sqlmap/1.5.2",
|
||||
type=ArtifactType.URL_STRING,
|
||||
role=ArtifactRole.ACTOR,
|
||||
value="sqlmap/1.5.2 (SQL Injection Scanner)"
|
||||
)
|
||||
|
||||
artifact_waf_server = ArtifactModel(
|
||||
name="web-3.example.com",
|
||||
type=ArtifactType.HOSTNAME,
|
||||
role=ArtifactRole.TARGET,
|
||||
value="web-3.example.com",
|
||||
owner="Web Operations"
|
||||
)
|
||||
|
||||
# Alert for SQL Injection Attack
|
||||
alert_sql_injection_siem = AlertModel(
|
||||
title="SQL Injection Attack Attempt Detected and Blocked by WAF",
|
||||
severity=Severity.HIGH,
|
||||
impact=ImpactLevel.MEDIUM,
|
||||
action=AlertAction.DENIED,
|
||||
disposition=Disposition.BLOCKED,
|
||||
confidence=Confidence.HIGH,
|
||||
uid="ALERT-SQL-INJ-001",
|
||||
labels=["sql-injection", "web-attack", "waf", "owasp-injection"],
|
||||
desc="Web Application Firewall detected and blocked SQL injection attack from external IP (Russia). Attacker used sqlmap scanner with multiple SQL injection payloads.",
|
||||
first_seen_time=past_30m,
|
||||
last_seen_time=past_30m,
|
||||
rule_id="WAF-RULE-SQLI-001",
|
||||
rule_name="SQL Injection Detection Rule",
|
||||
correlation_uid="CORR-SQL-INJ-001",
|
||||
count=1,
|
||||
src_url="https://waf.example.com/alerts/ALERT-SQL-INJ-001",
|
||||
source_uid="waf-sqli-001",
|
||||
data_sources=["WAF", "HTTP Traffic Analysis"],
|
||||
analytic_name="SQL Injection Detector",
|
||||
analytic_type=AlertAnalyticType.RULE,
|
||||
analytic_state=AlertAnalyticState.ACTIVE,
|
||||
analytic_desc="Detects SQL injection patterns in HTTP requests.",
|
||||
tactic="Exploitation",
|
||||
technique="T1190",
|
||||
sub_technique="",
|
||||
mitigation="WAF Rules, Input Validation, Parameterized Queries",
|
||||
product_category=ProductCategory.WAF,
|
||||
product_vendor="Palo Alto Networks",
|
||||
product_name="Advanced URL Filtering",
|
||||
product_feature="SQL-Injection-Detection",
|
||||
policy_name="Web Security Policy",
|
||||
policy_type=AlertPolicyType.SERVICE_CONTROL_POLICY,
|
||||
policy_desc="Block SQL injection attacks at the WAF.",
|
||||
risk_level=AlertRiskLevel.HIGH,
|
||||
risk_details="SQL injection could allow attacker to read/modify database contents, affecting all application data.",
|
||||
status=AlertStatus.NEW,
|
||||
status_detail="Attack was successfully blocked. No damage detected. Source IP monitoring enabled.",
|
||||
remediation="1. Add source IP to block list. 2. Review WAF logs for other attack attempts. 3. Audit application code for SQL injection vulnerabilities. 4. Implement parameterized queries in application. 5. Consider implementing request rate limiting.",
|
||||
comment="Attack method: sqlmap automated SQL injection scanner. Multiple injection vectors attempted including boolean blind, time-based, and UNION-based.",
|
||||
unmapped="",
|
||||
raw_data=json.dumps({"payload": "id=1' OR '1'='1", "waf_rule_id": "WAF-12345", "blocked_count": 1, "http_status": 403, "user_agent": "sqlmap/1.5.2"}),
|
||||
summary_ai="SQL injection attack from Russia was detected and blocked by WAF. Attacker used automated sqlmap tool. No database compromise detected.",
|
||||
case=None,
|
||||
enrichments=[enrichment_urlhaus_malware],
|
||||
artifacts=[artifact_malicious_url_sqli, artifact_sqlmap_tool, artifact_waf_server]
|
||||
)
|
||||
|
||||
# Artifacts for Ransomware Attack
|
||||
artifact_vssadmin_process = ArtifactModel(
|
||||
name="vssadmin.exe",
|
||||
type=ArtifactType.PROCESS_NAME,
|
||||
role=ArtifactRole.ACTOR,
|
||||
value="vssadmin.exe delete shadows /all /quiet"
|
||||
)
|
||||
|
||||
artifact_decryptor_malware = ArtifactModel(
|
||||
name="decryptor.exe",
|
||||
type=ArtifactType.FILE_NAME,
|
||||
role=ArtifactRole.ACTOR,
|
||||
value="decryptor.exe",
|
||||
reputation_provider="VirusTotal",
|
||||
reputation_score=ArtifactReputationScore.MALICIOUS
|
||||
)
|
||||
|
||||
artifact_ransom_note_file = ArtifactModel(
|
||||
name="README_TO_DECRYPT.txt",
|
||||
type=ArtifactType.FILE_NAME,
|
||||
role=ArtifactRole.RELATED,
|
||||
value="README_TO_DECRYPT.txt"
|
||||
)
|
||||
|
||||
artifact_encrypted_files = ArtifactModel(
|
||||
name="*.encrypted",
|
||||
type=ArtifactType.FILE_NAME,
|
||||
role=ArtifactRole.RELATED,
|
||||
value="Multiple encrypted files (docx, pdf, xlsx, jpg)"
|
||||
)
|
||||
|
||||
artifact_ransomware_host = ArtifactModel(
|
||||
name="srv-db-master",
|
||||
type=ArtifactType.HOSTNAME,
|
||||
role=ArtifactRole.TARGET,
|
||||
value="srv-db-master",
|
||||
owner="Database Team"
|
||||
)
|
||||
|
||||
artifact_ransomware_user = ArtifactModel(
|
||||
name="dbadmin@example.com",
|
||||
type=ArtifactType.EMAIL_ADDRESS,
|
||||
role=ArtifactRole.TARGET,
|
||||
value="dbadmin@example.com",
|
||||
owner="Database Team"
|
||||
)
|
||||
|
||||
# Alert for Ransomware Attack
|
||||
alert_ransomware_siem = AlertModel(
|
||||
title="Ransomware Execution Detected: Shadow Copy Deletion, File Encryption, Ransom Note",
|
||||
severity=Severity.CRITICAL,
|
||||
impact=ImpactLevel.CRITICAL,
|
||||
action=AlertAction.OBSERVED,
|
||||
disposition=Disposition.ALERT,
|
||||
confidence=Confidence.CRITICAL,
|
||||
uid="ALERT-RANSOMWARE-001",
|
||||
labels=["ransomware", "file-encryption", "shadow-copy-deletion", "critical"],
|
||||
desc="Multiple critical indicators of ransomware detected on srv-db-master: 1) vssadmin.exe deleted volume shadow copies 2) 20 files renamed to .encrypted extension 3) README_TO_DECRYPT.txt ransom note created. Immediate isolation required.",
|
||||
first_seen_time=past_2h,
|
||||
last_seen_time=past_2h,
|
||||
rule_id="EDR-RULE-RANSOMWARE-001",
|
||||
rule_name="Ransomware Multi-Indicator Detection",
|
||||
correlation_uid="CORR-RANSOMWARE-ACTIVE-001",
|
||||
count=22,
|
||||
src_url="https://edr.example.com/alerts/ALERT-RANSOMWARE-001",
|
||||
source_uid="edr-ransomware-001",
|
||||
data_sources=["EDR", "Process Monitoring", "File System Monitoring"],
|
||||
analytic_name="Ransomware Behavioral Detector",
|
||||
analytic_type=AlertAnalyticType.BEHAVIORAL,
|
||||
analytic_state=AlertAnalyticState.ACTIVE,
|
||||
analytic_desc="Detects three-stage ransomware attack: shadow copy deletion + file encryption + ransom note.",
|
||||
tactic="Impact",
|
||||
technique="T1486",
|
||||
sub_technique="",
|
||||
mitigation="EDR, Immutable Backups, Air-Gapped Recovery",
|
||||
product_category=ProductCategory.EDR,
|
||||
product_vendor="CrowdStrike",
|
||||
product_name="Falcon",
|
||||
product_feature="Ransomware-Prevention",
|
||||
policy_name="Ransomware Prevention Policy",
|
||||
policy_type=AlertPolicyType.SERVICE_CONTROL_POLICY,
|
||||
policy_desc="Immediate blocking of all ransomware indicators.",
|
||||
risk_level=AlertRiskLevel.CRITICAL,
|
||||
risk_details="Database server encryption would impact all database users. Potential data loss and extended downtime. Estimated impact: $100K+ per hour of downtime.",
|
||||
status=AlertStatus.NEW,
|
||||
status_detail="CRITICAL: Immediate action required. Automatic host isolation has been triggered.",
|
||||
remediation="IMMEDIATE ACTIONS: 1. Verify host isolation is complete (confirmed). 2. Do NOT power off infected host (may prevent recovery). 3. Disconnect all network cables. 4. Capture forensic image of storage drives. 5. Begin restore from clean backup prior to incident date. 6. Notify business stakeholders of estimated recovery time. INVESTIGATION: 1. Analyze attack entry point (email, SMB, RDP, etc.). 2. Check for lateral movement to other hosts. 3. Review backup integrity to ensure clean restore available. 4. Implement EDR hunting query to find similar patterns.",
|
||||
comment="This is a confirmed active ransomware attack. CRITICAL priority. Finance and Executive team notified. Legal/Compliance briefing initiated. Do NOT attempt to contact attacker or pay ransom without consulting law enforcement.",
|
||||
unmapped="",
|
||||
raw_data=json.dumps(
|
||||
{"shadow_copy_deleted": True, "encrypted_file_count": 20, "ransom_note_created": True, "process_execution": "vssadmin.exe delete shadows /all /quiet",
|
||||
"malware_hash": "5d41402abc4b2a76b9719d911017c592", "host": "srv-db-master", "user": "dbadmin", "time_elapsed": "120 seconds"}),
|
||||
summary_ai="CRITICAL: Active ransomware execution detected on production database server. All three indicators of ransomware present: shadow copy deletion, bulk file encryption, ransom note. Estimated 20 files already encrypted. Immediate isolation and recovery activation required.",
|
||||
case=None,
|
||||
enrichments=[enrichment_carbonblack_execution],
|
||||
artifacts=[artifact_vssadmin_process, artifact_decryptor_malware, artifact_ransom_note_file, artifact_encrypted_files, artifact_ransomware_host,
|
||||
artifact_ransomware_user]
|
||||
)
|
||||
|
||||
# === Case 1: Phishing Email Attack (100% Coverage) ===
|
||||
case1_phishing = CaseModel(
|
||||
title="Phishing Campaign Detected - 'Urgent Payroll Update'",
|
||||
@@ -1493,6 +1744,93 @@ case10_cloud_misconfig = CaseModel(
|
||||
alerts=[alert_cloud_config_change]
|
||||
)
|
||||
|
||||
# === Case 11: Brute Force SSH Attack (From SIEM Scenario) ===
|
||||
case11_brute_force = CaseModel(
|
||||
title="Brute Force Attack: Multiple Failed Login Attempts Followed by Successful Compromise",
|
||||
severity=Severity.CRITICAL,
|
||||
impact=ImpactLevel.HIGH,
|
||||
priority=CasePriority.CRITICAL,
|
||||
confidence=Confidence.HIGH,
|
||||
description="External attacker from China (IP: 45.95.11.22) conducted a brute force attack against production web server admin account. After 7 failed attempts, attacker successfully compromised the admin account.",
|
||||
category=ProductCategory.SIEM,
|
||||
tags=["brute-force", "ssh", "credential-attack", "account-compromise", "china", "high-risk"],
|
||||
status=CaseStatus.IN_PROGRESS,
|
||||
acknowledged_time=past_1h,
|
||||
comment="L2 Analyst: Admin account is confirmed compromised. Immediate password reset, session termination, and command audit in progress. Source IP blocked at firewall.",
|
||||
closed_time=None,
|
||||
verdict=None,
|
||||
summary="",
|
||||
correlation_uid="CORR-BRUTE-FORCE-001",
|
||||
workbook="### Brute Force Attack Response\n1. Confirm account compromise (`done`)\n2. Reset admin password (`done`)\n3. Terminate all admin sessions (`done`)\n4. Review command history (`in-progress`)\n5. Check for lateral movement (`in-progress`)\n6. Block source IP globally (`done`)\n7. Enable MFA for admin (`pending`)",
|
||||
analysis_rationale_ai="Attack pattern clearly indicates brute force: consistent failed auth attempts from single IP followed by immediate success. Source IP reputation is MALICIOUS. Geographic origin (China) is high-risk for admin account.",
|
||||
recommended_actions_ai="- IMMEDIATE: Force password reset for admin account. 2. Review all commands executed by admin since last_seen_time. 3. Block source IP 45.95.11.22 at firewall. 4. Enable MFA for admin account. 5. Review login history for other successful attempts from this IP.",
|
||||
attack_stage_ai="Credential Access",
|
||||
severity_ai=Severity.CRITICAL,
|
||||
confidence_ai=Confidence.HIGH,
|
||||
threat_hunting_report_ai="Query: Show all failed login attempts from external IPs in last 7 days | Show all successful logins from 45.95.11.22 in last 7 days | Check for similar brute force patterns from other IP ranges",
|
||||
tickets=[ticket_pagerduty],
|
||||
enrichments=[enrichment_greynoise_scanner, enrichment_geoip_russia],
|
||||
alerts=[alert_brute_force_siem]
|
||||
)
|
||||
|
||||
# === Case 12: SQL Injection Web Attack (From SIEM Scenario) ===
|
||||
case12_sql_injection = CaseModel(
|
||||
title="SQL Injection Attack: Automated Scanner Detected and Blocked by WAF",
|
||||
severity=Severity.HIGH,
|
||||
impact=ImpactLevel.MEDIUM,
|
||||
priority=CasePriority.HIGH,
|
||||
confidence=Confidence.HIGH,
|
||||
description="Web Application Firewall detected SQL injection attack from Russia using automated sqlmap tool. Attacker attempted multiple SQL injection vectors against the user API endpoint. All attacks were successfully blocked.",
|
||||
category=ProductCategory.WAF,
|
||||
tags=["sql-injection", "web-attack", "waf", "automated-scanner", "owasp-top-10"],
|
||||
status=CaseStatus.RESOLVED,
|
||||
acknowledged_time=past_30m,
|
||||
comment="L3 Security Engineer: Attack was fully contained by WAF rules. No database compromise detected. Recommended code review to identify and fix potential SQL injection vulnerabilities.",
|
||||
closed_time=now,
|
||||
verdict=CaseVerdict.TRUE_POSITIVE,
|
||||
summary="SQL injection attack was detected and blocked by WAF. No application or database compromise occurred. Attacker IP has been blocked and monitoring is ongoing.",
|
||||
correlation_uid="CORR-SQL-INJ-001",
|
||||
workbook="### SQL Injection Response\n1. Block attacker IP (`done`)\n2. Review WAF logs for patterns (`done`)\n3. Audit application code for injection vulnerabilities (`done`)\n4. Deploy parameterized query fixes (`pending`)\n5. Conduct SAST scan of codebase (`pending`)",
|
||||
analysis_rationale_ai="SQL injection attempt with multiple payloads (boolean blind, time-based, UNION-based) indicates automated tool usage (sqlmap). However, WAF successfully blocked all attempts. No evidence of database access or compromise.",
|
||||
recommended_actions_ai="- Update WAF rules with new detection patterns (COMPLETED)\n- Review application code for SQL injection vulnerabilities\n- Implement parameterized queries in API endpoint /api/user\n- Add request rate limiting\n- Conduct security code review of all database interactions\n- Plan penetration test after fixes are deployed",
|
||||
attack_stage_ai="Exploitation",
|
||||
severity_ai=Severity.HIGH,
|
||||
confidence_ai=Confidence.HIGH,
|
||||
threat_hunting_report_ai="",
|
||||
tickets=[ticket_jira],
|
||||
enrichments=[enrichment_urlhaus_malware],
|
||||
alerts=[alert_sql_injection_siem]
|
||||
)
|
||||
|
||||
# === Case 13: Active Ransomware Encryption (From SIEM Scenario) ===
|
||||
case13_ransomware = CaseModel(
|
||||
title="CRITICAL: Active Ransomware Execution on Production Database Server",
|
||||
severity=Severity.CRITICAL,
|
||||
impact=ImpactLevel.CRITICAL,
|
||||
priority=CasePriority.CRITICAL,
|
||||
confidence=Confidence.CRITICAL,
|
||||
description="CRITICAL INCIDENT: Ransomware malware detected executing on production database server 'srv-db-master' with three confirmed attack indicators: 1) Shadow Copy deletion via vssadmin.exe 2) Bulk file encryption (20+ files renamed to .encrypted) 3) Ransom note creation. Immediate response required.",
|
||||
category=ProductCategory.EDR,
|
||||
tags=["ransomware", "file-encryption", "critical-incident", "active-threat", "recovery-required"],
|
||||
status=CaseStatus.IN_PROGRESS,
|
||||
acknowledged_time=past_2h,
|
||||
comment="INCIDENT COMMANDER: All-hands-on-deck response initiated. Host isolated. Crisis management team assembled. Legal/Law Enforcement notifications pending. Do NOT negotiate with attacker. Do NOT shutdown infected system. Prepare for potential multi-day recovery.",
|
||||
closed_time=None,
|
||||
verdict=None,
|
||||
summary="",
|
||||
correlation_uid="CORR-RANSOMWARE-ACTIVE-001",
|
||||
workbook="### CRITICAL: Ransomware Response Playbook\n**IMMEDIATE ACTIONS (0-15 min):**\n- [x] Isolate infected host from network\n- [x] Preserve forensic evidence (disk/memory dumps initiated)\n- [x] Notify incident response team\n- [x] Activate disaster recovery plan\n\n**SHORT TERM (15 min - 2 hours):**\n- [x] Assess backup integrity\n- [ ] Identify attack vector (email, RDP, SMB, supply chain)\n- [ ] Hunt for lateral movement indicators\n- [ ] Review EDR logs for persistence mechanisms\n- [ ] Activate clean backup restoration\n\n**MEDIUM TERM (2-24 hours):**\n- [ ] Complete system restore from clean backup\n- [ ] Verify restored system integrity\n- [ ] Analyze forensic artifacts\n- [ ] Identify and patch vulnerability used for initial compromise\n- [ ] Review all privileged account activity\n\n**LONG TERM:**\n- [ ] Incident report and lessons learned\n- [ ] Security control improvements\n- [ ] Backup and recovery procedures review",
|
||||
analysis_rationale_ai="Three concurrent indicators confirm active ransomware: (1) vssadmin.exe shadow copy deletion removes backup recovery options, (2) Bulk file encryption of business-critical files with .encrypted extension, (3) Ransom note creation indicates attacker demand. This is NOT a false positive. This is a confirmed active attack requiring full incident response activation.",
|
||||
recommended_actions_ai="CRITICAL ACTIONS - EXECUTE IMMEDIATELY:\n1. ✓ NETWORK ISOLATION: Disconnect infected host from all networks (COMPLETED)\n2. ✓ PRESERVE EVIDENCE: Initiate forensic disk/memory capture (COMPLETED)\n3. ✓ DO NOT SHUTDOWN: Risk unrecoverable data if malware not fully executed\n4. BACKUP ASSESSMENT: Verify clean backup exists before infection date\n5. RECOVERY ACTIVATION: Prepare clean backup for immediate restoration\n6. ATTACK VECTOR IDENTIFICATION: Determine compromise method (email, RDP, SMB, web shell)\n7. LATERAL MOVEMENT CHECK: Hunt for infection spread to other systems\n8. PERSISTENCE SEARCH: Look for scheduled tasks, registry modifications, services\n9. STAKEHOLDER NOTIFICATION: Inform affected business units, customers, regulators\n10. LAW ENFORCEMENT: Contact FBI/local authorities for APT attribution and coordination",
|
||||
attack_stage_ai="Impact / Ransomware Execution",
|
||||
severity_ai=Severity.CRITICAL,
|
||||
confidence_ai=Confidence.CRITICAL,
|
||||
threat_hunting_report_ai="URGENT HUNTS:\n- Find all processes executed by user 'dbadmin' in last 2 hours\n- Identify all processes accessing files with .encrypted extension\n- Check for vssadmin.exe execution on all hosts (indicates lateral movement)\n- Review all RDP/SMB connections to this host in last 24 hours\n- Search for similar encrypted file extensions across file shares\n- Check for ransom notes on network shares (indicates spread)\n- Monitor command/control traffic patterns from isolated host\n- Identify initial entry point: email attachment, RDP brute force, SMB exploit, web shell",
|
||||
tickets=[ticket_servicenow, ticket_pagerduty],
|
||||
enrichments=[enrichment_carbonblack_execution],
|
||||
alerts=[alert_ransomware_siem]
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import os
|
||||
import django
|
||||
@@ -1510,6 +1848,9 @@ if __name__ == "__main__":
|
||||
case7_data_exfil,
|
||||
case8_email_campaign,
|
||||
case9_priv_esc,
|
||||
case10_cloud_misconfig
|
||||
case10_cloud_misconfig,
|
||||
case11_brute_force,
|
||||
case12_sql_injection,
|
||||
case13_ransomware
|
||||
]:
|
||||
Case.update_or_create(case)
|
||||
|
||||
+25
-6
@@ -1,7 +1,16 @@
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from models import AdaptiveQueryInput, SchemaExplorerInput
|
||||
from tools import SIEMToolKit
|
||||
|
||||
|
||||
def get_recent_time_range(minutes=5):
|
||||
"""获取最近N分钟的时间范围,返回ISO 8601格式的字符串"""
|
||||
end_time = datetime.utcnow()
|
||||
start_time = end_time - timedelta(minutes=minutes)
|
||||
return start_time.strftime("%Y-%m-%dT%H:%M:%SZ"), end_time.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
|
||||
def main():
|
||||
toolkit = SIEMToolKit()
|
||||
all = toolkit.explore_schema()
|
||||
@@ -9,12 +18,18 @@ def main():
|
||||
all = toolkit.explore_schema(SchemaExplorerInput(target_index="siem-aws-cloudtrail"))
|
||||
print(all)
|
||||
|
||||
# 获取最近5分钟的时间范围
|
||||
time_range_start, time_range_end = get_recent_time_range(5)
|
||||
|
||||
query_input = AdaptiveQueryInput(
|
||||
index_name="siem-aws-cloudtrail",
|
||||
time_field="@timestamp", # 这里可以改成任意 Date 类型字段,如 "event.created"
|
||||
time_range_start="2026-02-05T02:41:00Z",
|
||||
time_range_end="2026-02-05T02:41:10Z",
|
||||
filters={"event.outcome": "success", "source.ip": "45.33.22.11", "user.name": "github-actions-role"}
|
||||
time_range_start=time_range_start,
|
||||
time_range_end=time_range_end,
|
||||
filters={
|
||||
"event.outcome": "success",
|
||||
"user.name": "user_002"
|
||||
}
|
||||
)
|
||||
|
||||
result = toolkit.execute_adaptive_query(query_input)
|
||||
@@ -28,9 +43,13 @@ def main():
|
||||
|
||||
query_input = AdaptiveQueryInput(
|
||||
index_name="siem-network-traffic",
|
||||
time_range_start="2026-02-05T02:40:00Z",
|
||||
time_range_end="2026-02-05T02:45:10Z",
|
||||
filters={"event.dataset": "network", "destination.ip": "104.21.11.22"}
|
||||
time_range_start=time_range_start,
|
||||
time_range_end=time_range_end,
|
||||
filters={
|
||||
"event.dataset": "network",
|
||||
"destination.ip": "104.21.11.22",
|
||||
"event.action": "deny"
|
||||
}
|
||||
)
|
||||
|
||||
result = toolkit.execute_adaptive_query(query_input)
|
||||
|
||||
+104
-6
@@ -35,30 +35,128 @@ def get_backend_type(index_name: str) -> str:
|
||||
|
||||
# --- Static Registry Data ---
|
||||
STATIC_SCHEMA_REGISTRY: Dict[str, IndexInfo] = {
|
||||
# 1. ELK Index
|
||||
# 1. AWS CloudTrail Index (ELK)
|
||||
"siem-aws-cloudtrail": IndexInfo(
|
||||
name="siem-aws-cloudtrail",
|
||||
backend="ELK",
|
||||
description="AWS CloudTrail logs via ELK.",
|
||||
fields=[
|
||||
FieldInfo(name="@timestamp", type="date", description="Event time", is_key_field=False),
|
||||
FieldInfo(name="event.dataset", type="keyword", description="Dataset (aws.cloudtrail)", is_key_field=False),
|
||||
FieldInfo(name="event.module", type="keyword", description="Module (cloudtrail)", is_key_field=False),
|
||||
FieldInfo(name="event.action", type="keyword", description="API Action", is_key_field=True),
|
||||
FieldInfo(name="event.outcome", type="keyword", description="Result", is_key_field=True),
|
||||
FieldInfo(name="source.ip", type="ip", description="Requester IP", is_key_field=True)
|
||||
FieldInfo(name="event.category", type="keyword", description="Event category (iam/cloud)", is_key_field=True),
|
||||
FieldInfo(name="event.outcome", type="keyword", description="Result (success/failure)", is_key_field=True),
|
||||
FieldInfo(name="event.duration", type="long", description="Event duration in ms", is_key_field=False),
|
||||
FieldInfo(name="event.risk_score", type="long", description="Risk score (20-100)", is_key_field=False),
|
||||
FieldInfo(name="cloud.provider", type="keyword", description="Cloud provider (aws)", is_key_field=False),
|
||||
FieldInfo(name="cloud.service.name", type="keyword", description="Service name (ec2/iam/s3/lambda/rds)", is_key_field=True),
|
||||
FieldInfo(name="cloud.region", type="keyword", description="AWS region", is_key_field=True),
|
||||
FieldInfo(name="cloud.account.id", type="keyword", description="AWS Account ID", is_key_field=True),
|
||||
FieldInfo(name="cloud.account.name", type="keyword", description="Account name", is_key_field=False),
|
||||
FieldInfo(name="user.name", type="keyword", description="IAM user name", is_key_field=True),
|
||||
FieldInfo(name="user.id", type="keyword", description="User ID (AIDAI...)", is_key_field=True),
|
||||
FieldInfo(name="user.type", type="keyword", description="User type (IAMUser/IAMRole/AssumedRole/RootUser)", is_key_field=False),
|
||||
FieldInfo(name="user.access_key_id", type="keyword", description="Access key ID (AKIA...)", is_key_field=False),
|
||||
FieldInfo(name="source.ip", type="ip", description="Requester IP", is_key_field=True),
|
||||
FieldInfo(name="source.address", type="ip", description="Source address", is_key_field=False),
|
||||
FieldInfo(name="source.geo.country_name", type="keyword", description="Country name", is_key_field=False),
|
||||
FieldInfo(name="source.geo.country_iso_code", type="keyword", description="Country ISO code", is_key_field=False),
|
||||
FieldInfo(name="http.request.method", type="keyword", description="HTTP method (GET/POST/PUT/DELETE/PATCH)", is_key_field=False),
|
||||
FieldInfo(name="http.response.status_code", type="long", description="HTTP response status code", is_key_field=True),
|
||||
FieldInfo(name="http.request.body.content", type="text", description="Request body content", is_key_field=False),
|
||||
FieldInfo(name="user_agent", type="text", description="User agent string", is_key_field=False),
|
||||
FieldInfo(name="request_id", type="keyword", description="Request ID (UUID)", is_key_field=True),
|
||||
FieldInfo(name="event_id", type="keyword", description="Event ID (UUID)", is_key_field=True),
|
||||
FieldInfo(name="aws_service", type="keyword", description="AWS service (cloudtrail/config/guardduty/securityhub)", is_key_field=False),
|
||||
FieldInfo(name="aws_request_id", type="keyword", description="AWS request ID", is_key_field=False),
|
||||
FieldInfo(name="recipient_account_id", type="keyword", description="Recipient account ID", is_key_field=False),
|
||||
FieldInfo(name="additional_event_data", type="object", description="Additional event data (LoginTo/MobileVersion/MFAUsed)", is_key_field=False),
|
||||
FieldInfo(name="request_parameters", type="object", description="Request parameters", is_key_field=False),
|
||||
FieldInfo(name="response_elements", type="object", description="Response elements", is_key_field=False),
|
||||
FieldInfo(name="error_code", type="keyword", description="Error code if failed", is_key_field=False),
|
||||
FieldInfo(name="error_message", type="text", description="Error message if failed", is_key_field=False),
|
||||
FieldInfo(name="read_only", type="boolean", description="Read-only operation flag", is_key_field=False),
|
||||
FieldInfo(name="log.level", type="keyword", description="Log level (info/warning)", is_key_field=False)
|
||||
]
|
||||
),
|
||||
|
||||
# 2. Splunk Index
|
||||
# 2. Network Traffic Index (Splunk)
|
||||
"siem-network-traffic": IndexInfo(
|
||||
name="siem-network-traffic",
|
||||
backend="Splunk",
|
||||
description="Network traffic logs via Splunk.",
|
||||
fields=[
|
||||
FieldInfo(name="@timestamp", type="date", description="Event time", is_key_field=False),
|
||||
FieldInfo(name="event.dataset", type="keyword", description="Dataset (network)", is_key_field=False),
|
||||
FieldInfo(name="event.module", type="keyword", description="Module (firewall)", is_key_field=False),
|
||||
FieldInfo(name="event.category", type="keyword", description="Event category (network_traffic)", is_key_field=True),
|
||||
FieldInfo(name="event.type", type="keyword", description="Event type (connection)", is_key_field=False),
|
||||
FieldInfo(name="event.action", type="keyword", description="Action (allow/deny)", is_key_field=True),
|
||||
FieldInfo(name="event.outcome", type="keyword", description="Outcome (success/failure)", is_key_field=True),
|
||||
FieldInfo(name="network.protocol", type="keyword", description="Protocol (tcp/udp)", is_key_field=True),
|
||||
FieldInfo(name="network.direction", type="keyword", description="Direction (egress/ingress)", is_key_field=False),
|
||||
FieldInfo(name="network.bytes_in", type="long", description="Bytes in", is_key_field=False),
|
||||
FieldInfo(name="network.bytes_out", type="long", description="Bytes out", is_key_field=False),
|
||||
FieldInfo(name="network.packets", type="long", description="Packet count", is_key_field=False),
|
||||
FieldInfo(name="network.duration", type="long", description="Duration in ms", is_key_field=False),
|
||||
FieldInfo(name="source.ip", type="ip", description="Source IP", is_key_field=True),
|
||||
FieldInfo(name="source.port", type="long", description="Source port", is_key_field=False),
|
||||
FieldInfo(name="source.mac", type="keyword", description="Source MAC address", is_key_field=False),
|
||||
FieldInfo(name="destination.ip", type="ip", description="Destination IP", is_key_field=True),
|
||||
FieldInfo(name="destination.port", type="long", description="Dest Port", is_key_field=True),
|
||||
FieldInfo(name="event.action", type="keyword", description="Action (allow/block)", is_key_field=True)
|
||||
FieldInfo(name="destination.port", type="long", description="Destination port", is_key_field=True),
|
||||
FieldInfo(name="destination.service", type="keyword", description="Destination service (https/http/ssh/rdp/mysql/postgresql/redis/dns)",
|
||||
is_key_field=True),
|
||||
FieldInfo(name="host.name", type="keyword", description="Host name", is_key_field=True),
|
||||
FieldInfo(name="host.ip", type="ip", description="Host IP (source IP)", is_key_field=False),
|
||||
FieldInfo(name="process.pid", type="long", description="Process ID", is_key_field=False),
|
||||
FieldInfo(name="process.name", type="keyword", description="Process name", is_key_field=False),
|
||||
FieldInfo(name="user.name", type="keyword", description="User name", is_key_field=True),
|
||||
FieldInfo(name="user.id", type="keyword", description="User ID", is_key_field=False),
|
||||
FieldInfo(name="firewall.rule_id", type="keyword", description="Firewall rule ID", is_key_field=True),
|
||||
FieldInfo(name="firewall.rule_name", type="keyword", description="Firewall rule name", is_key_field=False),
|
||||
FieldInfo(name="log.level", type="keyword", description="Log level (info)", is_key_field=False)
|
||||
]
|
||||
),
|
||||
|
||||
# 3. Host Events Index (ELK)
|
||||
"siem-host-events": IndexInfo(
|
||||
name="siem-host-events",
|
||||
backend="ELK",
|
||||
description="Host endpoint events including process and file activities.",
|
||||
fields=[
|
||||
FieldInfo(name="@timestamp", type="date", description="Event time", is_key_field=False),
|
||||
FieldInfo(name="event.dataset", type="keyword", description="Dataset type (host)", is_key_field=False),
|
||||
FieldInfo(name="event.module", type="keyword", description="Module (endpoint)", is_key_field=False),
|
||||
FieldInfo(name="event.category", type="keyword", description="Event category (process/file)", is_key_field=True),
|
||||
FieldInfo(name="event.type", type="keyword", description="Event type (process_created/terminated/file_created/deleted/registry_modified)",
|
||||
is_key_field=True),
|
||||
FieldInfo(name="event.action", type="keyword", description="Event action", is_key_field=True),
|
||||
FieldInfo(name="event.outcome", type="keyword", description="Event outcome (success/failure)", is_key_field=False),
|
||||
FieldInfo(name="host.name", type="keyword", description="Host name", is_key_field=True),
|
||||
FieldInfo(name="host.id", type="keyword", description="Host ID (UUID)", is_key_field=True),
|
||||
FieldInfo(name="host.os.name", type="keyword", description="OS name (Windows/Linux/macOS)", is_key_field=False),
|
||||
FieldInfo(name="host.os.version", type="keyword", description="OS version", is_key_field=False),
|
||||
FieldInfo(name="host.architecture", type="keyword", description="Host architecture (x86_64/arm64)", is_key_field=False),
|
||||
FieldInfo(name="user.name", type="keyword", description="User name", is_key_field=True),
|
||||
FieldInfo(name="user.id", type="keyword", description="User ID (SID)", is_key_field=True),
|
||||
FieldInfo(name="user.domain", type="keyword", description="User domain (CORP/LOCAL/WORKGROUP)", is_key_field=False),
|
||||
FieldInfo(name="process.pid", type="long", description="Process ID", is_key_field=True),
|
||||
FieldInfo(name="process.ppid", type="long", description="Parent Process ID", is_key_field=False),
|
||||
FieldInfo(name="process.name", type="keyword", description="Process name", is_key_field=True),
|
||||
FieldInfo(name="process.executable", type="keyword", description="Process executable path", is_key_field=False),
|
||||
FieldInfo(name="process.command_line", type="text", description="Process command line", is_key_field=False),
|
||||
FieldInfo(name="process.hash.md5", type="keyword", description="Process MD5 hash", is_key_field=False),
|
||||
FieldInfo(name="process.hash.sha256", type="keyword", description="Process SHA256 hash", is_key_field=False),
|
||||
FieldInfo(name="process.parent.name", type="keyword", description="Parent process name", is_key_field=False),
|
||||
FieldInfo(name="process.parent.pid", type="long", description="Parent process ID", is_key_field=False),
|
||||
FieldInfo(name="file.name", type="keyword", description="File name", is_key_field=True),
|
||||
FieldInfo(name="file.path", type="keyword", description="File path", is_key_field=False),
|
||||
FieldInfo(name="file.size", type="long", description="File size in bytes", is_key_field=False),
|
||||
FieldInfo(name="file.hash.md5", type="keyword", description="File MD5 hash", is_key_field=False),
|
||||
FieldInfo(name="file.hash.sha256", type="keyword", description="File SHA256 hash", is_key_field=False),
|
||||
FieldInfo(name="log.level", type="keyword", description="Log level (info/warning/error)", is_key_field=False),
|
||||
FieldInfo(name="message", type="text", description="Log message", is_key_field=False)
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import json
|
||||
import time
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from splunklib.results import JSONResultsReader
|
||||
|
||||
@@ -13,7 +13,7 @@ from models import (
|
||||
)
|
||||
from registry import STATIC_SCHEMA_REGISTRY, get_default_agg_fields, get_backend_type
|
||||
|
||||
SUMMARY_THRESHOLD = 100
|
||||
SUMMARY_THRESHOLD = 1000
|
||||
SAMPLE_THRESHOLD = 20
|
||||
|
||||
|
||||
@@ -93,8 +93,12 @@ class SIEMToolKit(object):
|
||||
service = SplunkClient.get_service()
|
||||
|
||||
try:
|
||||
t_start = datetime.strptime(input_data.time_range_start, "%Y-%m-%dT%H:%M:%SZ").timestamp()
|
||||
t_end = datetime.strptime(input_data.time_range_end, "%Y-%m-%dT%H:%M:%SZ").timestamp()
|
||||
utc_format = "%Y-%m-%dT%H:%M:%SZ"
|
||||
dt_start_utc = datetime.strptime(input_data.time_range_start, utc_format).replace(tzinfo=timezone.utc)
|
||||
dt_end_utc = datetime.strptime(input_data.time_range_end, utc_format).replace(tzinfo=timezone.utc)
|
||||
|
||||
t_start = dt_start_utc.timestamp()
|
||||
t_end = dt_end_utc.timestamp()
|
||||
except ValueError:
|
||||
raise ValueError("Invalid UTC format.")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user