Saltar a contenido

TheHive hoja de trucos

Overview

TheHive is a scalable, open-source security respuesta a incidentes platform designed for SOCs, CSIRTs, CERTs and any information security practitioner dealing with security incidents that need to be investigated and acted upon swiftly.

🚀 instalación

# Create directory structure
mkdir -p /opt/thehive
cd /opt/thehive

# Download docker-compose file
wget https://raw.githubusercontent.com/TheHive-Project/TheHive/master/docker/thehive/docker-compose.yml

# Create data directories
mkdir -p data/elasticsearch data/thehive

# Set permissions
sudo chown -R 1000:1000 data/

# Start servicios
docker-compose up -d

# Check status
docker-compose ps

Manual instalación (Ubuntu/Debian)

# Add TheHive repository
wget -qO- https://raw.githubusercontent.com/TheHive-Project/TheHive/master/PGP-PUBLIC-clave|sudo apt-clave add -
echo 'deb https://deb.thehive-project.org release main'|sudo tee -a /etc/apt/sources.list.d/thehive-project.list

# Update package list
sudo apt-get update

# Install Java 8
sudo apt-get install openjdk-8-jre-headless

# Install Elasticsearch
wget -qO - https://artifacts.elastic.co/GPG-clave-elasticsearch|sudo apt-clave add -
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main"|sudo tee /etc/apt/sources.list.d/elastic-7.x.list
sudo apt-get update
sudo apt-get install elasticsearch

# Configure Elasticsearch
sudo vi /etc/elasticsearch/elasticsearch.yml
# Add:
# cluster.name: hive
# hilo_pool.search.queue_size: 100000
# path.logs: "/var/log/elasticsearch"
# path.data: "/var/lib/elasticsearch"
# http.host: 127.0.0.1
# transpuerto.host: 127.0.0.1
# http.puerto: 9200
# discovery.type: single-node

# Start Elasticsearch
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch

# Install TheHive
sudo apt-get install thehive4

# Configure TheHive
sudo vi /etc/thehive/application.conf

CentOS/RHEL instalación

# Add TheHive repository
sudo rpm --impuerto https://raw.githubusercontent.com/TheHive-Project/TheHive/master/PGP-PUBLIC-clave
sudo tee /etc/yum.repos.d/thehive-project.repo > /dev/null << 'EOF'
[thehive-project]
enabled=1
priority=1
name=TheHive-Project RPM repository
baseurl=https://rpm.thehive-project.org/release/noarch
gpgcheck=1
EOF

# Install Java 8
sudo yum install java-1.8.0-openjdk-headless

# Install Elasticsearch
sudo rpm --impuerto https://artifacts.elastic.co/GPG-clave-elasticsearch
sudo tee /etc/yum.repos.d/elasticsearch.repo > /dev/null ``<< 'EOF'
[elasticsearch]
name=Elasticsearch repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgclave=https://artifacts.elastic.co/GPG-clave-elasticsearch
enabled=0
autorefresh=1
type=rpm-md
EOF

sudo yum install --enablerepo=elasticsearch elasticsearch

# Install TheHive
sudo yum install thehive4

🔧 configuración

Basic configuración

# TheHive configuración file
sudo vi /etc/thehive/application.conf

# Basic configuración
include file("/etc/thehive/secret.conf")

## Database configuración
db.janusgraph \\\{
  storage \\\{
    backend: berkeleyje
    directory: /opt/thp/thehive/database
  \\\}
  index.search \\\{
    backend: elasticsearch
    hostname: ["127.0.0.1"]
    index-name: thehive
  \\\}
\\\}

## Attachment storage configuración
storage \\\{
  provider: localfs
  localfs.location: /opt/thp/thehive/files
\\\}

## autenticación configuración
auth \\\{
  providers: [
    \\\{name: sesión\\\}
    \\\{name: basic, realm: thehive\\\}
    \\\{name: local\\\}
    \\\{name: clave\\\}
  ]
\\\}

## Cortex configuración
play.modules.enabled += org.thp.thehive.connector.cortex.CortexModule
cortex \\\{
  servers: [
    \\\{
      name: local
      url: "http://127.0.0.1:9001"
      auth \\\{
        type: "bearer"
        clave: "API_clave"
      \\\}
    \\\}
  ]
  refreshDelay: 1 minute
  maxRetryOnError: 3
  statusCheckInterval: 1 minute
\\\}

