Aller au contenu

MISP Cheatsheet

MISP (logiciel malveillant Information Sharing Platform) is an open-source Renseignement sur les Menaces platform designed to improve the sharing of structured threat information between organizations and communities.

Installation and Setup

# Clone MISP Docker repository
git clone https://github.com/MISP/misp-docker.git
cd misp-docker

# Build and start MISP
docker-compose up -d

# Access MISP web interface
# URL: https://localhôte
# Default identifiants: admin@admin.test / admin

Ubuntu/Debian Installation

# Update system
sudo apt update && sudo apt upgrade -y

# Install dependencies
sudo apt install -y software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update

# Install required packages
sudo apt install -y python3.8 python3.8-dev python3.8-venv \
  apache2 mariadb-server libapache2-mod-php php php-cli \
  php-dev php-json php-mysql php-opcache php-readline \
  php-redis php-xml php-mbstring php-zip git

# Download MISP
cd /var/www
sudo git clone https://github.com/MISP/MISP.git
cd MISP
sudo git checkout tags/$(git describe --tags `git rev-list --tags --max-count=1`)
sudo git submodule update --init --recursive

CentOS/RHEL Installation

# Install EPEL repository
sudo yum install -y epel-release

# Install dependencies
sudo yum install -y httpd mariadb-server php php-mysql php-mbstring \
  php-xml php-bcmath php-opcache git python3 python3-pip

# Start services
sudo systemctl start httpd mariadb
sudo systemctl enable httpd mariadb

# Clone MISP
cd /var/www/html
sudo git clone https://github.com/MISP/MISP.git

Database Setup

# Secure MySQL Installation
sudo mysql_secure_Installation

# Create MISP database
sudo mysql -u root -p
CREATE DATABASE misp;
CREATE USER 'misp'@'localhôte' IDENTIFIED BY 'misp_mot de passe';
GRANT ALL PRIVILEGES ON misp.* TO 'misp'@'localhôte';
FLUSH PRIVILEGES;
EXIT;

Basic configuration

Initial Setup

# Set permissions
sudo chown -R www-data:www-data /var/www/MISP
sudo chmod -R 755 /var/www/MISP

# Copy configuration files
cd /var/www/MISP/app/Config
sudo cp bootstrap.default.php bootstrap.php
sudo cp database.default.php database.php
sudo cp core.default.php core.php
sudo cp config.default.php config.php

# Edit database configuration
sudo nano database.php

Database configuration

<?php
class DATABASE_CONFIG \\\\{
    public $default = array(
        'datasource' => 'Database/Mysql',
        'persistent' => false,
        'hôte' => 'localhôte',
        'login' => 'misp',
        'mot de passe' => 'misp_mot de passe',
        'database' => 'misp',
        'prefix' => '',
        'encoding' => 'utf8',
    );
\\\\}
?>

Apache configuration

# /etc/apache2/sites-available/misp.conf
<Virtualhôte *:80>
    ServerName misp.local
    DocumentRoot /var/www/MISP/app/webroot

    <Directory /var/www/MISP/app/webroot>
        options -Indexes
        AllowOverride all
        Require all granted
    </Directory>

    LogLevel warn
    ErrorLog /var/log/apache2/misp_error.log
    CustomLog /var/log/apache2/misp_access.log combined
    Serversignature Off
</Virtualhôte>
# Enable site and modules
sudo a2ensite misp
sudo a2enmod rewrite
sudo systemctl restart apache2

Web Interface utilisation

Initial Login

URL: http://your-misp-server
Default identifiants:
- nom d'utilisateur: admin@admin.test
- mot de passe: admin

User Management

# Create new user via CLI
cd /var/www/MISP/app/Console
sudo -u www-data ./cake User add [email] [org_id] [role_id]

# Change user mot de passe
sudo -u www-data ./cake User change_pw [email] [new_mot de passe]

# List users
sudo -u www-data ./cake User list

Organization Management

