Skip to content

Commit e59d4bc

Browse files
authored
Added Phase 7,8,9 to Automates Threat Hunting and few edits in Phase … (#296)
1 parent 23813cf commit e59d4bc

19 files changed

Lines changed: 548 additions & 4 deletions

docs/cybersecurity/Blue Team/Research/Automated Threat Hunting/Phase 1 - Core Setup and Wazuh Deployment.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ sidebar_position: 2
33
---
44

55
:::info
6-
**Document Creation:** 17 May 2025. **Last Edited:** 23 May 2025. **Authors:** Syed Mahmood Aleem Huzaifa.
6+
**Document Creation:** 17 May 2025. **Last Edited:** 09 September 2025. **Authors:** Syed Mahmood Aleem Huzaifa.
77
**Effective Date:** 23 May 2025. **Expiry Date:** 23 May 2026.
88
:::
99

@@ -12,7 +12,7 @@ sidebar_position: 2
1212

1313
Phase 1 covers the foundational setup of the Wazuh security monitoring system by deploying a manager on an Ubuntu virtual machine and an agent on a Debian virtual machine. It includes preparing the network, updating system packages, setting hostnames, and installing the Wazuh Manager and Agent using official repositories. The phase ensures secure communication between the manager and agent through key-based registration and custom configuration using ossec.conf. It also addresses logging limitations by installing rsyslog on Debian to enable proper authentication event logging. The phase concludes with the installation of the Wazuh Indexer and Dashboard to complete the all-in-one platform. This provides a web interface for managing alerts and agent activity, ensuring a fully functional and integrated Wazuh environment ready for threat detection and analysis.
1414

15-
### Step 1: Prepare your Virtual Machines
15+
### Step 1a: Prepare your Virtual Machines
1616

1717
**Manager VM:** Ubuntu 22.04 or 20.04
1818
**Agent VM:** Debian 11 or 12
@@ -24,7 +24,7 @@ Phase 1 covers the foundational setup of the Wazuh security monitoring system by
2424

2525
![Network Configuration on Virtual Box](img\networkconfig.png)
2626

27-
### Step 2: Update and Set Hostnames
27+
### Step 1b: Update and Set Hostnames
2828

2929
On both machines, first run the following command:
3030
```

docs/cybersecurity/Blue Team/Research/Automated Threat Hunting/Phase 5 - SOAR Deployment – The Hive and Cortex.md renamed to docs/cybersecurity/Blue Team/Research/Automated Threat Hunting/Phase 5 - SOAR Deployment-The Hive and Cortex.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ sidebar_position: 6
33
---
44

55
:::info
6-
**Document Creation:** 17 May 2025. **Last Edited:** 23 May 2025. **Authors:** Syed Mahmood Aleem Huzaifa.
6+
**Document Creation:** 17 May 2025. **Last Edited:** 09 September 2025. **Authors:** Syed Mahmood Aleem Huzaifa.
77
**Effective Date:** 23 May 2025. **Expiry Date:** 23 May 2026.
88
:::
99

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
---
2+
sidebar_position: 8
3+
---
4+
5+
:::info
6+
**Document Creation:** 3 September 2025. **Last Edited:** 3 September 2025. **Authors:** Syed Mahmood Aleem Huzaifa.
7+
**Effective Date:** 3 September 2025. **Expiry Date:** 3 September2026.
8+
:::
9+
10+
### Overview
11+
12+
Phase 1 focuses on establishing the integration between Wazuh and TheHive so that security alerts generated by Wazuh are automatically pushed into TheHive as cases. The main goal here is to eliminate the manual step of copying alerts from Wazuh into TheHive, ensuring that analysts have a single central platform to investigate and manage incidents. This means that whenever Wazuh detects suspicious activity, it will trigger the creation of a case in TheHive, where the details of the alert can be examined and escalated.
13+
14+
**To make this possible, both systems must already be properly set up: the Wazuh Manager should be actively running on the Ubuntu server where it was installed, TheHive should be online and accessible via its web interface, and you should have administrative access to both servers to configure API connectivity and permissions. This setup ensures a seamless pipeline where Wazuh handles detection and TheHive manages investigation, streamlining the incident response workflow.**
15+
16+
### Step 1: Preparing TheHive
17+
Before Wazuh can send alerts to TheHive, we need to set up an organisation and create a user who can receive alerts through TheHive’s API.
18+
1. Create an Organisation
19+
1. Log into TheHive web interface using the admin account.
20+
2. Go to Administration → Organisations.
21+
3. Create a new organisation: Example - Redback.
22+
2. Create a User for API Access
23+
1. Inside your organisation, create a new user.
24+
o Role: **Analyst** (can receive alerts and create cases, but not change system settings).
25+
2. Set a password for this user.
26+
3. Generate the API Key
27+
1. Edit the new user profile.
28+
2. Click **"Reveal"** under API Key.
29+
3. Copy the key somewhere safe — you’ll need it in the Wazuh configuration.
30+
31+
### Step 2: Install TheHive Python Module on Wazuh
32+
TheHive integration uses a Python library called thehive4py to send alerts. We need to install it inside Wazuh’s built-in Python environment.
33+
Run this command on your Wazuh Manager:
34+
```
35+
sudo /var/ossec/framework/python/bin/pip3 install thehive4py==1.8.1
36+
```
37+
### Step 3: Create the Custom Integration Script
38+
Wazuh needs a special script to format alerts and send them to TheHive.
39+
1. Creating the Python Script
40+
```
41+
sudo nano /var/ossec/integrations/custom-w2thive.py
42+
```
43+
Paste the below script into the python file
44+
```
45+
#!/var/ossec/framework/python/bin/python3
46+
import json
47+
import sys
48+
import os
49+
import re
50+
import logging
51+
import uuid
52+
from thehive4py.api import TheHiveApi
53+
from thehive4py.models import Alert, AlertArtifact
54+
55+
#start user config
56+
57+
# Global vars
58+
59+
#threshold for wazuh rules level
60+
lvl_threshold=0
61+
#threshold for suricata rules level
62+
suricata_lvl_threshold=3
63+
64+
debug_enabled = False
65+
#info about created alert
66+
info_enabled = True
67+
68+
#end user config
69+
70+
# Set paths
71+
pwd = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
72+
log_file = '{0}/logs/integrations.log'.format(pwd)
73+
logger = logging.getLogger(__name__)
74+
#set logging level
75+
logger.setLevel(logging.WARNING)
76+
if info_enabled:
77+
logger.setLevel(logging.INFO)
78+
if debug_enabled:
79+
logger.setLevel(logging.DEBUG)
80+
# create the logging file handler
81+
fh = logging.FileHandler(log_file)
82+
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
83+
fh.setFormatter(formatter)
84+
logger.addHandler(fh)
85+
86+
def main(args):
87+
logger.debug('#start main')
88+
logger.debug('#get alert file location')
89+
alert_file_location = args[1]
90+
logger.debug('#get TheHive url')
91+
thive = args[3]
92+
logger.debug('#get TheHive api key')
93+
thive_api_key = args[2]
94+
thive_api = TheHiveApi(thive, thive_api_key )
95+
logger.debug('#open alert file')
96+
w_alert = json.load(open(alert_file_location))
97+
logger.debug('#alert data')
98+
logger.debug(str(w_alert))
99+
logger.debug('#gen json to dot-key-text')
100+
alt = pr(w_alert,'',[])
101+
logger.debug('#formatting description')
102+
format_alt = md_format(alt)
103+
logger.debug('#search artifacts')
104+
artifacts_dict = artifact_detect(format_alt)
105+
alert = generate_alert(format_alt, artifacts_dict, w_alert)
106+
logger.debug('#threshold filtering')
107+
if w_alert['rule']['groups']==['ids','suricata']:
108+
#checking the existence of the data.alert.severity field
109+
if 'data' in w_alert.keys():
110+
if 'alert' in w_alert['data']:
111+
#checking the level of the source event
112+
if int(w_alert['data']['alert']['severity'])<=suricata_lvl_threshold:
113+
send_alert(alert, thive_api)
114+
elif int(w_alert['rule']['level'])>=lvl_threshold:
115+
#if the event is different from suricata AND suricata-event-type: alert check lvl_threshold
116+
send_alert(alert, thive_api)
117+
118+
def pr(data,prefix, alt):
119+
for key,value in data.items():
120+
if hasattr(value,'keys'):
121+
pr(value,prefix+'.'+str(key),alt=alt)
122+
else:
123+
alt.append((prefix+'.'+str(key)+'|||'+str(value)))
124+
return alt
125+
126+
def md_format(alt,format_alt=''):
127+
md_title_dict = {}
128+
#sorted with first key
129+
for now in alt:
130+
now = now[1:]
131+
#fix first key last symbol
132+
dot = now.split('|||')[0].find('.')
133+
if dot==-1:
134+
md_title_dict[now.split('|||')[0]] =[now]
135+
else:
136+
if now[0:dot] in md_title_dict.keys():
137+
(md_title_dict[now[0:dot]]).append(now)
138+
else:
139+
md_title_dict[now[0:dot]]=[now]
140+
for now in md_title_dict.keys():
141+
format_alt+='### '+now.capitalize()+'\n'+'| key | val |\n| ------ | ------ |\n'
142+
for let in md_title_dict[now]:
143+
key,val = let.split('|||')[0],let.split('|||')[1]
144+
format_alt+='| **' + key + '** | ' + val + ' |\n'
145+
return format_alt
146+
147+
148+
def artifact_detect(format_alt):
149+
artifacts_dict = {}
150+
artifacts_dict['ip'] = re.findall(r'\d+\.\d+\.\d+\.\d+',format_alt)
151+
artifacts_dict['url'] = re.findall(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+',format_alt)
152+
artifacts_dict['domain'] = []
153+
for now in artifacts_dict['url']: artifacts_dict['domain'].append(now.split('//')[1].split('/')[0])
154+
return artifacts_dict
155+
156+
def generate_alert(format_alt, artifacts_dict,w_alert):
157+
#generate alert sourceRef
158+
sourceRef = str(uuid.uuid4())[0:6]
159+
artifacts = []
160+
if 'agent' in w_alert.keys():
161+
if 'ip' not in w_alert['agent'].keys():
162+
w_alert['agent']['ip']='no agent ip'
163+
else:
164+
w_alert['agent'] = {'id':'no agent id', 'name':'no agent name'}
165+
166+
for key,value in artifacts_dict.items():
167+
for val in value:
168+
artifacts.append(AlertArtifact(dataType=key, data=val))
169+
alert = Alert(title=w_alert['rule']['description'],
170+
tlp=2,
171+
tags=['wazuh',
172+
'rule='+w_alert['rule']['id'],
173+
'agent_name='+w_alert['agent']['name'],
174+
'agent_id='+w_alert['agent']['id'],
175+
'agent_ip='+w_alert['agent']['ip'],],
176+
description=format_alt ,
177+
type='wazuh_alert',
178+
source='wazuh',
179+
sourceRef=sourceRef,
180+
artifacts=artifacts,)
181+
return alert
182+
183+
def send_alert(alert, thive_api):
184+
response = thive_api.create_alert(alert)
185+
if response.status_code == 201:
186+
logger.info('Create TheHive alert: '+ str(response.json()['id']))
187+
else:
188+
logger.error('Error create TheHive alert: {}/{}'.format(response.status_code, response.text))
189+
190+
if __name__ == "__main__":
191+
192+
try:
193+
logger.debug('debug mode') # if debug enabled
194+
# Main function
195+
main(sys.argv)
196+
197+
except Exception:
198+
logger.exception('EGOR')
199+
200+
```
201+
This Python script acts as a connector between Wazuh and TheHive by automatically converting Wazuh alerts into TheHive alerts (cases) for investigation. When Wazuh generates an alert, the script parses the JSON alert file, extracts key information, and formats it into a readable description. It also detects potential observables like IPs, URLs, and domains, which are attached as artifacts. Based on severity thresholds, it decides whether the alert should be forwarded to TheHive. If it passes the filter, the script sends the alert to TheHive using its API, where it becomes available for analysts to investigate further. Logging is enabled to track each step and confirm whether alerts were successfully created.
202+
203+
2. Create the Bash Wrapper Script
204+
Wazuh runs integration scripts through small shell wrappers.
205+
206+
Create a file:
207+
```
208+
sudo nano /var/ossec/integrations/custom-w2thive
209+
```
210+
The script that goes into this is below
211+
```
212+
#!/bin/sh
213+
WPYTHON_BIN="framework/python/bin/python3"
214+
SCRIPT_PATH_NAME="$0"
215+
DIR_NAME="$(cd $(dirname ${SCRIPT_PATH_NAME}); pwd -P)"
216+
SCRIPT_NAME="$(basename ${SCRIPT_PATH_NAME})"
217+
218+
case ${DIR_NAME} in
219+
*/active-response/bin | */wodles*)
220+
if [ -z "${WAZUH_PATH}" ]; then
221+
WAZUH_PATH="$(cd ${DIR_NAME}/../..; pwd)"
222+
fi
223+
PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py"
224+
;;
225+
*/bin)
226+
if [ -z "${WAZUH_PATH}" ]; then
227+
WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)"
228+
fi
229+
PYTHON_SCRIPT="${WAZUH_PATH}/framework/scripts/${SCRIPT_NAME}.py"
230+
;;
231+
*/integrations)
232+
if [ -z "${WAZUH_PATH}" ]; then
233+
WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)"
234+
fi
235+
PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py"
236+
;;
237+
esac
238+
239+
${WAZUH_PATH}/${WPYTHON_BIN} ${PYTHON_SCRIPT} $@
240+
241+
```
242+
This small shell wrapper is what allows Wazuh to execute your custom Python integration reliably. Since Wazuh can call integrations from different directories, the wrapper first checks its own location, then calculates the correct base path to Wazuh and to the Python script it needs to run. It then builds the path to your custom-w2thive.py script and finally uses Wazuh’s bundled Python interpreter (framework/python/bin/python3) to execute it, passing along any arguments that Wazuh supplies. In simple terms, the wrapper acts as a bridge: Wazuh calls the wrapper, the wrapper resolves the right paths, and then your Python script runs to forward alerts into TheHive. This ensures the integration works consistently regardless of where Wazuh launches it from.
243+
244+
### Step 4: Set Permissions
245+
These scripts must be executable and owned by the correct group (ossec in Wazuh).
246+
247+
```
248+
sudo chmod 755 /var/ossec/integrations/custom-w2thive.py
249+
sudo chmod 755 /var/ossec/integrations/custom-w2thive
250+
sudo chown root:ossec /var/ossec/integrations/custom-w2thive.py
251+
sudo chown root:ossec /var/ossec/integrations/custom-w2thive
252+
```
253+
These commands are making sure that both your wrapper (custom-w2thive) and the Python script (custom-w2thive.py) have the right permissions and ownership so Wazuh can execute them safely. By setting the mode to 755, you’re allowing the owner (root) to read, write, and execute, while members of the group and others can only read and execute. The ownership is set to root:ossec, which means the root user owns the files, but the ossec group also has access. This is important because Wazuh services run under the ossec group, so without this step, Wazuh would not be able to call your integration scripts.
254+
255+
### Step 5: Configure Wazuh to Use the Integration
256+
Edit the Wazuh Manager config file:
257+
```
258+
sudo nano /var/ossec/etc/ossec.conf
259+
```
260+
Add this inside "ossec_config":
261+
```
262+
<integration>
263+
<name>custom-w2thive</name>
264+
<hook_url>http://THEHIVE_SERVER_IP:9000</hook_url>
265+
<api_key>YOUR_API_KEY</api_key>
266+
<alert_format>json</alert_format>
267+
</integration>
268+
```
269+
*THEHIVE_SERVER_IP = IP address of your TheHive server (e.g., 127.0.0.1 if on the same machine).
270+
YOUR_API_KEY = the key you copied earlier*
271+
272+
### Step 6: Restart Wazuh
273+
```
274+
sudo systemctl restart wazuh-manager
275+
```
276+
### Step 7: Test the Integration
277+
278+
We’ll create fake alerts to see if they appear in TheHive.
279+
Example: Trigger a Syscheck alert by creating a file in /etc:
280+
```
281+
sudo touch /etc/wazuh_test.txt
282+
echo "test" | sudo tee -a /etc/wazuh_test.txt
283+
```
284+
285+
Example: Trigger an authentication failure alert:
286+
```ssh nouser@localhost
287+
```
288+
(Type any password — it will fail and create an alert.)
289+
290+
If everything works, you’ll see messages in:
291+
```
292+
sudo tail -n 50 /var/ossec/logs/integrations.log
293+
```
294+
![Wazuh Hive Integration logs](img\wazuh-hiveintegration.png)
295+
296+
Automatically, the cases are created as shown below
297+
![Wazuh Hive Alerts](img\wazuh-hivealerts.png)
298+
299+
### Conclusion
300+
This phase represents a major milestone in building an automated security operations pipeline, as it bridges the gap between detection and investigation. With the Wazuh ↔ TheHive integration in place, alerts no longer remain siloed within Wazuh but are automatically forwarded into TheHive, where they are transformed into actionable cases. This ensures that analysts can immediately work on verified incidents within a centralized platform rather than wasting time manually transferring data. In practice, this reduces friction, accelerates the response process, and makes sure that no critical alerts are overlooked due to human error or delays.
301+
302+
Beyond convenience, the integration adds structure and scalability to incident management. By feeding enriched alerts into TheHive, security teams can leverage case workflows, collaborative features, and task assignments that are built into TheHive’s design. This allows multiple analysts to coordinate effectively on the same incident, track progress, and document findings in one place. It also improves accountability, since every case in TheHive is linked to its originating Wazuh alert, creating an auditable chain of events.
303+
304+
From a strategic perspective, this integration lays the groundwork for more advanced automation in later phases, such as linking with Cortex for automated analysis, enriching cases with external threat intelligence, or triggering response actions directly from TheHive. What begins here as a simple alert forwarding mechanism evolves into the foundation of a full Security Orchestration, Automation, and Response (SOAR) pipeline. In other words, Phase 7 does not just close the loop between detection and investigation — it transforms the security workflow into a proactive, scalable, and collaborative system that strengthens the organization’s overall security posture.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
sidebar_position: 9
3+
---
4+
5+
:::info
6+
**Document Creation:** 3 September 2025. **Last Edited:** 3 September 2025. **Authors:** Syed Mahmood Aleem Huzaifa.
7+
**Effective Date:** 3 September 2025. **Expiry Date:** 3 September2026.
8+
:::
9+
10+
### Overview
11+
Running manual observables in TheHive is useful for on-demand data enrichment. Instead of waiting for automation or notifications to trigger analyzers, suspicious items can be checked quickly and supporting intelligence viewed immediately. This workflow ensures every piece of evidence is enriched, traceable, and stored within the case context for comprehensive investigation.
12+
13+
### Step 1 – Log in to TheHive
14+
Open TheHive web interface in a browser and log in with an analyst account. Access to the dashboard where cases and observables are managed requires proper permissions; **usually, the Analyst role** is necessary to create observables and trigger Cortex analyzers.
15+
![Create case](img\Create_case.png)
16+
17+
### Step 2 – Open a Case
18+
After logging in, create a new case or open an existing one. A case serves as a container for all investigation data, ensuring observables are associated with the correct incident context.
19+
20+
### Step 3 – Add an Observable
21+
Within the case, navigate to the *“Observables”* tab and select *“Add Observable.”* Choose the observable type such as IP address, domain, file hash, or URL. Provide the observable value and optionally add descriptions or tags to assist later correlation or filtering.
22+
![Add Observable](img\Add_Observable.png)
23+
24+
### Step 4 – Save the Observable
25+
Save the observable, which then appears in the case observables list. At this stage, the observable is stored but no analysis has yet been performed.
26+
![Adding An Observable](img\Adding_An_Observable.png)
27+
28+
### Step 5 – Run Cortex Analyzer Manually
29+
Select the observable and click *“Run analyzers.” TheHive displays available Cortex analyzers compatible with the observable type, for example, AbuseIPDB or VirusTotal for IP addresses. Select desired analyzers and confirm to send the observable to the connected Cortex instance for analysis.
30+
![Run Analyzer Option](img\Run_Analyzer_Option.png)
31+
![Select The Analyzer to run](img\Select-Analyzer.png)
32+
33+
**(Only the analyzers that are configured and enabled in Cortex would be visible here)**
34+
35+
### Step 6 – Review the Reports
36+
After analyzer jobs complete, click the observable to view detailed reports. Reports reveal findings such as malicious IP status, malware hash matches, or URL blocklist presence. These results are attached to the observable in TheHive, enabling efficient investigation continuation.
37+
![Report View](img\Viewing_Report.png)
38+
Analysis_of_a_report.png
39+
![Report Analysis View](img\Analysis_of_a_report.png)

0 commit comments

Comments
 (0)