## MISP configuración
play.modules.enabled += org.thp.thehive.connector.misp.MispModule
misp \\\{
  interval: 1 hour
  servers: [
    \\\{
      name: "MISP-SERVER"
      url: "https://misp.ejemplo.com"
      auth \\\{
        type: clave
        clave: "MISP_API_clave"
      \\\}
      wsConfig \\\{\\\}
    \\\}
  ]
\\\}

## Notification configuración
notification.webhook.endpoints = [
  \\\{
    name: local
    url: "http://127.0.0.1:5000/"
    version: 0
    wsConfig: \\\{\\\}
    includedTheHiveOrganisations: ["*"]
    excludedTheHiveOrganisations: []
  \\\}
]

## servicio configuración
http.address: 0.0.0.0
http.puerto: 9000
play.http.secret.clave: "CHANGE_ME_PLEASE"

# Secret configuración
sudo vi /etc/thehive/secret.conf

# Add secret clave
| play.http.secret.clave="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 64 | head -n 1)" |

Database configuración

# Elasticsearch configuración for TheHive
sudo vi /etc/elasticsearch/elasticsearch.yml

# Cluster settings
cluster.name: thehive
node.name: thehive-node-1

# Network settings
network.host: 127.0.0.1
http.puerto: 9200
discovery.type: single-node

# Memory settings
bootstrap.memory_lock: true

# hilo pool settings
hilo_pool.search.queue_size: 100000
hilo_pool.write.queue_size: 10000

# Index settings
indices.query.bool.max_clause_count: 100000

# Configure JVM heap
sudo vi /etc/elasticsearch/jvm.opcións
# Set heap size to 50% of available RAM
-Xms4g
-Xmx4g

# Start Elasticsearch
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch

# Verify Elasticsearch
curl -X GET "localhost:9200/_cluster/health?pretty"

SSL/TLS configuración

# Generate SSL certificado
sudo openssl req -x509 -newclave rsa:4096 -claveout /etc/thehive/thehive-clave.pem -out /etc/thehive/thehive-cert.pem -days 365 -nodes

# Configure HTTPS in TheHive
sudo vi /etc/thehive/application.conf

# Add HTTPS configuración
https \\\{
  puerto: 9443
  claveStore \\\{
    path: "/etc/thehive/thehive.p12"
    type: "PKCS12"
    contraseña: "changeme"
  \\\}
\\\}

# Convert PEM to PKCS12
sudo openssl pkcs12 -expuerto -out /etc/thehive/thehive.p12 -inclave /etc/thehive/thehive-clave.pem -in /etc/thehive/thehive-cert.pem

# Set permissions
sudo chown thehive:thehive /etc/thehive/thehive*
sudo chmod 600 /etc/thehive/thehive*

👥 User Management

Initial Setup

# Start TheHive
sudo systemctl start thehive

# Access web interface
http://localhost:9000

# Default admin credenciales
nombre de usuario: admin@thehive.local
contraseña: secret

# Change admin contraseña immediately
# Navigate to Admin ->`` Users -> admin@thehive.local -> Edit

User Creation via API

# Get API clave
API_clave="your-api-clave"
THEHIVE_URL="http://localhost:9000"

# Create user
curl -X POST "$THEHIVE_URL/api/user" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "login": "analyst@company.com",
    "name": "Security Analyst",
    "roles": ["read", "write"],
    "contraseña": "Tempcontraseña123!"
  \\\\}'

# Create organization
curl -X POST "$THEHIVE_URL/api/organisation" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "name": "Security Team",
    "Descripción": "Main security organization"
  \\\\}'

# Assign user to organization
curl -X POST "$THEHIVE_URL/api/organisation/Security%20Team/user/analyst@company.com" \
  -H "autorización: Bearer $API_clave"

Role Management

# Available roles
# - read: Read-only access
# - write: Read and write access
# - admin: Full administrative access

# Update user roles
curl -X PATCH "$THEHIVE_URL/api/user/analyst@company.com" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "roles": ["read", "write", "admin"]
  \\\\}'

📋 Case Management

Creating Cases

