Threat Stack est désormais F5 Distributed Cloud App Infrastructure Protection (AIP). Commencez à utiliser Distributed Cloud AIP avec votre équipe dès aujourd'hui .
Tous ceux qui ont travaillé dans les domaines des opérations, de l’ingénierie ou de la sécurité ont eu à un moment donné un ou plusieurs serveurs présentant un comportement inattendu. Il peut s'agir d'exécuter des processus étranges, de consommer plus de mémoire que prévu, d'accepter des requêtes, d'établir des connexions à GitHub, etc.
La première étape pour trier un événement est de savoir que vous en avez un. Il existe un certain nombre de sources de données qui peuvent potentiellement vous orienter vers un serveur hôte particulier :
À ce stade, il y a un serveur sur lequel nous souhaitons accéder et obtenir plus d'informations. En supposant que chaque élément de données système ne correspond pas nécessairement à notre SIEM, l’étape logique suivante consiste à se connecter à l’hôte et à commencer à interroger directement le système d’exploitation pour savoir ce qu’il fait. Selon votre niveau de familiarité avec l'environnement, cela peut être aussi large que des outils comme uname et vmstat jusqu'à des éléments plus spécifiques comme ps et lsof. Dans les deux cas, vous verrez ce que fait actuellement l'hôte. Voici le problème avec ce processus : En fait, vous ne vous souciez pas de l’état actuel ; vous voulez savoir ce qui a changé. Tout comme lorsque vous recevez une demande d’extraction dans Git, vous ne souhaitez pas examiner l’ensemble de la base de code, mais uniquement les parties qui ont été modifiées.
Ici, dans le cadre du programme Threat Stack Cloud SecOps℠, les analystes de sécurité de notre SOC ont développé une solution pour nous aider à répondre à ces types de questions pour nos clients. La plateforme Threat Stack Cloud Security Platform® dispose de cette fonctionnalité astucieuse que nous appelons la portabilité des données. À un niveau élevé, cela nous permet de prendre la télémétrie que nous collectons auprès des hôtes, y compris des éléments tels que les exécutables en cours d'exécution, les utilisateurs, les arguments de ligne de commande, les connexions, etc. et de les stocker dans des buckets S3.
L’avantage des blobs S3 est qu’ils constituent un moyen peu coûteux de stocker de très grandes quantités de données. Le problème est d’exploiter une grande quantité de données non indexées. À cette fin, nous avons fini par utiliser Amazon EMR pour créer des notebooks Jupyter PySpark afin d’utiliser Apache Spark DataFrames et Python pandas DataFrames pour créer un outil puissant permettant de comparer l’état actuel d’une machine à tout état antérieur que nous avons en conservation.
Voici quelques remarques avant de regarder nos exemples de code. Les tables et les références de schéma sont conservées dans AWS Glue et correspondent au format d'événement brut de Threat Stack pour les systèmes Linux . Vous pouvez ajouter ces données à votre lac de données existant. Ensuite, il existe un paramètre défini pour le cluster Spark qui lui indique de lire à partir de Glue pour savoir quelles tables et colonnes sont disponibles. Ensuite, lorsqu’un cluster est créé, vous pouvez référencer la table dans le notebook JupyterLab.
Note: Le code suivant est totalement réel ; la situation est artificielle. Un analyste de sécurité a été chargé de compromettre un hôte sur lequel notre agent était exécuté à un moment donné le jour de la Saint-Valentin. Le but était de comprendre ce qui avait été fait.
Les premières choses que nous devons créer sont notre SparkSession et SparkContext. Heureusement, lorsque nous utilisons un notebook PySpark, ceux-ci sont automatiquement instanciés lorsque nous exécutons notre première cellule.
Configuration de notre notebook PySpark.
Nous avons obtenu un objet spark auquel nous ferons référence plus tard, et nous avons également obtenu sc, qui est notre contexte spark. Nous pouvons ensuite l'utiliser pour charger pandas et Matplotlib .
Installation des packages.
Dans cette étape suivante, je vais confirmer les noms de colonnes en créant un spark.table()
basé sur les tables Glue, puis afficher mon schéma hérité.
Lecture de la structure de nos colonnes chargées depuis AWS Glue.
Génial, maintenant je peux voir quelles colonnes et quels types sont disponibles pour commencer à exécuter mes requêtes SQL. Je peux désormais prendre n'importe quel serveur et n'importe quelle plage horaire que je souhaite et les comparer. Ici, je crée deux Spark DataFrames, rassemblant les données dont j'aurai besoin pour effectuer une enquête pré-incident et une analyse médico-légale post-incident :
SÉLECTIONNEZ date_key, horodatage, tsEventType, appel système, connexion, utilisateur, commande, exe, args DANS compact.audit_v4 OÙ date_key >= '2020-02-05-00' ET date_key < '2020-02-14-00' ET organization_id = '5a8c4a54e11909bd290021ed' ET agent_id = 'b0f6bdb2-9904-11e9-b036-25972ec55a45' GROUP BY date_key, horodatage, tsEventType, appel système, connexion, utilisateur, commande, exe, args SÉLECTIONNEZ date_key, horodatage, tsEventType, appel système, connexion, utilisateur, commande, exe, args DANS compact.audit_v4 OÙ date_key >= '2020-02-14-00' ET date_key < '2020-02-17-00' ET organization_id = '5a8c4a54e11909bd290021ed' ET agent_id = 'b0f6bdb2-9904-11e9-b036-25972ec55a45' GROUP BY date_key, horodatage, tsEventType, appel système, connexion, utilisateur, commande, exe, args
Regrouper les données autour de notre date de compromis du 14 février. (Certaines cellules du bloc-notes sont affichées ici sous forme de GitHub Gists pour plus de lisibilité.)
Maintenant, pour un contrôle rapide de la quantité de données que j'ai collectées :
Compter le nombre d'enregistrements dans les deux Spark DataFrames pour garantir une quantité raisonnable pour l'enquête.
Cela semble juste. J'ai une plage de temps beaucoup plus large pour mon preCompromiseDf
par rapport à mon postCompromiseDf
. (Le « Df » sert à m’aider à me rappeler qu’il s’agit d’objets Spark DataFrame — simplement une convention de dénomination.)
Les DataFrames Apache Spark sont intéressants car ils stockent l'intégralité du DataFrame sur le cluster. C'est idéal pour les ensembles de données volumineux, mais dans ce cas, j'ai en fait un nombre relativement petit d'enregistrements que je souhaite comparer. À cette fin, j'exécute toPandas()
pour déplacer ces données dans la mémoire de mon ordinateur portable, ce qui permettra un calcul plus rapide.
Comme nous ne traitons pas de « big data », dans ce cas, il est plus rapide d’exécuter le reste de notre analyse localement.
Maintenant, je peux commencer à faire des choses puissantes, comme vérifier quels sont les nouveaux exécutables en cours d'exécution sur ce serveur depuis minuit le 14 février.
/tmp/EXCITÉ_PENDANT /usr/bin/wget /tmp/FRONT_RUN /tmp/COMBIN_INHABITUEL /tmp/VERROUILLAGE_ENVIRONNANT /tmp/nmap /usr/bin/scp /tmp/sliver /tmp/sliver2 /tmp/POUCE_PROUVÉE
Une liste des exécutables exécutés sur le serveur pendant la nuit en question.
Eh bien, bonjour, quelques noms d'exécutables aléatoires en majuscules : nmap, scp, wget et quelque chose appelé sliver. Une petite recherche sur Google révèle que Sliver est très probablement associé à https://github.com/BishopFox/sliver et qu'il s'agit d'un framework d'implant qui prend en charge la commande et le contrôle sur plusieurs protocoles.
J'ai la preuve dont j'ai besoin que mon serveur a été compromis, mais je veux faire preuve de diligence raisonnable et voir ce qui a réellement été fait avec ces exécutables. En utilisant ma liste comme filtre sur le même DataFrame, je peux extraire d’autres détails et indicateurs de compromission (IoC) :
arguments exe 80 /tmp/EXCITED_WHILE ./EXCITED_WHILE 162 /usr/bin/wget wget https://github.com/andrew-d/static-binari... 255 /tmp/EXCITÉ_PENDANT ./EXCITÉ_PENDANT 256 /tmp/COURSE_AVANT ./COURSE_AVANT 359 /tmp/COMBIN_INHABITUEL ./COMBIN_INHABITUEL 360 /tmp/VERROU_ENVIRONNEMENT ./VERROU_ENVIRONNEMENT 464 /tmp/nmap 494 /tmp/VERROU_ENVIRONNEMENT ./VERROU_ENVIRONNEMENT 533 /tmp/EXCITÉ_PENDANT ./EXCITÉ_PENDANT 589 /tmp/COURSE_AVANT ./COURSE_AVANT 603 /tmp/EXCITÉ_PENDANT ./EXCITÉ_PENDANT 658 /tmp/EXCITÉ_PENDANT ./EXCITÉ_PENDANT 660 /tmp/COURSE_AVANT ./COURSE_AVANT 671 /usr/bin/scp scp -t /tmp/ 699 /tmp/VERROU_ENVIRONNEMENT ./VERROU_ENVIRONNEMENT 738 /tmp/COMBIN_INHABITUEL ./COMBIN_INHABITUEL 762 /tmp/sliver ./sliver 816 /tmp/VERROU_ENVIRONNEMENT ./VERROU_ENVIRONNEMENT 834 /tmp/sliver2 ./sliver2 878 /tmp/nmap /tmp/nmap 909 /tmp/EXCITÉ_PENDANT ./EXCITÉ_PENDANT 937 /tmp/FRONT_RUN ./FRONT_RUN 992 /tmp/FRONT_RUN ./FRONT_RUN 1023 /tmp/FRONT_RUN 1040 /usr/bin/scp scp -t /tmp/ ...
Extraction de tous les arguments associés à ma liste d'exécutables suspects.
Donc, scp a été utilisé pour déplacer des fichiers, wget a récupéré du code de GitHub (aller à cette ligne me montre que c'est ainsi que nmap est arrivé sur le système), et les détails de l'exécution de ces autres fichiers sont contenus dans le fichier lui-même, car ils n'ont reçu aucun argument de ligne de commande. À ce stade, il est logique de prendre un instantané de l’hôte à titre de preuve et de mettre fin à l’instance.
L’étape finale consiste à confirmer qu’aucun autre hôte de l’environnement n’a été compromis. Pour cela, nous allons prendre quelques éléments de notre liste IoC précédente et les vérifier sur tous les serveurs.
SÉLECTIONNEZ date_key, horodatage, tsEventType, appel système, connexion, utilisateur, commande, exe, args, agentId, tty, session, cwd DE compact.audit_v4 OÙ date_key >= '2020-01-01' ET date_key <= '2020-02-29' ET organization_id = '5a8c4a54e11909bd290021ed' ET tsEventType = 'audit' ET syscall = 'execve' GROUP BY date_key, horodatage, tsEventType, appel système, connexion, utilisateur, commande, exe, args, agentId, tty, session, cwd
52
Cette requête renvoie 52 résultats sur l'ensemble de l'environnement pour une activité nmap et sliver suspecte. Nous pouvons affiner davantage cette vue en passant à un DataFrame pandas et en regroupant les résultats par serveur :
Merci d'être resté avec moi tout au long de ce post. Je suis très enthousiasmé par les possibilités offertes par ces données et par la recherche de nouvelles façons de les explorer. Si vous utilisez actuellement la plateforme Threat Stack, vous pouvez configurer votre propre portabilité des données en utilisant cette documentation comme guide. L’avantage est que vous pouvez décider du niveau de données approprié à conserver pour vos propres besoins professionnels.
Pour les personnes qui utilisent notre service Threat Stack Oversight℠, nous disposons de 30 jours de données d’événements et sommes heureux de travailler avec vous pour fournir une analyse plus approfondie de votre environnement en exploitant cet ensemble d’outils au cas où vous ne disposeriez pas d’un lac de données.
La prochaine étape pour l’équipe Threat Stack Security Operations consiste à commencer à chercher à intégrer davantage de graphiques et de diagrammes pour aider à analyser les données visuellement dans le cadre de notre prochaine analyse à l’aide de cahiers de science des données. Nous en dirons plus à ce sujet, mais voici un premier passage sur quelques IP géolocalisées (la densité de chaque cercle indique le nombre de connexions).
D'autres visualisations d'analyse seront bientôt disponibles auprès de l'équipe Threat Stack Security !
Threat Stack est désormais F5 Distributed Cloud App Infrastructure Protection (AIP). Commencez à utiliser Distributed Cloud AIP avec votre équipe dès aujourd'hui .