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ör notebook-filer på Microsoft Sentinel datasjö.
- Jupyter-tillägget för Visual Studio Code.
- Microsoft Sentinel datasjö som konfigurerats med lämpliga behörigheter. Mer information finns i Publicera för att Microsoft Sentinel datasjö.
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 Inmatning av tillgångsdata i Microsoft Sentinel datasjö.
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:
| Graph-åtgärd | Behörigheter som krävs |
|---|---|
| Modellera och skapa en notebook-graf | Använd en anpassad Microsoft Defender XDR enhetlig RBAC-roll med databehörigheter (hantera) över Microsoft Sentinel datainsamling. |
| 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 efter ett beständiga diagram | Använd en anpassad Microsoft Defender XDR enhetlig RBAC-roll med behörigheter för grundläggande säkerhetsdata (läsbehörighet) över Microsoft Sentinel datainsamling. |
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. Om du vill skapa en graf får du inte begränsas av ett Sentinel omfång. En begränsad användare kan inte skapa en anpassad graf.
Microsoft Entra ID roller ger bred åtkomst till 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
- Spara det anpassade diagrammet genom att schemalägga ett diagramjobb
- 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-fil och anslut till 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 till genom att välja triangelikonen för körningscellen 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
I följande exempel skapas ett diagram för att bläddra Microsoft Entra gruppmedlemskap och förstå kapslade grupprelationer. 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 från valfri tabell som är tillgänglig i Sentinel datasjö.
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 grafschemat och bind till dataramarna som skapades i föregående steg
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. Information om hur du sparar diagrammet för återanvändning och delning finns i Spara din anpassade graf
Nu har du skapat ett diagram i notebook-filen.
Om du vill visa en visuell representation av diagrammet klistrar du in och kör följande kod i en ny cell:
# 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 där grafdata uppdateras regelbundet väljer du Schemalagd i 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 Start i tid för att schemat ska börja köras.
Välj ett Slut i tid för att 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 finns i tidszonen.
Välj Skicka för att spara jobbkonfigurationen och publicera jobbet. Grafens byggprocess 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. Statusen ändras till I kö och sedan "Pågår" 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).