Microsoft Sentinel özel grafikleri kullanmaya başlama (önizleme)

Microsoft Sentinel'deki özel grafikler, güvenlik araştırmacılarının ve analistlerinin güvenlik verilerinin uyarlanmış grafik gösterimlerini oluşturmasına olanak tanır. Özel grafikler oluşturarak belirli saldırı desenlerini modelleyebilir, tehditleri araştırabilir ve dijital ortamınızdaki gizli ilişkileri ortaya çıkarmak için gelişmiş graf algoritmaları çalıştırabilirsiniz. Bu kılavuz, Microsoft Sentinel Visual Studio Code uzantısındaki Jupyter not defterlerini kullanarak özel graflar oluşturma ve yönetme adımlarında size yol gösterir.

Bu makale, kod kullanarak özel grafikleri el ile yazmaya odaklanır. Yapay zeka odaklı bir deneyim için bkz. Microsoft Sentinel'de yapay zeka destekli özel graf yazma.

Önkoşullar

Microsoft Sentinel'da özel graflar oluşturmak için aşağıdakiler gereklidir:

Bu makalenin örnek kodunda kullanılan Microsoft Entra varlık tablolarını almak için Microsoft Entra ID bağlayıcısını etkinleştirin. Daha fazla bilgi için bkz. Microsoft Sentinel veri gölünde varlık verileri alımı.

İzinler

Özel graflarla etkileşime geçmek için Sentinel data lake'te aşağıdaki XDR izinlerine ihtiyacınız vardır. Aşağıdaki tabloda yaygın graf işlemleri için izin gereksinimleri listelemektedir:

Graf işlemi Gerekli izinler
Not defteri grafiği modelleme ve oluşturma Microsoft Sentinel veri toplaması üzerinde veri (yönetme) izinlerine sahip özel bir Microsoft Defender XDR birleşik RBAC rolü kullanın.
Grafı kiracıda kalıcı olarak kaydetmek Aşağıdaki Microsoft Entra ID rollerinden birini kullanın:
Güvenlik operatörü
Güvenlik yöneticisi
Genel yönetici
Kalıcı grafı sorgulayın Microsoft Sentinel veri toplaması için güvenlik verisi temelleri (okuma) izinlerine sahip özel bir Microsoft Defender XDR birleşik RBAC rolü kullanın.

Önemli

Grafikte kullanılan verileri okuma izinleriniz olmalıdır. Belirli bir veri kümesine erişiminiz yoksa bu veriler grafiğe dahil edilmeyecektir. Graf oluşturmak için Sentinel kapsamıyla kısıtlanmamalısınız. Kapsamı belirlenmiş bir kullanıcı özel grafik oluşturamaz.

Microsoft Entra ID rolleri, veri gölündeki tüm çalışma alanları arasında geniş erişim sağlar. Daha fazla bilgi için bkz. Microsoft Sentinel'de roller ve izinler.

Visual Studio Code ve Microsoft Sentinel uzantısını yükleme

Microsoft Sentinel Visual Studio Code uzantısındaki Jupyter not defterlerini kullanarak özel grafikler oluşturun. Daha fazla bilgi için bkz. Visual Studio Code ve Microsoft Sentinel uzantısını yükleme

Özel grafik oluşturma

Özel grafikler oluşturmak ve bunlarla çalışmak için aşağıdaki adımları tamamlayın:

  1. Özel graf modelleme
  2. Grafik görevini zamanlayarak özel grafiği kalıcı olarak kaydetme
  3. Özel grafikleri görüntüleme ve yönetme

Özel graf modelleme

Microsoft Sentinel Visual Studio Code uzantısında jupyter not defteri kullanarak özel bir grafik oluşturun.

Aşağıdaki adımlar, örnek bir not defteri kullanarak ilk özel grafınızı oluşturma işleminde size yol gösterir.

Not defterinizi ayarlama ve data lake'e bağlanma

