Dans cette section, nous explorerons les composants nécessaires à la mise en place d'une plateforme de renseignements sur les menaces efficace. Comme indiqué précédemment, ce cours impliquera de tester des techniques de scraping de données sur des sites fictifs que vous pourrez configurer localement à l'aide de Docker. Vous découvrirez ici les types de sites sur lesquels nous allons travailler.

Les sujets abordés dans cette section sont les suivants :

  1. Forum Clearnet
  2. Forum Tor
  3. Approche non LLM de l'analyse de texte
  4. Gestion des technologies anti-scraping
  5. Listes de surveillance du renseignement

Forum Clearnet

Bien que la plupart des sites web consacrés à la cybercriminalité ne reposent pas beaucoup sur JavaScript, il est important de comprendre comment extraire des données des sites web Clearnet. La plupart des sites Clearnet récupèrent souvent des données à partir du backend à l'aide de JavaScript, puis mettent à jour le frontend de manière dynamique. Lorsque vous consultez le code source de la page, vous ne trouverez peut-être aucune donnée utilisable, car le contenu est chargé après le chargement initial de la page. Notre propre scraper en est un bon exemple, car presque tout son contenu est dynamique et change constamment.

Dans de tels cas, nous utilisons des navigateurs sans interface graphique tels que Playwright pour interagir avec la page et extraire les données du DOM (Document Object Model) une fois qu'elle a été entièrement chargée et rendue.

Pour vous exercer, vous pouvez télécharger le forum fictif sur la cybercriminalité créé pour ce cours sur GitHub :

https://github.com/CyberMounties/clearnet_forum

Le référentiel contient des instructions complètes pour configurer le forum localement.


Forum Tor

Une grande partie des activités cybercriminelles se déroule sur Tor en raison de son architecture axée sur la confidentialité. Notre forum Tor simulé est conçu sans JavaScript afin d'imiter des scénarios réels tout en restant simple. Contrairement au forum clearnet, qui comprend une fonctionnalité de shoutbox (chat général), le forum Tor n'en dispose pas.

Vous pouvez configurer le forum Tor factice pour ce cours en le téléchargeant depuis GitHub :

https://github.com/CyberMounties/tornet_forum

Le référentiel comprend des instructions détaillées pour configurer et exécuter le forum localement.


Approche non LLM de l'analyse de texte

Au lieu de vous fier aux grands modèles linguistiques (LLM) ou à l'IA, vous pouvez utiliser des bibliothèques traditionnelles de traitement du langage naturel (NLP) telles que spaCy pour analyser les données. Ces outils peuvent vous aider dans des tâches telles que la classification de texte, la reconnaissance d'entités et la correspondance de modèles. Cependant, ils présentent certaines limites : ils nécessitent généralement davantage de personnalisation manuelle, de création de règles et de formation pour obtenir des résultats comparables à ceux des LLM. Bien qu'ils puissent être efficaces dans certains cas, leur configuration pour des tâches complexes telles que l'identification des activités IAB peut demander beaucoup plus de temps et d'efforts.

Exemple avec spaCy

Créez un répertoire, configurez un environnement virtuel et installez les dépendances :

mkdir non_llm_cti && cd non_llm_cti
python3 -m venv venv
source venv/bin/activate
pip install spacy
python -m spacy download en_core_web_sm

Créez un fichier script nommé « main.py » et collez-y le code suivant :

import spacy
import re
from typing import Tuple

# Load spaCy's English model
nlp = spacy.load("en_core_web_sm")

# Define keywords and patterns for initial access detection
ACCESS_KEYWORDS = {
    "access", "vpn", "rdp", "network", "server", "admin", "credentials", 
    "login", "remote", "domain", "shell", "backdoor"
}
SALE_KEYWORDS = {"sell", "selling", "offer", "offering", "sale", "available", "price", "btc", "escrow"}
NEGATIVE_KEYWORDS = {"hosting", "vps", "software", "malware", "loader", "botnet"}
OBFUSCATION_PATTERNS = [
    r"acc[e3]ss",  # Handles "acc3ss", "access"
    r"v[pP][nN]",  # Handles "VPN", "VpN", "vpn"
    r"rd[pP]",     # Handles "RDP", "rdp"
]

def preprocess_text(text: str) -> str:
    """Normalize text by converting to lowercase and handling basic obfuscation."""
    text = text.lower()
    for pattern in OBFUSCATION_PATTERNS:
        text = re.sub(pattern, re.search(pattern, text).group().replace("3", "e"), text) if re.search(pattern, text) else text
    return text