# Add organization
sudo -u www-data ./cake Admin addOrg [org_name] [Description] [type] [nationality]

# List organizations
sudo -u www-data ./cake Admin listOrgs

Event Management

Creating Events

# Using PyMISP library
from pymisp import PyMISP

misp = PyMISP('https://your-misp-server', 'your-api-clé', ssl=False)

# Create new event
event = misp.new_event(
    distribution=1,
    threat_level_id=2,
    analysis=1,
    info="logiciel malveillant Campaign Analysis"
)

print(f"Event created with ID: \\\\{event['Event']['id']\\\\}")

Adding Attributes

# Add IP attribute
misp.add_attribute(
    event['Event']['id'],
    type='ip-dst',
    value='192.168.1.100',
    category='Network activity',
    to_ids=True,
    comment='C2 Server IP'
)

# Add hash attribute
misp.add_attribute(
    event['Event']['id'],
    type='sha256',
    value='a1b2c3d4e5f6...',
    category='charge utile delivery',
    to_ids=True,
    comment='logiciel malveillant hash'
)

# Add domain attribute
misp.add_attribute(
    event['Event']['id'],
    type='domain',
    value='malicious-domain.com',
    category='Network activity',
    to_ids=True
)
# Search events by tag
events = misp.search(tags=['apt', 'logiciel malveillant'])

# Search by attribute value
events = misp.search(value='192.168.1.100')

# Search by date range
events = misp.search(
    date_from='2024-01-01',
    date_to='2024-01-31'
)

# Complex search
events = misp.search(
    org='Your Organization',
    tags=['apt'],
    category='Network activity',
    type_attribute='ip-dst'
)

API utilisation

authentification

# Get API clé from web interface: Administration -> List Auth clés

# Test API connexion
curl -H "autorisation: YOUR_API_clé" \
     -H "Accept: application/json" \
     -H "Content-Type: application/json" \
     https://your-misp-server/events/index

REST API exemples

# Get all events
curl -H "autorisation: YOUR_API_clé" \
     -H "Accept: application/json" \
     https://your-misp-server/events/index

# Get specific event
curl -H "autorisation: YOUR_API_clé" \
     -H "Accept: application/json" \
     https://your-misp-server/events/view/1

# Create new event
curl -X POST \
     -H "autorisation: YOUR_API_clé" \
     -H "Accept: application/json" \
     -H "Content-Type: application/json" \
     -d '\\\\{"Event":\\\\{"info":"Test Event","distribution":"1","threat_level_id":"2","analysis":"1"\\\\}\\\\}' \
     https://your-misp-server/events/add

# Add attribute to event
curl -X POST \
     -H "autorisation: YOUR_API_clé" \
     -H "Accept: application/json" \
     -H "Content-Type: application/json" \
     -d '\\\\{"Attribute":\\\\{"type":"ip-dst","value":"192.168.1.1","category":"Network activity","to_ids":true\\\\}\\\\}' \
     https://your-misp-server/attributes/add/1

PyMISP Library

# Installation
pip install pymisp

# Basic utilisation
from pymisp import PyMISP

# Initialize connexion
misp = PyMISP('https://your-misp-server', 'your-api-clé', ssl=False)

# Test connexion
print(misp.get_version())

# Get all events
events = misp.search(all=True)

# Get event by ID
event = misp.get_event(1)

# Search attributes
attributes = misp.search(
    controller='attributes',
    type_attribute='ip-dst',
    to_ids=True
)

Renseignement sur les Menaces Feeds

Feed configuration

# Enable feeds via web interface
# Administration -> List Feeds -> Add Feed

# Common feed URLs:
# - CIRCL OSINT Feed: https://www.circl.lu/doc/misp/feed-osint/
# - Botvrij.eu: https://www.botvrij.eu/data/feed-osint/
# - SURBL: https://feeds.surbl.org/

Feed Management

# List available feeds
feeds = misp.feeds()

# Enable feed
misp.enable_feed(feed_id=1)

