Aller au contenu principal

Guide d’intégration

Reference set QRadar d’IP et de domaines malveillants rempli par l’API REST

QRadar ne télécharge aucune liste lui-même : un script télécharge la liste isMalicious complète avec votre clé API, vide un reference set et le remplit par l’API REST de QRadar. Des règles testent ensuite les propriétés des événements et des flux sur le set.

Aucune carte bancaire requise · Clé API gratuite

Chemin des données
  1. isMalicious

    api.ismalicious.com

    blocklist-ips-critical.txt

    Régénérée toutes les 12 h

  2. IBM QRadar

    Étape 4

    Installer le script et l’exécuter une fois

  3. Utiliser les sets dans des règles

    Étape 6
Sur cette page08

Ce que vous obtenez

Chaque liste remplit un reference set : de type IP pour les listes d’IP, ALNIC pour les domaines. Commencez par les listes ci-dessous ; les pages d’IBM lues pour ce guide n’indiquent aucune taille maximale de set.

ListeEntréesRégénéréeOffres
blocklist-ips-critical.txtPar défaut : set isMalicious IPs critical, de type IP, entrées IPv4 seulement. IP signalées par 6 sources de menaces ou plus, ou par 3 ou plus avec une catégorie critique.environ 89 000toutes les 12 hBasic, Pro et Enterprise
blocklist-ips-c2.txtSet isMalicious IPs C2, de type IP : IP de commande et contrôle (C2) signalées par des trackers de C2.environ 44 000toutes les 12 hBasic, Pro et Enterprise
blocklist-domains-c2.txtSet isMalicious domains C2, de type ALNIC : domaines de commande et contrôle (C2).environ 22 000toutes les 12 hBasic, Pro et Enterprise
blocklist-domains-ransomware.txtSet isMalicious domains ransomware, de type ALNIC : domaines de la catégorie ransomware.environ 3 600toutes les 12 hBasic, Pro et Enterprise
c2-indicatorsEn TAXII 2.1, avec l’app Threat Intelligence : IP et domaines des catégories C2 et botnet, pas tout le corpus. Un flux lit un seul type d’observable : la collection s’ajoute donc deux fois, les IP dans un reference set de type IP, les domaines dans un set de type ALNIC.paginéà chaque requêtePro et Enterprise

Nombres arrondis d’après la génération du  ; chaque liste est régénérée toutes les 12 heures. Les chiffres du jour sont publics et ne demandent aucune clé.

Ce que reçoit chaque offre

  • FreeCompte Free, ou aucune clé : les premiers 10 % de chaque liste, signalés par X-Blocklist-Version: lite.
  • Basic, Pro et EnterpriseBasic, Pro et Enterprise : toutes les listes, complètes.
  • Pro et EnterpriseCollections TAXII 2.1 : Pro et Enterprise.

Comparer les offres

Ce que renvoie un téléchargementHTTP

GET https://api.ismalicious.com/blocklist/download/blocklist-ips-critical.txt

Liste complète ou échantillon de 10 %

ChampBasic, Pro et EnterpriseFree
X-Blocklist-Version:fulllite
X-Blocklist-Percentage:10010
Total entries:<COUNT><COUNT> (Lite Version - 10% of <TOTAL>)

Premières lignes du fichier

# IsMalicious.com Blocklist - IPs (Critical)
# Format: Plain
# Generated: <BUILD_TIME>
# Total entries: <COUNT>
# Update frequency: every 12 hours
# Category: All
# Threat level: Critical
# Website: https://ismalicious.com
# © <YEAR> IsMalicious (compilation). Licensed to the downloading account under https://ismalicious.com/terms; redistribution of the compilation prohibited. Third-party entries remain under their providers' licences — see https://ismalicious.com/sources.
#

Les valeurs entre chevrons sont fixées à chaque génération.

Prérequis

  • IBM QRadar SIEM 7.5.0, avec l’API REST 16.0 ou ultérieure pour la mise à jour groupée.
  • Un hôte avec Python 3 qui joint à la fois api.ismalicious.com et la console QRadar.
  • Une clé API et son secret isMalicious, dans Compte › Accès API.
  • Un accès HTTPS sortant (TCP 443) en IPv4 depuis l’hôte du script vers api.ismalicious.com, qui n’a pas d’adresse IPv6.

