├── ossec.conf ├── LICENSE ├── custom-criminalip ├── rules.xml ├── custom-criminalip.py └── README.md /ossec.conf: -------------------------------------------------------------------------------- 1 | 2 | custom-criminalip 3 | API_KEY 4 | web, sshd, invalid_login, firewall, ids, system, database, application 5 | json 6 | 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 SHAHID IN SECURITY 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /custom-criminalip: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Define the Python binary location relative to the Wazuh installation 4 | WPYTHON_BIN="framework/python/bin/python3" 5 | 6 | # Capture the script's own path and name 7 | SCRIPT_PATH_NAME="$0" 8 | DIR_NAME="$(cd $(dirname ${SCRIPT_PATH_NAME}); pwd -P)" 9 | SCRIPT_NAME="$(basename ${SCRIPT_PATH_NAME})" 10 | 11 | # Determine the Wazuh path and Python script path based on directory 12 | case ${DIR_NAME} in 13 | */active-response/bin | */wodles*) 14 | if [ -z "${WAZUH_PATH}" ]; then 15 | WAZUH_PATH="$(cd ${DIR_NAME}/../..; pwd)" 16 | fi 17 | PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py" 18 | ;; 19 | */bin) 20 | if [ -z "${WAZUH_PATH}" ]; then 21 | WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)" 22 | fi 23 | PYTHON_SCRIPT="${WAZUH_PATH}/framework/scripts/${SCRIPT_NAME}.py" 24 | ;; 25 | */integrations) 26 | if [ -z "${WAZUH_PATH}" ]; then 27 | WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)" 28 | fi 29 | PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py" 30 | ;; 31 | esac 32 | 33 | # Run the Python script with all provided arguments 34 | ${WAZUH_PATH}/${WPYTHON_BIN} ${PYTHON_SCRIPT} "$@" 35 | -------------------------------------------------------------------------------- /rules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | json 5 | Parent rule for JSON Decoding detection. 6 | 7 | 8 | 9 | 10 | 200000 11 | criminalip 12 | criminalip 13 | CriminalIP Events 14 | 15 | 16 | 17 | 18 | 100623 19 | true 20 | VPN detected in IP address: $(criminalip.ip) 21 | vpn,criminalip 22 | 23 | 24 | 25 | 26 | 100623 27 | true 28 | TOR network detected in IP address: $(criminalip.ip) 29 | tor,criminalip 30 | 31 | 32 | 33 | 34 | 100623 35 | true 36 | Proxy server detected in IP address: $(criminalip.ip) 37 | proxy,criminalip 38 | 39 | 40 | 41 | 42 | 100623 43 | true 44 | Dark web activity detected in IP address: $(criminalip.ip) 45 | darkweb,criminalip 46 | 47 | 48 | 49 | 50 | 100623 51 | Critical 52 | Critical risk score for IP address: $(criminalip.ip) 53 | critical,criminalip 54 | 55 | 56 | 57 | 58 | 100623 59 | Dangerous 60 | Dangerous risk score for IP address: $(criminalip.ip) 61 | dangerous,criminalip 62 | 63 | 64 | 65 | 66 | 100623 67 | Moderate 68 | Moderate risk score for IP address: $(criminalip.ip) 69 | moderate,criminalip 70 | 71 | 72 | 73 | 74 | 100623 75 | Low 76 | Low risk score for IP address: $(criminalip.ip) 77 | low,criminalip 78 | 79 | 80 | 81 | 82 | 100623 83 | Safe 84 | Safe score for IP address: $(criminalip.ip) 85 | safe,criminalip 86 | 87 | 88 | 89 | 90 | 100623 91 | true 92 | Hosting service detected in IP address: $(criminalip.ip) 93 | hosting,criminalip 94 | 95 | 96 | 97 | 98 | 100623 99 | true 100 | Cloud service detected in IP address:$(criminalip.ip) 101 | cloud,criminalip 102 | 103 | 104 | 105 | 106 | 100623 107 | true 108 | Snort activity detected in IP address: $(criminalip.ip) 109 | snort,criminalip 110 | 111 | 112 | 113 | 114 | 100623 115 | true 116 | Scanner activity detected in IP address: $(criminalip.ip) 117 | scanner,criminalip 118 | 119 | 120 | 121 | 122 | 100623 123 | true 124 | Mobile network detected in IP address: $(criminalip.ip) 125 | mobile,criminalip 126 | 127 | 128 | 129 | 130 | 100623 131 | true 132 | Anonymous VPN detected in IP address: $(criminalip.ip) 133 | anonymous_vpn,criminalip 134 | 135 | 136 | 137 | 138 | 100623 139 | Debugging CriminalIP integration: $(criminalip.ip) 140 | debug,criminalip 141 | 142 | 143 | 144 | 145 | 100623 146 | .*Missing Parameter.* 147 | CriminalIP API error: Missing parameter in request 148 | error,criminalip 149 | 150 | 151 | 152 | 153 | 100623 154 | .*Invalid IP Address.* 155 | CriminalIP API error: Invalid IP address format 156 | error,criminalip 157 | 158 | 159 | 160 | 161 | 100623 162 | .*Internal Server Error.* 163 | CriminalIP API error: Internal server error encountered 164 | error,criminalip 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /custom-criminalip.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Shahidahktar@gmail.com 3 | # Developed by Shahid Akhter 4 | import sys 5 | import os 6 | import json 7 | import ipaddress 8 | import requests 9 | from requests.exceptions import ConnectionError, HTTPError 10 | from socket import socket, AF_UNIX, SOCK_DGRAM 11 | import time 12 | 13 | # Enable or disable debugging 14 | debug_enabled = True # Set to False to disable debug logging 15 | 16 | # File and socket paths 17 | pwd = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) 18 | socket_addr = f'{pwd}/queue/sockets/queue' 19 | 20 | # Set paths for logging 21 | now = time.strftime("%a %b %d %H:%M:%S %Z %Y") 22 | log_file = f'{pwd}/logs/integrations.log' 23 | 24 | 25 | def debug(msg): 26 | """Log debug messages.""" 27 | if debug_enabled: 28 | timestamped_msg = f"{now}: {msg}\n" 29 | print(timestamped_msg) 30 | with open(log_file, "a") as f: 31 | f.write(timestamped_msg) 32 | 33 | 34 | def send_event(msg, agent=None): 35 | """Send an event to the Wazuh Manager.""" 36 | try: 37 | if not agent or agent["id"] == "000": 38 | string = f'1:criminalip:{json.dumps(msg)}' 39 | else: 40 | string = f'1:[{agent["id"]}] ({agent["name"]}) {agent["ip"] if "ip" in agent else "any"}->criminalip:{json.dumps(msg)}' 41 | 42 | debug(f"Sending Event: {string}") 43 | with socket(AF_UNIX, SOCK_DGRAM) as sock: 44 | sock.connect(socket_addr) 45 | sock.send(string.encode()) 46 | except Exception as e: 47 | debug(f"Error sending event: {e}") 48 | 49 | 50 | # Read configuration parameters 51 | try: 52 | alert_file = open(sys.argv[1]) 53 | alert = json.loads(alert_file.read()) 54 | alert_file.close() 55 | debug("Alert loaded successfully") 56 | except Exception as e: 57 | debug(f"Error reading alert file: {e}") 58 | sys.exit(1) 59 | 60 | # New Alert Output for CriminalIP Alert or Error calling the API 61 | alert_output = {} 62 | 63 | # CriminalIP API AUTH KEY 64 | criminalip_api_key = api_key 65 | 66 | # API - HTTP Headers 67 | criminalip_apicall_headers = { 68 | "x-api-key": f"{criminalip_api_key}" 69 | } 70 | 71 | # Extract Event Source 72 | try: 73 | event_source = alert["rule"]["groups"] 74 | debug(f"Event source: {event_source}") 75 | except KeyError as e: 76 | debug(f"Missing expected key in alert: {e}") 77 | sys.exit(1) 78 | 79 | if any(group in ['web', 'sshd', 'invalid_login', 'firewall', 'ids', 'system', 'database', 'application'] for group in event_source): 80 | try: 81 | client_ip = alert["data"]["srcip"] # Extract client IP 82 | debug(f"Extracted Client IP: {client_ip}") 83 | if ipaddress.ip_address(client_ip).is_global: 84 | # Pass the client_ip value directly into the URL 85 | criminalip_search_url = f'https://api.criminalip.io/v1/asset/ip/report?ip={client_ip}&full=true' 86 | debug(f"CriminalIP API URL: {criminalip_search_url}") 87 | try: 88 | criminalip_api_response = requests.get(criminalip_search_url, headers=criminalip_apicall_headers) 89 | criminalip_api_response.raise_for_status() # Raise HTTPError for bad responses 90 | debug("API request successful") 91 | except ConnectionError as conn_err: 92 | alert_output["criminalip"] = {"error": 'Connection Error to CriminalIP API'} 93 | alert_output["integration"] = "criminalip" 94 | debug(f"ConnectionError: {conn_err}") 95 | send_event(alert_output, alert.get("agent")) 96 | except HTTPError as http_err: 97 | alert_output["criminalip"] = {"error": f'HTTP Error: {http_err}'} 98 | alert_output["integration"] = "criminalip" 99 | debug(f"HTTPError: {http_err}") 100 | send_event(alert_output, alert.get("agent")) 101 | except Exception as e: 102 | alert_output["criminalip"] = {"error": f'Unexpected Error: {e}'} 103 | alert_output["integration"] = "criminalip" 104 | debug(f"Unexpected Error: {e}") 105 | send_event(alert_output, alert.get("agent")) 106 | else: 107 | try: 108 | criminalip_api_response = criminalip_api_response.json() 109 | debug(f"API Response Data: {criminalip_api_response}") 110 | # Check if the response contains score information 111 | if "score" in criminalip_api_response and criminalip_api_response["score"]: 112 | # Generate Alert Output from CriminalIP Response 113 | score = criminalip_api_response["score"] 114 | issues = criminalip_api_response["issues"] 115 | alert_output["criminalip"] = { 116 | "ip": criminalip_api_response["ip"], 117 | "score_inbound": score.get("inbound", "Unknown"), 118 | "score_outbound": score.get("outbound", "Unknown"), 119 | "is_vpn": issues.get("is_vpn", False), 120 | "is_tor": issues.get("is_tor", False), 121 | "is_proxy": issues.get("is_proxy", False), 122 | "is_cloud": issues.get("is_cloud", False), 123 | "is_hosting": issues.get("is_hosting", False), 124 | "is_darkweb": issues.get("is_darkweb", False), 125 | "is_scanner": issues.get("is_scanner", False), 126 | "is_snort": issues.get("is_snort", False), 127 | "is_anonymous_vpn": issues.get("is_anonymous_vpn", False) 128 | } 129 | alert_output["integration"] = "criminalip" 130 | debug(f"Alert Output: {alert_output}") 131 | send_event(alert_output, alert.get("agent")) 132 | else: 133 | alert_output["criminalip"] = {"error": 'No score information found in CriminalIP response'} 134 | alert_output["integration"] = "criminalip" 135 | debug("No score information found in CriminalIP response") 136 | send_event(alert_output, alert.get("agent")) 137 | except Exception as e: 138 | alert_output["criminalip"] = {"error": f"Error parsing JSON response: {e}"} 139 | alert_output["integration"] = "criminalip" 140 | debug(f"Error parsing JSON response: {e}") 141 | send_event(alert_output, alert.get("agent")) 142 | else: 143 | debug(f"Client IP is not global: {client_ip}") 144 | sys.exit() 145 | except KeyError as e: 146 | alert_output["criminalip"] = {"error": f'Missing expected key: {e}'} 147 | alert_output["integration"] = "criminalip" 148 | debug(f"KeyError: {e}") 149 | send_event(alert_output, alert.get("agent")) 150 | sys.exit() 151 | else: 152 | debug(f"Event source is not found : {event_source}") 153 | sys.exit() 154 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wazuh-criminalip-integration 2 | 3 | 4 | 5 | Give a star to support developer!!! 6 | Shahid Akhter - Shahidahktar@gmail.com 7 | 8 | 9 | 10 | Understanding the Tools 11 | What is Wazuh? 12 | 13 | Wazuh is an open-source platform that provides unified security monitoring, incident detection, and compliance management across your infrastructure. It integrates host-based intrusion detection, vulnerability detection, log analysis, and configuration assessment into a single platform, offering a comprehensive security solution. 14 | 15 | Key Features of Wazuh: 16 | 17 | Real-time Threat Detection: Wazuh continuously monitors your infrastructure for potential threats and anomalies. 18 | Compliance Management: Helps ensure compliance with various regulations such as PCI DSS, HIPAA, and GDPR. 19 | Incident Response: Offers automated response actions, such as IP blocking or sending alerts. 20 | Scalability: Wazuh is highly scalable, capable of monitoring thousands of endpoints. 21 | Integration: Easily integrates with other security tools like SIEM systems, cloud platforms, and more. 22 | 23 | What is CriminalIP? 24 | 25 | CriminalIP is a threat intelligence service that provides detailed information about IP addresses, domains, and other network elements. It identifies malicious activities, assesses risks, and offers insights into potential threats. CriminalIP is particularly valuable for organizations looking to enrich their security data with actionable threat intelligence. 26 | 27 | Key Features of CriminalIP: 28 | 29 | Comprehensive IP Intelligence: CriminalIP provides detailed insights into IP addresses, including whether they are associated with malicious activities such as VPNs, proxies, TOR networks, or dark web activities. 30 | Risk Scoring: Offers inbound and outbound risk scores for IP addresses, helping prioritize threats. 31 | Global Coverage: CriminalIP covers IP addresses globally, offering a wide range of data to enhance threat detection. 32 | API Integration: Easy integration with existing security tools and platforms through its API. 33 | 34 | The Power of Risk Scoring and Threat Context 35 | 36 | One of the standout features of CriminalIP is its ability to assign risk scores to IP addresses. These scores, categorized as inbound and outbound, provide a quantitative measure of the risk associated with specific IPs. Understanding these scores and the associated context can significantly enhance your organization's ability to prioritize and respond to threats. 37 | Inbound and Outbound Risk Scores 38 | 39 | Inbound Risk Score: This score reflects the potential risk that an IP address poses to your network when it attempts to connect. A high inbound risk score indicates that the IP is likely involved in malicious activities such as scanning, brute-force attacks, or exploitation attempts. This score is crucial for blocking or further investigating suspicious connections. 40 | 41 | Outbound Risk Score: This score measures the risk posed by traffic leaving your network to a particular IP address. A high outbound risk score could indicate that a compromised system within your network is communicating with a malicious command and control (C2) server or other risky destinations. Monitoring outbound risk is vital for detecting data exfiltration or botnet activity. 42 | Additional Threat Indicators 43 | 44 | CriminalIP goes beyond risk scores by providing additional context about the nature of the threats associated with an IP address. These indicators include: 45 | 46 | Is VPN: Indicates whether the IP address is associated with a VPN service. VPNs can obscure the true origin of traffic, often used by threat actors to mask their activities. 47 | Is Proxy: Identifies if the IP address is using a proxy server. Proxies can be used to anonymize traffic, complicating attribution efforts. 48 | Is TOR: Highlights whether the IP is part of the TOR network, often associated with anonymized, potentially malicious traffic. 49 | Is Hosting: Shows if the IP is part of a hosting service, which might indicate a server being used for phishing, malware distribution, or other malicious activities. 50 | Is Cloud: Identifies if the IP is from a cloud provider, which can be a sign of infrastructure being used for launching attacks. 51 | Is Dark Web: Indicates if the IP has any known associations with dark web activities, such as marketplaces or forums known for illicit activities. 52 | Is Scanner: Shows whether the IP is known to be involved in scanning activities, which can be a precursor to an attack. 53 | Is Snort: Indicates if the IP has been flagged by Snort signatures, which are rules used to detect network attacks. 54 | Is Anonymous VPN: Specifically flags IPs that are using services designed to anonymize VPN traffic, which can be particularly challenging to track. 55 | 56 | Why Integrate Wazuh with CriminalIP? 57 | 58 | Integrating Wazuh with CriminalIP brings together the best of both worlds—Wazuh’s robust monitoring and incident detection capabilities with CriminalIP’s rich threat intelligence. This integration enhances your security operations by providing deeper context and actionable intelligence on detected threats. 59 | 60 | Benefits of the Integration: 61 | 62 | Enhanced Threat Detection: Enrich Wazuh alerts with CriminalIP’s threat intelligence, providing more context about the severity and nature of the detected threats. 63 | Improved Incident Response: With more detailed information, security teams can make better-informed decisions, improving the speed and effectiveness of incident response. 64 | Comprehensive Visibility: Gain a holistic view of your security landscape by correlating internal alerts with external threat data. 65 | Prioritized Alerts: Utilize CriminalIP’s risk scoring to prioritize which alerts require immediate attention, reducing alert fatigue and focusing on high-risk incidents. 66 | Scalable and Automated: The integration allows for automated enrichment of Wazuh alerts, ensuring your security operations scale effectively as your infrastructure grows. 67 | 68 | 69 | 70 | 71 | 72 | Configuring the Integration 73 | 74 | Before configuring, you’ll need to get an API key from criminalIP website. 75 | 76 | To implement the Wazuh and CriminalIP integration, follow these steps: 77 | 78 | Clone the Repository: Clone the repository from [GitHub] 79 | 80 | (https://github.com/shahidakhter786/wazuh-criminalip-integration) to your Wazuh server. 81 | 82 | 2. Set Up the Python Script: 83 | — The `custom-criminalip.py` script needs to be configured with your CriminalIP API key. This script queries CriminalIP’s API and processes the data received. Add your API key in the ossec.conf Integration block. 84 | — Place the script in the integratons folder on your Wazuh server. 85 | 86 | 3. Deploy the Rules: 87 | — The `rules.xml` file contains the necessary rules for Wazuh to parse and act upon the data received from CriminalIP. 88 | — Copy this file into the Wazuh rules directory to enable the integration. 89 | 90 | 4. Update Wazuh Configuration: 91 | — Use the provided `ossec.conf` to ensure that Wazuh is correctly configured to use the CriminalIP integration. This configuration file includes settings that direct Wazuh to trigger alerts based on CriminalIP data. Add your API key in the ossec.conf 92 | 93 | 5. Test the Integration: 94 | — After setting everything up, run test alerts through Wazuh to verify that the integration is functioning as expected. Check if Wazuh is generating alerts with enriched data from CriminalIP. 95 | --------------------------------------------------------------------------------