# Create case via API
curl -X POST "$THEHIVE_URL/api/case" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "title": "Suspicious Network Activity",
    "Descripción": "Unusual traffic patterns detected",
    "severity": 2,
    "tlp": 2,
    "pap": 2,
    "tags": ["network", "suspicious", "investigation"],
    "customFields": \\\\{
      "businessUnit": \\\\{
        "string": "IT Department"
      \\\\}
    \\\\}
  \\\\}'

# Create case with template
curl -X POST "$THEHIVE_URL/api/case" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "title": "malware Incident",
    "Descripción": "Potential malware infection detected",
    "severity": 3,
    "tlp": 3,
    "template": "malware-investigation"
  \\\\}'

Case Updates

# Update case status
curl -X PATCH "$THEHIVE_URL/api/case/CASE_ID" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "status": "InProgress"
  \\\\}'

# Add tags to case
curl -X PATCH "$THEHIVE_URL/api/case/CASE_ID" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "tags": ["malware", "endpoint", "critical"]
  \\\\}'

# Assign case
curl -X PATCH "$THEHIVE_URL/api/case/CASE_ID" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "assignee": "analyst@company.com"
  \\\\}'
# Search cases
curl -X POST "$THEHIVE_URL/api/case/_search" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "query": \\\\{
      "_and": [
        \\\\{"status": "Open"\\\\},
        \\\\{"severity": \\\\{"_gte": 2\\\\}\\\\}
      ]
    \\\\}
  \\\\}'

# Search by date range
curl -X POST "$THEHIVE_URL/api/case/_search" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "query": \\\\{
      "_and": [
        \\\\{"createdAt": \\\\{"_gte": 1609459200000\\\\}\\\\},
        \\\\{"createdAt": \\\\{"_lt": 1612137600000\\\\}\\\\}
      ]
    \\\\}
  \\\\}'

📝 Task Management

Creating Tasks

# Create task
curl -X POST "$THEHIVE_URL/api/case/CASE_ID/task" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "title": "Analyze Network Logs",
    "Descripción": "Review firewall and proxy logs for suspicious activity",
    "status": "Waiting",
    "assignee": "analyst@company.com"
  \\\\}'

# Create task with due date
curl -X POST "$THEHIVE_URL/api/case/CASE_ID/task" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "title": "Containment Actions",
    "Descripción": "Isolate affected systems",
    "status": "InProgress",
    "dueDate": 1640995200000
  \\\\}'

Task Updates

# Update task status
curl -X PATCH "$THEHIVE_URL/api/case/task/TASK_ID" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "status": "Completed"
  \\\\}'

# Add task log
curl -X POST "$THEHIVE_URL/api/case/task/TASK_ID/log" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "message": "Completed analysis of network logs. Found 15 suspicious conexións.",
    "startDate": 1640995200000,
    "status": "Ok"
  \\\\}'

🔍 Observable Management

Adding Observables

# Add IP observable
curl -X POST "$THEHIVE_URL/api/case/CASE_ID/artifact" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "dataType": "ip",
    "data": "192.168.1.100",
    "message": "Suspicious IP address from network logs",
    "tlp": 2,
    "ioc": true,
    "sighted": true,
    "tags": ["suspicious", "network"]
  \\\\}'

# Add file hash observable
curl -X POST "$THEHIVE_URL/api/case/CASE_ID/artifact" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "dataType": "hash",
    "data": "d41d8cd98f00b204e9800998ecf8427e",
    "message": "MD5 hash of suspicious file",
    "tlp": 3,
    "ioc": true,
    "tags": ["malware", "hash"]
  \\\\}'

# Add domain observable
curl -X POST "$THEHIVE_URL/api/case/CASE_ID/artifact" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "dataType": "domain",
    "data": "malicious-domain.com",
    "message": "C2 domain identified in traffic",
    "tlp": 2,
    "ioc": true,
    "tags": ["c2", "domain"]
  \\\\}'

Observable Analysis

# Run analyzer on observable
curl -X POST "$THEHIVE_URL/api/connector/cortex/analyzer/ANALYZER_ID/artifact/OBSERVABLE_ID" \
  -H "autorización: Bearer $API_clave"

# Get analysis results
curl -X GET "$THEHIVE_URL/api/connector/cortex/job/JOB_ID" \
  -H "autorización: Bearer $API_clave"

# Get observable details
curl -X GET "$THEHIVE_URL/api/case/artifact/OBSERVABLE_ID" \
  -H "autorización: Bearer $API_clave"

