Aller au contenu

Repérer un moissonnage applicatif : volumétrie, cadence, origine

Repérer un moissonnage applicatif : volumétrie, cadence, origine

Section intitulée « Repérer un moissonnage applicatif : volumétrie, cadence, origine »

Un compte ouvre une fiche, puis une autre, puis deux cent mille autres. Chaque requête est légitime : le compte existe, son mot de passe est bon, l’autorisation est accordée, le serveur répond 200. Rien, dans aucune de ces requêtes prise séparément, ne ressemble à une attaque. C’est précisément ce qui rend le moissonnage applicatif difficile à voir, et c’est pour cela qu’il faut le chercher ailleurs que dans la requête : dans sa répétition.

→ Lire l’explication complète de la marmotte

Ce qu’on cherche : une lecture légitime à l’échelle industrielle

Section intitulée « Ce qu’on cherche : une lecture légitime à l’échelle industrielle »

Le moissonnage, ou scraping, consiste à parcourir une application web avec un programme pour en recopier le contenu. Il n’a rien à voir avec l’exfiltration par vidage de base, qui laisse une trace nette du côté du serveur de données. Ici, l’attaquant passe par l’interface prévue pour les humains, ou par l’API qui la sert, et son programme se comporte comme un utilisateur très appliqué. Le rapport d’incident publié par l’ANSSI après la compromission de la DGFiP le formule en une phrase qui tient lieu de définition opérationnelle : la technique « impose de devoir initier autant de requêtes que de pages accédées ». Des centaines de milliers de fiches recopiées, donc des centaines de milliers de requêtes, sous un compte unique.

Deux conséquences suivent. D’abord, les contrôles qui cherchent une charge utile hostile ne servent à rien : il n’y a pas d’injection, pas de motif suspect, pas de chaîne bizarre dans un paramètre. Un pare-feu applicatif réglé sur les signatures d’attaque laissera passer l’intégralité du moissonnage, et il aura raison, puisqu’aucune requête n’est hostile. Ensuite, les contrôles d’autorisation ne suffisent pas non plus : si le compte a le droit de lire la fiche n° 1, il a le droit de lire la fiche n° 200 000. L’autorisation répond à « cet utilisateur peut-il voir cet objet ? », jamais à « a-t-il des raisons de voir tous les objets ? », nuance qui distingue un contrôle d’accès correct d’un contrôle d’accès suffisant, exposé dans la prévention des BOLA dans une API métier.

La détection doit donc porter sur le comportement agrégé d’un compte dans le temps, et pas sur le contenu de ses requêtes. C’est un déplacement de point de vue qui coûte cher en instrumentation, parce qu’il suppose de compter ce que l’application ne compte pas spontanément.

Le rapport de l’ANSSI a le mérite de lister exactement les paramètres qui existaient et que personne ne regardait pendant l’incident. La liste est courte, et elle épuise à peu près le sujet.

La volumétrie échangée d’abord : onze gigaoctets entre le 22 et le 25 juin 2026, trois gigaoctets entre le 21 et le 23 juillet, sans qu’aucune alerte ne se déclenche. Le signal est le plus facile à collecter, parce qu’il existe déjà dans les journaux de flux et dans ceux du serveur frontal. C’est aussi le plus trompeur : un téléchargement d’archive légitime pèse autant qu’une session de moissonnage, et les octets ne disent rien de ce qui a été lu.

La cadence, ensuite, c’est-à-dire le nombre de requêtes par compte sur une fenêtre de temps. Le rapport constate qu’il « n’est pas considéré ». C’est le signal le plus discriminant, parce qu’il est directement proportionnel au nombre d’objets métier consultés. Un agent qui traite une demande d’usager ouvre une fiche, la lit, répond, et passe à la suivante ; sa cadence se compte en dizaines de fiches par heure, pas en milliers. Mieux encore que les requêtes : le nombre d’enregistrements métier distincts renvoyés au compte, qui se compte dans l’application et nulle part ailleurs.

