L'intelligence artificielle désigne la vaste discipline informatique consacrée à la création de systèmes capables d'effectuer des tâches qui nécessitent généralement l'intelligence humaine. Dans ce domaine, les grands modèles linguistiques constituent une catégorie spécialisée de systèmes d'IA statistique entraînés sur des corpus textuels massifs afin de prédire et de générer un langage cohérent. Parmi les exemples notables, citons ChatGPT, Grok xAI, Claude et Gemini, qui excellent dans la traduction, la synthèse et les fonctions conversationnelles, mais qui fonctionnent par reconnaissance de formes plutôt que par véritable compréhension.

Les détracteurs affirment que l'amalgame entre IA et LLM occulte la diversité de la recherche en IA, qui englobe également des domaines tels que la vision par ordinateur, la robotique, les systèmes experts et la prise de décision autonome.

Nous ne sommes pas ici pour débattre de la science de l'IA ou des LLM, mais plutôt pour nous concentrer sur les applications possibles de l'IA dans le domaine de la cyberdéfense.

Les thèmes abordés dans cette section sont les suivants :

  1. Différents types d'utilisation de l'IA : incitation, RAG et ajustement
  2. Mise en place d'une API IA
  3. Incitation IA

Différents types d'utilisation de l'IA : incitation, RAG et ajustement

Contexte et objectif

Notre objectif est d'analyser les messages publiés sur les forums consacrés à la cybercriminalité afin d'identifier ceux qui traitent de la vente d'accès initiaux (IAB). Les messages sont classés comme suit :

  • Messages positifs : vente directe d'un accès non autorisé à une entreprise (par exemple, « Accès initial à RBC Bank disponible »).
  • Messages neutres : offres générales d'outils, d'exploits ou de logiciels malveillants sans mentionner de cible spécifique.
  • Messages négatifs : services hors sujet ou sans rapport, tels que l'hébergement, les outils de spam ou la vente de VPS génériques.

Prompting IA

Le prompting utilise des API pré-entraînées (par exemple OpenAI, xAI, Anthropic) en envoyant des invites conçues et en recevant des réponses non modifiées.

Coûts et frais techniques

  • Les appels à des API tierces varient de faibles (GPT-3.5 à environ 0,002 $ pour 1 000 jetons) à moyens (GPT-4 à environ 0,03-0,06 $ pour 1 000 jetons).

  • L'auto-hébergement entraîne des coûts matériels (serveurs GPU à 2-3 $/heure) et des frais de licence pour les modèles ouverts.

  • Infrastructure minimale au-delà du stockage sécurisé des journaux de prompt et des clés API.

Stockage des données Uniquement les modèles de prompt, les journaux et les métadonnées des publications ; généralement quelques mégaoctets par jour.

Considérations relatives à la confidentialité L'envoi d'informations sensibles sur les menaces à des API externes peut constituer une violation de la confidentialité. Les modèles locaux améliorent la confidentialité, mais augmentent les coûts d'infrastructure et de formation.

Facilité d'adoption Les invites sont le moyen le plus rapide de se lancer dans la CTI, car elles ne nécessitent aucune formation de modèle et une configuration minimale.

Génération augmentée par récupération (RAG)