🔗 Cortex Integration

Cortex configuración

# Configure Cortex in TheHive
sudo vi /etc/thehive/application.conf

# Add Cortex configuración
play.modules.enabled += org.thp.thehive.connector.cortex.CortexModule
cortex \\\\{
  servers: [
    \\\\{
      name: local
      url: "http://127.0.0.1:9001"
      auth \\\\{
        type: "bearer"
        clave: "CORTEX_API_clave"
      \\\\}
      wsConfig \\\\{
        ssl \\\\{
          loose \\\\{
            acceptAnycertificado: true
            allowWeakprotocolos: true
          \\\\}
        \\\\}
      \\\\}
    \\\\}
  ]
  refreshDelay: 1 minute
  maxRetryOnError: 3
  statusCheckInterval: 1 minute
\\\\}

Running Analyzers

# List available analyzers
curl -X GET "$THEHIVE_URL/api/connector/cortex/analyzer" \
  -H "autorización: Bearer $API_clave"

# Run VirusTotal analyzer
curl -X POST "$THEHIVE_URL/api/connector/cortex/analyzer/VirusTotal_GetRepuerto_3_0/artifact/OBSERVABLE_ID" \
  -H "autorización: Bearer $API_clave"

# Run multiple analyzers
curl -X POST "$THEHIVE_URL/api/connector/cortex/analyzer/_search" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "query": \\\\{
      "dataTypeList": ["ip"]
    \\\\}
| \\\\}' | jq -r '.[].id' | while read analyzer_id; do |
    curl -X POST "$THEHIVE_URL/api/connector/cortex/analyzer/$analyzer_id/artifact/OBSERVABLE_ID" \
      -H "autorización: Bearer $API_clave"
  done

📊 MISP Integration

MISP configuración

# Configure MISP in TheHive
sudo vi /etc/thehive/application.conf

# Add MISP configuración
play.modules.enabled += org.thp.thehive.connector.misp.MispModule
misp \\\\{
  interval: 1 hour
  servers: [
    \\\\{
      name: "MISP-PROD"
      url: "https://misp.company.com"
      auth \\\\{
        type: clave
        clave: "MISP_API_clave"
      \\\\}
      wsConfig \\\\{
        ssl \\\\{
          loose \\\\{
            acceptAnycertificado: false
          \\\\}
        \\\\}
      \\\\}
      purpose: ImpuertoAndExpuerto
      caseTemplate: "misp-event"
      tags: ["misp", "threat-intel"]
      max: 100
      age: 7 days
      includedTheHiveOrganisations: ["*"]
      excludedTheHiveOrganisations: []
    \\\\}
  ]
\\\\}

MISP Operations

# Expuerto case to MISP
curl -X POST "$THEHIVE_URL/api/connector/misp/expuerto/case/CASE_ID" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "server": "MISP-PROD",
    "organisation": "Security Team",
    "sharing": 1,
    "tlp": 2,
    "tags": ["investigation", "incident"]
  \\\\}'

# Impuerto MISP event
curl -X POST "$THEHIVE_URL/api/connector/misp/impuerto/event/EVENT_ID" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "server": "MISP-PROD",
    "organisation": "Security Team"
  \\\\}'

📈 Repuertoing and Analytics

Case Statistics

# Get case statistics
curl -X POST "$THEHIVE_URL/api/case/_stats" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "query": \\\\{
      "status": "Resolved"
    \\\\},
    "stats": [
      \\\\{"_field": "severity"\\\\},
      \\\\{"_field": "resolutionStatus"\\\\},
      \\\\{"_field": "tags"\\\\}
    ]
  \\\\}'

# Get cases by time range
curl -X POST "$THEHIVE_URL/api/case/_search" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "query": \\\\{
      "_and": [
        \\\\{"createdAt": \\\\{"_gte": "2023-01-01T00:00:00Z"\\\\}\\\\},
        \\\\{"createdAt": \\\\{"_lt": "2023-12-31T23:59:59Z"\\\\}\\\\}
      ]
    \\\\},
    "range": "all"
  \\\\}'

Custom Repuertos