L’origine, troisième famille, « n’est pas analysée » : l’attaquant se connectait depuis des adresses de sortie de VPN, depuis des adresses localisées en Inde, et depuis plusieurs adresses déjà catégorisées comme malveillantes. Le rapport pointe surtout une corrélation que personne n’avait faite : des adresses « utilisées pour se connecter à des comptes connus comme compromis à plusieurs semaines d’intervalle ». Une adresse qui apparaît sur deux comptes volés à un mois d’écart n’est pas une coïncidence, c’est un identifiant d’attaquant.

L’horaire, enfin, « n’est pas interprété », alors que des connexions nocturnes avaient été journalisées. La session d’exfiltration la plus volumineuse de l’incident commence à 04h26. Un agent des finances publiques qui consulte des dossiers à quatre heures et demie du matin fait soit preuve d’un dévouement remarquable, soit autre chose.

Le rapport prend soin d’ajouter l’avertissement sans lequel cette liste serait un piège : « Ces paramètres pris individuellement ne permettent généralement pas d’identifier des comportements suspects sans générer d’importants volumes de faux positifs, néanmoins la corrélation de plusieurs d’entre eux aurait pu permettre de lever des alertes. »

L’expérience confirme chacun des faux positifs annoncés. Le volume : une campagne de relance, un export annuel, une migration de données produisent des pointes qui écrasent n’importe quel seuil fixe. La cadence : un agent qui vide une file d’attente accumulée pendant les congés enchaîne les dossiers à un rythme qui ressemble à celui d’un programme. L’origine : le télétravail, les réseaux privés d’entreprise et les opérateurs mobiles génèrent des adresses instables, et le géo-filtrage se trompe dès qu’un agent voyage. L’horaire : une astreinte, une permanence de nuit, un décalage horaire suffisent. Chaque signal pris seul produit une alerte par jour et par mille comptes, ce qui, à l’échelle d’une administration, revient à ne rien produire du tout. Le mécanisme par lequel cette avalanche détruit une détection est décrit dans la fatigue d’alerte dans un SOC.

La conclusion n’est pas qu’il faut renoncer, mais qu’il faut cesser de chercher la règle unique. On ne détecte pas un moissonnage avec un seuil ; on le détecte avec une combinaison dont chaque terme est individuellement banal.

La forme utile est un score par compte et par fenêtre glissante, pas une suite de règles indépendantes. Quatre ou cinq termes suffisent, chacun exprimé en écart au comportement habituel du compte lui-même plutôt qu’en valeur absolue : nombre d’enregistrements distincts consultés comparé à la médiane des trente derniers jours du même compte, part des consultations hors plage horaire habituelle, nouveauté de l’adresse source pour ce compte, et appartenance de cette adresse à une liste de réputation ou à l’historique d’un autre compte signalé compromis. Le dernier terme est le plus précieux et le moins coûteux : il suppose seulement de conserver, pour chaque compte dont une compromission a été notifiée, la liste des adresses qui s’y sont connectées, et de la croiser avec les connexions en cours.

Le calibrage se fait à l’envers de l’intuition. On ne règle pas les seuils pour attraper le moissonnage théorique ; on les règle sur l’historique réel de l’application, en acceptant une alerte par semaine et par millier de comptes, et en vérifiant que les sessions d’un incident passé auraient été prises. Sans incident passé, l’exercice se fait avec un moissonnage de test mené par l’équipe, ce qui a en plus le mérite de révéler ce que les journaux ne contiennent pas. La méthode d’ensemble, hypothèse d’abord et mesure ensuite, est celle de la formulation d’une hypothèse de threat hunting, et les limites des approches purement statistiques sont rappelées dans pourquoi le ML échoue à détecter les menaces.

