├── 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 |
--------------------------------------------------------------------------------