# Fetch feed data
misp.fetch_feed(feed_id=1)

# Cache feed for faster access
misp.cache_feed(feed_id=1)

Custom Feed Creation

# Create custom feed
feed_data = \\\\{
    'Feed': \\\\{
        'name': 'Custom Threat Feed',
        'provider': 'Your Organization',
        'url': 'https://your-server.com/feed.json',
        'rules': '',
        'enabled': True,
        'distribution': 1,
        'sharing_group_id': 0,
        'tag_id': 0,
        'default': False,
        'source_format': 'misp',
        'fixed_event': False,
        'delta_merge': False,
        'event_id': 0,
        'publish': False,
        'override_ids': False,
        'settings': ''
    \\\\}
\\\\}

result = misp.add_feed(feed_data)

Automation and Integration

Automated Event Creation

#!/usr/bin/env python3
import json
from pymisp import PyMISP

def create_logiciel malveillant_event(iocs):
    misp = PyMISP('https://your-misp-server', 'your-api-clé', ssl=False)

    # Create event
    event = misp.new_event(
        distribution=1,
        threat_level_id=2,
        analysis=1,
        info=f"Automated logiciel malveillant Detection - \\\\{iocs['campaign']\\\\}"
    )

    event_id = event['Event']['id']

    # Add IOCs
    for ioc_type, values in iocs['indicators'].items():
        for value in values:
            misp.add_attribute(
                event_id,
                type=ioc_type,
                value=value,
                category='charge utile delivery',
                to_ids=True,
                comment='Automated detection'
            )

    # Add tags
    for tag in iocs.get('tags', []):
        misp.tag(event['Event']['uuid'], tag)

    # Publish event
    misp.publish(event_id)

    return event_id

# exemple utilisation
iocs = \\\\{
    'campaign': 'Banking cheval de Troie Campaign',
    'indicators': \\\\{
        'ip-dst': ['192.168.1.100', '10.0.0.50'],
        'domain': ['malicious-site.com', 'evil-domain.net'],
        'sha256': ['a1b2c3d4e5f6...', 'f6e5d4c3b2a1...']
    \\\\},
    'tags': ['banking-cheval de Troie', 'apt', 'financial-sector']
\\\\}

event_id = create_logiciel malveillant_event(iocs)
print(f"Created event with ID: \\\\{event_id\\\\}")

SIEM Integration

# Splunk integration exemple
import requests
import json

def send_to_splunk(misp_event):
    splunk_url = 'https://your-splunk-server:8088/services/collector'
    splunk_jeton = 'your-hec-jeton'

    headers = \\\\{
        'autorisation': f'Splunk \\\\{splunk_jeton\\\\}',
        'Content-Type': 'application/json'
    \\\\}

    # Convert MISP event to Splunk format
    splunk_event = \\\\{
        'time': misp_event['Event']['timestamp'],
        'source': 'misp',
        'sourcetype': 'misp:event',
        'event': \\\\{
            'event_id': misp_event['Event']['id'],
            'info': misp_event['Event']['info'],
            'threat_level': misp_event['Event']['threat_level_id'],
            'attributes': misp_event['Event']['Attribute']
        \\\\}
    \\\\}

    response = requests.post(
        splunk_url,
        headers=headers,
        data=json.dumps(splunk_event),
        verify=False
    )

    return response.status_code == 200

Email Notifications

# Configure email notifications
def setup_email_notifications():
    # Via web interface: Administration -> Server Settings -> Email
    # Or via API:

    email_settings = \\\\{
        'MISP.email': 'admin@your-domain.com',
        'MISP.contact': 'admin@your-domain.com',
        'MISP.smtp_hôte': 'smtp.your-domain.com',
        'MISP.smtp_port': 587,
        'MISP.smtp_nom d'utilisateur': 'smtp-user',
        'MISP.smtp_mot de passe': 'smtp-mot de passe',
        'MISP.smtp_chiffrement': 'tls'
    \\\\}

    for setting, value in email_settings.items():
        misp.set_server_setting(setting, value)