Not defteri oluşturmak ve Microsoft Sentinel veri gölüne bağlanmak için aşağıdaki adımları kullanın.

  1. Microsoft Sentinel uzantısının yüklü olduğu Visual Studio Code sol taraftaki menüden Microsoft Sentinel simgesini seçin.

  2. Grafikleri görüntülemek için Oturum aç'ı seçin

  3. 'Microsoft Sentinel' uzantısı Microsoft'u kullanarak oturum açmak istiyor metnini içeren bir iletişim kutusu görüntülenir. Oturum açmak için İzin Ver'i seçin.

  4. Kimlik bilgilerinizle oturum açın.

  5. Oturum açtıktan sonra + seçin, ardından Yeni not defteri oluştur seçin.

  6. Not defteri dosyasını adlandırın ve çalışma alanınızda uygun bir konuma kaydedin.

    Visual Studio Code'daki grafikler için oturum açma sayfasının ekran görüntüsü.

  7. Bir Spark işlem kümesi seçmek için not defteri penceresinin sağ üst köşesindeki Select kernel seçeneğini belirleyin.

  8. Microsoft Sentinel'i seçin, sonra kullanılabilir Spark havuzlarından herhangi birini seçin.

    Visual Studio Code çekirdek seçme sayfasının ekran görüntüsü.

    İpucu

    Özel grafik not defteri oluşturmanıza yardımcı olması için yapay zeka istemlerini kullanabilirsiniz. Daha fazla bilgi için bkz. Microsoft Sentinel'da yapay zeka destekli özel graf yazma.

  9. Hücrenin solundaki üçgen hücre çalıştırma simgesini seçerek bir hücreyi çalıştırın. Bir hücreyi ilk kez çalıştırdığınızda, daha önce bir çekirdek seçmediyseniz bir çekirdek seçmeniz istenebilir.

    İlk kez bir hücre çalıştırdığınızda Spark oturumunu başlatmak yaklaşık beş dakika sürer.

    Visual Studio Code'daki ilk hücrenin çalışmasını gösteren ekran görüntüsü.

Grafik oluşturma

Aşağıdaki örnek, Microsoft Entra grup üyelikleri arasında geçiş yapmak ve iç içe grup ilişkilerini anlamak için bir grafik oluşturur. Örnek kod, özel graf özelliğini öğrenmek ve araştırmalarınız için graf geçişinin gücünden yararlanmak için basit bir kullanım örneğini kullanmaya başlamanıza yardımcı olur. Sentinel veri gölünde bulunan herhangi bir tablodan grafik oluşturabilirsiniz.

  1. Grafı oluşturmaya başlamak için çalışma alanınıza bağlanın ve Entra varlık tablolarını okuyun.

    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")
    
  2. Grafiği oluşturmak için gereken düğüm ve kenar DataFrame'lerini hazırlayın

    # ============================================================
    # 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")))
    )
    
  3. Grafik şemanızı tanımlayın ve bu yordamda daha önce hazırladığınız düğüme ve uç DataFrame'lere bağlanın

    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()
    
  4. Grafik şemasını doğrulama

    # Check the schema of the graph spec to ensure it's correct
    entra_group_graph_spec.show_schema()
    
  5. Verileri hazırlama ve grafiği yayımlama dahil olmak üzere grafiği oluşturma

    # 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)
    

    Not

    Etkileşimli not defteri oturumları sırasında oluşturulan grafikler, not defteri oturumu kapatıldığında kaldırılır. Grafiği yeniden kullanmak ve paylaşmak için Özel grafiğinizi kalıcı olarak kaydetme bölümüne bakın.

Şimdi not defterinde bir grafik oluşturdunuz.

Aşağıdaki Python örneği, az önce oluşturduğunuz grafiğe karşı bir Grafik Sorgu Dili (GQL) sorgusu çalıştırarak iç içe grup ilişkilerini keşfetmektedir. Grafik oluşturulduktan sonra bu tür sorguları kullanarak üyelik hiyerarşilerini aşabilir ve dolaylı erişim yollarını ortaya çıkarabilirsiniz. Denemek için kodu yeni bir not defteri hücresine yapıştırın ve çalıştırın. Bu örnek sorgu, iç içe geçmiş Microsoft Entra grup üyeliklerini sekiz seviyeye kadar aşar ve ortaya çıkan ilişkileri gösterir:

# 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()

Bu kod, 8 düzeye kadar tüm iç içe grup üyeliğini almak için örnek bir Graph Sorgu Dili (GQL) sorgusu çalıştırır Sonuçta elde edilen grafik çıktıda görselleştirilir

Visual Studio Code grafiğin görselleştirmesini gösteren ekran görüntüsü.

Özel grafınızı kalıcı hale geçirme

Not defterinde grafik kodunu oluşturduktan sonra, not defterini etkileşimli bir oturumda çalıştırabilir veya grafik işi zamanlayabilirsiniz. Etkileşimli not defteri oturumu sırasında oluşturulan grafikler geçicidir ve yalnızca not defteri oturumu bağlamında kullanılabilir. Grafınızı kaydetmek ve ekibinizle paylaşmak için grafınızı sık sık yeniden oluşturacak bir graf işi zamanlayın. Graf kaydedildikten sonra buradan erişilebilir: Sentinel, Visual Studio Code Not Defterleri ve Graph sorgu API'leri altındaki Microsoft Defender portalındaki grafik deneyimi.

  1. Grafik not defterinizden Zamanlanmış İş Oluştur'u ve ardından Graf işi oluştur'u seçin.

    Grafik not defterinde zamanlanmış iş oluştur düğmesini gösteren ekran görüntüsü.

  2. Graf işi oluştur formunda Graf adını ve Açıklama'yı girin ve Yol'a doğru graf not defterinin eklendiğini doğrulayın.

  3. Yenileme zamanlaması yapılandırmadan grafı oluşturmak için Zamanlama bölümünde İsteğe bağlı'yı ve ardından Gönder'i seçerek grafiği oluşturun.

    Not

    İsteğe bağlı zamanlama kullanılarak oluşturulan grafiklerin varsayılan saklama süresi 30 gündür ve son kullanma tarihinde silinir.

  4. Graf verilerinin düzenli olarak yenilendiği grafı oluşturmak için Zamanlama bölümünde Zamanlanmış'ı seçin.

    1. İş için bir Yineleme sıklığı seçin. Dakika, Saatlik, Haftalık, Günlük veya Aylık seçeneklerinden birini belirleyebilirsiniz.

    2. Seçtiğiniz sıklık durumuna bağlı olarak zamanlamayı yapılandırmak için daha fazla seçenek görüntülenir. Örneğin haftanın günü, günün saati veya ayın günü.

    3. Zamanlamanın çalışmaya başlaması için bir Başlangıç saati seçin.

    4. Zamanlamanın duracağı bir Bitiş zamanı seçin. Zamanlama için bir bitiş saati ayarlamak istemiyorsanız, İşi süresiz olarak çalışacak şekilde ayarla'yı seçin. Tarihler ve saatler saat diliminizdedir.

    5. İş yapılandırmasını kaydetmek ve işi yayımlamak için Gönder'i seçin. Grafik oluşturma işlemi kiracınızda başlar. yeni oluşturulan grafiği ve en son durumunu Sentinel uzantısında görüntüleyin.

    Graf oluşturma işi sayfasının ekran görüntüsü.

Özel grafikleri görüntüleme ve yönetme