def analyze_post(text: str) -> Tuple[str, float]:
    """
    Analyze a post to determine if it offers initial access.
    Returns: (classification, confidence_score)
    Classifications: 'positive' (initial access sale), 'neutral' (general ad), 'negative' (unrelated)
    """
    # Preprocess text
    text = preprocess_text(text)
    doc = nlp(text)

    # Initialize scores
    access_score = 0.0
    sale_score = 0.0
    negative_score = 0.0

    # Rule 1: Check for access-related keywords
    for token in doc:
        if token.lemma_ in ACCESS_KEYWORDS:
            access_score += 0.4
        if token.lemma_ in SALE_KEYWORDS:
            sale_score += 0.3
        if token.lemma_ in NEGATIVE_KEYWORDS:
            negative_score += 0.5

    # Rule 2: Dependency parsing for sales intent (e.g., "selling access")
    for token in doc:
        if token.lemma_ in SALE_KEYWORDS and token.head.lemma_ in ACCESS_KEYWORDS:
            access_score += 0.3
            sale_score += 0.3
        elif token.lemma_ in ACCESS_KEYWORDS and token.head.lemma_ in SALE_KEYWORDS:
            access_score += 0.3
            sale_score += 0.3

    # Rule 3: Named entities (e.g., "RBC Bank", "EU telecom") for context
    for ent in doc.ents:
        if ent.label_ in ["ORG", "GPE"]:
            access_score += 0.2

    # Rule 4: Regex for specific patterns (e.g., "access to [entity]")
    access_pattern = r"\b(access|vpn|rdp)\b.*\b(to|for|at)\b.*\b(bank|telecom|network|company|org)\b"
    if re.search(access_pattern, text, re.IGNORECASE):
        access_score += 0.3

    # Rule 5: Cryptocurrency or escrow mentions
    if any(word in text for word in ["btc", "bitcoin", "escrow", "monero"]):
        sale_score += 0.2

    # Calculate total score and determine classification
    total_score = access_score + sale_score - negative_score
    if access_score >= 0.4 and sale_score >= 0.3 and total_score > 0.5:
        classification = "positive"
        confidence = min(total_score, 1.0)
    elif negative_score > access_score and negative_score > sale_score:
        classification = "negative"
        confidence = min(negative_score, 1.0)
    else:
        classification = "neutral"
        confidence = min(max(access_score, sale_score, negative_score), 1.0)

    return classification, confidence

def main():
    # Test cases
    test_posts = [
        # Positive: Initial access sale with details
        """Back again, mods nuked my last thread. Selling VPN access to a big EU telecom, one of them household names in Germany (you figure it out). Full internal access, you can pivot to servers, grab call logs, or mess with billing systems. Been stable for a month, no kicks. Asking $4,000 BTC, negotiable for bulk buyers (got 2 more telecoms). I'll throw in logs or a test connection for proof, but only if you're serious. Escrow or MM accepted, I'm vouched here. Hit me up in PM, let's make this quick. No skids, please.""",
        # Positive: Direct initial access sale
        "Initial access to RBC Bank available, full admin creds, $5k BTC, DM for details.",
        # Neutral: General ad, not access-related
        "Selling malware loader, high quality, $200, contact me for demo.",
        # Negative: Unrelated service
        "Offering VPS hosting, 16GB RAM, $50/month, legit service."
    ]

    for i, post in enumerate(test_posts, 1):
        classification, confidence = analyze_post(post)
        print(f"\nPost {i}:")
        print(f"Text: {post[:100]}..." if len(post) > 100 else f"Text: {post}")
        print(f"Classification: {classification.capitalize()}")
        print(f"Confidence: {confidence:.2f}")

if __name__ == "__main__":
    main()

Lancez-le et voyez les résultats par vous-même :

$ python3 main.py

Post 1:
Text: Back again, mods nuked my last thread. Selling VPN access to a big EU telecom, one of them household...
Classification: Positive
Confidence: 1.00

Post 2:
Text: Initial access to RBC Bank available, full admin creds, $5k BTC, DM for details.
Classification: Positive
Confidence: 1.00

Post 3:
Text: Selling malware loader, high quality, $200, contact me for demo.
Classification: Negative
Confidence: 1.00

Post 4:
Text: Offering VPS hosting, 16GB RAM, $50/month, legit service.
Classification: Negative
Confidence: 1.00

Comme démontré, cette approche est moins fiable, en particulier pour classer correctement le troisième message comme « neutre ». Elle nécessite une personnalisation et un réglage minutieux, ce qui, dans ce cas, l'emporte sur les avantages offerts par des solutions plus simples et plus adaptables telles que les API d'IA existantes.


Technologies anti-scraping