Data Analysis and Visualization

Attribute Statistics

# Get attribute statistics
def get_attribute_stats():
    stats = misp.search(
        controller='attributes',
        return_format='json',
        limit=0
    )

    type_counts = \\\\{\\\\}
    category_counts = \\\\{\\\\}

    for attr in stats['Attribute']:
        attr_type = attr['type']
        category = attr['category']

        type_counts[attr_type] = type_counts.get(attr_type, 0) + 1
        category_counts[category] = category_counts.get(category, 0) + 1

    return \\\\{
        'types': type_counts,
        'categories': category_counts,
        'total': len(stats['Attribute'])
    \\\\}

stats = get_attribute_stats()
print(f"Total attributes: \\\\{stats['total']\\\\}")
print(f"Top types: \\\\{sorted(stats['types'].items(), clé=lambda x: x[1], reverse=True)[:5]\\\\}")

Event Timeline

# Create event timeline
import matplotlib.pyplot as plt
from datetime import datetime

def create_event_timeline():
    events = misp.search(all=True)

    dates = []
    for event in events:
        timestamp = int(event['Event']['timestamp'])
        date = datetime.fromtimestamp(timestamp)
        dates.append(date)

    # Plot timeline
    plt.figure(figsize=(12, 6))
    plt.hist(dates, bins=30, alpha=0.7)
    plt.title('MISP Events Timeline')
    plt.xlabel('Date')
    plt.ylabel('Number of Events')
    plt.xticks(rotation=45)
    plt.tight_layout()
    plt.savefig('misp_timeline.png')
    plt.show()

IOC Correlation

# Find correlated IOCs
def find_correlations(ioc_value):
    # Search for the IOC
    results = misp.search(value=ioc_value)

    correlations = []
    for event in results:
        event_id = event['Event']['id']

        # Get all attributes from the same event
        full_event = misp.get_event(event_id)

        for attr in full_event['Event']['Attribute']:
            if attr['value'] != ioc_value:
                correlations.append(\\\\{
                    'event_id': event_id,
                    'type': attr['type'],
                    'value': attr['value'],
                    'category': attr['category']
                \\\\})

    return correlations

# exemple utilisation
correlations = find_correlations('192.168.1.100')
for corr in correlations[:10]:  # Show first 10
    print(f"Event \\\\{corr['event_id']\\\\}: \\\\{corr['type']\\\\} = \\\\{corr['value']\\\\}")

Security and Best Practices

Contrôle d'Accès

# Role-based Contrôle d'Accès
# 1. Site Admin - Full access
# 2. Org Admin - Organization management
# 3. User - Basic event access
# 4. Publisher - Can publish events
# 5. Sync User - For synchronization

# Create role via CLI
sudo -u www-data ./cake Admin addRole [role_name] [permissions]

Data chiffrement

# Enable HTTPS
sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d your-misp-domain.com

# Configure SSL in Apache
sudo nano /etc/apache2/sites-available/misp-ssl.conf
<Virtualhôte *:443>
    ServerName your-misp-domain.com
    DocumentRoot /var/www/MISP/app/webroot

    SSLEngine on
    SSLcertificatFile /etc/letsencrypt/live/your-misp-domain.com/fullchain.pem
    SSLcertificatcléFile /etc/letsencrypt/live/your-misp-domain.com/privclé.pem

    # Security headers
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Content-Type-options nosniff
    Header always set X-Frame-options DENY
    Header always set X-XSS-Protection "1; mode=block"
</Virtualhôte>

Backup and Recovery

# Database backup
mysqldump -u misp -p misp > misp_backup_$(date +%Y%m%d).sql

# File system backup
tar -czf misp_files_backup_$(date +%Y%m%d).tar.gz /var/www/MISP

# Automated backup script
#!/bin/bash
BACKUP_DIR="/backup/misp"
DATE=$(date +%Y%m%d_%H%M%S)