Mise en place

  1. Copier la clé API et le secret

    Ouvrez Compte › Accès API et copiez la Clé API et le Secret API. Les listes complètes demandent une offre Basic, Pro ou Enterprise ; avec une clé Free, le script reçoit l’échantillon de 10 % et le refuse.
  2. Créer un service autorisé QRadar

    Dans QRadar, créez un service autorisé avec un rôle autorisé à gérer les données de référence, et copiez son jeton : le script l’envoie dans l’en-tête SEC.
  3. Créer les reference sets une fois

    Créez un set par liste par l’API REST, qui répond avec le set et son id : le script en a besoin. Le jeton va dans un fichier de configuration curl en mode 600, ~/.qradar.curlrc, pas sur la ligne de commande. Réglez l’en-tête Version sur une version d’API listée à /api_doc/ sur votre console ; sans lui, QRadar utilise la dernière version, ce qui peut casser les intégrations après une mise à jour, prévient IBM.
    Créer un reference setsh
    # ~/.qradar.curlrc (mode 600) holds the token, off the command line:
    #   header = "SEC: <QRADAR_TOKEN>"
    curl -sS -K ~/.qradar.curlrc -X POST "https://<QRADAR_CONSOLE>/api/reference_data_collections/sets" \
      -H "Version: <API_VERSION>" -H "Content-Type: application/json" \
      --data '{"name": "isMalicious IPs critical", "entry_type": "IP", "description": "isMalicious blocklist-ips-critical"}'
    
    # Domain sets: "entry_type": "ALNIC" (alphanumeric, case-insensitive).
  4. Installer le script et l’exécuter une fois

    • Placez les identifiants dans /root/.ismalicious-qradar.env, en mode 600, et enregistrez le script sous /usr/local/sbin/ismalicious-qradar.py, en mode 700.
    • Il télécharge d’abord la liste et refuse une erreur, un contenu qui n’est pas une liste, l’échantillon de 10 % et un fichier dont le nombre d’entrées diffère de son en-tête, puis retire les lignes d’en-tête #, ainsi que les adresses IPv6 pour les sets d’IP.
    • Ensuite seulement, il vide le set, attend qu’il soit vide, et charge les valeurs par lots de 10 000 via la mise à jour groupée asynchrone, en attendant chaque tâche jusqu’à 30 minutes.
    /root/.ismalicious-qradar.envsh
    export ISM_KEY='<API_KEY>'
    export ISM_SECRET='<API_SECRET>'
    export QRADAR_URL='https://<QRADAR_CONSOLE>'
    export QRADAR_TOKEN='<QRADAR_TOKEN>'
    export QRADAR_API_VERSION='<API_VERSION>'
    # Optional: the console's CA bundle.
    # export QRADAR_CA=/etc/ssl/qradar-ca.pem
    /usr/local/sbin/ismalicious-qradar.pypython
    #!/usr/bin/env python3
    """Refresh a QRadar reference set from an isMalicious list.
    
    Usage: ismalicious-qradar.py <isMalicious file> <set id> <ip|domain>
    Environment: ISM_KEY, ISM_SECRET, QRADAR_URL (https://console), QRADAR_TOKEN,
    QRADAR_API_VERSION (a version the console lists at /api_doc/), optional
    QRADAR_CA (CA bundle path).
    """
    import base64, json, os, re, ssl, sys, time, urllib.error, urllib.request
    
    LIST, SET_ID, KIND = sys.argv[1], int(sys.argv[2]), sys.argv[3]
    BATCH = 10000
    
    def fetch_list(name):
        token = base64.b64encode(f"{os.environ['ISM_KEY']}:{os.environ['ISM_SECRET']}".encode()).decode()
        req = urllib.request.Request(
            f"https://api.ismalicious.com/blocklist/download/{name}",
            headers={"Authorization": f"Basic {token}"})
        try:
            with urllib.request.urlopen(req, timeout=300) as resp:
                text = resp.read().decode("utf-8")
        except urllib.error.HTTPError as err:
            sys.exit(f"{name}: HTTP {err.code}")
        lines = text.splitlines()
        if not lines or not lines[0].startswith(("# IsMalicious.com Blocklist", "! IsMalicious.com Blocklist")):
            sys.exit(f"{name}: not an isMalicious list")
        if "Lite Version" in text:
            sys.exit(f"{name}: lite list received, check the API key and the plan")
        if not text.endswith("\n"):  # every entry ends with a newline: cut inside a line
            sys.exit(f"{name}: cut short, no final newline")
        values = [l.strip() for l in lines if l.strip() and not l.startswith(("#", "!"))]
        totals = [l.split(":", 1)[1].strip().replace(",", "") for l in lines
                  if l.startswith(("# Total entries:", "! Total entries:"))]
        # One header, and as many entries as it says: never empty the set for an
        # empty, cut or doubled file.
        if len(totals) != 1 or not re.fullmatch(r"[0-9]+", totals[0]) \
                or int(totals[0]) == 0 or len(values) != int(totals[0]):
            sys.exit(f"{name}: {len(values)} entries, the header says {' / '.join(totals) or 'none'}")
        if KIND == "ip":
            values = [v for v in values if ":" not in v]  # IP sets take dotted IPv4
        return values
    
    CTX = ssl.create_default_context(cafile=os.environ.get("QRADAR_CA"))
    
    def qradar(method, path, body=None):
        req = urllib.request.Request(
            os.environ["QRADAR_URL"].rstrip("/") + "/api" + path, method=method,
            data=None if body is None else json.dumps(body).encode(),
            headers={"SEC": os.environ["QRADAR_TOKEN"],
                     "Version": os.environ["QRADAR_API_VERSION"],
                     "Content-Type": "application/json", "Accept": "application/json"})
        with urllib.request.urlopen(req, context=CTX, timeout=120) as resp:
            return json.loads(resp.read() or b"null")
    
    def wait(task):
        deadline = time.time() + 1800  # a task left PAUSED or QUEUED must not hang the run
        while task["status"] not in ("COMPLETED", "EXCEPTION", "CONFLICT", "CANCELLED", "INTERRUPTED"):
            if time.time() > deadline:
                sys.exit(f"bulk update task {task['id']} still {task['status']} after 30 minutes")
            time.sleep(5)
            task = qradar("GET", f"/reference_data_collections/set_bulk_update_tasks/{task['id']}")
        if task["status"] != "COMPLETED":
            sys.exit(f"bulk update task {task['id']} ended {task['status']}: {task.get('error_message')}")
    
    values = fetch_list(LIST)                     # download first: never empty the set on a failed fetch
    qradar("POST", f"/reference_data_collections/sets/{SET_ID}", {"delete_entries": True})
    for _ in range(120):                          # the docs do not say whether emptying is synchronous
        if qradar("GET", f"/reference_data_collections/sets/{SET_ID}").get("number_of_entries") == 0:
            break
        time.sleep(5)
    else:
        sys.exit(f"reference set {SET_ID} was not emptied within 10 minutes")
    for i in range(0, len(values), BATCH):
        chunk = [{"collection_id": SET_ID, "value": v} for v in values[i:i + BATCH]]
        wait(qradar("PATCH", "/reference_data_collections/set_entries", chunk))
    print(f"{LIST}: {len(values)} values loaded into reference set {SET_ID}")
    Première exécutionsh
    . /root/.ismalicious-qradar.env
    /usr/local/sbin/ismalicious-qradar.py blocklist-ips-critical.txt <SET_ID> ip
  5. Le planifier toutes les 12 heures

    Ajoutez une ligne cron par liste et par set : les listes sont régénérées toutes les 12 heures.
    /etc/cron.d/ismalicious-qradarcron
    17 3,15 * * *  root  . /root/.ismalicious-qradar.env && /usr/local/sbin/ismalicious-qradar.py blocklist-ips-critical.txt <SET_ID> ip
  6. Utiliser les sets dans des règles

    Dans l’assistant de règles, écrivez des règles qui testent des propriétés d’événements ou de flux, comme l’IP source ou de destination, ou la propriété d’hôte DNS ou d’URL que fournissent vos sources de journaux, sur ces reference sets.
  7. Ou importer un fichier à la main

    Téléchargez une liste avec un fichier netrc, comparez le nombre de l’en-tête au nombre d’entrées, vérifiez que ce n’est pas l’échantillon de 10 %, et retirez son en-tête. Puis, dans Admin › System Configuration › Reference Set Management, sélectionnez le set, cliquez sur View Contents, puis sur Import dans l’onglet Content, et choisissez le fichier : une valeur par ligne.
    Préparer un fichier pour l’importsh
    # ~/.ismalicious.netrc (mode 600) holds the three netrc lines of your key.
    curl -fsS --netrc-file ~/.ismalicious.netrc -o list.txt \
      https://api.ismalicious.com/blocklist/download/blocklist-ips-critical.txt
    # The header's count, the entries' count, and the 10% sample marker:
    grep -m1 'Total entries' list.txt
    grep -c '^[^#]' list.txt
    grep -q 'Lite Version' list.txt && echo 'lite list: check the key and the plan'
    # One value per line, no header; IP sets take dotted IPv4 only:
    grep -v '^#' list.txt | grep -v ':' > ismalicious-ips-critical.csv
  8. Ou interroger une collection TAXII 2.1 avec l’app Threat Intelligence (Pro ou Enterprise)

    • L’app QRadar Threat Intelligence lit TAXII 2.1 depuis la version 2.5.0, qui demande QRadar 7.5.0 UP7 ou ultérieur. La page de configuration d’IBM ne décrit encore que TAXII 1.x et 2.0.
    • Dans le Feeds Downloader de l’app, cliquez sur Add Threat Feed, puis sur Add TAXII Feed.
    • Dans l’onglet Connection, saisissez les valeurs ci-dessous, puis cliquez sur Discover. L’endpoint est l’URL des collections, l’endpoint Get Collections vers lequel la page d’IBM renvoie pour les serveurs TAXII 2.
    • Dans l’onglet Parameters, choisissez c2-indicators et un Observable Type. IBM : seuls les observables de ce type sont utilisés, tous les autres sont ignorés. Ajoutez le flux deux fois : une avec le type adresse IP, vers un reference set de type IP, une avec le type domaine, vers un set de type ALNIC. Réglez Polling Intervals (toutes les heures par défaut) et Poll Initial Date, et sélectionnez le reference set créé au préalable. L’app interroge un seul flux TAXII à la fois.
    • Ce chemin n’a pas été testé dans QRadar lui-même.
    Add TAXII Feed, onglet ConnectionGUI
    TAXII Endpoint
    https://api.ismalicious.com/taxii/api-root/collections/
    Version
    TAXII 2.1
    Authentication Method
    HTTP Basic: <API_KEY> / <API_SECRET>

    # After Discover, on the Parameters tab. A feed uses one observable type and

    # ignores the others, so add the collection twice:

    Collections
    c2-indicators (IP addresses, into an IP reference set)
    Collections
    c2-indicators (domains, into an ALNIC reference set)
    TAXII Endpoint ......... https://api.ismalicious.com/taxii/api-root/collections/
    Version ................ TAXII 2.1
    Authentication Method .. HTTP Basic: <API_KEY> / <API_SECRET>
    
    # After Discover, on the Parameters tab. A feed uses one observable type and
    # ignores the others, so add the collection twice:
    Collections ............ c2-indicators   (IP addresses, into an IP reference set)
    Collections ............ c2-indicators   (domains, into an ALNIC reference set)

