Some checks failed
Deployment Verification / deploy-and-test (push) Failing after 29s
1525 lines
93 KiB
Python
1525 lines
93 KiB
Python
#!/usr/bin/env python3
|
||
#
|
||
# IRIS Source Code
|
||
# Copyright (C) 2021 - Airbus CyberSecurity (SAS)
|
||
# ir@cyberactionlab.net
|
||
#
|
||
# This program is free software; you can redistribute it and/or
|
||
# modify it under the terms of the GNU Lesser General Public
|
||
# License as published by the Free Software Foundation; either
|
||
# version 3 of the License, or (at your option) any later version.
|
||
#
|
||
# This program is distributed in the hope that it will be useful,
|
||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
# Lesser General Public License for more details.
|
||
#
|
||
# You should have received a copy of the GNU Lesser General Public License
|
||
# along with this program; if not, write to the Free Software Foundation,
|
||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
import json
|
||
|
||
from pathlib import Path
|
||
|
||
import glob
|
||
import os
|
||
import random
|
||
import secrets
|
||
import string
|
||
import socket
|
||
import time
|
||
from alembic import command
|
||
from alembic.config import Config
|
||
from sqlalchemy import create_engine, exc, or_
|
||
from sqlalchemy_utils import create_database
|
||
from sqlalchemy_utils import database_exists
|
||
|
||
from app import app
|
||
from app import bc
|
||
from app import celery
|
||
from app import db
|
||
from app.datamgmt.iris_engine.modules_db import iris_module_disable_by_id
|
||
from app.datamgmt.manage.manage_groups_db import add_case_access_to_group
|
||
from app.datamgmt.manage.manage_users_db import add_user_to_group
|
||
from app.datamgmt.manage.manage_users_db import add_user_to_organisation
|
||
from app.iris_engine.access_control.utils import ac_add_user_effective_access
|
||
from app.iris_engine.demo_builder import create_demo_cases
|
||
from app.iris_engine.access_control.utils import ac_get_mask_analyst
|
||
from app.datamgmt.manage.manage_groups_db import get_group_by_name
|
||
from app.iris_engine.access_control.utils import ac_get_mask_full_permissions
|
||
from app.iris_engine.module_handler.module_handler import check_module_health
|
||
from app.iris_engine.module_handler.module_handler import instantiate_module_from_name
|
||
from app.iris_engine.module_handler.module_handler import register_module
|
||
from app.models import create_safe_limited
|
||
from app.models.alerts import Severity, AlertStatus, AlertResolutionStatus
|
||
from app.models.authorization import CaseAccessLevel
|
||
from app.models.authorization import Group
|
||
from app.models.authorization import Organisation
|
||
from app.models.authorization import User
|
||
from app.models.cases import Cases, CaseState
|
||
from app.models.cases import Client
|
||
from app.models.models import AnalysisStatus, CaseClassification, ReviewStatus, ReviewStatusList
|
||
from app.models.models import AssetsType
|
||
from app.models.models import EventCategory
|
||
from app.models.models import IocType
|
||
from app.models.models import IrisHook
|
||
from app.models.models import IrisModule
|
||
from app.models.models import Languages
|
||
from app.models.models import OsType
|
||
from app.models.models import ReportType
|
||
from app.models.models import ServerSettings
|
||
from app.models.models import TaskStatus
|
||
from app.models.models import Tlp
|
||
from app.models.models import create_safe
|
||
from app.models.models import create_safe_attr
|
||
from app.models.models import get_by_value_or_create
|
||
from app.models.models import get_or_create
|
||
from app.iris_engine.demo_builder import create_demo_users
|
||
|
||
log = app.logger
|
||
|
||
# Get the database host and port from environment variables
|
||
db_host = app.config.get('PG_SERVER')
|
||
db_port = int(app.config.get('PG_PORT'))
|
||
|
||
# Get the retry parameters from environment variables
|
||
retry_count = int(app.config.get('DB_RETRY_COUNT'))
|
||
retry_delay = int(app.config.get('DB_RETRY_DELAY'))
|
||
|
||
|
||
def connect_to_database(host: str, port: int) -> bool:
|
||
"""Attempts to connect to a database at the specified host and port.
|
||
|
||
Args:
|
||
host: A string representing the hostname or IP address of the database server.
|
||
port: An integer representing the port number to connect to.
|
||
|
||
Returns:
|
||
A boolean value indicating whether the connection was successful.
|
||
"""
|
||
# Create a new socket object
|
||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||
try:
|
||
# Try to connect to the database
|
||
s.connect((host, port))
|
||
# If the connection was successful, close the socket and return True
|
||
s.close()
|
||
return True
|
||
except socket.error:
|
||
# If the connection failed, close the socket and return False
|
||
s.close()
|
||
return False
|
||
|
||
|
||
def run_post_init(development=False):
|
||
"""Runs post-initiation steps for the IRIS application.
|
||
|
||
Args:
|
||
development: A boolean value indicating whether the application is running in development mode.
|
||
"""
|
||
# Log the IRIS version and post-initiation steps
|
||
log.info(f'IRIS {app.config.get("IRIS_VERSION")}')
|
||
log.info("Running post initiation steps")
|
||
|
||
conn = None
|
||
|
||
if os.getenv("IRIS_WORKER") is None:
|
||
# Attempt to connect to the database with retries
|
||
log.info("Attempting to connect to the database...")
|
||
for i in range(retry_count):
|
||
log.info("Connecting to database, attempt " + str(i+1) + "/" + str(retry_count))
|
||
conn = connect_to_database(db_host,db_port)
|
||
if conn is not None:
|
||
break
|
||
log.info("Retrying in " + str(retry_delay) + "seconds...")
|
||
time.sleep(retry_delay)
|
||
# If the connection is still not established, exit the script
|
||
if conn is None:
|
||
log.info("Failed to connect to database after " + str(retry_count) + " attempts.")
|
||
exit(1)
|
||
|
||
# Setup database before everything
|
||
log.info("Adding pgcrypto extension")
|
||
pg_add_pgcrypto_ext()
|
||
|
||
log.info("Creating all Iris tables")
|
||
db.create_all(bind=None)
|
||
db.session.commit()
|
||
|
||
log.info("Creating Celery metatasks tables")
|
||
create_safe_db(db_name="iris_tasks")
|
||
db.create_all(bind="iris_tasks")
|
||
db.session.commit()
|
||
|
||
log.info("Running DB migration")
|
||
|
||
alembic_cfg = Config(file_='app/alembic.ini')
|
||
alembic_cfg.set_main_option('sqlalchemy.url', app.config['SQLALCHEMY_DATABASE_URI'])
|
||
command.upgrade(alembic_cfg, 'head')
|
||
|
||
# Create base server settings if they don't exist
|
||
srv_settings = ServerSettings.query.first()
|
||
if srv_settings is None:
|
||
log.info("Creating base server settings")
|
||
create_safe_server_settings()
|
||
srv_settings = ServerSettings.query.first()
|
||
|
||
prevent_objects = srv_settings.prevent_post_objects_repush
|
||
|
||
# Create base languages, OS types, IOC types, attributes, report types, TLP, event categories, assets, analysis status, case classification, task status, severities, alert status, case states, and hooks
|
||
log.info("Creating base languages")
|
||
create_safe_languages()
|
||
|
||
log.info("Creating base os types")
|
||
create_safe_os_types()
|
||
|
||
if not prevent_objects:
|
||
log.info("Creating base IOC types")
|
||
create_safe_ioctypes()
|
||
|
||
log.info("Creating base attributes")
|
||
create_safe_attributes()
|
||
|
||
log.info("Creating base report types")
|
||
create_safe_report_types()
|
||
|
||
log.info("Creating base TLP")
|
||
create_safe_tlp()
|
||
|
||
log.info("Creating base events categories")
|
||
create_safe_events_cats()
|
||
|
||
if not prevent_objects:
|
||
log.info("Creating base assets")
|
||
create_safe_assets()
|
||
|
||
log.info("Creating base analysis status")
|
||
create_safe_analysis_status()
|
||
|
||
if not prevent_objects:
|
||
log.info("Creating base case classification")
|
||
create_safe_classifications()
|
||
|
||
log.info("Creating base tasks status")
|
||
create_safe_task_status()
|
||
|
||
log.info("Creating base severities")
|
||
create_safe_severities()
|
||
|
||
log.info("Creating base alert status")
|
||
create_safe_alert_status()
|
||
|
||
log.info("Creating base alert resolution status")
|
||
create_safe_alert_resolution_status()
|
||
|
||
if not prevent_objects:
|
||
log.info("Creating base case states")
|
||
create_safe_case_states()
|
||
|
||
log.info("Creating base review status")
|
||
create_safe_review_status()
|
||
|
||
log.info("Creating base hooks")
|
||
create_safe_hooks()
|
||
|
||
# Create initial authorization model, administrative user, and customer
|
||
log.info("Creating initial authorisation model")
|
||
def_org, gadm, ganalysts = create_safe_auth_model()
|
||
|
||
log.info("Creating first administrative user")
|
||
admin, pwd = create_safe_admin(def_org=def_org, gadm=gadm)
|
||
|
||
if not srv_settings.prevent_post_mod_repush:
|
||
log.info("Registering default modules")
|
||
register_default_modules()
|
||
|
||
log.info("Creating initial customer")
|
||
client = create_safe_client()
|
||
|
||
log.info("Creating initial case")
|
||
create_safe_case(
|
||
user=admin,
|
||
client=client,
|
||
groups=[gadm, ganalysts]
|
||
)
|
||
|
||
# Setup symlinks for custom_assets
|
||
log.info("Creating symlinks for custom asset icons")
|
||
custom_assets_symlinks()
|
||
|
||
# If demo mode is enabled, create demo users and cases
|
||
if app.config.get('DEMO_MODE_ENABLED') == 'True':
|
||
log.warning("============================")
|
||
log.warning("| THIS IS DEMO INSTANCE |")
|
||
log.warning("| DO NOT USE IN PRODUCTION |")
|
||
log.warning("============================")
|
||
users_data = create_demo_users(def_org, gadm, ganalysts,
|
||
int(app.config.get('DEMO_USERS_COUNT', 10)),
|
||
app.config.get('DEMO_USERS_SEED'),
|
||
int(app.config.get('DEMO_ADM_COUNT', 4)),
|
||
app.config.get('DEMO_ADM_SEED'))
|
||
|
||
create_demo_cases(users_data=users_data,
|
||
cases_count=int(app.config.get('DEMO_CASES_COUNT', 20)),
|
||
clients_count=int(app.config.get('DEMO_CLIENTS_COUNT', 4)))
|
||
|
||
# Log completion message
|
||
log.info("Post-init steps completed")
|
||
log.warning("===============================")
|
||
log.warning(f"| IRIS IS READY on port {os.getenv('INTERFACE_HTTPS_PORT')} |")
|
||
log.warning("===============================")
|
||
|
||
# If an administrative user was created, log their credentials
|
||
if pwd is not None:
|
||
log.info(f'You can now login with user {admin.user} and password >>> {pwd} <<< '
|
||
f'on {os.getenv("INTERFACE_HTTPS_PORT")}')
|
||
|
||
def create_safe_db(db_name):
|
||
"""Creates a new database with the specified name if it does not already exist.
|
||
|
||
Args:
|
||
db_name: A string representing the name of the database to create.
|
||
"""
|
||
# Create a new engine object for the specified database
|
||
engine = create_engine(app.config["SQALCHEMY_PIGGER_URI"] + db_name)
|
||
|
||
# Check if the database already exists
|
||
if not database_exists(engine.url):
|
||
# If the database does not exist, create it
|
||
create_database(engine.url)
|
||
|
||
# Dispose of the engine object
|
||
engine.dispose()
|
||
|
||
|
||
def create_safe_hooks():
|
||
# --- Alert
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_alert_create',
|
||
hook_description='Triggered on alert creation, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_alert_delete',
|
||
hook_description='Triggered on alert deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_alert_update',
|
||
hook_description='Triggered on alert update, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_alert_resolution_update',
|
||
hook_description='Triggered on alert resolution update, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_alert_status_update',
|
||
hook_description='Triggered on alert status update, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_alert_escalate',
|
||
hook_description='Triggered on alert escalation, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_alert_merge',
|
||
hook_description='Triggered on alert merge, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_alert_unmerge',
|
||
hook_description='Triggered on alert unmerge, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_manual_trigger_alert',
|
||
hook_description='Triggered upon user action')
|
||
|
||
|
||
# --- Case
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_case_create',
|
||
hook_description='Triggered on case creation, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_case_create',
|
||
hook_description='Triggered on case creation, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_case_delete',
|
||
hook_description='Triggered on case deletion, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_case_delete',
|
||
hook_description='Triggered on case deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_case_update',
|
||
hook_description='Triggered on case update, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_manual_trigger_case',
|
||
hook_description='Triggered upon user action')
|
||
|
||
# --- Assets
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_asset_create',
|
||
hook_description='Triggered on asset creation, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_asset_create',
|
||
hook_description='Triggered on asset creation, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_asset_update',
|
||
hook_description='Triggered on asset update, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_asset_update',
|
||
hook_description='Triggered on asset update, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_asset_delete',
|
||
hook_description='Triggered on asset deletion, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_asset_delete',
|
||
hook_description='Triggered on asset deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_manual_trigger_asset',
|
||
hook_description='Triggered upon user action')
|
||
|
||
# --- Notes
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_note_create',
|
||
hook_description='Triggered on note creation, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_note_create',
|
||
hook_description='Triggered on note creation, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_note_update',
|
||
hook_description='Triggered on note update, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_note_update',
|
||
hook_description='Triggered on note update, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_note_delete',
|
||
hook_description='Triggered on note deletion, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_note_delete',
|
||
hook_description='Triggered on note deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_manual_trigger_note',
|
||
hook_description='Triggered upon user action')
|
||
|
||
# --- iocs
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_ioc_create',
|
||
hook_description='Triggered on ioc creation, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_ioc_create',
|
||
hook_description='Triggered on ioc creation, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_ioc_update',
|
||
hook_description='Triggered on ioc update, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_ioc_update',
|
||
hook_description='Triggered on ioc update, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_ioc_delete',
|
||
hook_description='Triggered on ioc deletion, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_ioc_delete',
|
||
hook_description='Triggered on ioc deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_manual_trigger_ioc',
|
||
hook_description='Triggered upon user action')
|
||
|
||
# --- events
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_event_create',
|
||
hook_description='Triggered on event creation, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_event_create',
|
||
hook_description='Triggered on event creation, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_event_duplicate',
|
||
hook_description='Triggered on event duplication, before commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_event_update',
|
||
hook_description='Triggered on event update, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_event_update',
|
||
hook_description='Triggered on event update, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_event_delete',
|
||
hook_description='Triggered on event deletion, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_event_delete',
|
||
hook_description='Triggered on event deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_manual_trigger_event',
|
||
hook_description='Triggered upon user action')
|
||
|
||
# --- evidence
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_evidence_create',
|
||
hook_description='Triggered on evidence creation, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_evidence_create',
|
||
hook_description='Triggered on evidence creation, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_evidence_update',
|
||
hook_description='Triggered on evidence update, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_evidence_update',
|
||
hook_description='Triggered on evidence update, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_evidence_delete',
|
||
hook_description='Triggered on evidence deletion, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_evidence_delete',
|
||
hook_description='Triggered on evidence deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_manual_trigger_evidence',
|
||
hook_description='Triggered upon user action')
|
||
|
||
# --- tasks
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_task_create',
|
||
hook_description='Triggered on task creation, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_task_create',
|
||
hook_description='Triggered on task creation, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_task_update',
|
||
hook_description='Triggered on task update, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_task_update',
|
||
hook_description='Triggered on task update, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_task_delete',
|
||
hook_description='Triggered on task deletion, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_task_delete',
|
||
hook_description='Triggered on task deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_manual_trigger_task',
|
||
hook_description='Triggered upon user action')
|
||
|
||
# --- global tasks
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_global_task_create',
|
||
hook_description='Triggered on global task creation, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_global_task_create',
|
||
hook_description='Triggered on global task creation, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_global_task_update',
|
||
hook_description='Triggered on task update, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_global_task_update',
|
||
hook_description='Triggered on global task update, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_global_task_delete',
|
||
hook_description='Triggered on task deletion, before commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_global_task_delete',
|
||
hook_description='Triggered on global task deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_manual_trigger_global_task',
|
||
hook_description='Triggered upon user action')
|
||
|
||
# --- reports
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_report_create',
|
||
hook_description='Triggered on report creation, before generation in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_report_create',
|
||
hook_description='Triggered on report creation, before download of the document')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_preload_activities_report_create',
|
||
hook_description='Triggered on activities report creation, before generation in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_activities_report_create',
|
||
hook_description='Triggered on activities report creation, before download of the document')
|
||
|
||
# --- comments
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_asset_commented',
|
||
hook_description='Triggered on event commented, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_asset_comment_update',
|
||
hook_description='Triggered on event comment update, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_asset_comment_delete',
|
||
hook_description='Triggered on event comment deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_evidence_commented',
|
||
hook_description='Triggered on evidence commented, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_evidence_comment_update',
|
||
hook_description='Triggered on evidence comment update, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_evidence_comment_delete',
|
||
hook_description='Triggered on evidence comment deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_task_commented',
|
||
hook_description='Triggered on task commented, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_task_comment_update',
|
||
hook_description='Triggered on task comment update, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_task_comment_delete',
|
||
hook_description='Triggered on task comment deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_ioc_commented',
|
||
hook_description='Triggered on IOC commented, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_ioc_comment_update',
|
||
hook_description='Triggered on IOC comment update, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_ioc_comment_delete',
|
||
hook_description='Triggered on IOC comment deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_event_commented',
|
||
hook_description='Triggered on event commented, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_event_comment_update',
|
||
hook_description='Triggered on event comment update, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_event_comment_delete',
|
||
hook_description='Triggered on event comment deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_note_commented',
|
||
hook_description='Triggered on note commented, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_note_comment_update',
|
||
hook_description='Triggered on note comment update, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_note_comment_delete',
|
||
hook_description='Triggered on note comment deletion, after commit in DB')
|
||
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_alert_commented',
|
||
hook_description='Triggered on alert commented, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_alert_comment_update',
|
||
hook_description='Triggered on alert comment update, after commit in DB')
|
||
create_safe(db.session, IrisHook, hook_name='on_postload_alert_comment_delete',
|
||
hook_description='Triggered on alert comment deletion, after commit in DB')
|
||
|
||
|
||
def pg_add_pgcrypto_ext():
|
||
"""Adds the pgcrypto extension to the PostgreSQL database.
|
||
|
||
This extension provides cryptographic functions for PostgreSQL.
|
||
|
||
"""
|
||
# Open a connection to the database
|
||
with db.engine.connect() as con:
|
||
# Execute a SQL command to create the pgcrypto extension if it does not already exist
|
||
con.execute('CREATE EXTENSION IF NOT EXISTS pgcrypto;')
|
||
|
||
|
||
def create_safe_languages():
|
||
"""Creates new Language objects if they do not already exist.
|
||
|
||
This function creates new Language objects with the specified name and code
|
||
if they do not already exist in the database.
|
||
|
||
"""
|
||
# Create new Language objects for each language
|
||
create_safe(db.session, Languages, name="french", code="FR")
|
||
create_safe(db.session, Languages, name="english", code="EN")
|
||
create_safe(db.session, Languages, name="german", code="DE")
|
||
create_safe(db.session, Languages, name="bulgarian", code="BG")
|
||
create_safe(db.session, Languages, name="croatian", code="HR")
|
||
create_safe(db.session, Languages, name="danish", code="DK")
|
||
create_safe(db.session, Languages, name="dutch", code="NL")
|
||
create_safe(db.session, Languages, name="estonian", code="EE")
|
||
create_safe(db.session, Languages, name="finnish", code="FI")
|
||
create_safe(db.session, Languages, name="greek", code="GR")
|
||
create_safe(db.session, Languages, name="hungarian", code="HU")
|
||
create_safe(db.session, Languages, name="irish", code="IE")
|
||
create_safe(db.session, Languages, name="italian", code="IT")
|
||
create_safe(db.session, Languages, name="latvian", code="LV")
|
||
create_safe(db.session, Languages, name="lithuanian", code="LT")
|
||
create_safe(db.session, Languages, name="maltese", code="MT")
|
||
create_safe(db.session, Languages, name="polish", code="PL")
|
||
create_safe(db.session, Languages, name="portuguese", code="PT")
|
||
create_safe(db.session, Languages, name="romanian", code="RO")
|
||
create_safe(db.session, Languages, name="slovak", code="SK")
|
||
create_safe(db.session, Languages, name="slovenian", code="SI")
|
||
create_safe(db.session, Languages, name="spanish", code="ES")
|
||
create_safe(db.session, Languages, name="swedish", code="SE")
|
||
create_safe(db.session, Languages, name="indian", code="IN")
|
||
create_safe(db.session, Languages, name="chinese", code="CN")
|
||
create_safe(db.session, Languages, name="korean", code="KR")
|
||
create_safe(db.session, Languages, name="arabic", code="AR")
|
||
create_safe(db.session, Languages, name="japanese", code="JP")
|
||
create_safe(db.session, Languages, name="turkish", code="TR")
|
||
create_safe(db.session, Languages, name="vietnamese", code="VN")
|
||
create_safe(db.session, Languages, name="thai", code="TH")
|
||
create_safe(db.session, Languages, name="hebrew", code="IL")
|
||
create_safe(db.session, Languages, name="czech", code="CZ")
|
||
create_safe(db.session, Languages, name="norwegian", code="NO")
|
||
create_safe(db.session, Languages, name="brazilian", code="BR")
|
||
create_safe(db.session, Languages, name="ukrainian", code="UA")
|
||
create_safe(db.session, Languages, name="catalan", code="CA")
|
||
create_safe(db.session, Languages, name="serbian", code="RS")
|
||
create_safe(db.session, Languages, name="persian", code="IR")
|
||
create_safe(db.session, Languages, name="afrikaans", code="ZA")
|
||
create_safe(db.session, Languages, name="albanian", code="AL")
|
||
create_safe(db.session, Languages, name="armenian", code="AM")
|
||
|
||
|
||
def create_safe_events_cats():
|
||
"""Creates new EventCategory objects if they do not already exist.
|
||
|
||
This function creates new EventCategory objects with the specified name
|
||
if they do not already exist in the database.
|
||
|
||
"""
|
||
# Create new EventCategory objects for each category
|
||
create_safe(db.session, EventCategory, name="Unspecified")
|
||
create_safe(db.session, EventCategory, name="Legitimate")
|
||
create_safe(db.session, EventCategory, name="Remediation")
|
||
create_safe(db.session, EventCategory, name="Initial Access")
|
||
create_safe(db.session, EventCategory, name="Execution")
|
||
create_safe(db.session, EventCategory, name="Persistence")
|
||
create_safe(db.session, EventCategory, name="Privilege Escalation")
|
||
create_safe(db.session, EventCategory, name="Defense Evasion")
|
||
create_safe(db.session, EventCategory, name="Credential Access")
|
||
create_safe(db.session, EventCategory, name="Discovery")
|
||
create_safe(db.session, EventCategory, name="Lateral Movement")
|
||
create_safe(db.session, EventCategory, name="Collection")
|
||
create_safe(db.session, EventCategory, name="Command and Control")
|
||
create_safe(db.session, EventCategory, name="Exfiltration")
|
||
create_safe(db.session, EventCategory, name="Impact")
|
||
|
||
|
||
def create_safe_classifications():
|
||
"""Creates new CaseClassification objects if they do not already exist.
|
||
|
||
This function reads the MISP classification taxonomy from a JSON file and creates
|
||
new CaseClassification objects with the specified name, name_expanded, and description
|
||
if they do not already exist in the database.
|
||
|
||
"""
|
||
# Read the MISP classification taxonomy from a JSON file
|
||
log.info("Reading MISP classification taxonomy from resources/misp.classification.taxonomy.json")
|
||
with open(Path(__file__).parent / 'resources' / 'misp.classification.taxonomy.json') as data_file:
|
||
data = json.load(data_file)
|
||
# Iterate over each classification in the taxonomy
|
||
for c in data.get('values'):
|
||
predicate = c.get('predicate')
|
||
entries = c.get('entry')
|
||
# Iterate over each entry in the classification
|
||
for entry in entries:
|
||
# Create a new CaseClassification object with the specified name, name_expanded, and description
|
||
create_safe(db.session, CaseClassification,
|
||
name=f"{predicate}:{entry.get('value')}",
|
||
name_expanded=f"{predicate.title()}: {entry.get('expanded')}",
|
||
description=entry['description'])
|
||
|
||
|
||
def create_safe_analysis_status():
|
||
"""Creates new AnalysisStatus objects if they do not already exist.
|
||
|
||
This function creates new AnalysisStatus objects with the specified name
|
||
if they do not already exist in the database.
|
||
|
||
"""
|
||
# Create new AnalysisStatus objects for each status
|
||
create_safe(db.session, AnalysisStatus, name='Unspecified')
|
||
create_safe(db.session, AnalysisStatus, name='To be done')
|
||
create_safe(db.session, AnalysisStatus, name='Started')
|
||
create_safe(db.session, AnalysisStatus, name='Pending')
|
||
create_safe(db.session, AnalysisStatus, name='Canceled')
|
||
create_safe(db.session, AnalysisStatus, name='Done')
|
||
|
||
|
||
def create_safe_task_status():
|
||
"""Creates new TaskStatus objects if they do not already exist.
|
||
|
||
This function creates new TaskStatus objects with the specified status name,
|
||
status description, and Bootstrap color if they do not already exist in the database.
|
||
|
||
"""
|
||
# Create new TaskStatus objects for each status
|
||
create_safe(db.session, TaskStatus, status_name='To do', status_description="", status_bscolor="danger")
|
||
create_safe(db.session, TaskStatus, status_name='In progress', status_description="", status_bscolor="warning")
|
||
create_safe(db.session, TaskStatus, status_name='On hold', status_description="", status_bscolor="muted")
|
||
create_safe(db.session, TaskStatus, status_name='Done', status_description="", status_bscolor="success")
|
||
create_safe(db.session, TaskStatus, status_name='Canceled', status_description="", status_bscolor="muted")
|
||
|
||
|
||
def create_safe_severities():
|
||
"""Creates new Severity objects if they do not already exist.
|
||
|
||
This function creates new Severity objects with the specified severity name
|
||
and severity description if they do not already exist in the database.
|
||
|
||
"""
|
||
# Create new Severity objects for each severity level
|
||
create_safe(db.session, Severity, severity_name='Unspecified', severity_description="Unspecified")
|
||
create_safe(db.session, Severity, severity_name='Informational', severity_description="Informational")
|
||
create_safe(db.session, Severity, severity_name='Low', severity_description="Low")
|
||
create_safe(db.session, Severity, severity_name='Medium', severity_description="Medium")
|
||
create_safe(db.session, Severity, severity_name='High', severity_description="High")
|
||
create_safe(db.session, Severity, severity_name='Critical', severity_description="Critical")
|
||
|
||
|
||
def create_safe_alert_status():
|
||
"""Creates new AlertStatus objects if they do not already exist.
|
||
|
||
This function creates new AlertStatus objects with the specified status name
|
||
and status description if they do not already exist in the database.
|
||
|
||
"""
|
||
# Create new AlertStatus objects for each status
|
||
create_safe(db.session, AlertStatus, status_name='Unspecified', status_description="Unspecified")
|
||
create_safe(db.session, AlertStatus, status_name='New', status_description="Alert is new and unassigned")
|
||
create_safe(db.session, AlertStatus, status_name='Assigned', status_description="Alert is assigned to a user and pending "
|
||
"investigation")
|
||
create_safe(db.session, AlertStatus, status_name='In progress', status_description="Alert is being investigated")
|
||
create_safe(db.session, AlertStatus, status_name='Pending', status_description="Alert is in a pending state")
|
||
create_safe(db.session, AlertStatus, status_name='Closed', status_description="Alert closed, no action taken")
|
||
create_safe(db.session, AlertStatus, status_name='Merged', status_description="Alert merged into an existing case")
|
||
create_safe(db.session, AlertStatus, status_name='Escalated', status_description="Alert converted to a new case")
|
||
|
||
|
||
def create_safe_alert_resolution_status():
|
||
"""Creates new AlertResolutionStatus objects if they do not already exist.
|
||
|
||
This function creates new AlertResolutionStatus objects with the specified resolution_status_name
|
||
and resolution_status_description if they do not already exist in the database.
|
||
|
||
"""
|
||
create_safe(db.session, AlertResolutionStatus, resolution_status_name='False Positive',
|
||
resolution_status_description="The alert was a false positive")
|
||
create_safe(db.session, AlertResolutionStatus, resolution_status_name='True Positive With Impact',
|
||
resolution_status_description="The alert was a true positive and had an impact")
|
||
create_safe(db.session, AlertResolutionStatus, resolution_status_name='True Positive Without Impact',
|
||
resolution_status_description="The alert was a true positive but had no impact")
|
||
create_safe(db.session, AlertResolutionStatus, resolution_status_name='Not Applicable',
|
||
resolution_status_description="The alert is not applicable")
|
||
|
||
|
||
def create_safe_case_states():
|
||
"""Creates new CaseState objects if they do not already exist.
|
||
|
||
This function creates new CaseState objects with the specified state name,
|
||
state description, and protected status if they do not already exist in the database.
|
||
|
||
"""
|
||
# Create new CaseState objects for each state
|
||
create_safe(db.session, CaseState, state_name='Unspecified', state_description="Unspecified", protected=True)
|
||
create_safe(db.session, CaseState, state_name='In progress', state_description="Case is being investigated")
|
||
create_safe(db.session, CaseState, state_name='Open', state_description="Case is open", protected=True)
|
||
create_safe(db.session, CaseState, state_name='Containment', state_description="Containment is in progress")
|
||
create_safe(db.session, CaseState, state_name='Eradication', state_description="Eradication is in progress")
|
||
create_safe(db.session, CaseState, state_name='Recovery', state_description="Recovery is in progress")
|
||
create_safe(db.session, CaseState, state_name='Post-Incident', state_description="Post-incident phase")
|
||
create_safe(db.session, CaseState, state_name='Reporting', state_description="Reporting is in progress")
|
||
create_safe(db.session, CaseState, state_name='Closed', state_description="Case is closed", protected=True)
|
||
|
||
|
||
def create_safe_review_status():
|
||
"""Creates new ReviewStatus objects if they do not already exist.
|
||
|
||
This function creates new ReviewStatus objects with the specified status name
|
||
if they do not already exist in the database.
|
||
"""
|
||
create_safe(db.session, ReviewStatus, status_name=ReviewStatusList.no_review_required)
|
||
create_safe(db.session, ReviewStatus, status_name=ReviewStatusList.not_reviewed)
|
||
create_safe(db.session, ReviewStatus, status_name=ReviewStatusList.pending_review)
|
||
create_safe(db.session, ReviewStatus, status_name=ReviewStatusList.review_in_progress)
|
||
create_safe(db.session, ReviewStatus, status_name=ReviewStatusList.reviewed)
|
||
|
||
|
||
def create_safe_assets():
|
||
"""Creates new AssetsType objects if they do not already exist.
|
||
|
||
This function creates new AssetsType objects with the specified asset name,
|
||
asset description, and asset icons if they do not already exist in the database.
|
||
|
||
"""
|
||
# Create new AssetsType objects for each asset type
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Account",
|
||
asset_description="Generic Account", asset_icon_not_compromised="user.png",
|
||
asset_icon_compromised="ioc_user.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Firewall", asset_description="Firewall",
|
||
asset_icon_not_compromised="firewall.png", asset_icon_compromised="ioc_firewall.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Linux - Server",
|
||
asset_description="Linux server", asset_icon_not_compromised="server.png",
|
||
asset_icon_compromised="ioc_server.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Linux - Computer",
|
||
asset_description="Linux computer", asset_icon_not_compromised="desktop.png",
|
||
asset_icon_compromised="ioc_desktop.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Linux Account",
|
||
asset_description="Linux Account", asset_icon_not_compromised="user.png",
|
||
asset_icon_compromised="ioc_user.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Mac - Computer",
|
||
asset_description="Mac computer", asset_icon_not_compromised="desktop.png",
|
||
asset_icon_compromised="ioc_desktop.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Phone - Android",
|
||
asset_description="Android Phone", asset_icon_not_compromised="phone.png",
|
||
asset_icon_compromised="ioc_phone.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Phone - IOS",
|
||
asset_description="Apple Phone", asset_icon_not_compromised="phone.png",
|
||
asset_icon_compromised="ioc_phone.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Windows - Computer",
|
||
asset_description="Standard Windows Computer",
|
||
asset_icon_not_compromised="windows_desktop.png",
|
||
asset_icon_compromised="ioc_windows_desktop.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Windows - Server",
|
||
asset_description="Standard Windows Server", asset_icon_not_compromised="windows_server.png",
|
||
asset_icon_compromised="ioc_windows_server.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Windows - DC",
|
||
asset_description="Domain Controller", asset_icon_not_compromised="windows_server.png",
|
||
asset_icon_compromised="ioc_windows_server.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Router", asset_description="Router",
|
||
asset_icon_not_compromised="router.png", asset_icon_compromised="ioc_router.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Switch", asset_description="Switch",
|
||
asset_icon_not_compromised="switch.png", asset_icon_compromised="ioc_switch.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="VPN", asset_description="VPN",
|
||
asset_icon_not_compromised="vpn.png", asset_icon_compromised="ioc_vpn.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="WAF", asset_description="WAF",
|
||
asset_icon_not_compromised="firewall.png", asset_icon_compromised="ioc_firewall.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Windows Account - Local",
|
||
asset_description="Windows Account - Local", asset_icon_not_compromised="user.png",
|
||
asset_icon_compromised="ioc_user.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Windows Account - Local - Admin",
|
||
asset_description="Windows Account - Local - Admin", asset_icon_not_compromised="user.png",
|
||
asset_icon_compromised="ioc_user.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Windows Account - AD",
|
||
asset_description="Windows Account - AD", asset_icon_not_compromised="user.png",
|
||
asset_icon_compromised="ioc_user.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Windows Account - AD - Admin",
|
||
asset_description="Windows Account - AD - Admin", asset_icon_not_compromised="user.png",
|
||
asset_icon_compromised="ioc_user.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Windows Account - AD - krbtgt",
|
||
asset_description="Windows Account - AD - krbtgt", asset_icon_not_compromised="user.png",
|
||
asset_icon_compromised="ioc_user.png")
|
||
get_by_value_or_create(db.session, AssetsType, "asset_name", asset_name="Windows Account - AD - Service",
|
||
asset_description="Windows Account - AD - krbtgt", asset_icon_not_compromised="user.png",
|
||
asset_icon_compromised="ioc_user.png")
|
||
|
||
|
||
def create_safe_client():
|
||
"""Creates a new Client object if it does not already exist.
|
||
|
||
This function creates a new Client object with the specified client name
|
||
and client description if it does not already exist in the database.
|
||
|
||
"""
|
||
# Create a new Client object if it does not already exist
|
||
client = get_or_create(db.session, Client,
|
||
name="IrisInitialClient")
|
||
|
||
return client
|
||
|
||
|
||
def create_safe_auth_model():
|
||
"""Creates new Organisation, Group, and User objects if they do not already exist.
|
||
|
||
This function creates a new Organisation object with the specified name and description,
|
||
and creates new Group objects with the specified name, description, auto-follow status,
|
||
auto-follow access level, and permissions if they do not already exist in the database.
|
||
It also updates the attributes of the existing Group objects if they have changed.
|
||
|
||
"""
|
||
# Create new Organisation object
|
||
def_org = get_or_create(db.session, Organisation, org_name="Default Org",
|
||
org_description="Default Organisation")
|
||
|
||
# Create new Administrator Group object
|
||
try:
|
||
gadm = get_or_create(db.session, Group, group_name="Administrators", group_description="Administrators",
|
||
group_auto_follow=True, group_auto_follow_access_level=CaseAccessLevel.full_access.value,
|
||
group_permissions=ac_get_mask_full_permissions())
|
||
|
||
except exc.IntegrityError:
|
||
db.session.rollback()
|
||
log.warning('Administrator group integrity error. Group permissions were probably changed. Updating.')
|
||
gadm = Group.query.filter(
|
||
Group.group_name == "Administrators"
|
||
).first()
|
||
|
||
# Update Administrator Group object attributes
|
||
if gadm.group_permissions != ac_get_mask_full_permissions():
|
||
gadm.group_permissions = ac_get_mask_full_permissions()
|
||
|
||
if gadm.group_auto_follow_access_level != CaseAccessLevel.full_access.value:
|
||
gadm.group_auto_follow_access_level = CaseAccessLevel.full_access.value
|
||
|
||
if gadm.group_auto_follow is not True:
|
||
gadm.group_auto_follow = True
|
||
|
||
db.session.commit()
|
||
|
||
# Create new Analysts Group object
|
||
try:
|
||
ganalysts = get_or_create(db.session, Group, group_name="Analysts", group_description="Standard Analysts",
|
||
group_auto_follow=True, group_auto_follow_access_level=CaseAccessLevel.full_access.value,
|
||
group_permissions=ac_get_mask_analyst())
|
||
|
||
except exc.IntegrityError:
|
||
db.session.rollback()
|
||
log.warning('Analysts group integrity error. Group permissions were probably changed. Updating.')
|
||
ganalysts = get_group_by_name("Analysts")
|
||
|
||
# Update Analysts Group object attributes
|
||
if ganalysts.group_permissions != ac_get_mask_analyst():
|
||
ganalysts.group_permissions = ac_get_mask_analyst()
|
||
|
||
if ganalysts.group_auto_follow is not True:
|
||
ganalysts.group_auto_follow = True
|
||
|
||
if ganalysts.group_auto_follow_access_level != CaseAccessLevel.full_access.value:
|
||
ganalysts.group_auto_follow_access_level = CaseAccessLevel.full_access.value
|
||
|
||
db.session.commit()
|
||
|
||
return def_org, gadm, ganalysts
|
||
|
||
|
||
def create_safe_admin(def_org, gadm):
|
||
"""Creates a new admin user if one does not already exist.
|
||
|
||
This function creates a new admin user with the specified username, email, and password
|
||
if one does not already exist in the database. If an admin user already exists, it updates
|
||
the email address of the existing user if it has changed.
|
||
|
||
"""
|
||
# Get admin username and email from app config
|
||
admin_username = app.config.get('IRIS_ADM_USERNAME')
|
||
if admin_username is None:
|
||
admin_username = 'administrator'
|
||
|
||
admin_email = app.config.get('IRIS_ADM_EMAIL')
|
||
if admin_email is None:
|
||
admin_email = 'administrator@localhost'
|
||
|
||
# Check if admin user already exists
|
||
user = User.query.filter(or_(
|
||
User.user == admin_username,
|
||
User.email == admin_email
|
||
)).first()
|
||
password = None
|
||
|
||
if not user:
|
||
# Generate a new password if one was not provided in the app config
|
||
password = app.config.get('IRIS_ADM_PASSWORD')
|
||
if password is None:
|
||
password = ''.join(random.choices(string.printable[:-6], k=16))
|
||
|
||
log.info(f'Creating first admin user with username "{admin_username}"')
|
||
|
||
# Create new User object for admin user
|
||
user = User(
|
||
user=admin_username,
|
||
name=admin_username,
|
||
email=admin_email,
|
||
password=bc.generate_password_hash(password.encode('utf8')).decode('utf8'),
|
||
active=True
|
||
)
|
||
|
||
# Generate a new API key if one was not provided in the app config
|
||
api_key = app.config.get('IRIS_ADM_API_KEY')
|
||
if api_key is None:
|
||
api_key = secrets.token_urlsafe(nbytes=64)
|
||
|
||
user.api_key = api_key
|
||
db.session.add(user)
|
||
|
||
db.session.commit()
|
||
|
||
# Add admin user to admin group and default organisation
|
||
add_user_to_group(user_id=user.id, group_id=gadm.group_id)
|
||
add_user_to_organisation(user_id=user.id, org_id=def_org.org_id)
|
||
|
||
log.warning(f">>> Administrator password: {password}")
|
||
|
||
db.session.commit()
|
||
|
||
else:
|
||
if not os.environ.get('IRIS_ADM_PASSWORD'):
|
||
# Prevent leak of user set password in logs
|
||
log.warning(">>> Administrator already exists")
|
||
|
||
if user.email != admin_email:
|
||
# Update email address of existing admin user if it has changed
|
||
log.warning(f'Email of administrator will be updated via config to {admin_email}')
|
||
user.email = admin_email
|
||
db.session.commit()
|
||
|
||
return user, password
|
||
|
||
|
||
def create_safe_case(user, client, groups):
|
||
"""Creates a new case if one does not already exist for the specified client.
|
||
|
||
This function creates a new case with the specified name, description, SOC ID, user, and client
|
||
if one does not already exist in the database for the specified client. It also adds the specified
|
||
user and groups to the case with full access level.
|
||
|
||
"""
|
||
# Check if a case already exists for the client
|
||
case = Cases.query.filter(
|
||
Cases.client_id == client.client_id
|
||
).first()
|
||
|
||
if not case:
|
||
# Create a new case for the client
|
||
case = Cases(
|
||
name="Initial Demo",
|
||
description="This is a demonstration.",
|
||
soc_id="soc_id_demo",
|
||
user=user,
|
||
client_id=client.client_id
|
||
)
|
||
|
||
# Validate the case and save it to the database
|
||
case.validate_on_build()
|
||
case.save()
|
||
|
||
db.session.commit()
|
||
|
||
# Add the specified user and groups to the case with full access level
|
||
for group in groups:
|
||
add_case_access_to_group(group=group,
|
||
cases_list=[case.case_id],
|
||
access_level=CaseAccessLevel.full_access.value)
|
||
ac_add_user_effective_access(users_list=[user.id],
|
||
case_id=1,
|
||
access_level=CaseAccessLevel.full_access.value)
|
||
|
||
return case
|
||
|
||
|
||
def create_safe_report_types():
|
||
"""Creates new ReportType objects if they do not already exist.
|
||
|
||
This function creates new ReportType objects with the specified names if they do not already
|
||
exist in the database.
|
||
|
||
"""
|
||
create_safe(db.session, ReportType, name="Investigation")
|
||
create_safe(db.session, ReportType, name="Activities")
|
||
|
||
|
||
def create_safe_attributes():
|
||
"""Creates new Attribute objects if they do not already exist.
|
||
|
||
This function creates new Attribute objects with the specified display name, description,
|
||
object type, and content if they do not already exist in the database.
|
||
|
||
"""
|
||
create_safe_attr(db.session, attribute_display_name='IOC',
|
||
attribute_description='Defines default attributes for IOCs', attribute_for='ioc',
|
||
attribute_content={})
|
||
create_safe_attr(db.session, attribute_display_name='Events',
|
||
attribute_description='Defines default attributes for Events', attribute_for='event',
|
||
attribute_content={})
|
||
create_safe_attr(db.session, attribute_display_name='Assets',
|
||
attribute_description='Defines default attributes for Assets', attribute_for='asset',
|
||
attribute_content={})
|
||
create_safe_attr(db.session, attribute_display_name='Tasks',
|
||
attribute_description='Defines default attributes for Tasks', attribute_for='task',
|
||
attribute_content={})
|
||
create_safe_attr(db.session, attribute_display_name='Notes',
|
||
attribute_description='Defines default attributes for Notes', attribute_for='note',
|
||
attribute_content={})
|
||
create_safe_attr(db.session, attribute_display_name='Evidences',
|
||
attribute_description='Defines default attributes for Evidences', attribute_for='evidence',
|
||
attribute_content={})
|
||
create_safe_attr(db.session, attribute_display_name='Cases',
|
||
attribute_description='Defines default attributes for Cases', attribute_for='case',
|
||
attribute_content={})
|
||
create_safe_attr(db.session, attribute_display_name='Customers',
|
||
attribute_description='Defines default attributes for Customers', attribute_for='client',
|
||
attribute_content={})
|
||
|
||
|
||
def create_safe_ioctypes():
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="AS", type_description="Autonomous system", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="aba-rtn", type_description="ABA routing transit number",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="account", type_description="Account of any type",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="anonymised",
|
||
type_description="Anonymised value - described with the anonymisation object via a relationship",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="attachment", type_description="Attachment with external information",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="authentihash",
|
||
type_description="Authenticode executable signature hash", type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{64}", type_validation_expect="64 hexadecimal characters"
|
||
)
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="boolean", type_description="Boolean value - to be used in objects",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="btc", type_description="Bitcoin Address", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="campaign-id", type_description="Associated campaign ID",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="campaign-name", type_description="Associated campaign name",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="cdhash",
|
||
type_description="An Apple Code Directory Hash, identifying a code-signed Mach-O executable file",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="chrome-extension-id", type_description="Chrome extension id",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="community-id",
|
||
type_description="a community ID flow hashing algorithm to map multiple traffic monitors into common flow id",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="cookie",
|
||
type_description="HTTP cookie as often stored on the user web client. This can include authentication cookie or session cookie.",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="dash", type_description="Dash Address", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="datetime", type_description="Datetime in the ISO 8601 format",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="dkim", type_description="DKIM public key", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="dkim-signature", type_description="DKIM signature", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="dns-soa-email",
|
||
type_description="RFC1035 mandates that DNS zones should have a SOA (Statement Of Authority) record that contains an email address where a PoC for the domain could be contacted. This can sometimes be used for attribution/linkage between different domains even if protected by whois privacy",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="domain", type_description="A domain name used in the malware",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="domain|ip",
|
||
type_description="A domain name and its IP address (as found in DNS lookup) separated by a |",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email", type_description="An e-mail address", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email-attachment",
|
||
type_description="File name of the email attachment.", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email-body", type_description="Email body", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email-dst",
|
||
type_description="The destination email address. Used to describe the recipient when describing an e-mail.",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email-dst-display-name",
|
||
type_description="Email destination display name", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email-header", type_description="Email header", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email-message-id", type_description="The email message ID",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email-mime-boundary",
|
||
type_description="The email mime boundary separating parts in a multipart email", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email-reply-to", type_description="Email reply to header",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email-src",
|
||
type_description="The source email address. Used to describe the sender when describing an e-mail.",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email-src-display-name", type_description="Email source display name",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email-subject", type_description="The subject of the email",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email-thread-index", type_description="The email thread index header",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="email-x-mailer", type_description="Email x-mailer header",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="favicon-mmh3",
|
||
type_description="favicon-mmh3 is the murmur3 hash of a favicon as used in Shodan.", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename", type_description="Filename", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename-pattern", type_description="A pattern in the name of a file",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|authentihash", type_description="A checksum in md5 format",
|
||
type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{64}', type_validation_expect="filename|64 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|impfuzzy",
|
||
type_description="Import fuzzy hash - a fuzzy hash created based on the imports in the sample.",
|
||
type_taxonomy="", )
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|imphash",
|
||
type_description="Import hash - a hash created based on the imports in the sample.", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{32}', type_validation_expect="filename|32 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|md5",
|
||
type_description="A filename and an md5 hash separated by a |", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{32}', type_validation_expect="filename|32 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|pehash",
|
||
type_description="A filename and a PEhash separated by a |", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{40}', type_validation_expect="filename|40 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|sha1",
|
||
type_description="A filename and an sha1 hash separated by a |", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{40}', type_validation_expect="filename|40 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|sha224",
|
||
type_description="A filename and a sha-224 hash separated by a |", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{56}', type_validation_expect="filename|56 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|sha256",
|
||
type_description="A filename and an sha256 hash separated by a |", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{64}', type_validation_expect="filename|64 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|sha3-224",
|
||
type_description="A filename and an sha3-224 hash separated by a |", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{56}', type_validation_expect="filename|56 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|sha3-256",
|
||
type_description="A filename and an sha3-256 hash separated by a |", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{64}', type_validation_expect="filename|64 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|sha3-384",
|
||
type_description="A filename and an sha3-384 hash separated by a |", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{96}', type_validation_expect="filename|96 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|sha3-512",
|
||
type_description="A filename and an sha3-512 hash separated by a |", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{128}', type_validation_expect="filename|128 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|sha384",
|
||
type_description="A filename and a sha-384 hash separated by a |", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{96}', type_validation_expect="filename|96 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|sha512",
|
||
type_description="A filename and a sha-512 hash separated by a |", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{128}', type_validation_expect="filename|128 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|sha512/224",
|
||
type_description="A filename and a sha-512/224 hash separated by a |", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{56}', type_validation_expect="filename|56 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|sha512/256",
|
||
type_description="A filename and a sha-512/256 hash separated by a |", type_taxonomy="",
|
||
type_validation_regex='.+\|[a-f0-9]{64}', type_validation_expect="filename|64 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|ssdeep", type_description="A checksum in ssdeep format",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|tlsh",
|
||
type_description="A filename and a Trend Micro Locality Sensitive Hash separated by a |",
|
||
type_taxonomy="",
|
||
type_validation_regex='.+\|t?[a-f0-9]{35,}',
|
||
type_validation_expect="filename|at least 35 hexadecimal characters, optionally starting with t1 instead of hexadecimal characters"
|
||
)
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="filename|vhash",
|
||
type_description="A filename and a VirusTotal hash separated by a |", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="first-name", type_description="First name of a natural person",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="float", type_description="A floating point value.", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="full-name", type_description="Full name of a natural person",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="gene", type_description="GENE - Go Evtx sigNature Engine",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="git-commit-id", type_description="A git commit ID.", type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{40}", type_validation_expect="40 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="github-organisation", type_description="A github organisation",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="github-repository", type_description="A github repository",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="github-username", type_description="A github user name",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="hassh-md5",
|
||
type_description="hassh is a network fingerprinting standard which can be used to identify specific Client SSH implementations. The fingerprints can be easily stored, searched and shared in the form of an MD5 fingerprint.",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{32}", type_validation_expect="32 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="hasshserver-md5",
|
||
type_description="hasshServer is a network fingerprinting standard which can be used to identify specific Server SSH implementations. The fingerprints can be easily stored, searched and shared in the form of an MD5 fingerprint.",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{32}", type_validation_expect="32 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="hex", type_description="A value in hexadecimal format",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="hostname", type_description="A full host/dnsname of an attacker",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="hostname|port",
|
||
type_description="Hostname and port number separated by a |", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="http-method",
|
||
type_description="HTTP method used by the malware (e.g. POST, GET, …).", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="iban", type_description="International Bank Account Number",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="identity-card-number", type_description="Identity card number",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="impfuzzy",
|
||
type_description="A fuzzy hash of import table of Portable Executable format", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="imphash",
|
||
type_description="Import hash - a hash created based on the imports in the sample.", type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{32}", type_validation_expect="32 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="ip-any",
|
||
type_description="A source or destination IP address of the attacker or C&C server", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="ip-dst",
|
||
type_description="A destination IP address of the attacker or C&C server", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="ip-dst|port",
|
||
type_description="IP destination and port number separated by a |", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="ip-src", type_description="A source IP address of the attacker",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="ip-src|port",
|
||
type_description="IP source and port number separated by a |", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="ja3-fingerprint-md5",
|
||
type_description="JA3 is a method for creating SSL/TLS client fingerprints that should be easy to produce on any platform and can be easily shared for threat intelligence.",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{32}", type_validation_expect="32 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="jabber-id", type_description="Jabber ID", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="jarm-fingerprint",
|
||
type_description="JARM is a method for creating SSL/TLS server fingerprints.", type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{62}", type_validation_expect="62 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="kusto-query",
|
||
type_description="Kusto query - Kusto from Microsoft Azure is a service for storing and running interactive analytics over Big Data.",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="link", type_description="Link to an external information",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="mac-address", type_description="Mac address", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="mac-eui-64", type_description="Mac EUI-64 address", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="malware-sample",
|
||
type_description="Attachment containing encrypted malware sample", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="malware-type", type_description="Malware type", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="md5", type_description="A checksum in md5 format", type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{32}", type_validation_expect="32 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="middle-name", type_description="Middle name of a natural person",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="mime-type",
|
||
type_description="A media type (also MIME type and content type) is a two-part identifier for file formats and format contents transmitted on the Internet",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="mobile-application-id",
|
||
type_description="The application id of a mobile application", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="mutex",
|
||
type_description="Mutex, use the format \BaseNamedObjects<Mutex>", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="named pipe",
|
||
type_description="Named pipe, use the format .\pipe<PipeName>", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="other", type_description="Other attribute", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="file-path",
|
||
type_description="Path of file", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="pattern-in-file",
|
||
type_description="Pattern in file that identifies the malware", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="pattern-in-memory",
|
||
type_description="Pattern in memory dump that identifies the malware", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="pattern-in-traffic",
|
||
type_description="Pattern in network traffic that identifies the malware", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="pdb",
|
||
type_description="Microsoft Program database (PDB) path information", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="pehash",
|
||
type_description="PEhash - a hash calculated based of certain pieces of a PE executable file",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{40}", type_validation_expect="40 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="pgp-private-key", type_description="A PGP private key",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="pgp-public-key", type_description="A PGP public key", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="phone-number", type_description="Telephone Number", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="port", type_description="Port number", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="process-state", type_description="State of a process", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="prtn", type_description="Premium-Rate Telephone Number",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="regkey", type_description="Registry key or value", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="regkey|value", type_description="Registry value + data separated by |",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="sha1", type_description="A checksum in sha1 format", type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{40}", type_validation_expect="40 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="sha224", type_description="A checksum in sha-224 format",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{56}", type_validation_expect="56 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="sha256", type_description="A checksum in sha256 format",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{64}", type_validation_expect="64 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="sha3-224", type_description="A checksum in sha3-224 format",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{56}", type_validation_expect="56 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="sha3-256", type_description="A checksum in sha3-256 format",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{64}", type_validation_expect="64 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="sha3-384", type_description="A checksum in sha3-384 format",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{96}", type_validation_expect="96 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="sha3-512", type_description="A checksum in sha3-512 format",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{128}", type_validation_expect="128 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="sha384", type_description="A checksum in sha-384 format",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{96}", type_validation_expect="96 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="sha512", type_description="A checksum in sha-512 format",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{128}", type_validation_expect="128 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="sha512/224", type_description="A checksum in the sha-512/224 format",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{56}", type_validation_expect="56 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="sha512/256", type_description="A checksum in the sha-512/256 format",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{64}", type_validation_expect="64 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="sigma",
|
||
type_description="Sigma - Generic Signature Format for SIEM Systems", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="size-in-bytes", type_description="Size expressed in bytes",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="snort", type_description="An IDS rule in Snort rule-format",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="ssdeep", type_description="A checksum in ssdeep format",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="ssh-fingerprint", type_description="A fingerprint of SSH key material",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="stix2-pattern", type_description="STIX 2 pattern", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="target-email", type_description="Attack Targets Email(s)",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="target-external",
|
||
type_description="External Target Organizations Affected by this Attack", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="target-location",
|
||
type_description="Attack Targets Physical Location(s)", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="target-machine", type_description="Attack Targets Machine Name(s)",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="target-org",
|
||
type_description="Attack Targets Department or Organization(s)", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="target-user", type_description="Attack Targets Username(s)",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="telfhash",
|
||
type_description="telfhash is symbol hash for ELF files, just like imphash is imports hash for PE files.",
|
||
type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{70}", type_validation_expect="70 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="text", type_description="Name, ID or a reference", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="threat-actor", type_description="A string identifying the threat actor",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="tlsh",
|
||
type_description="A checksum in the Trend Micro Locality Sensitive Hash format", type_taxonomy="",
|
||
type_validation_regex="^t?[a-f0-9]{35,}",
|
||
type_validation_expect="at least 35 hexadecimal characters, optionally starting with t1 instead of hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="travel-details", type_description="Travel details", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="twitter-id", type_description="Twitter ID", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="uri", type_description="Uniform Resource Identifier", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="url", type_description="url", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="user-agent",
|
||
type_description="The user-agent used by the malware in the HTTP request.", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="vhash", type_description="A VirusTotal checksum", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="vulnerability",
|
||
type_description="A reference to the vulnerability used in the exploit", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="weakness",
|
||
type_description="A reference to the weakness used in the exploit", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="whois-creation-date",
|
||
type_description="The date of domain’s creation, obtained from the WHOIS information.",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="whois-registrant-email",
|
||
type_description="The e-mail of a domain’s registrant, obtained from the WHOIS information.",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="whois-registrant-name",
|
||
type_description="The name of a domain’s registrant, obtained from the WHOIS information.",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="whois-registrant-org",
|
||
type_description="The org of a domain’s registrant, obtained from the WHOIS information.",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="whois-registrant-phone",
|
||
type_description="The phone number of a domain’s registrant, obtained from the WHOIS information.",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="whois-registrar",
|
||
type_description="The registrar of the domain, obtained from the WHOIS information.", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="windows-scheduled-task", type_description="A scheduled task in windows",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="windows-service-displayname",
|
||
type_description="A windows service’s displayname, not to be confused with the windows-service-name. This is the name that applications will generally display as the service’s name in applications.",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="windows-service-name",
|
||
type_description="A windows service name. This is the name used internally by windows. Not to be confused with the windows-service-displayname.",
|
||
type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="x509-fingerprint-md5",
|
||
type_description="X509 fingerprint in MD5 format", type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{32}", type_validation_expect="32 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="x509-fingerprint-sha1",
|
||
type_description="X509 fingerprint in SHA-1 format", type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{40}", type_validation_expect="40 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="x509-fingerprint-sha256",
|
||
type_description="X509 fingerprint in SHA-256 format", type_taxonomy="",
|
||
type_validation_regex="[a-f0-9]{64}", type_validation_expect="64 hexadecimal characters")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="xmr", type_description="Monero Address", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="yara", type_description="Yara signature", type_taxonomy="")
|
||
create_safe_limited(db.session, IocType, ["type_name", "type_description"], type_name="zeek", type_description="An NIDS rule in the Zeek rule-format",
|
||
type_taxonomy="")
|
||
|
||
|
||
def create_safe_os_types():
|
||
create_safe(db.session, OsType, type_name="Windows")
|
||
create_safe(db.session, OsType, type_name="Linux")
|
||
create_safe(db.session, OsType, type_name="AIX")
|
||
create_safe(db.session, OsType, type_name="MacOS")
|
||
create_safe(db.session, OsType, type_name="Apple iOS")
|
||
create_safe(db.session, OsType, type_name="Cisco iOS")
|
||
create_safe(db.session, OsType, type_name="Android")
|
||
|
||
|
||
def create_safe_tlp():
|
||
create_safe(db.session, Tlp, tlp_name="red", tlp_bscolor="danger")
|
||
create_safe(db.session, Tlp, tlp_name="amber", tlp_bscolor="warning")
|
||
create_safe(db.session, Tlp, tlp_name="green", tlp_bscolor="success")
|
||
create_safe(db.session, Tlp, tlp_name="clear", tlp_bscolor="black")
|
||
|
||
|
||
def create_safe_server_settings():
|
||
if not ServerSettings.query.count():
|
||
create_safe(db.session, ServerSettings,
|
||
http_proxy="", https_proxy="", prevent_post_mod_repush=False,
|
||
prevent_post_objects_repush=False,
|
||
password_policy_min_length="12", password_policy_upper_case=True,
|
||
password_policy_lower_case=True, password_policy_digit=True,
|
||
password_policy_special_chars="")
|
||
|
||
|
||
def register_modules_pipelines():
|
||
modules = IrisModule.query.with_entities(
|
||
IrisModule.module_name,
|
||
IrisModule.module_config
|
||
).filter(
|
||
IrisModule.has_pipeline == True
|
||
).all()
|
||
|
||
for module in modules:
|
||
module = module[0]
|
||
inst, _ = instantiate_module_from_name(module)
|
||
if not inst:
|
||
continue
|
||
|
||
inst.internal_configure(celery_decorator=celery.task,
|
||
evidence_storage=None,
|
||
mod_web_config=module[1])
|
||
status = inst.get_tasks_for_registration()
|
||
if status.is_failure():
|
||
log.warning("Failed getting tasks for module {}".format(module))
|
||
continue
|
||
|
||
tasks = status.get_data()
|
||
for task in tasks:
|
||
celery.register_task(task)
|
||
|
||
|
||
def register_default_modules():
|
||
|
||
modules = ['iris_vt_module', 'iris_misp_module', 'iris_check_module',
|
||
'iris_webhooks_module', 'iris_intelowl_module']
|
||
|
||
for module_name in modules:
|
||
class_, _ = instantiate_module_from_name(module_name)
|
||
is_ready, logs = check_module_health(class_)
|
||
|
||
if not is_ready:
|
||
log.info("Attempted to initiate {mod}. Got {err}".format(mod=module_name, err=",".join(logs)))
|
||
return False
|
||
|
||
module, logs = register_module(module_name)
|
||
if module is None:
|
||
log.info("Attempted to add {mod}. Got {err}".format(mod=module_name, err=logs))
|
||
|
||
else:
|
||
iris_module_disable_by_id(module.id)
|
||
log.info('Successfully registered {mod}'.format(mod=module_name))
|
||
|
||
def custom_assets_symlinks():
|
||
try:
|
||
|
||
source_paths = glob.glob(os.path.join(app.config['ASSET_STORE_PATH'], "*"))
|
||
|
||
for store_fullpath in source_paths:
|
||
|
||
filename = store_fullpath.split(os.path.sep)[-1]
|
||
show_fullpath = os.path.join(app.config['APP_PATH'], 'app',
|
||
app.config['ASSET_SHOW_PATH'].strip(os.path.sep), filename)
|
||
if not os.path.islink(show_fullpath):
|
||
os.symlink(store_fullpath, show_fullpath)
|
||
log.info(f"Created assets img symlink {store_fullpath} -> {show_fullpath}")
|
||
|
||
except Exception as e:
|
||
log.error(f"Error: {e}")
|
||
|