# Create backup directory
mkdir -p $BACKUP_DIR

# Database backup
mysqldump -u misp -p misp > $BACKUP_DIR/misp_db_$DATE.sql

# Files backup
tar -czf $BACKUP_DIR/misp_files_$DATE.tar.gz /var/www/MISP

# Keep only last 7 days of backups
find $BACKUP_DIR -name "misp_*" -mtime +7 -delete

dépannage

Common Issues

# Check MISP logs
tail -f /var/www/MISP/app/tmp/logs/error.log
tail -f /var/www/MISP/app/tmp/logs/debug.log

# Check Apache logs
tail -f /var/log/apache2/misp_error.log
tail -f /var/log/apache2/misp_access.log

# Check database connectivity
mysql -u misp -p misp -e "SELECT COUNT(*) FROM events;"

# Check file permissions
ls -la /var/www/MISP/app/tmp/
ls -la /var/www/MISP/app/files/

Performance Optimization

# MySQL optimization
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld]
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
max_connexions = 200
query_cache_size = 64M
query_cache_limit = 2M
# PHP optimization
sudo nano /etc/php/7.4/apache2/php.ini
memory_limit = 512M
max_execution_time = 300
max_input_time = 300
post_max_size = 50M
upload_max_filesize = 50M

Diagnostic commandes

# MISP diagnostic
cd /var/www/MISP/app/Console
sudo -u www-data ./cake Admin runUpdates
sudo -u www-data ./cake Admin setSetting "MISP.python_bin" "/usr/bin/python3"

# Check MISP status
sudo -u www-data ./cake Admin getSetting all

# Test email configuration
sudo -u www-data ./cake Email test [email@domain.com]

Integration exemples

chasse aux menaces Integration

# Integration with chasse aux menaces tools
def hunt_iocs_in_logs(misp_event_id):
    # Get IOCs from MISP event
    event = misp.get_event(misp_event_id)
    iocs = []

    for attr in event['Event']['Attribute']:
        if attr['to_ids']:
            iocs.append(\\\\{
                'type': attr['type'],
                'value': attr['value']
            \\\\})

    # Search in log files (exemple with grep)
    import subprocessus

    results = []
    for ioc in iocs:
        if ioc['type'] in ['ip-dst', 'ip-src']:
            cmd = f"grep -r '\\\\{ioc['value']\\\\}' /var/log/"
            try:
                output = subprocessus.check_output(cmd, shell=True, text=True)
                if output:
                    results.append(\\\\{
                        'ioc': ioc,
                        'matches': output.strip().split('\n')
                    \\\\})
            except subprocessus.CalledprocessusError:
                pass

    return results

YARA Rule Generation

# Generate YARA rules from MISP attributes
def generate_yara_rule(event_id):
    event = misp.get_event(event_id)

    rule_name = f"MISP_Event_\\\\{event_id\\\\}"
    rule_Description = event['Event']['info']

    strings = []
    conditions = []

    for attr in event['Event']['Attribute']:
        if attr['type'] == 'sha256':
            strings.append(f'$hash_\\\\{len(strings)\\\\} = "\\\\{attr["value"]\\\\}"')
            conditions.append(f'$hash_\\\\{len(strings)-1\\\\}')
        elif attr['type'] in ['domain', 'hôtename']:
            strings.append(f'$domain_\\\\{len(strings)\\\\} = "\\\\{attr["value"]\\\\}" nocase')
            conditions.append(f'$domain_\\\\{len(strings)-1\\\\}')

    yara_rule = f'''
rule \\\\{rule_name\\\\} \\\\{\\\\{
    meta:
        Description = "\\\\{rule_Description\\\\}"
        misp_event_id = "\\\\{event_id\\\\}"
        generated = "\\\\{datetime.now().isoformat()\\\\}"

    strings:
        \\\\{chr(10).join(strings)\\\\}

    condition:
        any of them
\\\\}\\\\}
'''

    return yara_rule

Resources