feat: add 5 cybersecurity skills - CloudTrail anomalies, SSL/TLS assessment, Wazuh detection, Prefetch analysis, WMI lateral movement

This commit is contained in:
mukul975
2026-03-11 00:44:42 +01:00
parent 1ba371d7f7
commit 724fda0883
20 changed files with 1593 additions and 0 deletions
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Mahipal
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,40 @@
---
name: implementing-endpoint-detection-with-wazuh
description: Deploy and configure Wazuh SIEM/XDR for endpoint detection including agent management, custom decoder and rule XML creation, alert querying via the Wazuh REST API, and automated response actions.
domain: cybersecurity
subdomain: security-operations
tags: [siem, xdr, wazuh, endpoint-detection, custom-rules, incident-response]
version: "1.0"
author: mahipal
license: MIT
---
# Implementing Endpoint Detection with Wazuh
## Overview
Wazuh is an open-source SIEM and XDR platform for endpoint monitoring, threat detection, and compliance. This skill covers managing agents via the Wazuh REST API, creating custom decoders and rules in XML for organization-specific detections, querying alerts, and testing rule logic using the logtest endpoint.
## Prerequisites
- Wazuh Manager 4.x deployed with API enabled
- Python 3.9+ with `requests` library
- API credentials (username/password for JWT authentication)
- Understanding of Wazuh decoder and rule XML syntax
## Steps
### Step 1: Authenticate to Wazuh API
Obtain JWT token via POST to /security/user/authenticate.
### Step 2: List and Monitor Agents
Query agent status, versions, and last keep-alive via /agents endpoint.
### Step 3: Query Security Alerts
Search alerts by rule ID, severity, agent, or time range.
### Step 4: Test Custom Rules with Logtest
Use the /logtest endpoint to validate decoder and rule logic against sample log lines.
## Expected Output
JSON report with agent inventory, alert statistics, rule coverage, and logtest validation results.
@@ -0,0 +1,72 @@
# API Reference: Implementing Endpoint Detection with Wazuh
## Wazuh REST API Endpoints
| Endpoint | Method | Purpose |
|----------|--------|---------|
| /security/user/authenticate | POST | Get JWT token (Basic Auth) |
| /agents | GET | List agents with status |
| /agents/summary/status | GET | Agent status summary |
| /alerts | GET | Query security alerts |
| /rules | GET | List detection rules |
| /logtest | PUT | Test log against decoders/rules |
| /manager/configuration | GET | Manager configuration |
| /agents/{id}/restart | PUT | Restart specific agent |
## Authentication
```python
import requests
from requests.auth import HTTPBasicAuth
resp = requests.post(
"https://wazuh:55000/security/user/authenticate",
auth=HTTPBasicAuth("wazuh-wui", "password"),
verify=False,
)
token = resp.json()["data"]["token"]
headers = {"Authorization": f"Bearer {token}"}
```
## Custom Rule XML Syntax
```xml
<group name="custom_rules,">
<rule id="100001" level="12">
<if_sid>5716</if_sid>
<srcip>!192.168.1.0/24</srcip>
<description>SSH login from external IP</description>
<mitre><id>T1078</id></mitre>
</rule>
</group>
```
Location: `/var/ossec/etc/rules/local_rules.xml`
## Custom Decoder XML
```xml
<decoder name="custom_app">
<program_name>myapp</program_name>
<regex>^(\S+) (\S+) (\S+)</regex>
<order>srcip,user,action</order>
</decoder>
```
Location: `/var/ossec/etc/decoders/local_decoder.xml`
## Alert Query Parameters
| Parameter | Example | Description |
|-----------|---------|-------------|
| limit | 20 | Max results |
| sort | -timestamp | Sort descending |
| q | rule.level>=10 | Filter by level |
| search | brute force | Text search |
| select | rule.id,agent.name | Field selection |
## References
- Wazuh API Docs: https://documentation.wazuh.com/current/user-manual/api/
- Wazuh Rules Syntax: https://documentation.wazuh.com/current/user-manual/ruleset/ruleset-xml-syntax/rules.html
- Wazuh Custom Rules: https://documentation.wazuh.com/current/user-manual/ruleset/rules/custom.html
@@ -0,0 +1,192 @@
#!/usr/bin/env python3
"""Agent for implementing endpoint detection with Wazuh.
Manages Wazuh agents, queries alerts, tests custom decoder/rule
logic via logtest, and audits endpoint coverage using the
Wazuh REST API.
"""
import argparse
import json
import os
from datetime import datetime
from pathlib import Path
try:
import requests
from requests.auth import HTTPBasicAuth
except ImportError:
requests = None
class WazuhDetectionAgent:
"""Manages Wazuh endpoint detection via its REST API."""
def __init__(self, wazuh_url, username, password,
output_dir="./wazuh_detection"):
self.base_url = wazuh_url.rstrip("/")
self.output_dir = Path(output_dir)
self.output_dir.mkdir(parents=True, exist_ok=True)
self.findings = []
self.token = self._authenticate(username, password)
def _authenticate(self, username, password):
"""Authenticate and obtain JWT token."""
if not requests:
return None
try:
resp = requests.post(
f"{self.base_url}/security/user/authenticate",
auth=HTTPBasicAuth(username, password),
verify=False, timeout=10,
)
if resp.status_code == 200:
return resp.json().get("data", {}).get("token")
except requests.RequestException:
pass
return None
def _api(self, method, path, params=None, data=None):
if not requests or not self.token:
return None
try:
resp = requests.request(
method, f"{self.base_url}{path}",
headers={"Authorization": f"Bearer {self.token}"},
params=params, json=data, verify=False, timeout=15,
)
return resp.json() if resp.status_code == 200 else None
except requests.RequestException:
return None
def list_agents(self):
"""List all registered Wazuh agents with status."""
data = self._api("GET", "/agents", params={"limit": 500, "select": "id,name,status,os.name,os.version,version,lastKeepAlive,ip"})
if not data:
return []
agents = data.get("data", {}).get("affected_items", [])
disconnected = [a for a in agents if a.get("status") == "disconnected"]
if disconnected:
self.findings.append({
"severity": "medium", "type": "Disconnected Agents",
"detail": f"{len(disconnected)} agents disconnected",
})
return agents
def get_agent_summary(self):
"""Get agent status summary counts."""
data = self._api("GET", "/agents/summary/status")
if data:
return data.get("data", {})
return {}
def query_alerts(self, limit=20, level_min=10):
"""Query recent high-severity alerts."""
data = self._api("GET", "/alerts", params={
"limit": limit, "sort": "-timestamp",
"q": f"rule.level>={level_min}",
})
if not data:
return []
alerts = data.get("data", {}).get("affected_items", [])
return [{
"id": a.get("id"),
"timestamp": a.get("timestamp"),
"rule_id": a.get("rule", {}).get("id"),
"rule_description": a.get("rule", {}).get("description"),
"rule_level": a.get("rule", {}).get("level"),
"agent_name": a.get("agent", {}).get("name"),
"agent_id": a.get("agent", {}).get("id"),
} for a in alerts]
def get_rules_summary(self):
"""Get summary of active detection rules."""
data = self._api("GET", "/rules", params={"limit": 500, "select": "id,description,level,groups"})
if not data:
return {"total": 0}
rules = data.get("data", {}).get("affected_items", [])
total = data.get("data", {}).get("total_affected_items", len(rules))
levels = {}
for r in rules:
lvl = str(r.get("level", 0))
levels[lvl] = levels.get(lvl, 0) + 1
return {"total_rules": total, "by_level": levels}
def test_logtest(self, log_line, log_format="syslog"):
"""Test a log line against Wazuh decoders and rules."""
data = self._api("PUT", "/logtest", data={
"log_format": log_format,
"location": "test",
"event": log_line,
})
if not data:
return {"error": "Logtest failed"}
result = data.get("data", {})
return {
"decoder": result.get("decoder", {}).get("name"),
"rule_id": result.get("rule", {}).get("id"),
"rule_description": result.get("rule", {}).get("description"),
"rule_level": result.get("rule", {}).get("level"),
"output": result.get("output"),
}
def check_vulnerability_detection(self):
"""Check if vulnerability detection module is enabled."""
data = self._api("GET", "/manager/configuration",
params={"section": "vulnerability-detector"})
if data:
config = data.get("data", {}).get("affected_items", [])
if config:
enabled = config[0].get("vulnerability-detector", {}).get("enabled", "no")
if enabled != "yes":
self.findings.append({
"severity": "medium", "type": "Vuln Detection Disabled",
"detail": "Vulnerability detection module is not enabled",
})
return {"enabled": enabled == "yes"}
return {"enabled": False}
def generate_report(self):
agents = self.list_agents()
summary = self.get_agent_summary()
alerts = self.query_alerts()
rules = self.get_rules_summary()
vuln_det = self.check_vulnerability_detection()
report = {
"report_date": datetime.utcnow().isoformat(),
"wazuh_url": self.base_url,
"agent_summary": summary,
"agents": agents[:50],
"total_agents": len(agents),
"recent_critical_alerts": alerts,
"rules_summary": rules,
"vulnerability_detection": vuln_det,
"findings": self.findings,
"total_findings": len(self.findings),
}
out = self.output_dir / "wazuh_detection_report.json"
with open(out, "w") as f:
json.dump(report, f, indent=2, default=str)
print(json.dumps(report, indent=2, default=str))
return report
def main():
parser = argparse.ArgumentParser(
description="Manage Wazuh endpoint detection and query alerts"
)
parser.add_argument("wazuh_url", help="Wazuh API URL (e.g. https://wazuh:55000)")
parser.add_argument("--username", default="wazuh-wui", help="API username")
parser.add_argument("--password", required=True, help="API password")
parser.add_argument("--output-dir", default="./wazuh_detection")
args = parser.parse_args()
os.makedirs(args.output_dir, exist_ok=True)
agent = WazuhDetectionAgent(args.wazuh_url, args.username, args.password,
output_dir=args.output_dir)
agent.generate_report()
if __name__ == "__main__":
main()