Un point de vigilance sur la fenêtre : un moissonnage patient, étalé sur trois semaines à deux cents fiches par jour, passe sous toute fenêtre horaire ou journalière. Il faut donc deux échelles au moins, une fenêtre courte pour l’extraction brutale et un cumul mensuel par compte comparé à ce que la fonction de l’agent justifie. Le second est plus facile à défendre devant une direction métier, parce qu’il se formule dans sa langue.

Où placer la mesure : dans l’application, pas sur le réseau

Section intitulée « Où placer la mesure : dans l’application, pas sur le réseau »

La supervision réseau ne voit pas ce qui se passe. Le rapport de l’ANSSI est net sur ce point en ce qui concerne sa propre détection : « les acteurs malveillants utilisaient des comptes légitimes pour accéder aux applications et la supervision réseau de l’Agence n’a pas permis de les voir ». Le trafic est chiffré, l’authentification est valide, et le volume, seul signal visible de l’extérieur, n’est pas interprétable sans savoir à quoi correspondent les octets.

Le compteur doit donc vivre dans l’application, au point où elle sait quel enregistrement métier elle vient de renvoyer à quel compte. Cela suppose un journal applicatif qui porte, pour chaque consultation : l’identité du compte, l’identifiant de l’objet consulté, l’horodatage en temps universel, l’adresse source, et le canal d’accès. Un journal qui n’enregistre que la méthode et le chemin HTTP ne permet pas de distinguer deux cents consultations de deux cents objets d’une consultation répétée du même objet. La mise en place de cette collecte et sa fiabilisation relèvent de la collecte des logs de sécurité, et leur mise en forme comparable de la normalisation avec OCSF, ECS ou CIM.

Autre leçon de l’incident, et elle vaut d’être retenue : il ne sert à rien de superviser six portails sur sept. Le portail par lequel l’exfiltration de la DGFiP s’est faite n’était pas supervisé par son centre opérationnel pendant l’incident, et les alertes qui se déclenchaient sur le portail voisin ont donné l’illusion d’un traitement. Une couverture incomplète ne produit pas une détection partielle : elle produit une détection qui conclut à tort.

Détecter ne suffit pas, parce que la détection arrive après la lecture. Le rapport demande donc des mesures de restriction appliquées dans l’application : « application de quotas ; en volume de ressources métiers accédées, en nombre de requêtes ou en volume de données échangées sur une période donnée », et plus loin « des plafonds de consultation des ressources métiers doivent également être implémentés pour limiter l’impact d’un accès illégitime ».

Il faut bien voir la différence avec la limitation de débit telle qu’on la déploie contre un déni de service, décrite dans la mise en place d’un rate limiting. Celle-là protège la disponibilité du service et se règle en requêtes par seconde et par adresse. Le plafond de consultation, lui, protège la confidentialité des données et se règle en objets métier par compte et par jour, indépendamment de l’adresse et de la vitesse. Un attaquant qui ralentit son programme contourne le premier sans toucher au second. Les techniques de contournement de la limitation, rotation d’en-têtes et d’adresses, sont détaillées dans le contournement d’un rate limit ; elles supposent toutes que le compteur est attaché à autre chose que l’identité.

Le réglage d’un plafond est une discussion métier, et c’est pourquoi il échoue souvent. Un gestionnaire consulte trente dossiers par jour, un superviseur en consulte deux cents, un service de recouvrement en consulte mille en période de campagne. Le plafond doit donc être attaché au rôle, comporter une procédure de dépassement traçable plutôt qu’un blocage sec, et, dans l’intervalle, produire une alerte avant de bloquer. Un plafond qui casse une activité légitime est désactivé dans la semaine, ce qui donne au passage une excellente mesure de sa calibration.

Ce que l’attaquant fait quand la détection existe

Section intitulée « Ce que l’attaquant fait quand la détection existe »