Vérifier le résultat

  • Le nombre d’éléments du set, dans Reference Set Management ou en number_of_entries par l’API, égale le nombre affiché par le script : le count de la liste dans /blocklist/stats, moins les entrées IPv6 pour les sets d’IP.
  • Chaque exécution affiche une ligne avec le nombre chargé. Une sortie non nulle signifie que le téléchargement a échoué ou a été refusé, ou qu’une tâche groupée n’a pas abouti en 30 minutes ; dans ce dernier cas, le set reste vide ou partiel jusqu’à la prochaine exécution réussie. Une tâche terminée peut encore lister des échecs par entrée à set_bulk_update_tasks/ suivi de son identifiant et de /results.
  • Un événement ou un flux de test avec une adresse listée déclenche la règle.
  • Les premières lignes d’un téléchargement direct montrent Total entries sans Lite Version.
Vérificationssh
# Entries in the set (number_of_entries):
curl -sS -K ~/.qradar.curlrc -H "Version: <API_VERSION>" \
  "https://<QRADAR_CONSOLE>/api/reference_data_collections/sets/<SET_ID>"

# The key reaches isMalicious: no "Lite Version" in Total entries.
curl -sS --netrc-file ~/.ismalicious.netrc https://api.ismalicious.com/blocklist/download/blocklist-ips-critical.txt | head -12

