Comment repérer les personnes mal intentionnées qui se connectent avec des identifiants volés, grâce aux journaux d'audit détaillés de Databricks et à Genie
par Solomon Boyd, Alexis Merritt, Arun Pamulapati, Sam Pezzino et David Veuve
Chez Databricks, nous savons que vos données sont votre actif le plus précieux. Databricks a travaillé avec des milliers de clients pour déployer de manière sécurisée la Databricks Data + AI Platform avec les fonctionnalités appropriées pour répondre à leurs exigences de sécurité, de confidentialité et de réglementation.
La cyberattaque moderne ne commence pas toujours par un périmètre brisé ; elle commence par une connexion valide. Une fois qu'un adversaire obtient un cookie de session divulgué, un jeton d'accès personnel (PAT) ou un identifiant de principal de service, la brèche initiale est déjà complète. À partir de ce moment, tout son objectif est de se fondre dans la masse et d'agir sous l'identité de votre utilisateur ou service compromis.
Mais avoir une clé ne signifie pas que vous connaissez le bâtiment. Imaginez un intrus volant un badge pour entrer dans un bureau sécurisé. Il a peut-être franchi les portes tournantes, mais il doit encore faire face au agent de sécurité, deviner les étages auxquels il a accès et trouver où se trouve le coffre. Comme un attaquant ne possède pas le contexte localisé et approfondi de vos véritables employés, son comportement finira par le trahir. Repérer ces irrégularités est la façon de les attraper.
Dans cet article, nous expliquons comment se déroule une attaque basée sur les identifiants sur la plateforme Databricks, comment détecter le changement de comportement d'une identité à l'aide des journaux d'audit détaillés de Databricks et de Genie, comment réagir une fois que vous confirmez un compromis, et quels contrôles limitent ce qu'un identifiant volé peut faire en premier lieu.
Lors de l'établissement d'un accès via des identifiants légitimes, les adversaires, tout comme les professionnels de la sécurité, comprennent également que leur accès peut être révoqué à tout moment s'ils s'écartent trop du comportement attendu de l'identité. Les adversaires s'appuient sur un séquençage d'attaque non linéaire, tel que la validation d'un ensemble d'identifiants pour cartographier votre environnement, puis la récupération d'un autre ensemble d'identifiants pour revenir par une nouvelle identité ou un nouvel espace de travail qui n'est pas associé à une activité de reconnaissance. De plus, les adversaires peuvent collecter des informations sans établir de persistance ou s'assurer un moyen de revenir dans votre plateforme Databricks avant de terminer leurs objectifs.
Considérons un ingénieur de données dont le jeton d'accès personnel est copié à partir d'un journal d'intégration et de livraison continues (CI/CD) mal configuré. En quelques minutes, le jeton est utilisé à partir d'une nouvelle adresse IP pour lister les portées de secrets, les catalogues et les dépôts de l'espace de travail, ce que cet ingénieur n'a jamais fait. Un secret contenant un identifiant de principal de service est lu. Une heure plus tard, ce principal de service, et non l'ingénieur, crée une fonction, s'ajoute à un groupe d'administration et exporte une poignée de scripts d'initialisation. Chacun de ces événements pourrait passer pour une utilisation routinière de la plateforme, mais pris ensemble, ils montrent une intrusion progressant dans la chaîne d'attaque.
Chez Databricks, nous nous attendons à un séquençage d'événements non linéaire en lien avec les attaques basées sur les identifiants et nous utilisons ce modèle pour relier des événements individuels en une seule enquête plutôt que de les traiter comme des événements sans rapport.

