exaai-agent 2.0.5__py3-none-any.whl → 2.0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {exaai_agent-2.0.5.dist-info → exaai_agent-2.0.6.dist-info}/METADATA +1 -1
- {exaai_agent-2.0.5.dist-info → exaai_agent-2.0.6.dist-info}/RECORD +18 -10
- exaaiagnt/interface/tui.py +16 -2
- exaaiagnt/llm/__init__.py +13 -0
- exaaiagnt/llm/llm.py +14 -3
- exaaiagnt/llm/llm_traffic_controller.py +351 -0
- exaaiagnt/prompts/auto_loader.py +104 -0
- exaaiagnt/prompts/cloud/aws_cloud_security.jinja +235 -0
- exaaiagnt/prompts/frameworks/modern_js_frameworks.jinja +194 -0
- exaaiagnt/prompts/vulnerabilities/react2shell.jinja +187 -0
- exaaiagnt/tools/__init__.py +58 -0
- exaaiagnt/tools/response_analyzer.py +294 -0
- exaaiagnt/tools/smart_fuzzer.py +286 -0
- exaaiagnt/tools/tool_prompts.py +210 -0
- exaaiagnt/tools/vuln_validator.py +412 -0
- {exaai_agent-2.0.5.dist-info → exaai_agent-2.0.6.dist-info}/WHEEL +0 -0
- {exaai_agent-2.0.5.dist-info → exaai_agent-2.0.6.dist-info}/entry_points.txt +0 -0
- {exaai_agent-2.0.5.dist-info → exaai_agent-2.0.6.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tool Prompts - Enhanced prompts for security testing tools.
|
|
3
|
+
|
|
4
|
+
Provides intelligent prompts and guidance for:
|
|
5
|
+
- Smart Fuzzer usage
|
|
6
|
+
- Response analysis
|
|
7
|
+
- Vulnerability validation
|
|
8
|
+
- WAF bypass techniques
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
# Smart Fuzzer prompts
|
|
12
|
+
FUZZER_SYSTEM_PROMPT = """
|
|
13
|
+
You are an expert security fuzzer. When fuzzing parameters:
|
|
14
|
+
|
|
15
|
+
1. IDENTIFY PARAMETER TYPE:
|
|
16
|
+
- Numeric IDs → Test for IDOR, SQLi
|
|
17
|
+
- URLs → Test for SSRF, Open Redirect
|
|
18
|
+
- File paths → Test for Path Traversal
|
|
19
|
+
- User input → Test for XSS, SQLi, SSTI
|
|
20
|
+
|
|
21
|
+
2. USE CONTEXT-AWARE PAYLOADS:
|
|
22
|
+
- API endpoints → Focus on injection
|
|
23
|
+
- Authentication → Focus on bypass
|
|
24
|
+
- File operations → Focus on traversal
|
|
25
|
+
- Search/filter → Focus on SQLi
|
|
26
|
+
|
|
27
|
+
3. ANALYZE RESPONSES:
|
|
28
|
+
- 500 errors → Possible injection point
|
|
29
|
+
- Different content length → Boolean-based detection
|
|
30
|
+
- Time delays → Time-based injection
|
|
31
|
+
- Error messages → Information disclosure
|
|
32
|
+
|
|
33
|
+
4. PRIORITIZE:
|
|
34
|
+
- Critical: SQLi, Command Injection, SSRF
|
|
35
|
+
- High: XSS, Path Traversal, SSTI
|
|
36
|
+
- Medium: IDOR, Open Redirect
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
# Response Analyzer prompts
|
|
40
|
+
ANALYZER_SYSTEM_PROMPT = """
|
|
41
|
+
When analyzing responses, look for:
|
|
42
|
+
|
|
43
|
+
1. ERROR PATTERNS:
|
|
44
|
+
- SQL errors (MySQL, PostgreSQL, MSSQL, Oracle, SQLite)
|
|
45
|
+
- Stack traces (Python, Java, PHP, Node.js)
|
|
46
|
+
- Path disclosures (/var/www, C:\\inetpub, /home/)
|
|
47
|
+
|
|
48
|
+
2. INFORMATION LEAKAGE:
|
|
49
|
+
- API keys, secrets, tokens
|
|
50
|
+
- Internal IPs and hostnames
|
|
51
|
+
- Database connection strings
|
|
52
|
+
- Debug information
|
|
53
|
+
|
|
54
|
+
3. SECURITY HEADERS:
|
|
55
|
+
- Missing: X-Frame-Options, CSP, X-Content-Type-Options
|
|
56
|
+
- Weak: Permissive CORS, insecure cookies
|
|
57
|
+
|
|
58
|
+
4. BEHAVIORAL CHANGES:
|
|
59
|
+
- Response time differences (timing attacks)
|
|
60
|
+
- Content length variations (boolean-based)
|
|
61
|
+
- Status code changes
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
# Vulnerability Validator prompts
|
|
65
|
+
VALIDATOR_SYSTEM_PROMPT = """
|
|
66
|
+
When validating vulnerabilities:
|
|
67
|
+
|
|
68
|
+
1. CONFIRM THE FINDING:
|
|
69
|
+
- Reproduce the issue multiple times
|
|
70
|
+
- Test with different payloads
|
|
71
|
+
- Verify impact is real
|
|
72
|
+
|
|
73
|
+
2. ASSESS SEVERITY:
|
|
74
|
+
- Critical: RCE, SQLi with data access, Auth bypass
|
|
75
|
+
- High: XSS (stored), SSRF to internal services
|
|
76
|
+
- Medium: IDOR, Reflected XSS, Info disclosure
|
|
77
|
+
- Low: Self-XSS, Rate limit issues
|
|
78
|
+
|
|
79
|
+
3. GENERATE PoC:
|
|
80
|
+
- Clear step-by-step reproduction
|
|
81
|
+
- Include all necessary parameters
|
|
82
|
+
- Document expected vs actual behavior
|
|
83
|
+
|
|
84
|
+
4. PROVIDE REMEDIATION:
|
|
85
|
+
- Specific fix recommendations
|
|
86
|
+
- Code examples when possible
|
|
87
|
+
- Security best practices
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
# WAF Bypass prompts
|
|
91
|
+
WAF_BYPASS_PROMPT = """
|
|
92
|
+
When encountering WAF blocks:
|
|
93
|
+
|
|
94
|
+
1. IDENTIFY THE WAF:
|
|
95
|
+
- Check response headers (Server, X-*)
|
|
96
|
+
- Analyze block page content
|
|
97
|
+
- Note status codes (403, 406, 429)
|
|
98
|
+
|
|
99
|
+
2. TRY BYPASS TECHNIQUES:
|
|
100
|
+
- URL encoding variations
|
|
101
|
+
- Unicode normalization
|
|
102
|
+
- Case manipulation
|
|
103
|
+
- Comment insertion
|
|
104
|
+
- HTTP parameter pollution
|
|
105
|
+
- HTTP verb tampering
|
|
106
|
+
|
|
107
|
+
3. ENCODING STRATEGIES:
|
|
108
|
+
- Double URL encoding
|
|
109
|
+
- HTML entities
|
|
110
|
+
- Hex encoding
|
|
111
|
+
- Unicode escapes
|
|
112
|
+
|
|
113
|
+
4. EVASION PATTERNS:
|
|
114
|
+
- Payload splitting
|
|
115
|
+
- Null bytes
|
|
116
|
+
- Tab/newline injection
|
|
117
|
+
- JSON/XML smuggling
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
# Combined tool usage prompt
|
|
121
|
+
SECURITY_TESTING_PROMPT = """
|
|
122
|
+
# ExaAi Security Testing Workflow
|
|
123
|
+
|
|
124
|
+
## Step 1: Reconnaissance
|
|
125
|
+
- Map endpoints and parameters
|
|
126
|
+
- Identify input types and contexts
|
|
127
|
+
- Note authentication requirements
|
|
128
|
+
|
|
129
|
+
## Step 2: Intelligent Fuzzing
|
|
130
|
+
Use SmartFuzzer for context-aware testing:
|
|
131
|
+
```python
|
|
132
|
+
from exaaiagnt.tools import fuzz_parameter, VulnCategory
|
|
133
|
+
# Automatic payload selection based on parameter type
|
|
134
|
+
payloads = fuzz_parameter("user_id", "123")
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Step 3: Response Analysis
|
|
138
|
+
Analyze every response for indicators:
|
|
139
|
+
```python
|
|
140
|
+
from exaaiagnt.tools import analyze_response
|
|
141
|
+
result = analyze_response(response.text, response.status_code)
|
|
142
|
+
for detection in result.detections:
|
|
143
|
+
print(f"Found: {detection.detection_type} - {detection.evidence}")
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Step 4: WAF Detection & Bypass
|
|
147
|
+
If blocked, attempt bypass:
|
|
148
|
+
```python
|
|
149
|
+
from exaaiagnt.tools import detect_waf, generate_bypasses
|
|
150
|
+
waf_result = detect_waf(status_code, headers, body)
|
|
151
|
+
if waf_result.detected:
|
|
152
|
+
bypasses = generate_bypasses(original_payload)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Step 5: Vulnerability Validation
|
|
156
|
+
Confirm and document findings:
|
|
157
|
+
```python
|
|
158
|
+
from exaaiagnt.tools import create_vuln_report
|
|
159
|
+
report = create_vuln_report(
|
|
160
|
+
vuln_type="sql_injection",
|
|
161
|
+
url=target_url,
|
|
162
|
+
parameter="id",
|
|
163
|
+
payload="' OR 1=1--",
|
|
164
|
+
evidence="Database error in response"
|
|
165
|
+
)
|
|
166
|
+
# Generates PoC, CVSS, remediation
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Step 6: Report Generation
|
|
170
|
+
Compile all confirmed vulnerabilities with:
|
|
171
|
+
- Severity ratings
|
|
172
|
+
- Proof of Concept
|
|
173
|
+
- Remediation guidance
|
|
174
|
+
"""
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def get_fuzzer_prompt() -> str:
|
|
178
|
+
"""Get the fuzzer system prompt."""
|
|
179
|
+
return FUZZER_SYSTEM_PROMPT.strip()
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def get_analyzer_prompt() -> str:
|
|
183
|
+
"""Get the analyzer system prompt."""
|
|
184
|
+
return ANALYZER_SYSTEM_PROMPT.strip()
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def get_validator_prompt() -> str:
|
|
188
|
+
"""Get the validator system prompt."""
|
|
189
|
+
return VALIDATOR_SYSTEM_PROMPT.strip()
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def get_waf_bypass_prompt() -> str:
|
|
193
|
+
"""Get the WAF bypass prompt."""
|
|
194
|
+
return WAF_BYPASS_PROMPT.strip()
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def get_security_testing_prompt() -> str:
|
|
198
|
+
"""Get the combined security testing workflow prompt."""
|
|
199
|
+
return SECURITY_TESTING_PROMPT.strip()
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def get_all_tool_prompts() -> dict[str, str]:
|
|
203
|
+
"""Get all tool prompts as a dictionary."""
|
|
204
|
+
return {
|
|
205
|
+
"fuzzer": get_fuzzer_prompt(),
|
|
206
|
+
"analyzer": get_analyzer_prompt(),
|
|
207
|
+
"validator": get_validator_prompt(),
|
|
208
|
+
"waf_bypass": get_waf_bypass_prompt(),
|
|
209
|
+
"security_testing": get_security_testing_prompt(),
|
|
210
|
+
}
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Vulnerability Validator - Validates and confirms detected vulnerabilities.
|
|
3
|
+
|
|
4
|
+
Features:
|
|
5
|
+
- Confirmation testing
|
|
6
|
+
- PoC generation
|
|
7
|
+
- False positive reduction
|
|
8
|
+
- Severity assessment
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
import re
|
|
13
|
+
from dataclasses import dataclass, field
|
|
14
|
+
from enum import Enum
|
|
15
|
+
from typing import Any, Optional, Callable
|
|
16
|
+
from datetime import datetime
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class VulnStatus(Enum):
|
|
23
|
+
"""Vulnerability validation status."""
|
|
24
|
+
PENDING = "pending"
|
|
25
|
+
CONFIRMED = "confirmed"
|
|
26
|
+
FALSE_POSITIVE = "false_positive"
|
|
27
|
+
NEEDS_REVIEW = "needs_review"
|
|
28
|
+
EXPLOITABLE = "exploitable"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class Severity(Enum):
|
|
32
|
+
"""Vulnerability severity levels."""
|
|
33
|
+
CRITICAL = "critical"
|
|
34
|
+
HIGH = "high"
|
|
35
|
+
MEDIUM = "medium"
|
|
36
|
+
LOW = "low"
|
|
37
|
+
INFO = "informational"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass
|
|
41
|
+
class VulnerabilityReport:
|
|
42
|
+
"""A validated vulnerability report."""
|
|
43
|
+
vuln_id: str
|
|
44
|
+
vuln_type: str
|
|
45
|
+
status: VulnStatus
|
|
46
|
+
severity: Severity
|
|
47
|
+
url: str
|
|
48
|
+
parameter: str
|
|
49
|
+
payload: str
|
|
50
|
+
evidence: str
|
|
51
|
+
poc_steps: list[str] = field(default_factory=list)
|
|
52
|
+
remediation: str = ""
|
|
53
|
+
cvss_score: float = 0.0
|
|
54
|
+
discovered_at: str = field(default_factory=lambda: datetime.now().isoformat())
|
|
55
|
+
confirmed_at: Optional[str] = None
|
|
56
|
+
notes: str = ""
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@dataclass
|
|
60
|
+
class ValidationTest:
|
|
61
|
+
"""A validation test case."""
|
|
62
|
+
test_name: str
|
|
63
|
+
test_func: Callable
|
|
64
|
+
required: bool = True
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class VulnValidator:
|
|
68
|
+
"""
|
|
69
|
+
Vulnerability validation engine.
|
|
70
|
+
|
|
71
|
+
Features:
|
|
72
|
+
- Confirms vulnerabilities with additional tests
|
|
73
|
+
- Generates PoC steps
|
|
74
|
+
- Calculates CVSS scores
|
|
75
|
+
- Provides remediation advice
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
_instance: Optional["VulnValidator"] = None
|
|
79
|
+
|
|
80
|
+
def __new__(cls) -> "VulnValidator":
|
|
81
|
+
if cls._instance is None:
|
|
82
|
+
cls._instance = super().__new__(cls)
|
|
83
|
+
cls._instance._initialized = False
|
|
84
|
+
return cls._instance
|
|
85
|
+
|
|
86
|
+
def __init__(self):
|
|
87
|
+
if self._initialized:
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
self._reports: dict[str, VulnerabilityReport] = {}
|
|
91
|
+
self._remediation_db = self._load_remediation_db()
|
|
92
|
+
self._initialized = True
|
|
93
|
+
logger.info("VulnValidator initialized")
|
|
94
|
+
|
|
95
|
+
def _load_remediation_db(self) -> dict[str, dict[str, Any]]:
|
|
96
|
+
"""Load remediation advice database."""
|
|
97
|
+
return {
|
|
98
|
+
"sql_injection": {
|
|
99
|
+
"severity": Severity.CRITICAL,
|
|
100
|
+
"cvss_base": 9.8,
|
|
101
|
+
"remediation": """
|
|
102
|
+
1. Use parameterized queries (prepared statements)
|
|
103
|
+
2. Use ORM frameworks with built-in protection
|
|
104
|
+
3. Validate and sanitize all user inputs
|
|
105
|
+
4. Apply principle of least privilege to database accounts
|
|
106
|
+
5. Enable WAF with SQL injection rules
|
|
107
|
+
""",
|
|
108
|
+
"poc_template": [
|
|
109
|
+
"Navigate to {url}",
|
|
110
|
+
"Insert payload '{payload}' in parameter '{parameter}'",
|
|
111
|
+
"Observe the response showing SQL error or data leakage",
|
|
112
|
+
"Evidence: {evidence}"
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
"xss": {
|
|
116
|
+
"severity": Severity.HIGH,
|
|
117
|
+
"cvss_base": 7.1,
|
|
118
|
+
"remediation": """
|
|
119
|
+
1. Encode output based on context (HTML, JS, URL, CSS)
|
|
120
|
+
2. Use Content-Security-Policy header
|
|
121
|
+
3. Validate and sanitize input
|
|
122
|
+
4. Use frameworks with auto-escaping (React, Vue, Angular)
|
|
123
|
+
5. Set HttpOnly flag on cookies
|
|
124
|
+
""",
|
|
125
|
+
"poc_template": [
|
|
126
|
+
"Navigate to {url}",
|
|
127
|
+
"Insert XSS payload '{payload}' in parameter '{parameter}'",
|
|
128
|
+
"Observe JavaScript execution or DOM modification",
|
|
129
|
+
"Evidence: {evidence}"
|
|
130
|
+
]
|
|
131
|
+
},
|
|
132
|
+
"ssrf": {
|
|
133
|
+
"severity": Severity.HIGH,
|
|
134
|
+
"cvss_base": 8.6,
|
|
135
|
+
"remediation": """
|
|
136
|
+
1. Validate and whitelist allowed URLs/domains
|
|
137
|
+
2. Block requests to internal IP ranges
|
|
138
|
+
3. Disable unnecessary URL schemes (file://, gopher://)
|
|
139
|
+
4. Use network segmentation
|
|
140
|
+
5. Implement proper egress filtering
|
|
141
|
+
""",
|
|
142
|
+
"poc_template": [
|
|
143
|
+
"Navigate to {url}",
|
|
144
|
+
"Supply internal URL '{payload}' in parameter '{parameter}'",
|
|
145
|
+
"Observe access to internal resources",
|
|
146
|
+
"Evidence: {evidence}"
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
"path_traversal": {
|
|
150
|
+
"severity": Severity.HIGH,
|
|
151
|
+
"cvss_base": 7.5,
|
|
152
|
+
"remediation": """
|
|
153
|
+
1. Validate and sanitize file paths
|
|
154
|
+
2. Use whitelist of allowed files
|
|
155
|
+
3. Chroot or sandbox file access
|
|
156
|
+
4. Remove ../ sequences from input
|
|
157
|
+
5. Use secure file APIs
|
|
158
|
+
""",
|
|
159
|
+
"poc_template": [
|
|
160
|
+
"Navigate to {url}",
|
|
161
|
+
"Supply path traversal payload '{payload}' in parameter '{parameter}'",
|
|
162
|
+
"Observe disclosure of system files",
|
|
163
|
+
"Evidence: {evidence}"
|
|
164
|
+
]
|
|
165
|
+
},
|
|
166
|
+
"command_injection": {
|
|
167
|
+
"severity": Severity.CRITICAL,
|
|
168
|
+
"cvss_base": 10.0,
|
|
169
|
+
"remediation": """
|
|
170
|
+
1. Never pass user input to system commands
|
|
171
|
+
2. Use language-specific APIs instead of shell commands
|
|
172
|
+
3. If unavoidable, use strict input validation
|
|
173
|
+
4. Apply least privilege to application user
|
|
174
|
+
5. Use containerization/sandboxing
|
|
175
|
+
""",
|
|
176
|
+
"poc_template": [
|
|
177
|
+
"Navigate to {url}",
|
|
178
|
+
"Insert command injection payload '{payload}' in parameter '{parameter}'",
|
|
179
|
+
"Observe command execution on server",
|
|
180
|
+
"Evidence: {evidence}"
|
|
181
|
+
]
|
|
182
|
+
},
|
|
183
|
+
"idor": {
|
|
184
|
+
"severity": Severity.MEDIUM,
|
|
185
|
+
"cvss_base": 6.5,
|
|
186
|
+
"remediation": """
|
|
187
|
+
1. Implement proper authorization checks
|
|
188
|
+
2. Use indirect object references (GUIDs)
|
|
189
|
+
3. Verify user has access to requested resource
|
|
190
|
+
4. Log and monitor access patterns
|
|
191
|
+
5. Implement rate limiting
|
|
192
|
+
""",
|
|
193
|
+
"poc_template": [
|
|
194
|
+
"Authenticate as User A",
|
|
195
|
+
"Navigate to {url}",
|
|
196
|
+
"Change parameter '{parameter}' to another user's ID '{payload}'",
|
|
197
|
+
"Observe access to User B's data",
|
|
198
|
+
"Evidence: {evidence}"
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
"ssti": {
|
|
202
|
+
"severity": Severity.CRITICAL,
|
|
203
|
+
"cvss_base": 9.8,
|
|
204
|
+
"remediation": """
|
|
205
|
+
1. Never pass user input directly to templates
|
|
206
|
+
2. Use sandboxed template engines
|
|
207
|
+
3. Disable dangerous template features
|
|
208
|
+
4. Validate and sanitize input
|
|
209
|
+
5. Use Content-Security-Policy
|
|
210
|
+
""",
|
|
211
|
+
"poc_template": [
|
|
212
|
+
"Navigate to {url}",
|
|
213
|
+
"Insert template payload '{payload}' in parameter '{parameter}'",
|
|
214
|
+
"Observe template expression evaluation",
|
|
215
|
+
"Evidence: {evidence}"
|
|
216
|
+
]
|
|
217
|
+
},
|
|
218
|
+
"open_redirect": {
|
|
219
|
+
"severity": Severity.LOW,
|
|
220
|
+
"cvss_base": 4.7,
|
|
221
|
+
"remediation": """
|
|
222
|
+
1. Validate redirect URLs against whitelist
|
|
223
|
+
2. Use relative URLs only
|
|
224
|
+
3. Remove user control over redirect destination
|
|
225
|
+
4. Add confirmation page for external redirects
|
|
226
|
+
5. Log redirect attempts
|
|
227
|
+
""",
|
|
228
|
+
"poc_template": [
|
|
229
|
+
"Navigate to {url}",
|
|
230
|
+
"Supply external URL '{payload}' in parameter '{parameter}'",
|
|
231
|
+
"Observe redirect to external site",
|
|
232
|
+
"Evidence: {evidence}"
|
|
233
|
+
]
|
|
234
|
+
},
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
def create_report(
|
|
238
|
+
self,
|
|
239
|
+
vuln_type: str,
|
|
240
|
+
url: str,
|
|
241
|
+
parameter: str,
|
|
242
|
+
payload: str,
|
|
243
|
+
evidence: str,
|
|
244
|
+
status: VulnStatus = VulnStatus.PENDING
|
|
245
|
+
) -> VulnerabilityReport:
|
|
246
|
+
"""Create a new vulnerability report."""
|
|
247
|
+
vuln_id = f"{vuln_type}_{hash(url + parameter + payload) & 0xFFFFFFFF:08x}"
|
|
248
|
+
|
|
249
|
+
# Get info from remediation DB
|
|
250
|
+
vuln_info = self._remediation_db.get(vuln_type, {})
|
|
251
|
+
severity = vuln_info.get("severity", Severity.MEDIUM)
|
|
252
|
+
cvss = vuln_info.get("cvss_base", 5.0)
|
|
253
|
+
remediation = vuln_info.get("remediation", "Review and fix the vulnerability.")
|
|
254
|
+
|
|
255
|
+
# Generate PoC steps
|
|
256
|
+
poc_template = vuln_info.get("poc_template", [])
|
|
257
|
+
poc_steps = [
|
|
258
|
+
step.format(url=url, parameter=parameter, payload=payload, evidence=evidence)
|
|
259
|
+
for step in poc_template
|
|
260
|
+
]
|
|
261
|
+
|
|
262
|
+
report = VulnerabilityReport(
|
|
263
|
+
vuln_id=vuln_id,
|
|
264
|
+
vuln_type=vuln_type,
|
|
265
|
+
status=status,
|
|
266
|
+
severity=severity,
|
|
267
|
+
url=url,
|
|
268
|
+
parameter=parameter,
|
|
269
|
+
payload=payload,
|
|
270
|
+
evidence=evidence,
|
|
271
|
+
poc_steps=poc_steps,
|
|
272
|
+
remediation=remediation.strip(),
|
|
273
|
+
cvss_score=cvss
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
self._reports[vuln_id] = report
|
|
277
|
+
logger.info(f"Created vulnerability report: {vuln_id}")
|
|
278
|
+
|
|
279
|
+
return report
|
|
280
|
+
|
|
281
|
+
def confirm_vulnerability(self, vuln_id: str, additional_evidence: str = "") -> bool:
|
|
282
|
+
"""Mark a vulnerability as confirmed."""
|
|
283
|
+
if vuln_id not in self._reports:
|
|
284
|
+
return False
|
|
285
|
+
|
|
286
|
+
report = self._reports[vuln_id]
|
|
287
|
+
report.status = VulnStatus.CONFIRMED
|
|
288
|
+
report.confirmed_at = datetime.now().isoformat()
|
|
289
|
+
|
|
290
|
+
if additional_evidence:
|
|
291
|
+
report.evidence += f"\n\nAdditional evidence:\n{additional_evidence}"
|
|
292
|
+
|
|
293
|
+
logger.info(f"Confirmed vulnerability: {vuln_id}")
|
|
294
|
+
return True
|
|
295
|
+
|
|
296
|
+
def mark_exploitable(self, vuln_id: str, exploit_details: str) -> bool:
|
|
297
|
+
"""Mark a vulnerability as exploitable with details."""
|
|
298
|
+
if vuln_id not in self._reports:
|
|
299
|
+
return False
|
|
300
|
+
|
|
301
|
+
report = self._reports[vuln_id]
|
|
302
|
+
report.status = VulnStatus.EXPLOITABLE
|
|
303
|
+
report.notes += f"\n\nExploit details:\n{exploit_details}"
|
|
304
|
+
|
|
305
|
+
# Increase severity for exploitable vulns
|
|
306
|
+
if report.severity == Severity.MEDIUM:
|
|
307
|
+
report.severity = Severity.HIGH
|
|
308
|
+
elif report.severity == Severity.HIGH:
|
|
309
|
+
report.severity = Severity.CRITICAL
|
|
310
|
+
|
|
311
|
+
logger.info(f"Marked vulnerability as exploitable: {vuln_id}")
|
|
312
|
+
return True
|
|
313
|
+
|
|
314
|
+
def mark_false_positive(self, vuln_id: str, reason: str) -> bool:
|
|
315
|
+
"""Mark a vulnerability as false positive."""
|
|
316
|
+
if vuln_id not in self._reports:
|
|
317
|
+
return False
|
|
318
|
+
|
|
319
|
+
report = self._reports[vuln_id]
|
|
320
|
+
report.status = VulnStatus.FALSE_POSITIVE
|
|
321
|
+
report.notes = f"False positive reason: {reason}"
|
|
322
|
+
|
|
323
|
+
logger.info(f"Marked as false positive: {vuln_id}")
|
|
324
|
+
return True
|
|
325
|
+
|
|
326
|
+
def get_report(self, vuln_id: str) -> Optional[VulnerabilityReport]:
|
|
327
|
+
"""Get a vulnerability report by ID."""
|
|
328
|
+
return self._reports.get(vuln_id)
|
|
329
|
+
|
|
330
|
+
def get_all_reports(
|
|
331
|
+
self,
|
|
332
|
+
status: Optional[VulnStatus] = None,
|
|
333
|
+
severity: Optional[Severity] = None
|
|
334
|
+
) -> list[VulnerabilityReport]:
|
|
335
|
+
"""Get all reports, optionally filtered."""
|
|
336
|
+
reports = list(self._reports.values())
|
|
337
|
+
|
|
338
|
+
if status:
|
|
339
|
+
reports = [r for r in reports if r.status == status]
|
|
340
|
+
|
|
341
|
+
if severity:
|
|
342
|
+
reports = [r for r in reports if r.severity == severity]
|
|
343
|
+
|
|
344
|
+
return reports
|
|
345
|
+
|
|
346
|
+
def get_confirmed_vulns(self) -> list[VulnerabilityReport]:
|
|
347
|
+
"""Get all confirmed vulnerabilities."""
|
|
348
|
+
return [
|
|
349
|
+
r for r in self._reports.values()
|
|
350
|
+
if r.status in [VulnStatus.CONFIRMED, VulnStatus.EXPLOITABLE]
|
|
351
|
+
]
|
|
352
|
+
|
|
353
|
+
def generate_summary(self) -> dict[str, Any]:
|
|
354
|
+
"""Generate a summary of all findings."""
|
|
355
|
+
all_reports = list(self._reports.values())
|
|
356
|
+
|
|
357
|
+
summary = {
|
|
358
|
+
"total": len(all_reports),
|
|
359
|
+
"by_status": {},
|
|
360
|
+
"by_severity": {},
|
|
361
|
+
"by_type": {},
|
|
362
|
+
"critical_count": 0,
|
|
363
|
+
"high_count": 0,
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
for report in all_reports:
|
|
367
|
+
# By status
|
|
368
|
+
status_key = report.status.value
|
|
369
|
+
summary["by_status"][status_key] = summary["by_status"].get(status_key, 0) + 1
|
|
370
|
+
|
|
371
|
+
# By severity
|
|
372
|
+
sev_key = report.severity.value
|
|
373
|
+
summary["by_severity"][sev_key] = summary["by_severity"].get(sev_key, 0) + 1
|
|
374
|
+
|
|
375
|
+
# By type
|
|
376
|
+
summary["by_type"][report.vuln_type] = summary["by_type"].get(report.vuln_type, 0) + 1
|
|
377
|
+
|
|
378
|
+
# Critical/High counts
|
|
379
|
+
if report.severity == Severity.CRITICAL:
|
|
380
|
+
summary["critical_count"] += 1
|
|
381
|
+
elif report.severity == Severity.HIGH:
|
|
382
|
+
summary["high_count"] += 1
|
|
383
|
+
|
|
384
|
+
return summary
|
|
385
|
+
|
|
386
|
+
def clear_reports(self):
|
|
387
|
+
"""Clear all reports."""
|
|
388
|
+
self._reports.clear()
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
# Global instance
|
|
392
|
+
_validator: Optional[VulnValidator] = None
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def get_vuln_validator() -> VulnValidator:
|
|
396
|
+
"""Get or create the global validator instance."""
|
|
397
|
+
global _validator
|
|
398
|
+
if _validator is None:
|
|
399
|
+
_validator = VulnValidator()
|
|
400
|
+
return _validator
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
def create_vuln_report(
|
|
404
|
+
vuln_type: str,
|
|
405
|
+
url: str,
|
|
406
|
+
parameter: str,
|
|
407
|
+
payload: str,
|
|
408
|
+
evidence: str
|
|
409
|
+
) -> VulnerabilityReport:
|
|
410
|
+
"""Convenience function to create a vulnerability report."""
|
|
411
|
+
validator = get_vuln_validator()
|
|
412
|
+
return validator.create_report(vuln_type, url, parameter, payload, evidence)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|