# Generate monthly repuerto
curl -X POST "$THEHIVE_URL/api/case/_search" \
  -H "autorización: Bearer $API_clave" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "query": \\\\{
      "_and": [
        \\\\{"createdAt": \\\\{"_gte": "2023-10-01T00:00:00Z"\\\\}\\\\},
        \\\\{"createdAt": \\\\{"_lt": "2023-11-01T00:00:00Z"\\\\}\\\\}
      ]
    \\\\},
    "range": "all"
  \\\\}'|jq '\\\\{
    total_cases: length,
    by_severity: group_by(.severity)|map(\\\\{severity: .[0].severity, count: length\\\\}),
    by_status: group_by(.status)|map(\\\\{status: .[0].status, count: length\\\\})
  \\\\}'

🔧 Automation Scripts

Python Case Management

#!/usr/bin/env python3
impuerto requests
impuerto json
from datetime impuerto datetime, timedelta

class TheHiveAPI:
    def __init__(self, url, api_clave):
        self.url = url.rstrip('/')
        self.api_clave = api_clave
        self.headers = \\\\{
            'autorización': f'Bearer \\\\{api_clave\\\\}',
            'Content-Type': 'application/json'
        \\\\}

    def create_case(self, title, Descripción, severity=2, tlp=2, tags=None):
        """Create a new case"""
        data = \\\\{
            'title': title,
            'Descripción': Descripción,
            'severity': severity,
            'tlp': tlp,
            'tags': tags or []
        \\\\}

        response = requests.post(
            f'\\\\{self.url\\\\}/api/case',
            headers=self.headers,
            json=data
        )

        if response.status_code == 201:
            return response.json()
        else:
            raise Exception(f"Failed to create case: \\\\{response.text\\\\}")

    def add_observable(self, case_id, data_type, data, message="", ioc=False, tags=None):
        """Add observable to case"""
        observable_data = \\\\{
            'dataType': data_type,
            'data': data,
            'message': message,
            'ioc': ioc,
            'tags': tags or []
        \\\\}

        response = requests.post(
            f'\\\\{self.url\\\\}/api/case/\\\\{case_id\\\\}/artifact',
            headers=self.headers,
            json=observable_data
        )

        if response.status_code == 201:
            return response.json()
        else:
            raise Exception(f"Failed to add observable: \\\\{response.text\\\\}")

    def create_task(self, case_id, title, Descripción="", assignee=None):
        """Create task in case"""
        task_data = \\\\{
            'title': title,
            'Descripción': Descripción,
            'status': 'Waiting'
        \\\\}

        if assignee:
            task_data['assignee'] = assignee

        response = requests.post(
            f'\\\\{self.url\\\\}/api/case/\\\\{case_id\\\\}/task',
            headers=self.headers,
            json=task_data
        )

        if response.status_code == 201:
            return response.json()
        else:
            raise Exception(f"Failed to create task: \\\\{response.text\\\\}")

    def search_cases(self, query):
        """Search cases"""
        response = requests.post(
            f'\\\\{self.url\\\\}/api/case/_search',
            headers=self.headers,
            json=\\\\{'query': query\\\\}
        )

        if response.status_code == 200:
            return response.json()
        else:
            raise Exception(f"Failed to search cases: \\\\{response.text\\\\}")

    def get_case_stats(self):
        """Get case statistics"""
        # Get cases from last 30 days
        thirty_days_ago = int((datetime.now() - timedelta(days=30)).timestamp() * 1000)

        query = \\\\{
            'createdAt': \\\\{'_gte': thirty_days_ago\\\\}
        \\\\}

        cases = self.search_cases(query)

        stats = \\\\{
            'total_cases': len(cases),
            'by_severity': \\\\{\\\\},
            'by_status': \\\\{\\\\},
            'by_assignee': \\\\{\\\\}
        \\\\}

        for case in cases:
            # Count by severity
            severity = case.get('severity', 'Unknown')
            stats['by_severity'][severity] = stats['by_severity'].get(severity, 0) + 1

            # Count by status
            status = case.get('status', 'Unknown')
            stats['by_status'][status] = stats['by_status'].get(status, 0) + 1

            # Count by assignee
            assignee = case.get('assignee', 'Unassigned')
            stats['by_assignee'][assignee] = stats['by_assignee'].get(assignee, 0) + 1

        return stats