Dépannage

« HTTP 401 » affiché par le script

La clé ou le secret est faux ou incomplet. Le script s’arrête avant de vider le set : l’ancien contenu reste. Le corps de la réponse indique « Blocklist not found or empty » ; fiez-vous au code HTTP. Régénérer la clé dans Compte › Accès API invalide l’ancienne paire.

« lite list received »

Aucun identifiant n’est parvenu au serveur, ou l’offre est Free ou interrompue : un abonnement impayé, en retard de paiement, annulé, incomplet ou suspendu compte comme Free. Vérifiez la clé, le secret et l’offre.

« entries, the header says » ou « cut short, no final newline »

Le fichier était vide, tronqué ou n’était pas une des listes, comme quand un proxy ou un portail captif répond. Le script s’arrête avant de vider le set : l’ancien contenu reste ; l’exécution suivante réessaie.

Délais dépassés ou 502

Un téléchargement qui prend plus de 30 secondes de notre côté finit en délai dépassé ou en 502 : prenez une liste par niveau ou par catégorie du tableau.

401 ou 403 depuis QRadar

Le jeton SEC est faux ou expiré, ou son rôle ne peut pas gérer les données de référence.

422 depuis QRadar

Une valeur ne correspond pas au type d’entrée du set, par exemple un domaine envoyé à un set d’IP : vérifiez le type et le dernier argument du script.

