Files
Wazuh-API-Helper/README.md
2025-11-10 11:37:13 -06:00

269 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Wazuh API Helper (Python)
A lightweight helper around the Wazuh/OpenSearch APIs with a tiny DSL for building queries. It includes:
* `wazuh_dsl_query` build OpenSearch-style bool/range/terms queries programmatically
* `wazuh_api` convenience wrapper for common Wazuh operations (search, SQL, counts, snapshots, MITRE rollups, vuln reporting, etc.)
> Note: Some hooks in the code reference proprietary utilities (e.g., Jira helpers) that are not included. Those paths are noted in comments and are safe to remove or replace.
---
## Features at a Glance
* Simple DSL to compose filters, ranges, exists checks, wildcard/multi-match, aggregations
* Search helpers for `wazuh-alerts-*` indices
* OpenSearch SQL endpoint helper
* Aggregation parsers (agents, MITRE tactics/techniques, actionable alert groupings)
* Vulnerability detector report helpers (with `jq`-based shaping)
* Token-based calls to the Wazuh Security API (overview endpoints)
* Snapshot existence/creation helpers (example uses `AWS-S3` repo)
* Alert retrieval by ID and recent alerts by level/time window
---
## Requirements
* Python 3.10+ recommended
* System dependency for `jq` Python package:
* Linux: `sudo apt-get install -y libjq1` (Debian/Ubuntu) or `sudo yum install jq` (RHEL/CentOS)
* macOS: `brew install jq`
* Python packages (see `requirements.txt` below)
### `requirements.txt`
```txt
requests>=2.31.0
jq>=1.6.0
```
---
## Installation
```bash
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
If you see `Unable to load external libraries`, ensure the virtualenv is active and `libjq/jq` is installed.
---
## Quick Start
```python
from wazuh_api import wazuh_api, wazuh_dsl_query # adjust if your filename/module is different
api = wazuh_api(
indexer_url="https://wazuh-indexer.example.com:9200",
analyst_url="https://wazuh.example.com",
admin_api_url="https://wazuh.example.com:55000",
user="wazuh_reader",
password="******",
admin_username="wazuh_admin",
admin_password="******",
)
# Basic health check
assert api.settings_valid(), "Wazuh API settings are not valid"
# Build a DSL query for alerts between two ISO timestamps
q = wazuh_dsl_query("2025-01-01T00:00:00.000Z", "2025-01-01T23:59:59.999Z")
q.set_size(10)
q.add_filter_range("rule.level", 12, 16) # actionable levels
q.add_filter_field_must_exist("rule.level")
query = q.get_query(exclude_size=False)
hits = api.do_wazuh_search(query) # returns hits list
print(f"Found {len(hits)} hits")
```
---
## Common Recipes
### 1) Get Alerts in the Last N Minutes
```python
recent = api.get_alerts(
index="wazuh-alerts-*",
min_alert_level=12,
max_alert_level=16,
max_alerts=200,
minutes_back=60,
)
```
### 2) Count Alerts in a Time Range
```python
count_resp = api.get_alerts_count_for_time_range(
"2025-01-01T00:00:00.000Z",
"2025-01-01T12:00:00.000Z",
)
print(count_resp) # OpenSearch _count response
```
### 3) Search Logs Related to a Specific Alert (by field/value)
```python
related = api.search_logs_related_to_alert(
timestamp="2025-01-01T05:15:30.000Z",
minutes_around=2,
filter_label="rule.id",
filter_value="123456",
)
```
### 4) MITRE TTP Rollups (Aggregations)
```python
ttp = api.get_mitre_attack_data(
"2025-01-01T00:00:00.000Z",
"2025-01-02T00:00:00.000Z",
)
# Returns dict with buckets for 'mitre_tactics' and 'mitre_tech'
```
### 5) Top Agents with Alerts
```python
agents = api.get_top_agents_with_alerts(
"2025-01-01T00:00:00.000Z",
"2025-01-02T00:00:00.000Z",
)
```
### 6) Vulnerability Detector Report (example)
```python
vuln_rows = api.get_vuln_report_data_v2(
start_date_iso="2025-01-01T00:00:00.000Z",
end_date_iso="2025-01-31T23:59:59.999Z",
limit=True, # only sample a few agents
)
# List of dicts like "Machine Name", "IP", "Application", "CVE ID", etc.
```
### 7) OpenSearch SQL
```python
resp = api.do_wazuh_sql_query("SELECT agent.name FROM wazuh-alerts-* LIMIT 5")
print(resp)
```
### 8) Alert by Document ID
```python
alert = api.get_alert_by_id(alert_id="Aw123...docid...", date="2025-02-11")
```
---
## Class Overview
### `wazuh_dsl_query`
* `set_size(n)` set result size
* `add_filter_range(field, gte, lte, timestamp=False)` range filter; set `timestamp=True` to include OpenSearch date format
* `add_filter_exact_match(field, value)` exact match via `match_phrase`
* `add_filter_value_in_field(field, values)` OR of several exact matches
* `add_filter_field_must_exist(field)` `exists` filter
* `add_filter_wildcard_match(value)` `multi_match` (lenient) text search
* `add_filter_exclude(field, value)` append `must_not` for a value
* `add_agg_count(name, field)` value_count aggregation
* `add_agg_count_group(name, field, max_size=20)` terms aggregation
* `get_query(exclude_size=True)` build final query dict
### `wazuh_api`
Core settings:
* `indexer_url` OpenSearch/Indexer base (e.g., `https://host:9200`)
* `analyst_url` Wazuh web (used in some orgs; not strictly required in helper methods)
* `admin_api_url` Wazuh API (e.g., `https://host:55000`)
* `user/password` basic auth for indexer
* `admin_username/admin_password` admin creds for Wazuh Security API token calls
Key methods:
* Search & SQL: `do_wazuh_search`, `do_wazuh_sql_query`, `get_count_for_wazuh_query`
* Snapshots: `check_snapshot_exits(date)`, `do_snapshot(date)`
* Helpers: `get_time_around_wazuh_alert_time`, `search_logs_related_to_alert`
* Reporting/Aggs: `get_top_agents_with_alerts`, `get_mitre_attack_data`, `get_data_for_actionable_alerts`
* Security API: `get_token`, `get_agent_overview`
* Alert utils: `get_alert_by_id`, `get_alerts`
* Vuln parsing: `get_vuln_report_data_v2`, `format_cve_list`, `__parse_vuln_record` (uses `jq`)
---
## Configuration Tips
* The code initializes a basic logger:
```python
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s")
```
Replace with your own logging setup in production.
* TLS verification is disabled (`verify=False`) in requests for convenience. **Strongly** consider enabling verification and providing a CA bundle in production.
* The snapshot helpers assume a repository named `AWS-S3`. Snapshot repo name is configurable via snapshot_repo in the constructor (default: AWS-S3)..
* Integration-specific parsers can be added by defining methods named parse_{integration}_integration (Wazuhs data.integration with - replaced by _). A fallback parse_default_integration is provided.
---
## Security Notes
* Avoid committing real credentials. Use environment variables or a secrets manager.
* Consider rotating to token-based auth for indexer access as supported by your deployment.
* Re-enable certificate verification and pin CA where possible.
---
## Error Handling
* Methods return `{}`, `[]`, or `False` on errors and log details with `logger.critical`/`logger.error`.
* Wrap calls in your code to handle these cases gracefully.
---
## Known Gaps / TODO
* Expand unit tests and add type hints where appropriate for stricter usage.
---
## Project Structure (suggested)
```
your-repo/
├─ wazuh_api.py # this module (rename as needed)
├─ requirements.txt
├─ examples/
│ └─ quickstart.py
└─ README.md
```
---
## License
MIT (suggested). Replace with your preferred license.
---
## Changelog
* **v0.1.0** Initial public extraction: search/SQL helpers, DSL, aggregations, vuln report shaping, snapshot helpers.
---
## Support
Open an issue or PR on this repo. If you extend parsers for additional Wazuh integrations, consider contributing back minimal, non-proprietary versions.