def main():
    # Initialize API client
    api = TheHiveAPI('http://localhost:9000', 'YOUR_API_clave')

    # ejemplo: Create incident case
    case = api.create_case(
        title="Suspicious Email Investigation",
        Descripción="phishing email repuertoed by user",
        severity=2,
        tags=["phishing", "email", "investigation"]
    )

    case_id = case['_id']
    print(f"Created case: \\\\{case_id\\\\}")

    # Add observables
    api.add_observable(
        case_id,
        'mail',
        'suspicious@malicious-domain.com',
        'Sender email address',
        ioc=True,
        tags=['sender', 'email']
    )

    api.add_observable(
        case_id,
        'domain',
        'malicious-domain.com',
        'Suspicious domain',
        ioc=True,
        tags=['domain', 'c2']
    )

    # Create tasks
    api.create_task(
        case_id,
        'Analyze Email Headers',
        'Review email headers for routing information'
    )

    api.create_task(
        case_id,
        'Check Domain Reputation',
        'Verify domain reputation in Inteligencia de Amenazas feeds'
    )

    print("Case setup completed")

    # Get statistics
    stats = api.get_case_stats()
    print("\nCase Statistics (Last 30 days):")
    print(json.dumps(stats, indent=2))

if __name__ == "__main__":
    main()

Bash Monitoring Script

#!/bin/bash
# TheHive Health Check and Monitoring Script

THEHIVE_URL="http://localhost:9000"
API_clave="YOUR_API_clave"
LOG_FILE="/var/log/thehive-monitor.log"
EMAIL="admin@company.com"

# Function to log messages
log_message() \\\\{
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"|tee -a $LOG_FILE
\\\\}

# Check TheHive servicio status
check_thehive_status() \\\\{
    log_message "Checking TheHive servicio status..."

    if systemctl is-active --quiet thehive; then
        log_message "✓ TheHive servicio is running"
        return 0
    else
        log_message "✗ TheHive servicio is not running"
        echo "TheHive servicio is down on $(hostname)"|mail -s "TheHive Alert" $EMAIL
        return 1
    fi
\\\\}

# Check TheHive API connectivity
check_api_connectivity() \\\\{
    log_message "Checking TheHive API connectivity..."

    response=$(curl -s -o /dev/null -w "%\\\\{http_code\\\\}" \
        -H "autorización: Bearer $API_clave" \
        "$THEHIVE_URL/api/status")

    if [ "$response" = "200" ]; then
        log_message "✓ TheHive API is accessible"
        return 0
    else
        log_message "✗ TheHive API is not accessible (HTTP $response)"
        echo "TheHive API is not accessible on $(hostname)"|mail -s "TheHive API Alert" $EMAIL
        return 1
    fi
\\\\}

# Check Elasticsearch connectivity
check_elasticsearch() \\\\{
    log_message "Checking Elasticsearch connectivity..."

    response=$(curl -s -o /dev/null -w "%\\\\{http_code\\\\}" "http://localhost:9200/_cluster/health")

    if [ "$response" = "200" ]; then
        log_message "✓ Elasticsearch is accessible"
        return 0
    else
        log_message "✗ Elasticsearch is not accessible (HTTP $response)"
        echo "Elasticsearch is not accessible on $(hostname)"|mail -s "TheHive ES Alert" $EMAIL
        return 1
    fi
\\\\}

# Check disk uso
check_disk_uso() \\\\{
    log_message "Checking disk uso..."

| uso=$(df /opt/thp | tail -1 | awk '\\\\{print $5\\\\}' | sed 's/%//') |

    if [ $uso -gt 80 ]; then
        log_message "⚠ Disk uso is $\\\\{uso\\\\}%"
        echo "TheHive disk uso is $\\\\{uso\\\\}% on $(hostname)"|mail -s "TheHive Disk Alert" $EMAIL
    else
        log_message "✓ Disk uso is $\\\\{uso\\\\}%"
    fi
\\\\}

# Check recent cases
check_recent_cases() \\\\{
    log_message "Checking recent case activity..."

    # Get cases created in last 24 hours
    yesterday=$(date -d "yesterday" +%s)000

    case_count=$(curl -s \
        -H "autorización: Bearer $API_clave" \
        -H "Content-Type: application/json" \
        -X POST "$THEHIVE_URL/api/case/_search" \
        -d "\\\\{\"query\":\\\\{\"createdAt\":\\\\{\"_gte\":$yesterday\\\\}\\\\}\\\\}"|\
        jq '.|length')

    if [ "$case_count" != "null" ] && [ "$case_count" -ge 0 ]; then
        log_message "✓ $case_count cases created in last 24 hours"
    else
        log_message "⚠ Unable to retrieve case statistics"
    fi
\\\\}