Bir grafik işi oluşturduktan sonra, kiracınızdaki grafiği Visual Studio Code'daki Microsoft Sentinel uzantısından görüntüleyebilir ve yönetebilirsiniz.

  1. Grafikler listesinden, ayrıntılarını görüntülemek için somutlaştırılmış grafiğinizi seçin.

  2. Son çalışma zamanı, sonraki çalışma zamanı ve derleme işlemi sırasında karşılaşılan hatalar dahil olmak üzere grafik işinin durumunu görüntülemek için İş Ayrıntıları sekmesini seçin.

  3. Zamanlanan saatlerin dışında bir graf derlemesini el ile tetiklemek için Şimdi Çalıştır'ı seçin. Durum, Kuyruğa alındı olarak değişir, ardından grafik oluşturulurken "Devam ediyor" olur.

    Visual Studio Code grafik işi ayrıntıları sekmesini gösteren ekran görüntüsü.

  4. Grafik derlemesi tamamlandığında Durum, Hazır olarak güncelleştirilir. Graf hakkındaki bilgileri görüntülemek için Graf Ayrıntıları sekmesini seçin.

    Grafik ayrıntıları sekmesinin ekran görüntüsü.

  5. Artık Defender portalındaki Microsoft Sentinel grafik görselleştirmesinden grafınızı sorgulayabilir ve görselleştirebilirsiniz. Daha fazla bilgi için bkz. Microsoft Sentinel grafiğinde grafikleri görselleştirme (önizleme).

Özel grafikleri güncelleştirme

Not defteri grafik kodunu güncelleştirdikten sonra, grafik işini güncelleştirmeden önce değişikliklerinizi doğrulamak için not defterini yerel olarak çalıştırın.

Mevcut özel graf ayrıntılarını düzenleme

Mevcut bir grafik işini düzenlemek için bu iş akışını kullanın.

  1. Visual Studio Code Microsoft Sentinel Graph panelinde, güncelleştirmek istediğiniz grafik için Graf işini düzenle'yi seçin ve ardından Graf adı>İş ayrıntıları'na gidin.

  2. Değiştirmek istediğiniz alanları güncelleştirin:

    • Grafik adı (isteğe bağlı). Grafik adını güncelleştirmek kiracınızda yeni bir grafik oluşturur. Mevcut grafik değişmeden kalır.
    • Açıklama (isteğe bağlı). Açıklamanın güncelleştirilmesi geçerli grafik açıklamasının yerini alır ve grafiği yeniden oluşturur.
    • Küme yapılandırması (isteğe bağlı). Küme yapılandırmasını güncelleştirmek işlem boyutunu değiştirir ve grafiği yeniden oluşturur.
    • İş sıklığı (isteğe bağlı). İş sıklığını güncelleştirmek yinelenen zamanlamayı değiştirir ve grafiği yeniden oluşturur.

Visual Studio Code Microsoft Sentinel Graph panelinde graf işini düzenle iş akışını gösteren ekran görüntüsü.

Mevcut özel grafiğin üzerine yazma

Bir grafı yeniden oluşturmak ve aynı ada sahip mevcut bir grafiğin üzerine yazmak istediğinizde bu iş akışını kullanın.

  1. Güncelleştirilmiş not defterini açın.

  2. Sentinel not defteri deneyiminde Zamanlanmış İş Oluştur'u ve ardından Grafik işi oluştur'u seçin.

  3. Grafik oluştur formunda bir grafik adı girin.

    • Yeni bir grafik adı sağlarsanız kiracıda yeni bir grafik oluşturulur ve mevcut grafik kullanılabilir durumda kalır.
    • Kiracı için mevcut bir grafik adını yeniden kullandığınızda, onaydan sonra var olan grafiğin üzerine yazılır. Grafik adları benzersizdir, yinelenen grafik adları desteklenmez.
  4. Path'in güncelleştirilmiş not defterinize başvurduğunu doğrulayın.

  5. Grafın Açıklamasını güncelleştirin.

  6. Yeni graf oluşturmaya benzer şekilde Küme yapılandırması ve İş sıklığı'na tıklayın.

  7. Gerekirse Zamanlama bilgilerini güncelleştirin.

  8. Açıklama alanını gerektiği gibi yeniden güncelleştirin.

  9. Grafiği kiracınızda yeniden oluşturmak için Gönder'i seçin.

Visual Studio Code'da var olan bir özel grafiğin üzerine yazmak için kullanılan Grafik oluştur formunu gösteren ekran görüntüsü.