misp-guard

misp-guard is a mitmproxy addon that inspects the synchronization traffic (via PUSH or PULL) between different MISP instances and applies a set of customizable rules defined in a JSON file.

NOTE: By default this addon will block all outgoing HTTP requests that are not required during a MISP server sync. However, individual URLs or domains can be allowed if necessary.

PUSH

sequenceDiagram
    participant MISP A 
    participant MISP Guard
    participant MISP B

    MISP B->>MISP Guard: [GET]/servers/getVersion
    MISP Guard->>MISP A: [GET]/servers/getVersion
    MISP A->>MISP Guard: [GET]/servers/getVersion
    MISP Guard->>MISP B: [GET]/servers/getVersion
    
    MISP B->>MISP Guard: [HEAD]/events/view/[UUID]
    note right of MISP Guard: Only `minimal` search requests to /events/index are allowed
    MISP Guard->>MISP A: [HEAD]/events/view/[UUID]
    MISP A->>MISP Guard: [HEAD]/events/view/[UUID]
    MISP Guard->>MISP B: [HEAD]/events/view/[UUID]
    
    rect rgb(191, 223, 255)
    note left of MISP Guard: 404: If the event does not exists in MISP A
    MISP B->>+MISP Guard: [POST]/events/add
    note right of MISP Guard: Outgoing Event is inspected and rejected with 403 if any block rule matches
    MISP Guard->>-MISP A: [POST]/events/add
    MISP A->>MISP Guard: [POST]/events/add
    MISP Guard->>MISP B: [POST]/events/add
    end

    rect rgb(191, 223, 255)
    note left of MISP Guard: 200: If the event already exists in MISP A
    MISP B->>+MISP Guard: [POST]/events/edit/[UUID]
    note right of MISP Guard: Outgoing Event is inspected and rejected with 403 if any block rule matches
    MISP Guard->>-MISP A: [POST]/events/edit/[UUID]
    MISP A->>MISP Guard: [POST]/events/edit/[UUID]
    MISP Guard->>MISP B: [POST]/events/edit/[UUID]
    end

    rect rgb(191, 223, 255)
    MISP B->>+MISP Guard: [POST]/galaxies/pushCluster
    note right of MISP Guard: Outgoing Galaxy Cluster is inspected and rejected with 403 if any block rule matches
    MISP Guard->>-MISP A: [POST]/galaxies/pushCluster
    MISP A->>MISP Guard: [POST]/galaxies/pushCluster
    MISP Guard->>MISP B: [POST]/galaxies/pushCluster
    end

    rect rgb(191, 223, 255)
    MISP B->>+MISP Guard: [POST]/sightings/bulkSaveSightings/[UUID]
    note right of MISP Guard: Outgoing Sightings are inspected and rejected with 403 if any block rule matches
    MISP Guard->>-MISP A: [POST]/sightings/bulkSaveSightings/[UUID]
    MISP A->>MISP Guard: [POST]/sightings/bulkSaveSightings/[UUID]
    MISP Guard->>MISP B: [POST]/sightings/bulkSaveSightings/[UUID]
    end

PULL

sequenceDiagram
    participant MISP A
    participant MISP Guard
    participant MISP B

    MISP A->>MISP Guard: [GET]/servers/getVersion
    MISP Guard->>MISP B: [GET]/servers/getVersion
    MISP B->>MISP Guard: [GET]/servers/getVersion
    MISP Guard->>MISP A: [GET]/servers/getVersion

    MISP A->>+MISP Guard: [POST]/events/index
    note right of MISP Guard: Only `minimal` search requests to /events/index are allowed
    MISP Guard->>-MISP B: [POST]/events/index
    MISP B->>MISP Guard: [POST]/events/index
    MISP Guard->>MISP A: [POST]/events/index

    MISP A->>MISP Guard: [GET]/events/view/[UUID]
    MISP Guard->>MISP B: [GET]/events/view/[UUID]
    MISP B->>+MISP Guard: [GET]/events/view/[UUID]
    note right of MISP Guard: Incoming Event is inspected and rejected with 403 if any block rule matches
    MISP Guard->>-MISP A: [GET]/events/view/[UUID]

    MISP A->>MISP Guard: [GET]/shadow_attributes/index
    MISP Guard->>MISP B: [GET]/shadow_attributes/index
    MISP B->>+MISP Guard: [GET]/shadow_attributes/index
    note right of MISP Guard: Incoming Shadow Attributes are inspected and rejected with 403 if any block rule matches
    MISP Guard->>-MISP A: [GET]/shadow_attributes/index

    MISP A->>+MISP Guard: [POST]/galaxy_clusters/restSearch
    note right of MISP Guard: Only `minimal` search requests to /galaxy_clusters/restSearch are allowed
    MISP Guard->>-MISP B: [POST]/galaxy_clusters/restSearch
    MISP B->>MISP Guard: [POST]/galaxy_clusters/restSearch
    MISP Guard->>MISP A: [POST]/galaxy_clusters/restSearch

    MISP A->>MISP Guard: [GET]/galaxy_clusters/view/[UUID]
    MISP Guard->>MISP B: [GET]/galaxy_clusters/view/[UUID]
    MISP B->>+MISP Guard: [GET]/galaxy_clusters/view/[UUID]
    note right of MISP Guard: Incoming Galaxy Cluster is inspected and rejected with 403 if any block rule matches
    MISP Guard->>-MISP A: [GET]/galaxy_clusters/view/[UUID]

    MISP A->>MISP Guard: [POST]/sightings/restSearch/event
    MISP Guard->>MISP B: [POST]/sightings/restSearch/event
    MISP B->>+MISP Guard: [POST]/sightings/restSearch/event
    note right of MISP Guard: Incoming Sightings are inspected and rejected with 403 if any block rule matches
    MISP Guard->>-MISP A: [POST]/sightings/restSearch/event

NOTE: The MISP A server needs to have the misp-guard hostname configured as the server hostname you are going to pull from, **not the MISP B hostname.**

Supported block rules:

Allowlist

See sample config here.

Instructions

Installation

$ git clone https://github.com/MISP/misp-guard.git
$ cd src/
$ pip install -r requirements.txt

Setup

  1. Define your block rules in the config.json file.
  2. Start mitmproxy with the mispguard addon:
     $ mitmdump -s mispguard.py -p 8888 --certs *=cert.pem --set config=config.json
     Loading script mispguard.py
     MispGuard initialized
     Proxy server listening at *:8888
    

    Add -k to accept self-signed certificates.

  3. Configure the proxy in your MISP instance, set the following MISP Proxy.host and Proxy.port settings accordingly.

Done, outgoing MISP sync requests will be inspected and dropped according to the specified block rules.

NOTE: add -v to mitmdump to increase verbosity and display debug logs.

Testing

 src src/
 pytest