shodan_analyzer.py aktualisiert
This commit is contained in:
		
							parent
							
								
									4fd7bc0fbc
								
							
						
					
					
						commit
						db302f4a55
					
				@ -4,6 +4,7 @@ import requests
 | 
			
		||||
import json
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
import ipaddress
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
class ShodanEnrichmentAnalyzer(interface.BaseAnalyzer):
 | 
			
		||||
    """Analyzer to enrich IP addresses with Shodan data."""
 | 
			
		||||
@ -15,14 +16,13 @@ class ShodanEnrichmentAnalyzer(interface.BaseAnalyzer):
 | 
			
		||||
    def __init__(self, index_name, sketch_id, timeline_id=None):
 | 
			
		||||
        super().__init__(index_name, sketch_id, timeline_id)
 | 
			
		||||
        
 | 
			
		||||
        # Get API key from config or environment
 | 
			
		||||
        config = self.get_config()
 | 
			
		||||
        self.shodan_api_key = config.get('api_key', '')
 | 
			
		||||
        self.max_time_diff_hours = config.get('max_time_diff_hours', 24)
 | 
			
		||||
        self.rate_limit_delay = config.get('rate_limit_delay', 1)
 | 
			
		||||
        # Get API key from environment variables
 | 
			
		||||
        self.shodan_api_key = os.environ.get('SHODAN_API_KEY', '')
 | 
			
		||||
        self.max_time_diff_hours = 24
 | 
			
		||||
        self.rate_limit_delay = 1
 | 
			
		||||
        
 | 
			
		||||
        if not self.shodan_api_key:
 | 
			
		||||
            self.logger.error("Shodan API key not configured")
 | 
			
		||||
            self.logger.error("Shodan API key not configured in environment variables")
 | 
			
		||||
    
 | 
			
		||||
    def run(self):
 | 
			
		||||
        """Main analyzer logic."""
 | 
			
		||||
@ -48,6 +48,7 @@ class ShodanEnrichmentAnalyzer(interface.BaseAnalyzer):
 | 
			
		||||
            timestamp = event.source.get('timestamp')
 | 
			
		||||
            
 | 
			
		||||
            if source_ip and self._is_public_ip(source_ip):
 | 
			
		||||
                self.logger.info(f"Processing IP: {source_ip}")
 | 
			
		||||
                shodan_data = self._get_shodan_data(source_ip)
 | 
			
		||||
                if shodan_data:
 | 
			
		||||
                    self._enrich_event(event, shodan_data)
 | 
			
		||||
@ -68,26 +69,26 @@ class ShodanEnrichmentAnalyzer(interface.BaseAnalyzer):
 | 
			
		||||
                'history': 'true'
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            self.logger.info(f"Querying Shodan API for IP: {ip}")
 | 
			
		||||
            response = requests.get(url, params=params, timeout=10)
 | 
			
		||||
            
 | 
			
		||||
            if response.status_code == 200:
 | 
			
		||||
                self.logger.info(f"Successfully retrieved Shodan data for {ip}")
 | 
			
		||||
                return response.json()
 | 
			
		||||
            elif response.status_code == 404:
 | 
			
		||||
                self.logger.debug(f'No Shodan data found for {ip}')
 | 
			
		||||
                return None
 | 
			
		||||
            else:
 | 
			
		||||
                self.logger.warning(f'Shodan API error for {ip}: {response.status_code}')
 | 
			
		||||
                self.logger.warning(f'Shodan API error for {ip}: {response.status_code} - {response.text}')
 | 
			
		||||
                return None
 | 
			
		||||
                
 | 
			
		||||
        except requests.exceptions.RequestException as e:
 | 
			
		||||
            self.logger.warning(f'Request error for {ip}: {e}')
 | 
			
		||||
            return None
 | 
			
		||||
        except json.JSONDecodeError as e:
 | 
			
		||||
            self.logger.warning(f'JSON decode error for {ip}: {e}')
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            self.logger.warning(f'Error fetching Shodan data for {ip}: {e}')
 | 
			
		||||
            return None
 | 
			
		||||
    
 | 
			
		||||
    def _enrich_event(self, event, shodan_data):
 | 
			
		||||
        """Add Shodan data to the event."""
 | 
			
		||||
        try:
 | 
			
		||||
            enrichment = {
 | 
			
		||||
                'shodan_ports': shodan_data.get('ports', []),
 | 
			
		||||
                'shodan_org': shodan_data.get('org', ''),
 | 
			
		||||
@ -99,31 +100,35 @@ class ShodanEnrichmentAnalyzer(interface.BaseAnalyzer):
 | 
			
		||||
                '__ts_analyzer_shodan_enrichment': True
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
        # Add service banners from latest scan
 | 
			
		||||
            # Add service information from latest scan
 | 
			
		||||
            if shodan_data.get('data'):
 | 
			
		||||
            latest_scan = shodan_data['data'][0]  # Most recent scan
 | 
			
		||||
            enrichment['shodan_services'] = []
 | 
			
		||||
                services = []
 | 
			
		||||
                for service in shodan_data.get('data', [])[:5]:  # Limit to first 5 services
 | 
			
		||||
                    service_info = f"Port {service.get('port', 'Unknown')}/{service.get('transport', 'tcp')}"
 | 
			
		||||
                    if service.get('product'):
 | 
			
		||||
                        service_info += f" - {service.get('product', '')}"
 | 
			
		||||
                    if service.get('version'):
 | 
			
		||||
                        service_info += f" {service.get('version', '')}"
 | 
			
		||||
                    services.append(service_info)
 | 
			
		||||
                
 | 
			
		||||
            for service in shodan_data.get('data', []):
 | 
			
		||||
                service_info = {
 | 
			
		||||
                    'port': service.get('port'),
 | 
			
		||||
                    'protocol': service.get('transport', 'tcp'),
 | 
			
		||||
                    'service': service.get('product', ''),
 | 
			
		||||
                    'version': service.get('version', ''),
 | 
			
		||||
                    'timestamp': service.get('timestamp', '')
 | 
			
		||||
                }
 | 
			
		||||
                enrichment['shodan_services'].append(service_info)
 | 
			
		||||
                enrichment['shodan_services'] = services
 | 
			
		||||
            
 | 
			
		||||
            event.add_attributes(enrichment)
 | 
			
		||||
            event.add_tags(['shodan-enriched'])
 | 
			
		||||
            event.commit()
 | 
			
		||||
            
 | 
			
		||||
            self.logger.info(f"Successfully enriched event with Shodan data")
 | 
			
		||||
            
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            self.logger.error(f"Error enriching event: {e}")
 | 
			
		||||
    
 | 
			
		||||
    def _is_public_ip(self, ip):
 | 
			
		||||
        """Check if IP is public (not RFC1918 private ranges)."""
 | 
			
		||||
        try:
 | 
			
		||||
            ip_obj = ipaddress.ip_address(ip)
 | 
			
		||||
            return ip_obj.is_global
 | 
			
		||||
        except (ValueError, ipaddress.AddressValueError):
 | 
			
		||||
            self.logger.debug(f"Invalid IP address format: {ip}")
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
# Register the analyzer
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user