Appearance
MISP Cheatsheet
MISP (Malware Information Sharing Platform) is an open-source threat intelligence platform designed to improve the sharing of structured threat information between organizations and communities.
Installation and Setup
Docker Installation (Recommended)
bash
# 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://localhost
# Default credentials: admin@admin.test / admin
Ubuntu/Debian Installation
bash
# 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
bash
# 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
bash
# Secure MySQL installation
sudo mysql_secure_installation
# Create MISP database
sudo mysql -u root -p
sql
CREATE DATABASE misp;
CREATE USER 'misp'@'localhost' IDENTIFIED BY 'misp_password';
GRANT ALL PRIVILEGES ON misp.* TO 'misp'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Basic Configuration
Initial Setup
bash
# 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
<?php
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'misp',
'password' => 'misp_password',
'database' => 'misp',
'prefix' => '',
'encoding' => 'utf8',
);
}
?>
Apache Configuration
apache
# /etc/apache2/sites-available/misp.conf
<VirtualHost *: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
</VirtualHost>
bash
# Enable site and modules
sudo a2ensite misp
sudo a2enmod rewrite
sudo systemctl restart apache2
Web Interface Usage
Initial Login
URL: http://your-misp-server
Default credentials:
- Username: admin@admin.test
- Password: admin
User Management
bash
# 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 password
sudo -u www-data ./cake User change_pw [email] [new_password]
# List users
sudo -u www-data ./cake User list
Organization Management
bash
# 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
python
# Using PyMISP library
from pymisp import PyMISP
misp = PyMISP('https://your-misp-server', 'your-api-key', ssl=False)
# Create new event
event = misp.new_event(
distribution=1,
threat_level_id=2,
analysis=1,
info="Malware Campaign Analysis"
)
print(f"Event created with ID: {event['Event']['id']}")
Adding Attributes
python
# 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='Payload delivery',
to_ids=True,
comment='Malware hash'
)
# Add domain attribute
misp.add_attribute(
event['Event']['id'],
type='domain',
value='malicious-domain.com',
category='Network activity',
to_ids=True
)
Event Search
python
# Search events by tag
events = misp.search(tags=['apt', 'malware'])
# 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 Usage
Authentication
bash
# Get API key from web interface: Administration -> List Auth Keys
# Test API connection
curl -H "Authorization: YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
https://your-misp-server/events/index
REST API Examples
bash
# Get all events
curl -H "Authorization: YOUR_API_KEY" \
-H "Accept: application/json" \
https://your-misp-server/events/index
# Get specific event
curl -H "Authorization: YOUR_API_KEY" \
-H "Accept: application/json" \
https://your-misp-server/events/view/1
# Create new event
curl -X POST \
-H "Authorization: YOUR_API_KEY" \
-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 "Authorization: YOUR_API_KEY" \
-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
python
# Installation
pip install pymisp
# Basic usage
from pymisp import PyMISP
# Initialize connection
misp = PyMISP('https://your-misp-server', 'your-api-key', ssl=False)
# Test connection
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
)
Threat Intelligence Feeds
Feed Configuration
bash
# 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
python
# 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
python
# 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
python
#!/usr/bin/env python3
import json
from pymisp import PyMISP
def create_malware_event(iocs):
misp = PyMISP('https://your-misp-server', 'your-api-key', ssl=False)
# Create event
event = misp.new_event(
distribution=1,
threat_level_id=2,
analysis=1,
info=f"Automated Malware 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='Payload 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
# Example usage
iocs = {
'campaign': 'Banking Trojan Campaign',
'indicators': {
'ip-dst': ['192.168.1.100', '10.0.0.50'],
'domain': ['malicious-site.com', 'evil-domain.net'],
'sha256': ['a1b2c3d4e5f6...', 'f6e5d4c3b2a1...']
},
'tags': ['banking-trojan', 'apt', 'financial-sector']
}
event_id = create_malware_event(iocs)
print(f"Created event with ID: {event_id}")
SIEM Integration
python
# Splunk integration example
import requests
import json
def send_to_splunk(misp_event):
splunk_url = 'https://your-splunk-server:8088/services/collector'
splunk_token = 'your-hec-token'
headers = {
'Authorization': f'Splunk {splunk_token}',
'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
python
# 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_host': 'smtp.your-domain.com',
'MISP.smtp_port': 587,
'MISP.smtp_username': 'smtp-user',
'MISP.smtp_password': 'smtp-password',
'MISP.smtp_encryption': 'tls'
}
for setting, value in email_settings.items():
misp.set_server_setting(setting, value)
Data Analysis and Visualization
Attribute Statistics
python
# 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(), key=lambda x: x[1], reverse=True)[:5]}")
Event Timeline
python
# 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
python
# 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
# Example usage
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
Access Control
bash
# Role-based access control
# 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 Encryption
bash
# 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
apache
<VirtualHost *:443>
ServerName your-misp-domain.com
DocumentRoot /var/www/MISP/app/webroot
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/your-misp-domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your-misp-domain.com/privkey.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"
</VirtualHost>
Backup and Recovery
bash
# 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
Troubleshooting
Common Issues
bash
# 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
bash
# MySQL optimization
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
ini
[mysqld]
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
max_connections = 200
query_cache_size = 64M
query_cache_limit = 2M
bash
# PHP optimization
sudo nano /etc/php/7.4/apache2/php.ini
ini
memory_limit = 512M
max_execution_time = 300
max_input_time = 300
post_max_size = 50M
upload_max_filesize = 50M
Diagnostic Commands
bash
# 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 Examples
Threat Hunting Integration
python
# Integration with threat hunting 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 (example with grep)
import subprocess
results = []
for ioc in iocs:
if ioc['type'] in ['ip-dst', 'ip-src']:
cmd = f"grep -r '{ioc['value']}' /var/log/"
try:
output = subprocess.check_output(cmd, shell=True, text=True)
if output:
results.append({
'ioc': ioc,
'matches': output.strip().split('\n')
})
except subprocess.CalledProcessError:
pass
return results
YARA Rule Generation
python
# 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', 'hostname']:
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