Adding in rule generation from github exploits
This commit is contained in:
parent
cc825fdb86
commit
5a9ae34996
6 changed files with 618 additions and 34 deletions
|
@ -2,6 +2,11 @@
|
||||||
# Get your free API key at: https://nvd.nist.gov/developers/request-an-api-key
|
# Get your free API key at: https://nvd.nist.gov/developers/request-an-api-key
|
||||||
NVD_API_KEY=your_nvd_api_key_here
|
NVD_API_KEY=your_nvd_api_key_here
|
||||||
|
|
||||||
|
# GitHub API Configuration (Optional - for exploit analysis)
|
||||||
|
# Get your personal access token at: https://github.com/settings/tokens
|
||||||
|
# Only needs "public_repo" scope for searching public repositories
|
||||||
|
GITHUB_TOKEN=your_github_token_here
|
||||||
|
|
||||||
# Database Configuration (Docker Compose will use defaults)
|
# Database Configuration (Docker Compose will use defaults)
|
||||||
# DATABASE_URL=postgresql://cve_user:cve_password@localhost:5432/cve_sigma_db
|
# DATABASE_URL=postgresql://cve_user:cve_password@localhost:5432/cve_sigma_db
|
||||||
|
|
||||||
|
|
88
README.md
88
README.md
|
@ -5,10 +5,13 @@ An automated platform that fetches CVE data and automatically generates SIGMA ru
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Automated CVE Fetching**: Regularly polls the NVD (National Vulnerability Database) for CVEs from July 2025
|
- **Automated CVE Fetching**: Regularly polls the NVD (National Vulnerability Database) for CVEs from July 2025
|
||||||
- **Intelligent SIGMA Rule Generation**: Automatically creates SIGMA rules based on CVE characteristics
|
- **GitHub Exploit Analysis**: Automatically searches GitHub for exploit code related to each CVE
|
||||||
|
- **Intelligent SIGMA Rule Generation**: Creates SIGMA rules based on CVE characteristics AND actual exploit code
|
||||||
|
- **Exploit-Based Detection**: Enhanced rules using real indicators extracted from GitHub exploits
|
||||||
- **Modern Web Interface**: React-based UI for browsing CVEs and managing SIGMA rules
|
- **Modern Web Interface**: React-based UI for browsing CVEs and managing SIGMA rules
|
||||||
- **Real-time Updates**: Background tasks keep CVE data current with current 2025 vulnerabilities
|
- **Real-time Updates**: Background tasks keep CVE data current with current 2025 vulnerabilities
|
||||||
- **Rule Templates**: Configurable templates for different types of vulnerabilities
|
- **Rule Templates**: Configurable templates for different types of vulnerabilities
|
||||||
|
- **MITRE ATT&CK Mapping**: Automatic mapping to MITRE ATT&CK techniques
|
||||||
- **API Testing**: Built-in NVD API connectivity testing
|
- **API Testing**: Built-in NVD API connectivity testing
|
||||||
- **Enhanced Error Handling**: Robust fallback mechanisms and detailed logging
|
- **Enhanced Error Handling**: Robust fallback mechanisms and detailed logging
|
||||||
- **Docker Compose**: Easy deployment and orchestration
|
- **Docker Compose**: Easy deployment and orchestration
|
||||||
|
@ -101,9 +104,25 @@ curl -X POST http://localhost:8000/api/fetch-cves
|
||||||
### Environment Variables
|
### Environment Variables
|
||||||
|
|
||||||
- `DATABASE_URL`: PostgreSQL connection string
|
- `DATABASE_URL`: PostgreSQL connection string
|
||||||
- `NVD_API_KEY`: Optional NVD API key for higher rate limits
|
- `NVD_API_KEY`: Optional NVD API key for higher rate limits (5→50 requests/30s)
|
||||||
|
- `GITHUB_TOKEN`: Optional GitHub personal access token for exploit analysis
|
||||||
- `REACT_APP_API_URL`: Backend API URL for frontend
|
- `REACT_APP_API_URL`: Backend API URL for frontend
|
||||||
|
|
||||||
|
### GitHub Integration (Optional)
|
||||||
|
|
||||||
|
For enhanced SIGMA rule generation with exploit analysis:
|
||||||
|
|
||||||
|
1. **Create GitHub Token**: Visit https://github.com/settings/tokens
|
||||||
|
2. **Required Permissions**: Only needs "public_repo" scope for searching public repositories
|
||||||
|
3. **Add to Environment**: `GITHUB_TOKEN=your_token_here` in `.env` file
|
||||||
|
4. **Benefits**:
|
||||||
|
- Automatically searches for CVE-related exploit code
|
||||||
|
- Extracts real indicators (processes, files, network connections)
|
||||||
|
- Generates more accurate and specific SIGMA rules
|
||||||
|
- Higher confidence ratings for exploit-based rules
|
||||||
|
|
||||||
|
**Rate Limits**: 5000 requests/hour with token, 60/hour without
|
||||||
|
|
||||||
### Rule Templates
|
### Rule Templates
|
||||||
|
|
||||||
The application includes pre-configured rule templates for:
|
The application includes pre-configured rule templates for:
|
||||||
|
@ -115,19 +134,55 @@ Additional templates can be added to the database via the `rule_templates` table
|
||||||
|
|
||||||
## SIGMA Rule Generation Logic
|
## SIGMA Rule Generation Logic
|
||||||
|
|
||||||
The rule generation process:
|
The enhanced rule generation process:
|
||||||
|
|
||||||
1. **CVE Analysis**: Analyzes CVE description and affected products
|
1. **CVE Analysis**: Analyzes CVE description and affected products
|
||||||
2. **Template Selection**: Chooses appropriate SIGMA rule template
|
2. **GitHub Exploit Search**: Searches GitHub for exploit code using multiple query strategies
|
||||||
3. **Indicator Extraction**: Extracts suspicious processes, ports, or file patterns
|
3. **Code Analysis**: Extracts specific indicators from exploit code:
|
||||||
4. **Rule Population**: Fills template with CVE-specific data
|
- Process names and command lines
|
||||||
5. **Confidence Scoring**: Assigns confidence level based on CVSS score
|
- File paths and registry keys
|
||||||
|
- Network connections and ports
|
||||||
|
- PowerShell commands and scripts
|
||||||
|
- Command execution patterns
|
||||||
|
4. **Template Selection**: Chooses appropriate SIGMA rule template based on exploit analysis
|
||||||
|
5. **Enhanced Rule Population**: Fills template with real exploit indicators
|
||||||
|
6. **MITRE ATT&CK Mapping**: Maps to specific MITRE ATT&CK techniques
|
||||||
|
7. **Confidence Scoring**: Higher confidence for exploit-based rules
|
||||||
|
|
||||||
|
### Rule Quality Levels
|
||||||
|
|
||||||
|
- **Basic Rules**: Generated from CVE description only
|
||||||
|
- **Exploit-Based Rules**: Enhanced with GitHub exploit analysis (marked with 🔍)
|
||||||
|
- **Confidence Ratings**:
|
||||||
|
- **High**: CVSS ≥9.0 + exploit analysis
|
||||||
|
- **Medium**: CVSS ≥7.0 or exploit analysis
|
||||||
|
- **Low**: Basic CVE description only
|
||||||
|
|
||||||
### Template Matching
|
### Template Matching
|
||||||
|
|
||||||
- **Process Execution**: Keywords like "process", "execution", "command"
|
- **PowerShell Execution**: Exploit contains PowerShell scripts or cmdlets
|
||||||
- **Network Connection**: Keywords like "network", "remote", "connection"
|
- **Process Execution**: Exploit shows process creation or command execution
|
||||||
- **File Modification**: Keywords like "file", "write", "filesystem"
|
- **Network Connection**: Exploit demonstrates network communications
|
||||||
|
- **File Modification**: Exploit involves file system operations
|
||||||
|
|
||||||
|
### Example Enhanced Rule
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
title: CVE-2025-1234 Exploit-Based Detection
|
||||||
|
description: Detection for CVE-2025-1234 remote code execution [Enhanced with GitHub exploit analysis]
|
||||||
|
tags:
|
||||||
|
- attack.t1059.001
|
||||||
|
- cve-2025-1234
|
||||||
|
- exploit.github
|
||||||
|
detection:
|
||||||
|
selection:
|
||||||
|
Image|contains:
|
||||||
|
- "powershell.exe"
|
||||||
|
- "malicious_payload.exe"
|
||||||
|
- "reverse_shell.ps1"
|
||||||
|
condition: selection
|
||||||
|
level: high
|
||||||
|
```
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
|
@ -217,7 +272,8 @@ docker-compose ps
|
||||||
|
|
||||||
### API Key Setup
|
### API Key Setup
|
||||||
|
|
||||||
For optimal performance, get a free NVD API key:
|
**NVD API (Recommended)**
|
||||||
|
For optimal CVE fetching performance:
|
||||||
1. Visit: https://nvd.nist.gov/developers/request-an-api-key
|
1. Visit: https://nvd.nist.gov/developers/request-an-api-key
|
||||||
2. Add to your `.env` file: `NVD_API_KEY=your_key_here`
|
2. Add to your `.env` file: `NVD_API_KEY=your_key_here`
|
||||||
3. Restart the application
|
3. Restart the application
|
||||||
|
@ -225,6 +281,16 @@ For optimal performance, get a free NVD API key:
|
||||||
Without an API key: 5 requests per 30 seconds
|
Without an API key: 5 requests per 30 seconds
|
||||||
With an API key: 50 requests per 30 seconds
|
With an API key: 50 requests per 30 seconds
|
||||||
|
|
||||||
|
**GitHub API (Optional)**
|
||||||
|
For enhanced exploit-based SIGMA rules:
|
||||||
|
1. Visit: https://github.com/settings/tokens
|
||||||
|
2. Create token with "public_repo" scope
|
||||||
|
3. Add to your `.env` file: `GITHUB_TOKEN=your_token_here`
|
||||||
|
4. Restart the application
|
||||||
|
|
||||||
|
Without a GitHub token: Basic rules only
|
||||||
|
With a GitHub token: Enhanced rules with exploit analysis (🔍 Exploit-Based)
|
||||||
|
|
||||||
### Rate Limits
|
### Rate Limits
|
||||||
|
|
||||||
Without an API key, NVD limits requests to 5 per 30 seconds. With an API key, the limit increases to 50 per 30 seconds.
|
Without an API key, NVD limits requests to 5 per 30 seconds. With an API key, the limit increases to 50 per 30 seconds.
|
||||||
|
|
412
backend/main.py
412
backend/main.py
|
@ -15,6 +15,10 @@ from typing import List, Optional
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
import asyncio
|
import asyncio
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
|
import base64
|
||||||
|
from github import Github
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
import hashlib
|
||||||
|
|
||||||
# Database setup
|
# Database setup
|
||||||
DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://cve_user:cve_password@localhost:5432/cve_sigma_db")
|
DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://cve_user:cve_password@localhost:5432/cve_sigma_db")
|
||||||
|
@ -49,6 +53,9 @@ class SigmaRule(Base):
|
||||||
log_source = Column(String(100))
|
log_source = Column(String(100))
|
||||||
confidence_level = Column(String(20))
|
confidence_level = Column(String(20))
|
||||||
auto_generated = Column(Boolean, default=True)
|
auto_generated = Column(Boolean, default=True)
|
||||||
|
exploit_based = Column(Boolean, default=False)
|
||||||
|
github_repos = Column(ARRAY(String))
|
||||||
|
exploit_indicators = Column(Text) # JSON string of extracted indicators
|
||||||
created_at = Column(TIMESTAMP, default=datetime.utcnow)
|
created_at = Column(TIMESTAMP, default=datetime.utcnow)
|
||||||
updated_at = Column(TIMESTAMP, default=datetime.utcnow)
|
updated_at = Column(TIMESTAMP, default=datetime.utcnow)
|
||||||
|
|
||||||
|
@ -85,12 +92,271 @@ class SigmaRuleResponse(BaseModel):
|
||||||
log_source: Optional[str] = None
|
log_source: Optional[str] = None
|
||||||
confidence_level: Optional[str] = None
|
confidence_level: Optional[str] = None
|
||||||
auto_generated: bool = True
|
auto_generated: bool = True
|
||||||
|
exploit_based: bool = False
|
||||||
|
github_repos: Optional[List[str]] = None
|
||||||
|
exploit_indicators: Optional[str] = None
|
||||||
created_at: datetime
|
created_at: datetime
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|
||||||
# CVE and SIGMA Rule Generator Service
|
# GitHub Exploit Analysis Service
|
||||||
|
class GitHubExploitAnalyzer:
|
||||||
|
def __init__(self):
|
||||||
|
self.github_token = os.getenv("GITHUB_TOKEN")
|
||||||
|
self.github = Github(self.github_token) if self.github_token else None
|
||||||
|
|
||||||
|
async def search_exploits_for_cve(self, cve_id: str) -> List[dict]:
|
||||||
|
"""Search GitHub for exploit code related to a CVE"""
|
||||||
|
if not self.github:
|
||||||
|
print(f"No GitHub token configured, skipping exploit search for {cve_id}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(f"Searching GitHub for exploits for {cve_id}")
|
||||||
|
|
||||||
|
# Search queries to find exploit code
|
||||||
|
search_queries = [
|
||||||
|
f"{cve_id} exploit",
|
||||||
|
f"{cve_id} poc",
|
||||||
|
f"{cve_id} vulnerability",
|
||||||
|
f'"{cve_id}" exploit code',
|
||||||
|
f"{cve_id.replace('-', '_')} exploit"
|
||||||
|
]
|
||||||
|
|
||||||
|
exploits = []
|
||||||
|
seen_repos = set()
|
||||||
|
|
||||||
|
for query in search_queries[:2]: # Limit to 2 queries to avoid rate limits
|
||||||
|
try:
|
||||||
|
# Search repositories
|
||||||
|
repos = self.github.search_repositories(
|
||||||
|
query=query,
|
||||||
|
sort="updated",
|
||||||
|
order="desc"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get top 5 results per query
|
||||||
|
for repo in repos[:5]:
|
||||||
|
if repo.full_name in seen_repos:
|
||||||
|
continue
|
||||||
|
seen_repos.add(repo.full_name)
|
||||||
|
|
||||||
|
# Analyze repository
|
||||||
|
exploit_info = await self._analyze_repository(repo, cve_id)
|
||||||
|
if exploit_info:
|
||||||
|
exploits.append(exploit_info)
|
||||||
|
|
||||||
|
if len(exploits) >= 10: # Limit total exploits
|
||||||
|
break
|
||||||
|
|
||||||
|
if len(exploits) >= 10:
|
||||||
|
break
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error searching GitHub with query '{query}': {str(e)}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
print(f"Found {len(exploits)} potential exploits for {cve_id}")
|
||||||
|
return exploits
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error searching GitHub for {cve_id}: {str(e)}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
async def _analyze_repository(self, repo, cve_id: str) -> Optional[dict]:
|
||||||
|
"""Analyze a GitHub repository for exploit code"""
|
||||||
|
try:
|
||||||
|
# Check if repo name or description mentions the CVE
|
||||||
|
repo_text = f"{repo.name} {repo.description or ''}".lower()
|
||||||
|
if cve_id.lower() not in repo_text and cve_id.replace('-', '_').lower() not in repo_text:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Get repository contents
|
||||||
|
exploit_files = []
|
||||||
|
indicators = {
|
||||||
|
'processes': set(),
|
||||||
|
'files': set(),
|
||||||
|
'registry': set(),
|
||||||
|
'network': set(),
|
||||||
|
'commands': set(),
|
||||||
|
'powershell': set(),
|
||||||
|
'urls': set()
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
contents = repo.get_contents("")
|
||||||
|
for content in contents[:20]: # Limit files to analyze
|
||||||
|
if content.type == "file" and self._is_exploit_file(content.name):
|
||||||
|
file_analysis = await self._analyze_file_content(repo, content, cve_id)
|
||||||
|
if file_analysis:
|
||||||
|
exploit_files.append(file_analysis)
|
||||||
|
# Merge indicators
|
||||||
|
for key, values in file_analysis.get('indicators', {}).items():
|
||||||
|
if key in indicators:
|
||||||
|
indicators[key].update(values)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error analyzing repo contents for {repo.full_name}: {str(e)}")
|
||||||
|
|
||||||
|
if not exploit_files:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return {
|
||||||
|
'repo_name': repo.full_name,
|
||||||
|
'repo_url': repo.html_url,
|
||||||
|
'description': repo.description,
|
||||||
|
'language': repo.language,
|
||||||
|
'stars': repo.stargazers_count,
|
||||||
|
'updated': repo.updated_at.isoformat(),
|
||||||
|
'files': exploit_files,
|
||||||
|
'indicators': {k: list(v) for k, v in indicators.items()}
|
||||||
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error analyzing repository {repo.full_name}: {str(e)}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _is_exploit_file(self, filename: str) -> bool:
|
||||||
|
"""Check if a file is likely to contain exploit code"""
|
||||||
|
exploit_extensions = ['.py', '.ps1', '.sh', '.c', '.cpp', '.js', '.rb', '.pl', '.php', '.java']
|
||||||
|
exploit_names = ['exploit', 'poc', 'payload', 'shell', 'reverse', 'bind', 'attack']
|
||||||
|
|
||||||
|
filename_lower = filename.lower()
|
||||||
|
|
||||||
|
# Check extension
|
||||||
|
if not any(filename_lower.endswith(ext) for ext in exploit_extensions):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Check filename for exploit-related terms
|
||||||
|
return any(term in filename_lower for term in exploit_names) or 'cve' in filename_lower
|
||||||
|
|
||||||
|
async def _analyze_file_content(self, repo, file_content, cve_id: str) -> Optional[dict]:
|
||||||
|
"""Analyze individual file content for exploit indicators"""
|
||||||
|
try:
|
||||||
|
if file_content.size > 100000: # Skip files larger than 100KB
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Decode file content
|
||||||
|
content = file_content.decoded_content.decode('utf-8', errors='ignore')
|
||||||
|
|
||||||
|
# Check if file actually mentions the CVE
|
||||||
|
if cve_id.lower() not in content.lower() and cve_id.replace('-', '_').lower() not in content.lower():
|
||||||
|
return None
|
||||||
|
|
||||||
|
indicators = self._extract_indicators_from_code(content, file_content.name)
|
||||||
|
|
||||||
|
if not any(indicators.values()):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return {
|
||||||
|
'filename': file_content.name,
|
||||||
|
'path': file_content.path,
|
||||||
|
'size': file_content.size,
|
||||||
|
'indicators': indicators
|
||||||
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error analyzing file {file_content.name}: {str(e)}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _extract_indicators_from_code(self, content: str, filename: str) -> dict:
|
||||||
|
"""Extract security indicators from exploit code"""
|
||||||
|
indicators = {
|
||||||
|
'processes': set(),
|
||||||
|
'files': set(),
|
||||||
|
'registry': set(),
|
||||||
|
'network': set(),
|
||||||
|
'commands': set(),
|
||||||
|
'powershell': set(),
|
||||||
|
'urls': set()
|
||||||
|
}
|
||||||
|
|
||||||
|
# Process patterns
|
||||||
|
process_patterns = [
|
||||||
|
r'CreateProcess[AW]?\s*\(\s*["\']([^"\']+)["\']',
|
||||||
|
r'ShellExecute[AW]?\s*\([^,]*,\s*["\']([^"\']+)["\']',
|
||||||
|
r'system\s*\(\s*["\']([^"\']+)["\']',
|
||||||
|
r'exec\s*\(\s*["\']([^"\']+)["\']',
|
||||||
|
r'subprocess\.(?:call|run|Popen)\s*\(\s*["\']([^"\']+)["\']'
|
||||||
|
]
|
||||||
|
|
||||||
|
# File patterns
|
||||||
|
file_patterns = [
|
||||||
|
r'(?:fopen|CreateFile|WriteFile|ReadFile)\s*\(\s*["\']([^"\']+\.[a-zA-Z0-9]+)["\']',
|
||||||
|
r'(?:copy|move|del|rm)\s+["\']?([^\s"\']+\.[a-zA-Z0-9]+)["\']?',
|
||||||
|
r'\\\\[^\\]+\\[^\\]+\\([^\\]+\.[a-zA-Z0-9]+)',
|
||||||
|
r'[C-Z]:\\\\[^\\]+\\\\([^\\]+\.[a-zA-Z0-9]+)'
|
||||||
|
]
|
||||||
|
|
||||||
|
# Registry patterns
|
||||||
|
registry_patterns = [
|
||||||
|
r'(?:RegOpenKey|RegSetValue|RegCreateKey)\s*\([^,]*,\s*["\']([^"\']+)["\']',
|
||||||
|
r'HKEY_[A-Z_]+\\\\([^"\'\\]+)',
|
||||||
|
r'reg\s+add\s+["\']?([^"\'\\]+\\\\[^"\']+)["\']?'
|
||||||
|
]
|
||||||
|
|
||||||
|
# Network patterns
|
||||||
|
network_patterns = [
|
||||||
|
r'(?:connect|bind|listen)\s*\([^,]*,\s*(\d+)',
|
||||||
|
r'socket\.connect\s*\(\s*\(["\']?([^"\']+)["\']?,\s*(\d+)\)',
|
||||||
|
r'(?:http|https|ftp)://([^\s"\'<>]+)',
|
||||||
|
r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+)'
|
||||||
|
]
|
||||||
|
|
||||||
|
# PowerShell patterns
|
||||||
|
powershell_patterns = [
|
||||||
|
r'(?:powershell|pwsh)\s+(?:-[a-zA-Z]+\s+)*["\']?([^"\']+)["\']?',
|
||||||
|
r'Invoke-(?:Expression|Command|WebRequest|RestMethod)\s+["\']?([^"\']+)["\']?',
|
||||||
|
r'Start-Process\s+["\']?([^"\']+)["\']?',
|
||||||
|
r'Get-Process\s+["\']?([^"\']+)["\']?'
|
||||||
|
]
|
||||||
|
|
||||||
|
# Command patterns
|
||||||
|
command_patterns = [
|
||||||
|
r'(?:cmd|command)\s+(?:/[a-zA-Z]+\s+)*["\']?([^"\']+)["\']?',
|
||||||
|
r'(?:ping|nslookup|netstat|tasklist|wmic)\s+([^\s"\']+)',
|
||||||
|
r'(?:net|sc|schtasks)\s+[a-zA-Z]+\s+([^\s"\']+)'
|
||||||
|
]
|
||||||
|
|
||||||
|
# Extract indicators using regex patterns
|
||||||
|
patterns = {
|
||||||
|
'processes': process_patterns,
|
||||||
|
'files': file_patterns,
|
||||||
|
'registry': registry_patterns,
|
||||||
|
'powershell': powershell_patterns,
|
||||||
|
'commands': command_patterns
|
||||||
|
}
|
||||||
|
|
||||||
|
for category, pattern_list in patterns.items():
|
||||||
|
for pattern in pattern_list:
|
||||||
|
matches = re.findall(pattern, content, re.IGNORECASE | re.MULTILINE)
|
||||||
|
for match in matches:
|
||||||
|
if isinstance(match, tuple):
|
||||||
|
indicators[category].add(match[0])
|
||||||
|
else:
|
||||||
|
indicators[category].add(match)
|
||||||
|
|
||||||
|
# Special handling for network indicators
|
||||||
|
for pattern in network_patterns:
|
||||||
|
matches = re.findall(pattern, content, re.IGNORECASE)
|
||||||
|
for match in matches:
|
||||||
|
if isinstance(match, tuple):
|
||||||
|
if len(match) >= 2:
|
||||||
|
indicators['network'].add(f"{match[0]}:{match[1]}")
|
||||||
|
else:
|
||||||
|
indicators['network'].add(match[0])
|
||||||
|
else:
|
||||||
|
indicators['network'].add(match)
|
||||||
|
|
||||||
|
# Convert sets to lists and filter out empty/invalid indicators
|
||||||
|
cleaned_indicators = {}
|
||||||
|
for key, values in indicators.items():
|
||||||
|
cleaned_values = [v for v in values if v and len(v.strip()) > 2 and len(v) < 200]
|
||||||
|
if cleaned_values:
|
||||||
|
cleaned_indicators[key] = cleaned_values[:10] # Limit to 10 per category
|
||||||
|
|
||||||
|
return cleaned_indicators
|
||||||
class CVESigmaService:
|
class CVESigmaService:
|
||||||
def __init__(self, db: Session):
|
def __init__(self, db: Session):
|
||||||
self.db = db
|
self.db = db
|
||||||
|
@ -207,11 +473,33 @@ class CVESigmaService:
|
||||||
self.db.add(sigma_rule)
|
self.db.add(sigma_rule)
|
||||||
return sigma_rule
|
return sigma_rule
|
||||||
|
|
||||||
def _select_template(self, description: str, affected_products: List[str]):
|
def _select_template(self, description: str, affected_products: List[str], exploit_indicators: dict = None):
|
||||||
"""Select appropriate SIGMA rule template"""
|
"""Select appropriate SIGMA rule template based on CVE and exploit analysis"""
|
||||||
templates = self.db.query(RuleTemplate).all()
|
templates = self.db.query(RuleTemplate).all()
|
||||||
|
|
||||||
# Simple template selection logic
|
# If we have exploit indicators, use them to determine the best template
|
||||||
|
if exploit_indicators:
|
||||||
|
if exploit_indicators.get('powershell'):
|
||||||
|
powershell_template = next((t for t in templates if "PowerShell" in t.template_name), None)
|
||||||
|
if powershell_template:
|
||||||
|
return powershell_template
|
||||||
|
|
||||||
|
if exploit_indicators.get('network'):
|
||||||
|
network_template = next((t for t in templates if "Network Connection" in t.template_name), None)
|
||||||
|
if network_template:
|
||||||
|
return network_template
|
||||||
|
|
||||||
|
if exploit_indicators.get('files'):
|
||||||
|
file_template = next((t for t in templates if "File Modification" in t.template_name), None)
|
||||||
|
if file_template:
|
||||||
|
return file_template
|
||||||
|
|
||||||
|
if exploit_indicators.get('processes') or exploit_indicators.get('commands'):
|
||||||
|
process_template = next((t for t in templates if "Process Execution" in t.template_name), None)
|
||||||
|
if process_template:
|
||||||
|
return process_template
|
||||||
|
|
||||||
|
# Fallback to original logic
|
||||||
if any("windows" in p or "microsoft" in p for p in affected_products):
|
if any("windows" in p or "microsoft" in p for p in affected_products):
|
||||||
if "process" in description or "execution" in description:
|
if "process" in description or "execution" in description:
|
||||||
return next((t for t in templates if "Process Execution" in t.template_name), None)
|
return next((t for t in templates if "Process Execution" in t.template_name), None)
|
||||||
|
@ -223,24 +511,50 @@ class CVESigmaService:
|
||||||
# Default to process execution template
|
# Default to process execution template
|
||||||
return next((t for t in templates if "Process Execution" in t.template_name), None)
|
return next((t for t in templates if "Process Execution" in t.template_name), None)
|
||||||
|
|
||||||
def _populate_template(self, cve: CVE, template: RuleTemplate) -> str:
|
def _populate_template(self, cve: CVE, template: RuleTemplate, exploit_indicators: dict = None) -> str:
|
||||||
"""Populate template with CVE-specific data"""
|
"""Populate template with CVE-specific data and exploit indicators"""
|
||||||
try:
|
try:
|
||||||
# Extract suspicious indicators from description
|
# Use exploit indicators if available, otherwise extract from description
|
||||||
suspicious_processes = self._extract_suspicious_indicators(cve.description, "process")
|
if exploit_indicators:
|
||||||
suspicious_ports = self._extract_suspicious_indicators(cve.description, "port")
|
suspicious_processes = exploit_indicators.get('processes', []) + exploit_indicators.get('commands', [])
|
||||||
file_patterns = self._extract_suspicious_indicators(cve.description, "file")
|
suspicious_ports = []
|
||||||
|
file_patterns = exploit_indicators.get('files', [])
|
||||||
|
|
||||||
|
# Extract ports from network indicators
|
||||||
|
for net_indicator in exploit_indicators.get('network', []):
|
||||||
|
if ':' in str(net_indicator):
|
||||||
|
try:
|
||||||
|
port = int(str(net_indicator).split(':')[-1])
|
||||||
|
suspicious_ports.append(port)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# Fallback to original extraction
|
||||||
|
suspicious_processes = self._extract_suspicious_indicators(cve.description, "process")
|
||||||
|
suspicious_ports = self._extract_suspicious_indicators(cve.description, "port")
|
||||||
|
file_patterns = self._extract_suspicious_indicators(cve.description, "file")
|
||||||
|
|
||||||
# Determine severity level
|
# Determine severity level
|
||||||
level = "high" if cve.cvss_score and cve.cvss_score >= 7.0 else "medium"
|
level = "high" if cve.cvss_score and cve.cvss_score >= 7.0 else "medium"
|
||||||
|
|
||||||
|
# Create enhanced description
|
||||||
|
enhanced_description = cve.description[:200] + "..." if len(cve.description) > 200 else cve.description
|
||||||
|
if exploit_indicators:
|
||||||
|
enhanced_description += " [Enhanced with GitHub exploit analysis]"
|
||||||
|
|
||||||
|
# Build tags
|
||||||
|
tags = [f"attack.{self._get_mitre_technique(cve.description, exploit_indicators)}", cve.cve_id.lower()]
|
||||||
|
if exploit_indicators:
|
||||||
|
tags.append("exploit.github")
|
||||||
|
|
||||||
rule_content = template.template_content.format(
|
rule_content = template.template_content.format(
|
||||||
title=f"CVE-{cve.cve_id} Exploitation Attempt",
|
title=f"CVE-{cve.cve_id} {'Exploit-Based ' if exploit_indicators else ''}Detection",
|
||||||
description=cve.description[:200] + "..." if len(cve.description) > 200 else cve.description,
|
description=enhanced_description,
|
||||||
rule_id=str(uuid.uuid4()),
|
rule_id=str(uuid.uuid4()),
|
||||||
date=datetime.utcnow().strftime("%Y/%m/%d"),
|
date=datetime.utcnow().strftime("%Y/%m/%d"),
|
||||||
cve_url=f"https://nvd.nist.gov/vuln/detail/{cve.cve_id}",
|
cve_url=f"https://nvd.nist.gov/vuln/detail/{cve.cve_id}",
|
||||||
cve_id=cve.cve_id.lower(),
|
cve_id=cve.cve_id.lower(),
|
||||||
|
tags="\n - ".join(tags),
|
||||||
suspicious_processes=suspicious_processes or ["suspicious.exe", "malware.exe"],
|
suspicious_processes=suspicious_processes or ["suspicious.exe", "malware.exe"],
|
||||||
suspicious_ports=suspicious_ports or [4444, 8080, 9999],
|
suspicious_ports=suspicious_ports or [4444, 8080, 9999],
|
||||||
file_patterns=file_patterns or ["temp", "malware", "exploit"],
|
file_patterns=file_patterns or ["temp", "malware", "exploit"],
|
||||||
|
@ -253,6 +567,37 @@ class CVESigmaService:
|
||||||
print(f"Error populating template: {str(e)}")
|
print(f"Error populating template: {str(e)}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def _get_mitre_technique(self, description: str, exploit_indicators: dict = None) -> str:
|
||||||
|
"""Map CVE and exploit indicators to MITRE ATT&CK techniques"""
|
||||||
|
desc_lower = description.lower()
|
||||||
|
|
||||||
|
# Check exploit indicators first
|
||||||
|
if exploit_indicators:
|
||||||
|
if exploit_indicators.get('powershell'):
|
||||||
|
return "t1059.001" # PowerShell
|
||||||
|
elif exploit_indicators.get('commands'):
|
||||||
|
return "t1059.003" # Windows Command Shell
|
||||||
|
elif exploit_indicators.get('network'):
|
||||||
|
return "t1071.001" # Web Protocols
|
||||||
|
elif exploit_indicators.get('files'):
|
||||||
|
return "t1105" # Ingress Tool Transfer
|
||||||
|
elif exploit_indicators.get('processes'):
|
||||||
|
return "t1106" # Native API
|
||||||
|
|
||||||
|
# Fallback to description analysis
|
||||||
|
if "powershell" in desc_lower:
|
||||||
|
return "t1059.001"
|
||||||
|
elif "command" in desc_lower or "cmd" in desc_lower:
|
||||||
|
return "t1059.003"
|
||||||
|
elif "network" in desc_lower or "remote" in desc_lower:
|
||||||
|
return "t1071.001"
|
||||||
|
elif "file" in desc_lower or "upload" in desc_lower:
|
||||||
|
return "t1105"
|
||||||
|
elif "process" in desc_lower or "execution" in desc_lower:
|
||||||
|
return "t1106"
|
||||||
|
else:
|
||||||
|
return "execution" # Generic
|
||||||
|
|
||||||
def _extract_suspicious_indicators(self, description: str, indicator_type: str) -> List:
|
def _extract_suspicious_indicators(self, description: str, indicator_type: str) -> List:
|
||||||
"""Extract suspicious indicators from CVE description"""
|
"""Extract suspicious indicators from CVE description"""
|
||||||
if indicator_type == "process":
|
if indicator_type == "process":
|
||||||
|
@ -272,8 +617,19 @@ class CVESigmaService:
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _determine_detection_type(self, description: str) -> str:
|
def _determine_detection_type(self, description: str, exploit_indicators: dict = None) -> str:
|
||||||
"""Determine detection type based on CVE description"""
|
"""Determine detection type based on CVE description and exploit indicators"""
|
||||||
|
if exploit_indicators:
|
||||||
|
if exploit_indicators.get('powershell'):
|
||||||
|
return "powershell"
|
||||||
|
elif exploit_indicators.get('network'):
|
||||||
|
return "network"
|
||||||
|
elif exploit_indicators.get('files'):
|
||||||
|
return "file"
|
||||||
|
elif exploit_indicators.get('processes') or exploit_indicators.get('commands'):
|
||||||
|
return "process"
|
||||||
|
|
||||||
|
# Fallback to original logic
|
||||||
if "remote" in description or "network" in description:
|
if "remote" in description or "network" in description:
|
||||||
return "network"
|
return "network"
|
||||||
elif "process" in description or "execution" in description:
|
elif "process" in description or "execution" in description:
|
||||||
|
@ -283,11 +639,27 @@ class CVESigmaService:
|
||||||
else:
|
else:
|
||||||
return "general"
|
return "general"
|
||||||
|
|
||||||
def _calculate_confidence(self, cve: CVE) -> str:
|
def _calculate_confidence(self, cve: CVE, exploit_based: bool = False) -> str:
|
||||||
"""Calculate confidence level for the generated rule"""
|
"""Calculate confidence level for the generated rule"""
|
||||||
if cve.cvss_score and cve.cvss_score >= 9.0:
|
base_confidence = 0
|
||||||
|
|
||||||
|
# CVSS score contributes to confidence
|
||||||
|
if cve.cvss_score:
|
||||||
|
if cve.cvss_score >= 9.0:
|
||||||
|
base_confidence += 3
|
||||||
|
elif cve.cvss_score >= 7.0:
|
||||||
|
base_confidence += 2
|
||||||
|
else:
|
||||||
|
base_confidence += 1
|
||||||
|
|
||||||
|
# Exploit-based rules get higher confidence
|
||||||
|
if exploit_based:
|
||||||
|
base_confidence += 2
|
||||||
|
|
||||||
|
# Map to confidence levels
|
||||||
|
if base_confidence >= 4:
|
||||||
return "high"
|
return "high"
|
||||||
elif cve.cvss_score and cve.cvss_score >= 7.0:
|
elif base_confidence >= 2:
|
||||||
return "medium"
|
return "medium"
|
||||||
else:
|
else:
|
||||||
return "low"
|
return "low"
|
||||||
|
@ -427,6 +799,9 @@ async def get_sigma_rules(skip: int = 0, limit: int = 50, db: Session = Depends(
|
||||||
'log_source': rule.log_source,
|
'log_source': rule.log_source,
|
||||||
'confidence_level': rule.confidence_level,
|
'confidence_level': rule.confidence_level,
|
||||||
'auto_generated': rule.auto_generated,
|
'auto_generated': rule.auto_generated,
|
||||||
|
'exploit_based': rule.exploit_based or False,
|
||||||
|
'github_repos': rule.github_repos or [],
|
||||||
|
'exploit_indicators': rule.exploit_indicators,
|
||||||
'created_at': rule.created_at
|
'created_at': rule.created_at
|
||||||
}
|
}
|
||||||
result.append(SigmaRuleResponse(**rule_dict))
|
result.append(SigmaRuleResponse(**rule_dict))
|
||||||
|
@ -447,6 +822,9 @@ async def get_sigma_rules_by_cve(cve_id: str, db: Session = Depends(get_db)):
|
||||||
'log_source': rule.log_source,
|
'log_source': rule.log_source,
|
||||||
'confidence_level': rule.confidence_level,
|
'confidence_level': rule.confidence_level,
|
||||||
'auto_generated': rule.auto_generated,
|
'auto_generated': rule.auto_generated,
|
||||||
|
'exploit_based': rule.exploit_based or False,
|
||||||
|
'github_repos': rule.github_repos or [],
|
||||||
|
'exploit_indicators': rule.exploit_indicators,
|
||||||
'created_at': rule.created_at
|
'created_at': rule.created_at
|
||||||
}
|
}
|
||||||
result.append(SigmaRuleResponse(**rule_dict))
|
result.append(SigmaRuleResponse(**rule_dict))
|
||||||
|
|
|
@ -8,3 +8,7 @@ python-multipart==0.0.6
|
||||||
redis==5.0.1
|
redis==5.0.1
|
||||||
alembic==1.13.1
|
alembic==1.13.1
|
||||||
asyncpg==0.29.0
|
asyncpg==0.29.0
|
||||||
|
pygithub==2.1.1
|
||||||
|
gitpython==3.1.40
|
||||||
|
beautifulsoup4==4.12.2
|
||||||
|
lxml==4.9.3
|
||||||
|
|
|
@ -275,7 +275,37 @@ function App() {
|
||||||
Auto-generated
|
Auto-generated
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
{rule.exploit_based && (
|
||||||
|
<span className="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-red-100 text-red-800">
|
||||||
|
🔍 Exploit-Based
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
{rule.github_repos && rule.github_repos.length > 0 && (
|
||||||
|
<div className="mt-2">
|
||||||
|
<p className="text-xs text-gray-500">
|
||||||
|
Based on {rule.github_repos.length} GitHub repository{rule.github_repos.length > 1 ? 's' : ''}:
|
||||||
|
</p>
|
||||||
|
<div className="flex flex-wrap gap-1 mt-1">
|
||||||
|
{rule.github_repos.slice(0, 3).map((repo, index) => (
|
||||||
|
<a
|
||||||
|
key={index}
|
||||||
|
href={repo}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-xs text-blue-600 hover:text-blue-800 underline"
|
||||||
|
>
|
||||||
|
{repo.split('/').slice(-2).join('/')}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
{rule.github_repos.length > 3 && (
|
||||||
|
<span className="text-xs text-gray-500">
|
||||||
|
+{rule.github_repos.length - 3} more
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm text-gray-500">
|
<span className="text-sm text-gray-500">
|
||||||
{formatDate(rule.created_at)}
|
{formatDate(rule.created_at)}
|
||||||
|
@ -291,12 +321,52 @@ function App() {
|
||||||
{rule.rule_content}
|
{rule.rule_content}
|
||||||
</SyntaxHighlighter>
|
</SyntaxHighlighter>
|
||||||
</div>
|
</div>
|
||||||
|
{rule.exploit_indicators && (
|
||||||
|
<div className="mt-4 p-3 bg-gray-50 rounded-md">
|
||||||
|
<h4 className="text-sm font-medium text-gray-700 mb-2">Exploit Indicators Found:</h4>
|
||||||
|
<ExploitIndicators indicators={rule.exploit_indicators} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const ExploitIndicators = ({ indicators }) => {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(indicators);
|
||||||
|
return (
|
||||||
|
<div className="space-y-2">
|
||||||
|
{Object.entries(parsed).map(([category, items]) => (
|
||||||
|
items.length > 0 && (
|
||||||
|
<div key={category} className="flex flex-wrap items-center gap-2">
|
||||||
|
<span className="text-xs font-medium text-gray-600 capitalize min-w-0">
|
||||||
|
{category}:
|
||||||
|
</span>
|
||||||
|
<div className="flex flex-wrap gap-1">
|
||||||
|
{items.slice(0, 5).map((item, index) => (
|
||||||
|
<span
|
||||||
|
key={index}
|
||||||
|
className="inline-flex px-2 py-1 text-xs rounded bg-gray-200 text-gray-700 font-mono"
|
||||||
|
>
|
||||||
|
{typeof item === 'string' && item.length > 30 ? item.substring(0, 30) + '...' : item}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
{items.length > 5 && (
|
||||||
|
<span className="text-xs text-gray-500">+{items.length - 5} more</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return <p className="text-xs text-gray-500">Invalid indicator data</p>;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const CVEDetail = ({ cve, onClose }) => {
|
const CVEDetail = ({ cve, onClose }) => {
|
||||||
const [cveRules, setCveRules] = useState([]);
|
const [cveRules, setCveRules] = useState([]);
|
||||||
|
|
||||||
|
@ -393,8 +463,38 @@ function App() {
|
||||||
<span className="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">
|
<span className="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">
|
||||||
{rule.confidence_level}
|
{rule.confidence_level}
|
||||||
</span>
|
</span>
|
||||||
|
{rule.exploit_based && (
|
||||||
|
<span className="inline-flex px-2 py-1 text-xs font-semibold rounded-full bg-red-100 text-red-800">
|
||||||
|
🔍 Exploit-Based
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{rule.github_repos && rule.github_repos.length > 0 && (
|
||||||
|
<div className="mb-3 p-2 bg-blue-50 rounded">
|
||||||
|
<p className="text-xs text-blue-700 font-medium mb-1">
|
||||||
|
Based on GitHub exploit analysis:
|
||||||
|
</p>
|
||||||
|
<div className="flex flex-wrap gap-1">
|
||||||
|
{rule.github_repos.slice(0, 2).map((repo, index) => (
|
||||||
|
<a
|
||||||
|
key={index}
|
||||||
|
href={repo}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-xs text-blue-600 hover:text-blue-800 underline"
|
||||||
|
>
|
||||||
|
{repo.split('/').slice(-2).join('/')}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
{rule.github_repos.length > 2 && (
|
||||||
|
<span className="text-xs text-blue-600">
|
||||||
|
+{rule.github_repos.length - 2} more
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<SyntaxHighlighter
|
<SyntaxHighlighter
|
||||||
language="yaml"
|
language="yaml"
|
||||||
style={tomorrow}
|
style={tomorrow}
|
||||||
|
@ -403,6 +503,12 @@ function App() {
|
||||||
>
|
>
|
||||||
{rule.rule_content}
|
{rule.rule_content}
|
||||||
</SyntaxHighlighter>
|
</SyntaxHighlighter>
|
||||||
|
{rule.exploit_indicators && (
|
||||||
|
<div className="mt-3 p-2 bg-gray-50 rounded">
|
||||||
|
<p className="text-xs font-medium text-gray-700 mb-1">Exploit Indicators:</p>
|
||||||
|
<ExploitIndicators indicators={rule.exploit_indicators} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
37
init.sql
37
init.sql
|
@ -27,6 +27,9 @@ CREATE TABLE sigma_rules (
|
||||||
log_source VARCHAR(100),
|
log_source VARCHAR(100),
|
||||||
confidence_level VARCHAR(20),
|
confidence_level VARCHAR(20),
|
||||||
auto_generated BOOLEAN DEFAULT TRUE,
|
auto_generated BOOLEAN DEFAULT TRUE,
|
||||||
|
exploit_based BOOLEAN DEFAULT FALSE,
|
||||||
|
github_repos TEXT[],
|
||||||
|
exploit_indicators TEXT,
|
||||||
created_at TIMESTAMP DEFAULT NOW(),
|
created_at TIMESTAMP DEFAULT NOW(),
|
||||||
updated_at TIMESTAMP DEFAULT NOW()
|
updated_at TIMESTAMP DEFAULT NOW()
|
||||||
);
|
);
|
||||||
|
@ -54,8 +57,7 @@ date: {date}
|
||||||
references:
|
references:
|
||||||
- {cve_url}
|
- {cve_url}
|
||||||
tags:
|
tags:
|
||||||
- attack.execution
|
- {tags}
|
||||||
- {cve_id}
|
|
||||||
logsource:
|
logsource:
|
||||||
category: process_creation
|
category: process_creation
|
||||||
product: windows
|
product: windows
|
||||||
|
@ -80,8 +82,7 @@ date: {date}
|
||||||
references:
|
references:
|
||||||
- {cve_url}
|
- {cve_url}
|
||||||
tags:
|
tags:
|
||||||
- attack.command_and_control
|
- {tags}
|
||||||
- {cve_id}
|
|
||||||
logsource:
|
logsource:
|
||||||
category: network_connection
|
category: network_connection
|
||||||
product: windows
|
product: windows
|
||||||
|
@ -107,8 +108,7 @@ date: {date}
|
||||||
references:
|
references:
|
||||||
- {cve_url}
|
- {cve_url}
|
||||||
tags:
|
tags:
|
||||||
- attack.defense_evasion
|
- {tags}
|
||||||
- {cve_id}
|
|
||||||
logsource:
|
logsource:
|
||||||
category: file_event
|
category: file_event
|
||||||
product: windows
|
product: windows
|
||||||
|
@ -122,6 +122,31 @@ falsepositives:
|
||||||
level: {level}',
|
level: {level}',
|
||||||
ARRAY['file', 'filesystem', 'modification'],
|
ARRAY['file', 'filesystem', 'modification'],
|
||||||
'Template for file modification detection'
|
'Template for file modification detection'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'PowerShell Execution',
|
||||||
|
'title: {title}
|
||||||
|
description: {description}
|
||||||
|
id: {rule_id}
|
||||||
|
status: experimental
|
||||||
|
author: CVE-SIGMA Auto Generator
|
||||||
|
date: {date}
|
||||||
|
references:
|
||||||
|
- {cve_url}
|
||||||
|
tags:
|
||||||
|
- {tags}
|
||||||
|
logsource:
|
||||||
|
product: windows
|
||||||
|
category: ps_script
|
||||||
|
detection:
|
||||||
|
selection:
|
||||||
|
ScriptBlockText|contains: {suspicious_processes}
|
||||||
|
condition: selection
|
||||||
|
falsepositives:
|
||||||
|
- Legitimate PowerShell scripts
|
||||||
|
level: {level}',
|
||||||
|
ARRAY['powershell', 'script', 'ps1'],
|
||||||
|
'Template for PowerShell script execution detection'
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Create indexes
|
-- Create indexes
|
||||||
|
|
Loading…
Add table
Reference in a new issue