itteration
This commit is contained in:
parent
689e8c00d4
commit
949fbdbb45
@ -19,7 +19,7 @@ class Config:
|
|||||||
|
|
||||||
# --- General Settings ---
|
# --- General Settings ---
|
||||||
self.default_recursion_depth = 2
|
self.default_recursion_depth = 2
|
||||||
self.default_timeout = 10
|
self.default_timeout = 15
|
||||||
self.max_concurrent_requests = 5
|
self.max_concurrent_requests = 5
|
||||||
self.large_entity_threshold = 100
|
self.large_entity_threshold = 100
|
||||||
self.max_retries_per_target = 3
|
self.max_retries_per_target = 3
|
||||||
@ -27,7 +27,7 @@ class Config:
|
|||||||
|
|
||||||
# --- Rate Limiting (requests per minute) ---
|
# --- Rate Limiting (requests per minute) ---
|
||||||
self.rate_limits = {
|
self.rate_limits = {
|
||||||
'crtsh': 60,
|
'crtsh': 30,
|
||||||
'shodan': 60,
|
'shodan': 60,
|
||||||
'dns': 100
|
'dns': 100
|
||||||
}
|
}
|
||||||
|
@ -80,8 +80,8 @@ class GraphManager:
|
|||||||
return
|
return
|
||||||
if len(value) < 4 or value.lower() in ['true', 'false', 'unknown', 'none', 'crt.sh']:
|
if len(value) < 4 or value.lower() in ['true', 'false', 'unknown', 'none', 'crt.sh']:
|
||||||
return
|
return
|
||||||
elif isinstance(value, int) and abs(value) < 9999:
|
elif isinstance(value, int) and (abs(value) < 1024 or abs(value) > 65535):
|
||||||
return # Ignore small integers
|
return # Ignore small integers and common port numbers
|
||||||
elif isinstance(value, bool):
|
elif isinstance(value, bool):
|
||||||
return # Ignore boolean values
|
return # Ignore boolean values
|
||||||
|
|
||||||
@ -421,10 +421,14 @@ class GraphManager:
|
|||||||
def _get_confidence_distribution(self) -> Dict[str, int]:
|
def _get_confidence_distribution(self) -> Dict[str, int]:
|
||||||
"""Get distribution of edge confidence scores."""
|
"""Get distribution of edge confidence scores."""
|
||||||
distribution = {'high': 0, 'medium': 0, 'low': 0}
|
distribution = {'high': 0, 'medium': 0, 'low': 0}
|
||||||
for _, _, confidence in self.graph.edges(data='confidence_score', default=0):
|
for _, _, data in self.graph.edges(data=True):
|
||||||
if confidence >= 0.8: distribution['high'] += 1
|
confidence = data.get('confidence_score', 0)
|
||||||
elif confidence >= 0.6: distribution['medium'] += 1
|
if confidence >= 0.8:
|
||||||
else: distribution['low'] += 1
|
distribution['high'] += 1
|
||||||
|
elif confidence >= 0.6:
|
||||||
|
distribution['medium'] += 1
|
||||||
|
else:
|
||||||
|
distribution['low'] += 1
|
||||||
return distribution
|
return distribution
|
||||||
|
|
||||||
def get_statistics(self) -> Dict[str, Any]:
|
def get_statistics(self) -> Dict[str, Any]:
|
||||||
@ -439,9 +443,10 @@ class GraphManager:
|
|||||||
# Calculate distributions
|
# Calculate distributions
|
||||||
for node_type in NodeType:
|
for node_type in NodeType:
|
||||||
stats['node_type_distribution'][node_type.value] = self.get_nodes_by_type(node_type).__len__()
|
stats['node_type_distribution'][node_type.value] = self.get_nodes_by_type(node_type).__len__()
|
||||||
for _, _, rel_type in self.graph.edges(data='relationship_type', default='unknown'):
|
for _, _, data in self.graph.edges(data=True):
|
||||||
|
rel_type = data.get('relationship_type', 'unknown')
|
||||||
stats['relationship_type_distribution'][rel_type] = stats['relationship_type_distribution'].get(rel_type, 0) + 1
|
stats['relationship_type_distribution'][rel_type] = stats['relationship_type_distribution'].get(rel_type, 0) + 1
|
||||||
for _, _, provider in self.graph.edges(data='source_provider', default='unknown'):
|
provider = data.get('source_provider', 'unknown')
|
||||||
stats['provider_distribution'][provider] = stats['provider_distribution'].get(provider, 0) + 1
|
stats['provider_distribution'][provider] = stats['provider_distribution'].get(provider, 0) + 1
|
||||||
return stats
|
return stats
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ class ForensicLogger:
|
|||||||
Maintains detailed audit trail of all reconnaissance activities.
|
Maintains detailed audit trail of all reconnaissance activities.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, session_id: str = None):
|
def __init__(self, session_id: str = ""):
|
||||||
"""
|
"""
|
||||||
Initialize forensic logger.
|
Initialize forensic logger.
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import traceback
|
|||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
import importlib
|
import importlib
|
||||||
from typing import List, Set, Dict, Any, Tuple
|
from typing import List, Set, Dict, Any, Tuple, Optional
|
||||||
from concurrent.futures import ThreadPoolExecutor, as_completed, CancelledError, Future
|
from concurrent.futures import ThreadPoolExecutor, as_completed, CancelledError, Future
|
||||||
from collections import defaultdict, deque
|
from collections import defaultdict, deque
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
@ -49,7 +49,7 @@ class Scanner:
|
|||||||
self.max_depth = 2
|
self.max_depth = 2
|
||||||
self.stop_event = threading.Event()
|
self.stop_event = threading.Event()
|
||||||
self.scan_thread = None
|
self.scan_thread = None
|
||||||
self.session_id = None # Will be set by session manager
|
self.session_id: Optional[str] = None # Will be set by session manager
|
||||||
self.task_queue = deque([])
|
self.task_queue = deque([])
|
||||||
self.target_retries = defaultdict(int)
|
self.target_retries = defaultdict(int)
|
||||||
self.scan_failed_due_to_retries = False
|
self.scan_failed_due_to_retries = False
|
||||||
@ -170,9 +170,10 @@ class Scanner:
|
|||||||
attribute = getattr(module, attribute_name)
|
attribute = getattr(module, attribute_name)
|
||||||
if isinstance(attribute, type) and issubclass(attribute, BaseProvider) and attribute is not BaseProvider:
|
if isinstance(attribute, type) and issubclass(attribute, BaseProvider) and attribute is not BaseProvider:
|
||||||
provider_class = attribute
|
provider_class = attribute
|
||||||
provider_name = provider_class(session_config=self.config).get_name()
|
provider = provider_class(name=attribute_name, session_config=self.config)
|
||||||
|
provider_name = provider.get_name()
|
||||||
|
|
||||||
if self.config.is_provider_enabled(provider_name):
|
if self.config.is_provider_enabled(provider_name):
|
||||||
provider = provider_class(session_config=self.config)
|
|
||||||
if provider.is_available():
|
if provider.is_available():
|
||||||
provider.set_stop_event(self.stop_event)
|
provider.set_stop_event(self.stop_event)
|
||||||
self.providers.append(provider)
|
self.providers.append(provider)
|
||||||
@ -459,7 +460,7 @@ class Scanner:
|
|||||||
provider_states = node_data.get('metadata', {}).get('provider_states', {})
|
provider_states = node_data.get('metadata', {}).get('provider_states', {})
|
||||||
return provider_name in provider_states
|
return provider_name in provider_states
|
||||||
|
|
||||||
def _query_single_provider_forensic(self, provider, target: str, is_ip: bool, current_depth: int) -> List:
|
def _query_single_provider_forensic(self, provider, target: str, is_ip: bool, current_depth: int) -> Optional[List]:
|
||||||
"""Query a single provider with stop signal checking."""
|
"""Query a single provider with stop signal checking."""
|
||||||
provider_name = provider.get_name()
|
provider_name = provider.get_name()
|
||||||
start_time = datetime.now(timezone.utc)
|
start_time = datetime.now(timezone.utc)
|
||||||
@ -493,7 +494,7 @@ class Scanner:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def _update_provider_state(self, target: str, provider_name: str, status: str,
|
def _update_provider_state(self, target: str, provider_name: str, status: str,
|
||||||
results_count: int, error: str, start_time: datetime) -> None:
|
results_count: int, error: Optional[str], start_time: datetime) -> None:
|
||||||
"""Update provider state in node metadata for forensic tracking."""
|
"""Update provider state in node metadata for forensic tracking."""
|
||||||
if not self.graph.graph.has_node(target):
|
if not self.graph.graph.has_node(target):
|
||||||
return
|
return
|
||||||
@ -785,7 +786,7 @@ class Scanner:
|
|||||||
if isinstance(attribute, type) and issubclass(attribute, BaseProvider) and attribute is not BaseProvider:
|
if isinstance(attribute, type) and issubclass(attribute, BaseProvider) and attribute is not BaseProvider:
|
||||||
provider_class = attribute
|
provider_class = attribute
|
||||||
# Instantiate to get metadata, even if not fully configured
|
# Instantiate to get metadata, even if not fully configured
|
||||||
temp_provider = provider_class(session_config=self.config)
|
temp_provider = provider_class(name=attribute_name, session_config=self.config)
|
||||||
provider_name = temp_provider.get_name()
|
provider_name = temp_provider.get_name()
|
||||||
|
|
||||||
# Find the actual provider instance if it exists, to get live stats
|
# Find the actual provider instance if it exists, to get live stats
|
||||||
|
@ -228,7 +228,7 @@ class BaseProvider(ABC):
|
|||||||
self.total_requests += 1
|
self.total_requests += 1
|
||||||
|
|
||||||
# Prepare request
|
# Prepare request
|
||||||
request_headers = self.session.headers.copy()
|
request_headers = dict(self.session.headers).copy()
|
||||||
if headers:
|
if headers:
|
||||||
request_headers.update(headers)
|
request_headers.update(headers)
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ class CrtShProvider(BaseProvider):
|
|||||||
Now uses session-specific configuration and caching.
|
Now uses session-specific configuration and caching.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, session_config=None):
|
def __init__(self, name=None, session_config=None):
|
||||||
"""Initialize CrtSh provider with session-specific configuration."""
|
"""Initialize CrtSh provider with session-specific configuration."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
name="crtsh",
|
name="crtsh",
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
# dnsrecon/providers/dns_provider.py
|
# dnsrecon/providers/dns_provider.py
|
||||||
|
|
||||||
import dns.resolver
|
from dns import resolver, reversename
|
||||||
import dns.reversename
|
|
||||||
from typing import List, Dict, Any, Tuple
|
from typing import List, Dict, Any, Tuple
|
||||||
from .base_provider import BaseProvider
|
from .base_provider import BaseProvider
|
||||||
from utils.helpers import _is_valid_ip, _is_valid_domain
|
from utils.helpers import _is_valid_ip, _is_valid_domain
|
||||||
@ -13,7 +12,7 @@ class DNSProvider(BaseProvider):
|
|||||||
Now uses session-specific configuration.
|
Now uses session-specific configuration.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, session_config=None):
|
def __init__(self, name=None, session_config=None):
|
||||||
"""Initialize DNS provider with session-specific configuration."""
|
"""Initialize DNS provider with session-specific configuration."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
name="dns",
|
name="dns",
|
||||||
@ -23,7 +22,7 @@ class DNSProvider(BaseProvider):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Configure DNS resolver
|
# Configure DNS resolver
|
||||||
self.resolver = dns.resolver.Resolver()
|
self.resolver = resolver.Resolver()
|
||||||
self.resolver.timeout = 5
|
self.resolver.timeout = 5
|
||||||
self.resolver.lifetime = 10
|
self.resolver.lifetime = 10
|
||||||
#self.resolver.nameservers = ['127.0.0.1']
|
#self.resolver.nameservers = ['127.0.0.1']
|
||||||
@ -87,7 +86,7 @@ class DNSProvider(BaseProvider):
|
|||||||
try:
|
try:
|
||||||
# Perform reverse DNS lookup
|
# Perform reverse DNS lookup
|
||||||
self.total_requests += 1
|
self.total_requests += 1
|
||||||
reverse_name = dns.reversename.from_address(ip)
|
reverse_name = reversename.from_address(ip)
|
||||||
response = self.resolver.resolve(reverse_name, 'PTR')
|
response = self.resolver.resolve(reverse_name, 'PTR')
|
||||||
self.successful_requests += 1
|
self.successful_requests += 1
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ class ShodanProvider(BaseProvider):
|
|||||||
Now uses session-specific API keys.
|
Now uses session-specific API keys.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, session_config=None):
|
def __init__(self, name=None, session_config=None):
|
||||||
"""Initialize Shodan provider with session-specific configuration."""
|
"""Initialize Shodan provider with session-specific configuration."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
name="shodan",
|
name="shodan",
|
||||||
|
@ -376,7 +376,7 @@ class GraphManager {
|
|||||||
// Single correlation value
|
// Single correlation value
|
||||||
const value = Array.isArray(values) && values.length > 0 ? values[0] : (metadata.value || 'Unknown');
|
const value = Array.isArray(values) && values.length > 0 ? values[0] : (metadata.value || 'Unknown');
|
||||||
const displayValue = typeof value === 'string' && value.length > 20 ? value.substring(0, 17) + '...' : value;
|
const displayValue = typeof value === 'string' && value.length > 20 ? value.substring(0, 17) + '...' : value;
|
||||||
processedNode.label = `Corr: ${displayValue}`;
|
processedNode.label = `${displayValue}`;
|
||||||
processedNode.title = `Correlation: ${value}`;
|
processedNode.title = `Correlation: ${value}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user