Lorsque les adversaires exploitent des identifiants compromis dans un environnement de type Platform-as-a-Service (PaaS), tel que Databricks, leur activité peut être regroupée en six étapes, bien qu'ils progressent rarement de manière linéaire. Chaque étape ci-dessous décrit ce que l'adversaire essaie de faire et ce qu'il faut rechercher dans les tables de journaux d'audit Databricks. Considérez ce guide comme un point de départ et ajustez-le à l'automatisation normale de votre environnement.
Remarque : Les événements sont écrits sous la forme service_name.action_name, par exemple secrets.getSecret.
La connexion elle-même semble rarement inhabituelle. Parce que l'identifiant est réel, l'authentification réussit comme pour le propriétaire légitime. Cependant, ce que fait l'identité dans les minutes suivant sa connexion est souvent très différent de son activité normale, et c'est ce changement que les équipes de réponse peuvent détecter. Dans l'exemple de l'ingénieur de données, le jeton volé s'authentifie avec succès, et la seule différence lors de la connexion est une adresse IP source que l'ingénieur n'a jamais utilisée. L'activité qui suit est ce qui se démarque.
Objectif de l'adversaire : Accéder à l'espace de travail avec des identifiants valides, qu'il s'agisse d'une session de navigateur volée, d'un PAT rejoué ou d'un identifiant de principal de service, et se fondre dans l'activité que les contrôles sont conçus pour autoriser.
Ce qu'il faut rechercher :
user_identity, source_ip_address, user_agent, sessionId, request_id et workspace_id vous permettent de suivre ce que l'identifiant fait ensuite.accounts.tokenLogin qui arrivent en rafale courte à partir d'un client inconnu et sont suivis par l'utilisation du même jeton à partir d'une adresse IP source différente. Ce modèle peut indiquer que quelqu'un teste un jeton volé, et requestParams.tokenId vous permet de lier ces événements au même jeton.Ensuite, l'adversaire doit découvrir ce que l'identifiant peut atteindre avant que l'accès ne soit révoqué. Par conséquent, une identité compromise peut passer de son activité ordinaire à l'énumération de données, de secrets, de code et de contrôles réseau en quelques secondes. Cette reconnaissance s'étend généralement sur plusieurs services à la fois et se déplace plus rapidement qu'une personne naviguant dans l'interface utilisateur. Dans notre scénario, cette étape correspond à la rafale d'appels listant les portées de secrets, les catalogues et les dépôts dans les minutes suivant l'utilisation du jeton, ce qui constitue une activité que l'ingénieur n'a jamais effectuée auparavant.
Objectif de l'adversaire : Établir une carte des données accessibles, des identifiants, des dépôts et des barrières de protection pour planifier un chemin plus profond dans l'environnement avant que l'accès ne soit révoqué.
Ce qu'il faut rechercher :
secrets.listScopes / listSecrets, unityCatalog.listMetastores / listCatalogs / listSchemas / listExternalLocations / listStorageCredentials, repos.listRepos, et au niveau du compte accountsManager.listWorkspaceConfigurations / listNetworkConfigurations / listStorageConfigurations. Par exemple, cinq API de découverte distinctes ou plus appelées en une minute ne correspondent probablement pas à une personne naviguant sur la plateforme.SHOW TABLES contre les schémas de contrôle d'accès et de configuration, est plus significative qu'un volume élevé d'appels. Lorsque la journalisation d'audit détaillée est activée, commandSubmit préserve la requête dans commandText.IpAccessDenied d'une identité, en particulier lorsqu'elle suit accounts.oidcTokenAuthorization ou se répète dans les espaces de travail. Dans ce cas, l'autorisation a réussi mais la requête provenait d'un réseau bloqué, ce qui constitue souvent le plus ancien enregistrement d'un identifiant rejoué à partir d'un emplacement non approuvé.La récolte d'identifiants prend généralement plusieurs étapes. L'adversaire liste les portées de secrets, liste les secrets qu'elles contiennent, puis lit ceux qui semblent utiles. La valeur qu'il récupère lui permet de revenir sous une identité différente, souvent dotée de privilèges supérieurs. Pour cette raison, chaque secret lu par une identité suspecte mérite d'être suivi. Dans l'exemple de l'ingénieur de données, l'adversaire lit un secret qui contient un identifiant de principal de service. À partir de ce moment, l'enquête doit suivre deux identités : l'ingénieur et le principal de service.
Objectif de l'adversaire : Récupérer un jeton, une clé d'API ou un secret de principal de service qui fait passer le point d'ancrage initial à un accès à l'échelle de l'environnement sous une nouvelle identité.
À surveiller :
secrets.listScopes de manière isolée est courant et génère du bruit. Cependant, listScopes suivi de listSecrets puis de getSecret, répété sur plusieurs périmètres en peu de temps, indique une collecte de données. listSecrets enregistre le périmètre, et getSecret enregistre à la fois le périmètre et la clé.getSecret refusé sur un périmètre étroitement contrôlé, suivi d'une lecture réussie de la même clé ou d'une clé associée dans un périmètre moins restreint, suggère que l'identité recherche une copie accessible.submitCommand et Databricks SQL commandSubmit peuvent montrer du code appelant des utilitaires de secrets ou exécutant read_files() sur des chemins contenant des informations d'identification. Gardez à l'esprit que le texte soumis montre ce qui a été exécuté, mais ne confirme pas qu'une valeur a été renvoyée.accounts.tokenLogin, une activité de principal de service observée pour la première fois, un changement d'IP ou d'agent utilisateur, ou des appels generateTemporaryTableCredential / generateTemporaryVolumeCredential. Lors de la réponse, renouvelez chaque information d'identification que l'identité a pu atteindre et vérifiez où chacune a été utilisée en plus de l'endroit où elle a été stockée.Une fois l'accès établi, les adversaires cherchent un moyen d'exécuter leur propre code. Sur Databricks, cela se produit généralement par le biais de fonctions définies par l'utilisateur (UDF) et de travaux. Une fonction peut envelopper une charge utile dans du code d'apparence ordinaire qui peut être appelé de manière répétée, et un travail peut exécuter ce code selon une planification sur différents environnements de calcul. Par conséquent, la question clé pour la détection est de savoir si une identité a commencé à effectuer des actions qu'elle n'avait pas réalisées auparavant. Pour en revenir à l'ingénieur de données, une heure après la lecture du secret, le principal de service crée une fonction. Étant donné que le principal de service, plutôt que l'ingénieur, effectue cette action, une recherche limitée à l'activité de l'ingénieur ne la détecterait pas.
Objectif de l'adversaire : Établir un moyen fiable et réutilisable d'exécuter des charges utiles, avec une solution de repli lorsqu'une route de calcul est bloquée.
À surveiller :
function_info dans system.access.audit est masqué, sauf pour les administrateurs de compte et databricks_pii_access, associez donc les données d'audit aux inventaires de fonctions.importNotebook, puis changeJobAcl, Jobs create, runNow et getRunOutput. Ces événements préservent rarement le corps du carnet, conservez donc les versions des carnets et les configurations de travaux à leurs côtés. Une activité répétée d'importation et d'exécution provenant d'une seule source constitue un signal plus fort que l'une ou l'autre action prise isolément.submitRun suivie peu de temps après par startWarehouse, ou par un nouveau travail sur un autre calcul, peut indiquer qu'un adversaire contourne un chemin bloqué. Les codes de réponse et le court intervalle entre les événements sont ce qui sépare cette séquence des erreurs de routine. Le calcul sans serveur est une solution de repli courante.Disposant d'un moyen d'exécuter du code, les adversaires tentent ensuite de s'assurer qu'ils pourront revenir après la révocation du justificatif d'origine. Les méthodes de persistance courantes incluent les attributions d'accès, les jetons nouvellement créés, les modifications de l'appartenance aux groupes et aux espaces de travail, ainsi que les modifications du plan de contrôle. Le signal le plus utile est une modification sensible effectuée par une identité ou un contexte d'exécution non familier. Par exemple, une modification de permission effectuée depuis l'intérieur d'un travail mérite plus d'attention que la même modification effectuée par un administrateur dans la console. Ensuite dans le scénario, le principal de service s'ajoute à un groupe d'administrateurs. Même si le jeton de l'ingénieur est révoqué, cette appartenance au groupe maintient l'accès de l'adversaire en place.
Objectif de l'adversaire : Créer des chemins d'accès durables et indépendants qui survivent à la révocation du justificatif compromis.
À surveiller :
putAcl sur un périmètre de secret, updatePermissionAssignment, addPrincipalToGroup ou setAdmin. Soyez particulièrement attentif lorsqu'un principal de service accorde l'accès à une autre identité, ou lorsque plusieurs attributions se produisent sur une courte période.setSetting / deleteSetting, les modifications de la liste d'accès IP et createPrivateAccessSettings. Examinez la modification demandée, la réponse et la source avant de conclure si un contrôle a réellement été contourné. Examinez également les modifications de groupe SCIM provenant d'une source autre que le fournisseur d'identité attendu.generateDbToken provenant d'une source non familière ou lors de l'exécution d'un travail. Chaque jeton résultant est un justificatif distinct qui devra être révoqué.run_by, run_as et la fenêtre d'exécution attendue. Si un travail continue de modifier des groupes, des permissions ou des paramètres après l'arrêt de l'activité interactive de l'adversaire, il se peut qu'il maintienne l'accès de manière autonome. Conservez la définition du travail et les artefacts avant de le terminer.La collecte de données peut se limiter à quelques exportations ciblées, et le nettoyage peut impliquer plus que la simple suppression de fichiers. Surveillez les exportations ciblées, les demandes de justificatifs temporaires, la suppression d'outils à durée de vie courte et les commandes obscurcies qui rendent l'activité plus difficile à reconstituer. Chacun de ces événements peut sembler routinier, de sorte que la séquence qui les entoure importe plus que l'exportation ou la suppression individuelle. Enfin, le principal de service de notre scénario exporte une poignée de scripts d'initialisation. En soi, il s'agit d'une petite exportation. Cependant, comme elle fait suite à la lecture d'un secret et à une nouvelle fonction provenant du même principal de service, elle doit faire l'objet d'une enquête dans le cadre de la même intrusion.
Objectif de l'adversaire : S'emparer des données importantes et effacer les outils les plus évidents tout en laissant en place un accès plus discret.
À surveiller :
workspaceExport enregistre le chemin, le format et s'il s'agissait d'un téléchargement direct. Donnez la priorité aux exportations effectuées par des identités non familières, vers des chemins inhabituels ou dans des formats inhabituels, à partir de réseaux jusqu'alors invisibles, ou qui font suite à un accès aux secrets ou à une nouvelle exécution. Une petite exportation ciblée de scripts d'initialisation peut fuiter davantage qu'un vidage SOURCE en bloc.createFunction suivi de deleteFunction pour la même fonction au cours d'une même session, ou un cycle répété de création, suppression et recréation, peut indiquer une tentative de suppression de traces. Conservez les définitions et l'horodatage avant d'annuler quoi que ce soit. Les objets qui persistent ont souvent des noms plus plausibles que ceux qui ont été supprimés.generateTemporaryTableCredential, generateTemporaryVolumeCredential, Delta Sharing, lectures sur le stockage cloud) aux activités de reconnaissance initiales. Les commandes encodées ou scriptées sont trop courantes pour générer une alerte à elles seules, alors corrélez-les avec un agent utilisateur inconnu, un calendrier de type automatisé, un accès secret ou de nouvelles fonctions.En vous appuyant sur la chaîne d'attaque basée sur les identifiants, vous pouvez guider Genie pour parcourir les différentes étapes de l'attaque sans avoir à rédiger chaque requête à partir de zéro. Chaque détection de cet article s'appuie sur la télémétrie dont vous disposez déjà. Databricks écrit l'activité du plan de contrôle dans la table système system.access.audit.
Pour commencer, installez l'application de détection, qui ajoute un agent Genie pour la journalisation d'audit de Databricks. Vous pouvez l'utiliser depuis Genie One de deux manières :
Gardez deux limites à l'esprit. Tout d'abord, un résultat vide ne signifie pas que rien ne s'est produit. L'événement se trouve peut-être en dehors de votre fenêtre temporelle, ou la journalisation d'audit détaillée est peut-être désactivée. Ensuite, les journaux d'audit enregistrent qu'un changement a eu lieu et qui l'a effectué, mais rarement les anciennes ou les nouvelles valeurs.
Une fois qu'une investigation met en évidence une identité qui ne correspond pas à son profil habituel, l'attention se porte sur les accès dont l'adversaire dispose encore. Les attaques basées sur les identifiants n'étant pas linéaires, le premier accès découvert est rarement le seul. Dans l'exemple de l'ingénieur data, la révocation du jeton de l'ingénieur laisserait en place les identifiants du principal de service, son appartenance au groupe d'administrateurs et la fonction qu'il a créée. Une réponse complète supprime les identifiants d'origine ainsi que tous les chemins créés par la suite par l'adversaire, y compris les attributions, les jetons, les fonctions et les tâches qui continuent de s'exécuter après la désactivation de l'utilisateur.
En cas de compromission suspectée d'un espace de travail, les équipes de réponse doivent :
Pour reprendre l'analogie du bâtiment de bureaux : l'entrée basée sur le contexte décide qui franchit les portes tournantes, et le principe du moindre privilège détermine les étages auxquels leur badge donne accès. Une détection précoce offre un temps de réaction précieux, mais les contrôles préventifs limitent l'impact potentiel d'un identifiant volé. Les contrôles ci-dessous sont regroupés selon ce qu'ils retirent à l'adversaire, approximativement dans l'ordre où ils brisent sa chaîne d'attaque.

Le contrôle préventif le plus efficace contre la réutilisation d'identifiants est le contrôle d'entrée basé sur le contexte. Il évalue l'émetteur d'une requête, son origine et son objectif, au lieu de se reposer sur un périmètre réseau unique. C'est particulièrement utile à l'heure où de plus en plus d'organisations se passent de VPN. Même sans réseau d'entreprise sur lequel s'appuyer, vous pouvez limiter un jeton volé aux contextes réellement utilisés par son propriétaire. Par exemple, vous pouvez restreindre un principal de service privilégié aux requêtes d'API provenant de réseaux de confiance tout en appliquant une politique différente aux utilisateurs humains.
system.access.inbound_network, protégez d'abord les principaux de service privilégiés, puis appliquez les règles une fois que vous avez pris en compte l'automatisation légitime et les intégrations de partenaires.N'oubliez pas que l'impact d'un identifiant volé dépend uniquement des privilèges qui lui sont attribués. Réduisez cette exposition et soyez capable de rechercher des activités anormales en procédant ainsi :
(Cet article de blog a été traduit à l'aide d'outils basés sur l'intelligence artificielle) Article original
Abonnez-vous à notre blog et recevez les derniers articles directement dans votre boîte mail.