Une tâche groupée finit en EXCEPTION

Lisez son error_message dans set_bulk_update_tasks, puis relancez le script. Une tâche encore en file ou en pause après 30 minutes arrête aussi l’exécution.

Erreurs de certificat

Vers la console, indiquez son magasin d’autorités dans QRADAR_CA. Vers api.ismalicious.com, elles signalent une inspection TLS ou un magasin d’autorités ancien.

« Unexpected Response. Got Content-Type » dans l’app Threat Intelligence

La Version du flux est TAXII 2.0, ou l’app est antérieure à la 2.5.0 : un client TAXII 2.0 refuse une réponse TAXII 2.1. Mettez l’app à jour, puis réglez Version sur TAXII 2.1.

Limites

  • Le chemin TAXII 2.1 demande l’app Threat Intelligence 2.5.0 ou ultérieure et n’a pas été testé dans QRadar. IBM ne documente la configuration TAXII que pour 1.x et 2.0, et pas la façon dont l’app range les indicateurs STIX 2.1 dans les reference sets. Un flux lit une seule collection et un seul type d’observable.
  • Le script vide un set avant de le remplir : les règles manquent des correspondances pendant les tâches groupées.
  • Les entrées IPv6 sont écartées des sets d’IP : la documentation d’import d’IBM donne des adresses IPv4 pointées.
  • Les reference sets contiennent des valeurs littérales. Aucune liste CIDR ou à jokers n’est servie : le type d’entrée CIDR reste inutilisé.
  • IBM ne documente ni taille maximale de set ni taille maximale de requête groupée dans les pages lues pour ce guide : le lot de 10 000 valeurs est notre choix.
  • L’échantillon de 10 % est le premier dixième d’un fichier non trié, pas le dixième le plus risqué : le script le refuse.

Questions fréquentes

L’app QRadar Threat Intelligence peut-elle interroger le flux TAXII d’isMalicious ?

Depuis la version 2.5.0 de l’app, qui lit TAXII 2.1, avec une offre Pro ou Enterprise : ajoutez c2-indicators deux fois avec l’URL des collections et HTTP Basic, un flux par type d’observable (adresses IP, domaines), comme dans l’étape TAXII. L’association n’a pas été testée dans QRadar lui-même ; le script des reference sets fonctionne quelle que soit la version de l’app.

QRadar peut-il télécharger une blocklist dans un reference set lui-même ?

Non. Un reference set prend un fichier importé à la main ou des entrées envoyées par l’API REST. Le script télécharge la liste avec votre clé API et la charge par l’API.

Pourquoi le script écarte-t-il les adresses IPv6 ?

La documentation d’import d’IBM donne les adresses IP valides en IPv4 pointé : le script garde donc les entrées IPv4 pour les sets de type IP.

À quelle fréquence rafraîchir les reference sets ?

Toutes les 12 heures, au rythme de régénération des listes. Chaque exécution vide le set avant de le remplir : les règles manquent des correspondances pendant le chargement.

Commencer

Prêt à commencer ?

Aucune carte bancaire requise · Clé API gratuite