L'extraction de données à partir de sites web est simple à petite échelle, mais elle devient complexe lorsque les sites déploient des technologies anti-scraping pour bloquer l'accès automatisé. De nombreux sites web appliquent des conditions d'utilisation qui interdisent le scraping, et les développeurs mettent en œuvre des mesures de protection pour faire respecter ces restrictions.

Les techniques anti-scraping courantes comprennent :

  • CAPTCHAs : obligent les utilisateurs à résoudre des énigmes ou des défis basés sur des images pour vérifier qu'ils ne sont pas des robots.
  • Limitation du débit : limite le nombre de requêtes provenant d'une seule adresse IP ou d'un seul compte dans un délai spécifique.
  • Verrouillage de compte : suspension temporaire ou permanente des comptes après détection d'une activité suspecte ou d'un nombre excessif de tentatives de connexion infructueuses.
  • Bannissement d'IP : blocage du trafic provenant d'adresses IP présentant des comportements automatisés ou abusifs.
  • Vérification des en-têtes et du comportement : détection des requêtes qui s'écartent du comportement habituel des navigateurs, telles que des en-têtes manquants ou des modèles d'interaction irréalistes.

Des outils tels que Playwright peuvent aider à contourner certaines défenses anti-bot en simulant un navigateur réel, mais cela n'est pas suffisant. Vous pouvez utiliser undetected chrome driver.

Bien que ce cours ne traite pas de toutes les techniques avancées de contournement des mesures anti-scraping, l'exemple ci-dessous illustre comment utiliser Playwright pour simuler une vitesse de frappe similaire à celle d'un humain.

Pour commencer, configurez un environnement et installez les dépendances :

mkdir play && cd play
touch play.py
python3 -m venv venv
source venv/bin/activate
sudo apt install libavif16
pip3 install playwright
playwright install

Ouvrez « play.py » et entrez ce code :

from playwright.sync_api import sync_playwright
import time
import os

def fill_input_slowly():
    text_to_type = "This is a test string"
    local_html = """
    <!DOCTYPE html>
    <html>
    <body>
        <form>
            <input type="text" id="fname" name="fname" value="Hamy">
        </form>
    </body>
    </html>
    """
    
    # Write the HTML to a temporary file
    html_file_path = "temp.html"
    with open(html_file_path, "w") as f:
        f.write(local_html)
    
    with sync_playwright() as p:
        # Set headless to True if you don't want to see the browser
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        
        try:
            page.goto(f"file://{os.path.abspath(html_file_path)}", timeout=60000)
            input_field = page.locator("input#fname[name='fname']")
            input_field.wait_for(timeout=10000) 
            input_field.clear()

            for char in text_to_type:
                input_field.type(char, delay=750)
            time.sleep(2)
            
        except Exception as e:
            print(f"Error occurred: {e}")
        
        finally:
            browser.close()
            if os.path.exists(html_file_path):
                os.remove(html_file_path)

if __name__ == "__main__":
    fill_input_slowly()

Listes de surveillance

L'une des principales caractéristiques qui distingue cette formation de la plupart des formations en CTI est qu'elle vous apprend à créer des listes de surveillance réalistes. Ces listes fonctionnent comme un système de surveillance automatisé, qui surveille en permanence l'activité d'un utilisateur au fil du temps. Au lieu de simplement collecter des instantanés de données, vous créerez des outils capables de suivre les changements et les actions au fur et à mesure qu'ils se produisent.

L'objectif principal de ces listes de surveillance est de montrer comment croiser les activités d'un acteur malveillant sur plusieurs plateformes, afin de vous aider à dresser un tableau complet de son comportement. Cela est essentiel pour suivre les acteurs malveillants prolifiques, corréler les données provenant de différentes sources et comprendre les schémas qui peuvent signaler une intention malveillante.

Pour créer un profil de liste de surveillance, vous définirez :

  • Lien : l'identifiant de la personne ou de l'entité que vous souhaitez surveiller.
  • Fréquence : la fréquence à laquelle le système vérifie s'il y a de nouvelles activités. Les options sont les suivantes :
  • Faible : toutes les 24 heures
  • Moyenne : toutes les 12 heures
  • Élevée : toutes les 6 heures
  • Très élevée : toutes les heures
  • Critique : toutes les 5 minutes
  • Priorité : le niveau de détail des informations collectées. Les options disponibles sont les suivantes :
  • Tout : toutes les données disponibles (publications et commentaires)
  • Publications uniquement : uniquement le contenu publié par l'utilisateur
  • Commentaires uniquement : uniquement les commentaires publiés par l'utilisateur

Par exemple, une liste de surveillance à faible priorité vérifie l'activité toutes les 24 heures et collecte les données pertinentes. Les résultats peuvent être exportés au format JSON pour être facilement téléchargés et croisés avec d'autres plateformes.