Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Anpassade grafer i Microsoft Sentinel göra det möjligt för säkerhetsforskare och analytiker att skapa skräddarsydda grafrepresentationer av sina säkerhetsdata. Genom att skapa anpassade grafer kan du modellera specifika attackmönster, undersöka hot och köra avancerade grafalgoritmer för att upptäcka dolda relationer i din digitala miljö. Den här guiden vägleder dig genom stegen för att skapa och hantera anpassade grafer med hjälp av Jupyter Notebooks i Microsoft Sentinel Visual Studio Code-tillägget.
Den här artikeln fokuserar på att manuellt redigera anpassade grafer med hjälp av kod. En AI-driven upplevelse finns i AI-assisterad anpassad grafredigering i Microsoft Sentinel.
Förhandskrav
Följande krävs för att skapa anpassade grafer i Microsoft Sentinel:
- Microsoft Sentinel tillägg för Visual Studio Code. Mer information finns i Köra notebook-filer i Microsoft Sentinels datasjö.
- Jupyter-tillägget för Visual Studio Code.
- Microsoft Sentinel-datasjö är konfigurerad med rätt behörigheter. Mer information finns i Anslut till Microsoft Sentinel-data lake.
Aktivera Microsoft Entra ID-anslutningsappen för att mata in de Microsoft Entra tillgångstabeller som används i den här artikelns exempelkod. Mer information finns i Insamling av resursdata i Microsoft Sentinel-datasjön.
Behörigheter
Om du vill interagera med anpassade grafer behöver du följande XDR-behörigheter i Sentinel datasjö. I följande tabell visas behörighetskraven för vanliga grafåtgärder:
| Grafåtgärd | Behörigheter som krävs |
|---|---|
| Modellera och bygg en anteckningsboksgraf | Använd en anpassad enhetlig RBAC-roll i Microsoft Defender XDR med behörigheten data (hantera) för Microsoft Sentinel-datainsamlingen. |
| Spara ett diagram i klientorganisationen | Använd någon av följande Microsoft Entra ID roller: Säkerhetsoperatör Säkerhetsadministratör Global administratör |
| Fråga en sparad graf | Använd en anpassad, enhetlig RBAC-roll i Microsoft Defender XDR med behörigheten säkerhetsdatagrunder (läs) för datainsamlingen i Microsoft Sentinel. |
Viktigt
Du måste ha behörighet att läsa de data som används i diagrammet. Om du inte har åtkomst till en specifik datauppsättning inkluderas inte dessa data i diagrammet. För att skapa ett diagram får du inte vara begränsad av en Sentinel-omfattning. En begränsad användare kan inte skapa en anpassad graf.
Microsoft Entra ID-roller ger omfattande åtkomst i alla arbetsytor i datasjön. Mer information finns i Roller och behörigheter i Microsoft Sentinel.
Installera Visual Studio Code och Microsoft Sentinel-tillägget
Skapa anpassade grafer med hjälp av Jupyter Notebooks i Microsoft Sentinel Visual Studio Code-tillägget. Mer information finns i Installera Visual Studio Code och Microsoft Sentinel-tillägget
Skapa en anpassad graf
Utför följande steg för att skapa och arbeta med anpassade grafer:
- Modellera en anpassad graf
- Bevara den anpassade grafen genom att schemalägga ett grafjobb
- Visa och hantera anpassade grafer
Modellera en anpassad graf
Skapa en anpassad graf med hjälp av en Jupyter-anteckningsbok i Microsoft Sentinel Visual Studio Code-tillägget.
Följande steg vägleder dig genom att skapa din första anpassade graf med hjälp av en exempelanteckningsbok.
Konfigurera din notebook och anslut till datasjön
Använd följande steg för att skapa en anteckningsbok och ansluta till Microsoft Sentinel-datasjön.
I Visual Studio Code med tillägget Microsoft Sentinel installerat väljer du ikonen Microsoft Sentinel i den vänstra menyn.
Välj Logga in för att visa diagram
En dialogruta visas med texten Tillägget "Microsoft Sentinel" vill logga in med Microsoft. Välj Tillåt för att logga in.
Logga in med dina autentiseringsuppgifter.
När du har loggat in väljer du + sedan Skapa ny anteckningsbok.
Ge notebook-filen ett namn och spara den på en lämplig plats på din arbetsyta.
Välj Välj kernel längst upp till höger i notebook-fönstret för att välja en Spark-beräkningspool.
Välj Microsoft Sentinel och välj sedan någon av de tillgängliga Spark-poolerna.
Tips
Du kan använda AI-prompter för att skapa en anpassad grafanteckningsbok. Mer information finns i AI-assisterad anpassad grafredigering i Microsoft Sentinel.
Kör en cell genom att välja triangelikonen Kör cell till vänster om cellen. Första gången du kör en cell kan du uppmanas att välja en kernel om du inte redan har valt en.
Första gången du kör en cell tar det ungefär fem minuter att starta Spark-sessionen.
Skapa ett diagram
Följande exempel skapar ett diagram för att kartlägga Microsoft Entra-gruppmedlemskap och förstå relationer mellan nästlade grupper. Exempelkoden hjälper dig att komma igång med ett enkelt användningsfall för att lära dig den anpassade graffunktionen och utnyttja kraften i grafbläddering för dina undersökningar. Du kan skapa ett diagram utifrån valfri tabell i Sentinel-datasjön.
Anslut till din arbetsyta och läs Entra tillgångstabeller för att börja skapa diagrammet.
from pyspark.sql import functions as F from sentinel_lake.providers import MicrosoftSentinelProvider lake_provider = MicrosoftSentinelProvider(spark=spark) # Use the "System tables" workspace which contains the Entra* Assets tables # If you are data is in a different workspace, update this variable accordingly and ensure the tables are present LOG_ANALYTICS_WORKSPACE = "System tables" # Dynamically get the latest snapshot time from EntraUsers snapshot_time = ( lake_provider.read_table("EntraUsers", LOG_ANALYTICS_WORKSPACE) .df.agg(F.max("_SnapshotTime").alias("max_snapshot")) .collect()[0]["max_snapshot"] .strftime("%Y-%m-%dT%H:%M:%SZ") ) print(f"Using snapshot_time: {snapshot_time}") snapshot_filter = (F.col("_SnapshotTime") == F.lit(snapshot_time).cast("timestamp")) # Load EntraMembers - edges: group contains user/group/servicePrincipal df_members = ( lake_provider.read_table("EntraMembers", LOG_ANALYTICS_WORKSPACE) .filter( snapshot_filter & (F.col("sourceType") == "group") & (F.col("targetType").isin("user", "group", "servicePrincipal")) ) ) # Load EntraGroups - nodes df_groups = ( lake_provider.read_table("EntraGroups", LOG_ANALYTICS_WORKSPACE) .filter(snapshot_filter) .select("id", "displayName", "mailEnabled") ) # Load EntraUsers - nodes df_users = ( lake_provider.read_table("EntraUsers", LOG_ANALYTICS_WORKSPACE) .filter(snapshot_filter) .select("id", "accountEnabled", "displayName", "department", "lastPasswordChangeDateTime", "userPrincipalName", "usageLocation") ) # Load EntraServicePrincipals - nodes df_service_principals = ( lake_provider.read_table("EntraServicePrincipals", LOG_ANALYTICS_WORKSPACE) .filter(snapshot_filter) .select("accountEnabled", "id", "displayName", "servicePrincipalType", "tenantId", "organizationId") ) # Fix for Spark 3.x Parquet datetime rebase issue. Required when reading Parquet files # written by Spark 2.x which used the Julian calendar, whereas Spark 3.x uses Proleptic # Gregorian. Without these settings, timestamp columns (e.g. lastPasswordChangeDateTime) # may throw errors or return incorrect values. Safe to remove if all data was written by # Spark 3.x (typical for current Fabric/Sentinel environments). spark.conf.set("spark.sql.parquet.datetimeRebaseModeInRead", "CORRECTED") spark.conf.set("spark.sql.parquet.datetimeRebaseModeInWrite", "CORRECTED") spark.conf.set("spark.sql.parquet.int96RebaseModeInRead", "CORRECTED") spark.conf.set("spark.sql.parquet.int96RebaseModeInWrite", "CORRECTED")Förbereda noden och gränsdataramarna som krävs för att skapa grafen
# ============================================================ # NODE PREPARATION # ============================================================ # EntraUser nodes - keyed by user id user_nodes = ( df_users.df .select( F.col("id"), F.col("displayName"), F.col("accountEnabled"), F.col("department"), F.col("lastPasswordChangeDateTime"), F.col("userPrincipalName"), F.col("usageLocation") ) ) # EntraGroup nodes - keyed by group id group_nodes = ( df_groups.df .select( F.col("id"), F.col("displayName"), F.col("mailEnabled") ) ) # EntraServicePrincipal nodes - keyed by SP id sp_nodes = ( df_service_principals.df .select( F.col("id"), F.col("displayName"), F.col("accountEnabled"), F.col("servicePrincipalType"), F.col("tenantId"), F.col("organizationId") ) ) # ============================================================ # EDGE PREPARATION # ============================================================ # Edge: EntraGroup --Contains--> EntraUser edge_group_contains_user = ( df_members.df .filter(F.col("targetType") == "user") .select( F.col("sourceId").alias("SourceGroupId"), F.col("targetId").alias("TargetUserId") ) .distinct() .withColumn("EdgeKey", F.concat_ws("_", F.col("SourceGroupId"), F.col("TargetUserId"))) ) # Edge: EntraGroup --Contains--> EntraGroup (nested groups) edge_group_contains_group = ( df_members.df .filter(F.col("targetType") == "group") .select( F.col("sourceId").alias("SourceGroupId"), F.col("targetId").alias("TargetGroupId") ) .distinct() .withColumn("EdgeKey", F.concat_ws("_", F.col("SourceGroupId"), F.col("TargetGroupId"))) ) # Edge: EntraGroup --Contains--> EntraServicePrincipal edge_group_contains_sp = ( df_members.df .filter(F.col("targetType") == "servicePrincipal") .select( F.col("sourceId").alias("SourceGroupId"), F.col("targetId").alias("TargetSPId") ) .distinct() .withColumn("EdgeKey", F.concat_ws("_", F.col("SourceGroupId"), F.col("TargetSPId"))) )Definiera ditt grafschema och koppla det till de nod- och kant-DataFrame som du förberedde tidigare i den här proceduren
from sentinel_graph import GraphSpecBuilder, Graph # Define the graph schema entra_group_graph_spec = ( GraphSpecBuilder.start() # === NODES === .add_node("EntraUser") .from_dataframe(user_nodes) # Native Spark DataFrame (from .df + .select + .distinct) .with_columns( "id", "displayName", "accountEnabled", "department", "lastPasswordChangeDateTime", "userPrincipalName", "usageLocation", key="id", display="displayName" ) .add_node("EntraGroup") .from_dataframe(group_nodes) # Native Spark DataFrame .with_columns( "id", "displayName", "mailEnabled", key="id", display="displayName" ) .add_node("EntraServicePrincipal") .from_dataframe(sp_nodes) # Native Spark DataFrame .with_columns( "id", "displayName", "accountEnabled", "servicePrincipalType", "tenantId", "organizationId", key="id", display="displayName" ) # === EDGES === # EntraGroup --ContainsUser--> EntraUser .add_edge("ContainsUser") .from_dataframe(edge_group_contains_user) # Native Spark DataFrame .source(id_column="SourceGroupId", node_type="EntraGroup") .target(id_column="TargetUserId", node_type="EntraUser") .with_columns("SourceGroupId", "TargetUserId", "EdgeKey", key="EdgeKey", display="EdgeKey") # EntraGroup --ContainsGroup--> EntraGroup (nested groups) .add_edge("ContainsGroup") .from_dataframe(edge_group_contains_group) # Native Spark DataFrame .source(id_column="SourceGroupId", node_type="EntraGroup") .target(id_column="TargetGroupId", node_type="EntraGroup") .with_columns("SourceGroupId", "TargetGroupId", "EdgeKey", key="EdgeKey", display="EdgeKey") # EntraGroup --ContainsServicePrincipal--> EntraServicePrincipal .add_edge("ContainsServicePrincipal") .from_dataframe(edge_group_contains_sp) # Native Spark DataFrame .source(id_column="SourceGroupId", node_type="EntraGroup") .target(id_column="TargetSPId", node_type="EntraServicePrincipal") .with_columns("SourceGroupId", "TargetSPId", "EdgeKey", key="EdgeKey", display="EdgeKey") ).done()Verifiera grafschemat
# Check the schema of the graph spec to ensure it's correct entra_group_graph_spec.show_schema()Skapa grafen, inklusive att förbereda data och publicera grafen
# Build the graph from the spec - this will validate the spec and prepare it for querying # Alter options is to use Graph.prepare() to prepare the graph nodes and edges in the lake # and then use Graph.publish() to create the graph. You would typically call prepare() and publish() # seperately to understand the cost of Graph API calls that are triggeterd by Graph.publish() # see https://learn.microsoft.com/azure/sentinel/billing?tabs=simplified%2Ccommitment-tiers intra_group_graph = Graph.build(entra_group_graph_spec)Obs!
Diagram som skapas under interaktiva notebook-sessioner tas bort när notebook-sessionen stängs. Om du vill spara grafen för återanvändning och delning, se Spara din anpassade graf
Nu har du skapat ett diagram i anteckningsboken.
Följande Python-exempel kör en Graph Query Language (GQL)-fråga mot den graf du just skapade för att utforska nästlade grupprelationer. Använd sådana här frågor efter grafskapandet för att navigera i medlemshierarkier och upptäcka indirekta åtkomstvägar. För att testa, klistra in koden i en ny anteckningscell och kör den. Detta exempelfråga går igenom nästlade Microsoft Entra-gruppmedlemskap upp till åtta nivåer djupt och visar de resulterande relationerna:
# Query 1: Find nested group relationships nexting up to 8 levels deep
# Update the Entra Group name that you want to traverse from
query_nested_groups = """
MATCH p=(g1:EntraGroup)-[cg]->{1,8}(g2)
WHERE g1.displayName = 'tmplevel3'
RETURN *
"""
intra_group_graph.query(query_nested_groups).show()
Den här koden kör ett exempel på en GQL-fråga (Graph Query Language) för att hämta alla kapslade gruppmedlemskap upp till 8 nivåer djupt Det resulterande diagrammet visualiseras i utdata
Spara din anpassade graf
När du har skapat grafkoden i notebook-filen kan du köra notebook-filen i en interaktiv session eller schemalägga ett diagramjobb. Diagram som skapas under den interaktiva notebook-sessionen är tillfälliga och är endast tillgängliga i kontexten för notebook-sessionen. Om du vill spara grafen och dela med ditt team schemalägger du ett grafjobb för att återskapa grafen ofta. När grafen har sparats är den tillgänglig från: grafupplevelsen i Microsoft Defender-portalen under Sentinel, Visual Studio Code Notebooks och Graph-fråge-API:er.
I din diagramanteckningsbok väljer du Skapa schemalagt jobb och sedan Skapa ett diagramjobb.
I formuläret Skapa diagramjobb anger du Graph-namnet och Beskrivning och kontrollerar att rätt diagramanteckningsbok ingår i Sökväg.
Om du vill skapa grafen utan att konfigurera ett uppdateringsschema väljer du På begäran i avsnittet Schema och väljer sedan Skicka för att skapa diagrammet.
Obs!
Grafer som skapas med schema på begäran har standardkvarhållning på 30 dagar och tas bort vid förfallodatum.
Om du vill skapa grafen med regelbundet uppdaterade diagramdata väljer du Schemalagd under avsnittet Schema.
Välj en Upprepningsfrekvens för jobbet. Du kan välja mellan Per minut, Varje timme, Varje vecka, Varje dag eller Varje månad.
Fler alternativ visas för att konfigurera schemat, beroende på vilken frekvens du väljer. Till exempel veckodag, tid på dagen eller dag i månaden.
Välj en starttid för när schemat ska börja köras.
Välj en Sluttid då schemat ska sluta köras. Om du inte vill ange en sluttid för schemat väljer du Ange jobb som ska köras på obestämd tid. Datum och tider visas i din tidszon.
Välj Skicka för att spara jobbkonfigurationen och publicera jobbet. Processen för att skapa grafen startar i din klientorganisation. Visa det nyligen skapade diagrammet och dess senaste status i Sentinel-tillägget.
Visa och hantera anpassade grafer
När du har skapat ett grafjobb kan du visa och hantera diagrammet i din klientorganisation från Microsoft Sentinel-tillägget i Visual Studio Code.
I listan med grafer väljer du den materialiserade grafen för att visa dess information.
Välj fliken Jobbinformation för att visa status för grafjobbet, inklusive senaste körningstid, nästa körningstid och eventuella fel som påträffades under byggprocessen.
Välj Kör nu för att manuellt utlösa en grafversion utanför de schemalagda tiderna. Status ändras först till I kö och sedan till "Pågående" medan grafen skapas.
När grafversionen är klar uppdateras statusen till Klar. Välj fliken Diagraminformation för att visa information om diagrammet.
Nu kan du fråga och visualisera grafen från grafvisualiseringen i Microsoft Sentinel i Defender-portalen. Mer information finns i Visualisera grafer i Microsoft Sentinel graf (förhandsversion).
Uppdatera anpassade grafer
När du har uppdaterat diagramkoden för notebook-filer kör du anteckningsboken lokalt för att verifiera ändringarna innan du uppdaterar ett diagramjobb.
Redigera befintlig anpassad grafinformation
Använd det här arbetsflödet för att redigera ett befintligt diagramjobb.
I panelen Visual Studio Code Microsoft Sentinel Graph väljer du Redigera diagramjobb för diagrammet som du vill uppdatera och går sedan till Diagramnamn>Jobbinformation.
Uppdatera de fält som du vill ändra:
- Grafnamn (valfritt). När du uppdaterar grafnamnet skapas en ny graf i din klientorganisation. Det befintliga diagrammet förblir oförändrat.
- Beskrivning (valfritt). När du uppdaterar beskrivningen ersätts den aktuella diagrambeskrivningen och grafen återskapas.
- Klusterkonfiguration (valfritt). När klusterkonfigurationen uppdateras ändras beräkningsstorleken och diagrammet återskapas.
- Jobbfrekvens (valfritt). När jobbfrekvensen uppdateras ändras det återkommande schemat och diagrammet återskapas.
Skriv över ett befintligt anpassat diagram
Använd det här arbetsflödet när du vill återskapa ett diagram och skriva över ett befintligt diagram med samma namn.
Öppna den uppdaterade notebooken.
Välj Skapa schemalagt jobb i Sentinel-notebook-miljön och välj sedan Skapa ett diagramjobb.
Ange ett diagramnamn i formuläret Skapa graf .
- Om du anger ett nytt diagramnamn skapas ett nytt diagram i klientorganisationen och det befintliga diagrammet förblir tillgängligt.
- Om du återanvänder ett befintligt diagramnamn för klientorganisationen, skrivs det befintliga diagrammet över efter att du har bekräftat detta. Grafnamn är unika, dubbletter av grafnamn stöds inte.
Kontrollera att Path pekar på den uppdaterade anteckningsboken.
Uppdatera beskrivningen för diagrammet.
Välj Klusterkonfiguration och Jobbfrekvens, ungefär som när du skapar ett nytt diagram.
Uppdatera schemainformationen om det behövs.
Uppdatera fältet Beskrivning igen efter behov.
Välj Skicka för att återskapa grafen i din klientorganisation.