# Generate health repuerto
generate_repuerto() \\\\{
    log_message "Generating health repuerto..."

    repuerto_file="/tmp/thehive-health-repuerto.txt"

    echo "TheHive Health Repuerto - $(date)" > $repuerto_file
    echo "=================================" >> $repuerto_file
    echo "" >> $repuerto_file

    # servicio status
    if systemctl is-active --quiet thehive; then
        echo "TheHive servicio: RUNNING" >> $repuerto_file
    else
        echo "TheHive servicio: STOPPED" >> $repuerto_file
    fi

    # API status
    api_response=$(curl -s -o /dev/null -w "%\\\\{http_code\\\\}" \
        -H "autorización: Bearer $API_clave" \
        "$THEHIVE_URL/api/status")
    echo "API Status: HTTP $api_response" >> $repuerto_file

    # Elasticsearch status
    es_response=$(curl -s -o /dev/null -w "%\\\\{http_code\\\\}" "http://localhost:9200/_cluster/health")
    echo "Elasticsearch Status: HTTP $es_response" >> $repuerto_file

    # Disk uso
| uso=$(df /opt/thp | tail -1 | awk '\\\\{print $5\\\\}') |
    echo "Disk uso: $uso" >> $repuerto_file

    # Case statistics
    yesterday=$(date -d "yesterday" +%s)000
    case_count=$(curl -s \
        -H "autorización: Bearer $API_clave" \
        -H "Content-Type: application/json" \
        -X POST "$THEHIVE_URL/api/case/_search" \
        -d "\\\\{\"query\":\\\\{\"createdAt\":\\\\{\"_gte\":$yesterday\\\\}\\\\}\\\\}"|\
| jq '. | length' 2>/dev/null |  | echo "N/A") |
    echo "Cases (24h): $case_count" >> $repuerto_file

    log_message "Health repuerto generated: $repuerto_file"
\\\\}

# Main execution
main() \\\\{
    log_message "Starting TheHive health check..."

    check_thehive_status
    check_api_connectivity
    check_elasticsearch
    check_disk_uso
    check_recent_cases
    generate_repuerto

    log_message "Health check completed"
\\\\}

# Run main function
main "$@"

🔍 solución de problemas

Common Issues

# TheHive won't start
sudo systemctl status thehive
sudo journalctl -u thehive -f

# Check configuración sintaxis
sudo /opt/thehive/bin/thehive -Dconfig.file=/etc/thehive/application.conf

# Database conexión issues
curl -X GET "localhost:9200/_cluster/health?pretty"
sudo tail -f /var/log/thehive/application.log

# Permission issues
sudo chown -R thehive:thehive /opt/thp/
sudo chmod -R 750 /opt/thp/

# Memory issues
sudo vi /etc/thehive/application.conf
# Add: play.server.akka.max-header-value-length = 16k

Performance Issues

# High CPU uso
top -p $(pgrep -f thehive)

# Memory issues
free -h
sudo cat /proc/meminfo

# Database performance
curl -X GET "localhost:9200/_nodes/stats?pretty"
curl -X GET "localhost:9200/_cluster/stats?pretty"

# Network issues
sudo netstat -tlnp|grep 9000
sudo tcpdump -i any puerto 9000

📖 Best Practices

Security

  • Change default contraseñas and API claves
  • Use HTTPS for web interface
  • Implement proper firewall rules
  • Regular security updates
  • Monitor access logs

Performance

  • Tune Elasticsearch configuración
  • Implement proper indexing strategy
  • Monitor resource uso
  • Use SSD storage for database
  • Regular maintenance and cleanup

Operations

  • Regular backup of data and configuración
  • Implement monitoring and alerting
  • Document respuesta a incidentes procedures
  • Train staff on TheHive uso
  • Regular testing of integrations

⚠️ Security Notice: TheHive should only be used for authorized respuesta a incidentes activities. Ensure compliance with organizational policies and legal requirements.

📚 Additional Resources: - TheHive documentación - TheHive GitHub - TheHive Community