Reste à savoir ce qu’il faut attendre d’un adversaire qui sait être surveillé, parce que c’est ce qui décide des signaux qu’on garde. Il ralentit, et la cadence s’écrase sous les seuils courts : seul le cumul par compte le rattrape. Il répartit son extraction sur plusieurs comptes volés, et c’est le compteur par compte qui devient aveugle : seule l’origine partagée relie les sessions entre elles. Il passe par des adresses résidentielles louées, et la réputation d’adresse perd son pouvoir : restent la cadence et l’horaire. Il imite la pagination normale de l’interface, et la forme des requêtes devient indistinguable : reste le nombre d’objets distincts.

Aucune de ces esquives n’annule l’ensemble, et c’est tout l’argument en faveur de la corrélation plutôt que de la règle. Chaque contournement sacrifie un signal pour en exposer un autre, et ralentir coûte du temps à l’attaquant, donc des jours supplémentaires pendant lesquels une notification de compte compromis peut arriver. L’économie de l’opération, et le fait que l’attaquant arbitre lui aussi entre coût et discrétion, sont exposés dans les courtiers d’accès initial.

Sans compteur d’enregistrements métier par compte, l’extraction complète d’une base par l’interface prévue pour la consulter ne laisse aucune anomalie : chaque requête est autorisée, le journal ne porte que des codes 200, et le volume total se perd dans le trafic ordinaire. Sans conservation des adresses associées aux comptes déjà signalés compromis, la même adresse peut revenir sur un autre compte des semaines plus tard sans que rien ne la rapproche de la première. Sans journal applicatif portant l’identifiant de l’objet consulté, l’investigation postérieure ne peut pas dire quelles données sont sorties, et l’organisation se trouve à notifier une fuite dont elle ignore le périmètre. Sans plafond de consultation attaché au rôle, un compte non privilégié conserve un droit de lecture illimité sur l’ensemble de la base, et la détection, quand elle finit par arriver, ne fait que documenter ce qui est déjà parti. Et sans supervision de tous les canaux d’accès, l’alerte qui se déclenche sur le portail surveillé fait conclure à un incident traité pendant que l’extraction se poursuit sur l’autre.

Une application contient des dossiers, et un employé a le droit de les consulter un par un pour faire son travail. Si quelqu’un vole son identifiant et son mot de passe, il peut faire la même chose, mais avec un programme : ouvrir un dossier, le recopier, passer au suivant, cent mille fois de suite. C’est ce qu’on appelle un moissonnage. Rien n’est forcé, rien n’est cassé, et chaque consultation est parfaitement autorisée.

Les protections habituelles ne voient rien. Les systèmes qui cherchent des attaques cherchent des requêtes anormales, et celles-ci sont normales. Les systèmes qui vérifient les droits confirment que ce compte a bien le droit de lire ce dossier, ce qui est vrai pour chaque dossier pris séparément.

Ce qui trahit le moissonnage, c’est l’accumulation. Quatre choses se mesurent : la quantité de données sorties, le nombre de dossiers ouverts par le compte en une journée, l’endroit d’où la connexion arrive, et l’heure à laquelle elle arrive. Chacune de ces mesures, seule, se trompe souvent : un employé pressé, un collègue en déplacement, une permanence de nuit sont parfaitement innocents. Mais les quatre réunies dessinent quelque chose qu’un employé ne fait jamais.

Il faut compter au bon endroit, c’est-à-dire dans l’application elle-même, parce qu’elle seule sait quel dossier a été envoyé à qui, le réseau ne voyant que du trafic chiffré. Et il faut compter sur tous les accès, sinon on croit avoir réglé un problème qui continue ailleurs. Détecter ne suffit pas, enfin, parce qu’une alerte arrive après la lecture : on fixe donc une limite au nombre de dossiers qu’un compte peut consulter par jour selon son métier, avec une procédure pour la dépasser quand c’est justifié. Un voleur ralentira pour passer sous la limite, ce qui lui coûtera des semaines, du temps pendant lequel on peut encore l’arrêter.

À lire aussi

Pages voisines

: les deux pages se citent l’une l’autre.