La RAG combine un magasin de documents contenant des données CTI avec un LLM. Elle récupère des passages pertinents (par exemple à partir de rapports sur les logiciels malveillants ou d'archives de fuites) afin d'enrichir le contexte des invites.

Composants principaux et coûts

  1. Magasin vectoriel (par exemple FAISS, Pinecone)

  2. Modèle d'intégration (intégrations OpenAI ou alternatives open source)

  3. LLM

  4. Principaux LLM cloud : GPT-4, Claude 2

  5. Modèles auto-hébergés : Llama 2-70B, Mistral Instruct

Les coûts d'inférence dans le cloud comprennent les appels d'intégration et les appels de génération (similaires aux invites). L'auto-hébergement nécessite des GPU (A100 ou équivalent), avec 40 à 80 Go de VRAM pour les modèles volumineux.

Charges techniques La mise en place d'un pipeline de récupération, l'indexation des documents et la maintenance des bases de données vectorielles nécessitent des compétences techniques.

Stockage des données Stockage du corpus (des dizaines à des centaines de gigaoctets) plus les index vectoriels (environ 2 à 5 fois la taille du corpus).

Exigences en matière de calcul

  • Embedding : quelques secondes par document sur GPU

  • Génération : dépend de la taille du modèle ; les modèles GPT-4 ou 70 B-paramètres nécessitent des GPU haut de gamme pour une inférence à faible latence.

Réglage fin

Le réglage fin adapte un LLM à la CTI en l'entraînant sur des exemples étiquetés (par exemple, des classifications de messages ou des résumés de rapports de menaces).

Meilleurs LLM de raisonnement et besoins informatiques

  • Cloud† : réglage fin de GPT-3.5 et GPT-4 (nécessite une puissance de calcul minimale de la part de l'utilisateur).
  • Auto-hébergé : Mistral 7B/13B, variantes Llama 2, série Falcon.
  • Le réglage fin de modèles volumineux (30 milliards de paramètres ou plus) nécessite plusieurs GPU A100 et peut prendre plusieurs heures, voire plusieurs jours.

Coûts et frais techniques

  • Cloud : frais de réglage basés sur des jetons (~0,03 à 0,12 $ pour 1 000 jetons) plus le stockage du modèle réglé.
  • Sur site : location de clusters GPU (3 à 10 $/heure par GPU), pipelines de prétraitement des données, maintenance de l'infrastructure de formation.

Stockage des données Ensembles de données d'entraînement (jusqu'à plusieurs gigaoctets) plus les points de contrôle du modèle final (10 à 200 Go selon la taille).

Pour commencer le réglage fin, voici un exemple d'ensemble de données que vous pouvez utiliser :

https://github.com/0xHamy/minimal_scraper/tree/main/datasets

Pour générer davantage de données similaires, vous pouvez utiliser des API de paragraphe.

Résumé comparatif

| Aspect | Invite | RAG | Réglage fin | |----------------------|-------------------------------|---------------------------------------------|--------------------------------------| | Confidentialité | Faible (API publique) ou élevée (locale) | Moyenne (corpus local, LLM public) | Élevée (modèle local) | | Temps de configuration | Minutes | Heures à jours | Jours à semaines | | Infrastructure | Minimale | Modérée (base de données vectorielle, serveur de récupération) | Étendue (parc de GPU, pile de formation) | | Profil de coût | Faible à moyen | Moyen à élevé | Élevé | | Stockage des données | Journaux et métadonnées | Documents + index | Données d'entraînement + points de contrôle du modèle | | Raisonnement du modèle | Limité à la conception des invites | Amélioré par la récupération du contexte | Meilleur alignement du domaine | | Courbe d'apprentissage | Très facile | Intermédiaire | Difficile |


Configuration d'une API IA

Comme indiqué précédemment, le prompting est la manière la plus simple de commencer. Mais comment sélectionner les modèles adaptés à nos tâches ?

Les fournisseurs d'IA répertoriés ci-dessous proposent une gamme de modèles allant au-delà de ceux mentionnés. Je vous encourage à explorer leurs offres et à comprendre leurs capacités. Notez que les abonnements à l'IA (par exemple, pour ChatGPT ou Claude) diffèrent des API d'IA, qui nécessitent l'achat de crédits API. Ceux-ci commencent généralement à 5 $ et ont une durée considérable.

Anthropic

Claude 3.5 Sonnet d'Anthropic est un modèle que j'utilise fréquemment. Il excelle dans le raisonnement et dispose de garde-fous robustes, ce qui le rend idéal pour identifier les publications liées aux ventes initiales, aux discours haineux ou au cyberharcèlement. De plus, il fonctionne bien dans la reconnaissance optique de caractères (OCR), en particulier pour résoudre les CAPTCHA en extrayant efficacement le texte des images.

Pour commencer :

https://www.anthropic.com/api

xAI

Le Grok 3 de xAI est exceptionnel pour l'écriture et l'analyse de bases de code volumineuses, pouvant traiter jusqu'à 2 000 lignes de code. Bien qu'il soit adapté à l'analyse de logiciels malveillants, il est moins efficace dans les tâches de raisonnement, telles que les débats, où il a du mal à générer des arguments uniques. Claude 3.5 Sonnet surpasse Grok 3 dans le raisonnement général et les débats, mais Grok 3 est en tête dans les tâches de codage.

Pour commencer :

https://x.ai/api

OpenAI

OpenAI propose différents modèles, parmi lesquels o1 se distingue pour le débogage de code et la résolution d'erreurs. Ce modèle s'est révélé inestimable pour le dépannage de bases de code volumineuses. Au fur et à mesure que vous développerez des plateformes CTI étendues, vous rencontrerez de nombreuses erreurs, et o1 est un outil fiable pour trouver des solutions.

Pour commencer :

https://openai.com/api/


Prompting IA

Les fournisseurs d'API IA mentionnés précédemment proposent une documentation complète détaillant comment interagir avec leurs API à l'aide de langages de programmation tels que Python ou JavaScript. Dans cette section, je vais approfondir le sujet et expliquer comment tirer parti de l'IA d'Anthropic pour des cas d'utilisation spécifiques, tels que la distinction entre les publications traitant des ventes d'accès initial et celles qui n'en traitent pas.

Identifier une vente d'accès initial avec Claude

Pour identifier les ventes d'accès initial avec Claude, nous pouvons demander à l'IA de faire une inférence. Pour commencer, configurez un environnement virtuel Python :

mkdir ai_prompting && cd ai_prompting
python3 -m venv venv
source venv/bin/activate
pip install anthropic
touch iab_identifier.py

Ouvrez « iab_identifier.py » et collez le code suivant :

from anthropic import Anthropic
import json


def claude_classify(
    api_key: str,
    model_name: str,
    post_content: str,
    max_tokens: int = 100,
    temperature: float = 0.1
) -> dict:
    """
    Classify a post using Claude (e.g., Sonnet) to determine if it discusses selling initial access,
    unrelated items, or warnings/complaints.

    Args:
        api_key (str): Anthropic API key.
        model_name (str): Claude model name (e.g., 'claude-3-5-sonnet-20241022').
        post_content (str): Post text to classify.
        max_tokens (int, optional): Max output tokens. Defaults to 100.
        temperature (float, optional): Sampling temperature. Defaults to 0.1.

    Returns:
        dict: JSON with classification, scores, and error (if any).
    """
    client = Anthropic(api_key=api_key)
    prompt_template = """
    Does this post discuss selling initial access to a company (e.g., RDP, VPN, admin access), selling unrelated items (e.g., accounts, tools), or warnings/complaints? Classify it as:
- Positive Posts: direct sale of unauthorized access to a company, this usually include the target's name.
- Neutral Posts: general offers for tools, exploits or malware without naming a specific target.
- Negative Posts: off-topic or unrelated services such as hosting, spam tools or generic VPS sales.

The content must be specifically about selling access to a company or business whose name is mentioned in the post. 

Return **only** a JSON object with:
- `classification`: "Positive", "Neutral", or "Negative".
- `scores`: Probabilities for `positive`, `neutral`, `negative` (summing to 1).

Wrap the JSON in ```json
{
  ...
}
``` to ensure proper formatting. Do not include any reasoning or extra text.

Post:
```markdown
{{POST}}
``` 
"""
    prompt = prompt_template.replace("{{POST}}", post_content)

    try:
        message = client.messages.create(
            model=model_name,
            max_tokens=max_tokens,
            temperature=temperature,
            messages=[
                {"role": "user", "content": prompt}
            ]
        )
        content = message.content[0].text
        # Extract JSON between ```json and ```
        start = content.index("```json\n") + 7
        end = content.index("\n```", start)
        result = json.loads(content[start:end])
        return result
    except Exception as e:
        return {"error": f"Failed to classify post: {str(e)}", "classification": None, "scores": None}


# Example usage 
if __name__ == "__main__":
    API_KEY = "" 
    MODEL_NAME = "claude-3-7-sonnet-20250219"

    sample_post = """Selling access to Horizon Logistics\nRevenue: $1.2B\nAccess: RDP with DA\nPrice: 0.8 BTC\nDM for details"""

    result = claude_classify(
        api_key=API_KEY,
        model_name=MODEL_NAME,
        post_content=sample_post,
        max_tokens=100,
        temperature=0.1
    )
    print("API response:")
    print(json.dumps(result, indent=4))

C'est ce qu'on appelle une chaîne docstring de fonction :

    """
    Classify a post using Claude (e.g., Sonnet) to determine if it discusses selling initial access,
    unrelated items, or warnings/complaints.

    Args:
        api_key (str): Anthropic API key.
        model_name (str): Claude model name (e.g., 'claude-3-5-sonnet-20241022').
        post_content (str): Post text to classify.
        max_tokens (int, optional): Max output tokens. Defaults to 100.
        temperature (float, optional): Sampling temperature. Defaults to 0.1.

    Returns:
        dict: JSON with classification, scores, and error (if any).
    """

Les chaînes de documentation sont utilisées pour documenter le fonctionnement du code.

Ce code peut également être utilisé comme module. Par exemple, vous pouvez importer claude_classify depuis iab_identifier.py, passer les arguments requis et l'utiliser.

Ici, nous définissons une instruction conditionnelle, if __name__ == « __main__ »:, pour vérifier si le programme est exécuté en tant que script. Si c'est le cas, le code contenu dans le bloc conditionnel est exécuté.

Pour l'utiliser, définissez votre clé API dans la variable API_KEY et spécifiez le nom du modèle dans la variable MODEL_NAME. Pour sample_post, vous pouvez fournir soit un seul message, soit une liste de messages et les parcourir.

Voici un exemple utilisant trois messages tels que positive, neutral et negative, provenant de l'ensemble de données suivant :

https://github.com/0xHamy/minimal_scraper/blob/main/datasets/base.csv

# Example usage 
if __name__ == "__main__":
    API_KEY = "sk-ant-apixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 
    MODEL_NAME = "claude-3-5-sonnet-20241022"

    sample_posts = ["Selling access to Capital Freight Co. (Texas-based logistics) \nRevenue: ~$900M \nAccess: Full RDP, domain admin via svc_x backup creds \nExtras: Internal invoices, mapped drives, Outlook web creds \nEDR: minimal – Defender only \nPrice: 0.6 BTC firm, BTC only, DM me quick", 
	"Private obfuscator for Python tools \nRandom junk + encryption \nFUD for most stealers \n0.012 BTC",
	"Selling 150k+ Netflix logins from Latin America \nMost accounts active, pulled from private stealer logs \nNo warranty – buy at your own risk \n0.02 BTC per 1k – discounts on bulk \nDM for sample"
	]

    for idx, post in enumerate(sample_posts, start=1):
        result = claude_classify(
            api_key=API_KEY,
            model_name=MODEL_NAME,
            post_content=post,
            max_tokens=100,
            temperature=0.1
        )
        print(f"API response for post number {idx}:\n")
        print(json.dumps(result, indent=4))
        print(60 * '*')

Voici le résultat :

-> % python3 iab_identifier.py
API response for post number 1:

{
    "classification": "Positive",
    "scores": {
        "positive": 0.95,
        "neutral": 0.04,
        "negative": 0.01
    }
}
************************************************************
API response for post number 2:

{
    "classification": "Neutral",
    "scores": {
        "positive": 0.05,
        "neutral": 0.85,
        "negative": 0.1
    }
}
************************************************************
API response for post number 3:

{
    "classification": "Negative",
    "scores": {
        "positive": 0.05,
        "neutral": 0.15,
        "negative": 0.8
    }
}
************************************************************

Cette approche est très efficace et permet d'accomplir la tâche rapidement. Si les API peuvent parfois classer de manière erronée les publications « neutres » et « négatives », elles identifient toujours avec précision les publications « positives », ce qui est essentiel. Les activités cybercriminelles générales relèvent souvent des catégories « négatives » ou « neutres », mais les ventes d'accès initiaux peuvent toujours être distinguées de manière fiable.