Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Os gráficos personalizados no Microsoft Sentinel permitem que investigadores e analistas de segurança criem representações de gráficos personalizadas dos respetivos dados de segurança. Ao criar gráficos personalizados, pode modelar padrões de ataque específicos, investigar ameaças e executar algoritmos de gráfico avançados para descobrir relações ocultas no seu ambiente digital. Este guia orienta-o ao longo dos passos para criar e gerir gráficos personalizados com os blocos de notas do Jupyter na extensão Microsoft Sentinel Visual Studio Code.
Este artigo centra-se na criação manual de gráficos personalizados com código. Para obter uma experiência orientada por IA, veja Criação de grafos personalizados assistidos por IA no Microsoft Sentinel.
Pré-requisitos
Os itens a seguir são necessários para criar gráficos personalizados no Microsoft Sentinel:
- extensão do Microsoft Sentinel para o Visual Studio Code. Para obter mais informações, veja Executar blocos de notas no Microsoft Sentinel data lake.
- Extensão jupyter para Visual Studio Code.
- Microsoft Sentinel data lake configurado com as permissões adequadas. Para obter mais informações, consulte Integrar-se ao data lake do Microsoft Sentinel.
Ative o conector Microsoft Entra ID para ingerir as tabelas de recursos Microsoft Entra utilizadas no código de exemplo deste artigo. Para obter mais informações, veja Ingestão de dados de recursos no data lake do Microsoft Sentinel.
Permissões
Para interagir com gráficos personalizados, precisa das seguintes permissões XDR no Sentinel data lake. A tabela seguinte lista os requisitos de permissão para operações de grafos comuns:
| Operação de gráfico | Permissões obrigatórias |
|---|---|
| Modelar e criar um gráfico de bloco de notas | Use uma função personalizada de RBAC unificado do Microsoft Defender XDR com permissões de dados (gerenciar) sobre a coleta de dados do Microsoft Sentinel. |
| Manter um gráfico no inquilino | Use uma das seguintes funções do Microsoft Entra ID: Operador de segurança Administrador de segurança Administrador global |
| Consultar um gráfico persistente | Utilize uma função RBAC unificada Microsoft Defender XDR personalizada com permissões básicas de dados de segurança (leitura) através da recolha de dados Microsoft Sentinel. |
Importante
Tem de ter permissões para ler os dados utilizados no gráfico. Se não tiver acesso a um conjunto de dados específico, esses dados não serão incluídos no gráfico. Para criar um gráfico, você não deve estar restrito por um escopo do Sentinel. Um usuário com escopo restrito não pode criar um gráfico personalizado.
As funções do Microsoft Entra ID fornecem amplo acesso a todos os espaços de trabalho em todo o data lake. Para obter mais informações, veja Funções e permissões no Microsoft Sentinel.
Instalar Visual Studio Code e a extensão Microsoft Sentinel
Crie gráficos personalizados com blocos de notas do Jupyter na extensão Microsoft Sentinel Visual Studio Code. Para obter mais informações, veja Instalar Visual Studio Code e a extensão Microsoft Sentinel
Criar um gráfico personalizado
Para criar e trabalhar com gráficos personalizados, conclua os seguintes passos:
- Modelar um gráfico personalizado
- Manter o gráfico personalizado ao agendar uma tarefa de gráfico
- Ver e gerir gráficos personalizados
Modelar um gráfico personalizado
Crie um gráfico personalizado com um bloco de notas do Jupyter na extensão Microsoft Sentinel Visual Studio Code.
Os passos seguintes explicam como criar o seu primeiro gráfico personalizado com um bloco de notas de exemplo.
Configure seu notebook e conecte-se ao data lake
Use as etapas a seguir para criar um notebook e conectar-se ao data lake Microsoft Sentinel.
Em Visual Studio Code com a extensão Microsoft Sentinel instalada, selecione o ícone Microsoft Sentinel no menu esquerdo.
Selecione Iniciar sessão para ver gráficos
É apresentada uma caixa de diálogo com o texto A extensão "Microsoft Sentinel" quer iniciar sessão com a Microsoft. Selecione Permitir para iniciar sessão.
Inicie sessão com as suas credenciais.
Depois de iniciar sessão, selecione +Criar novo bloco de notas.
Dê um nome ao ficheiro do bloco de notas e guarde-o numa localização adequada na área de trabalho.
Selecione Selecionar kernel no canto superior direito da janela do notebook para selecionar um pool de computação do Spark.
Selecione Microsoft Sentinel e, em seguida, selecione qualquer um dos pools do Spark disponíveis.
Dica
Pode utilizar pedidos de IA para o ajudar a criar um bloco de notas de gráficos personalizado. Para obter mais informações, veja Criação de grafos personalizados assistidos por IA no Microsoft Sentinel.
Execute uma célula selecionando o ícone de triângulo Executar célula à esquerda da célula. Na primeira vez que executar uma célula, poderá ser-lhe pedido que selecione um kernel se ainda não tiver selecionado um.
A primeira vez que você executa uma célula, iniciar a sessão do Spark leva cerca de cinco minutos.
Criar um gráfico
O exemplo a seguir cria um grafo para percorrer as associações a grupos no Microsoft Entra e compreender as relações entre grupos aninhados. O código de exemplo ajuda você a começar com um caso de uso simples para conhecer o recurso de grafo personalizado e aproveitar o poder da travessia de grafos em suas investigações. Pode criar um gráfico a partir de qualquer tabela disponível no Sentinel data lake.
Conecte-se ao seu espaço de trabalho e leia as tabelas de ativos do Entra para começar a criar o grafo.
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")Prepare os DataFrames de nós e arestas necessários para construir o grafo
# ============================================================ # 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"))) )Defina o esquema do seu grafo e vincule-o aos DataFrames de nós e arestas que você preparou anteriormente neste procedimento
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()Validar o esquema do gráfico
# Check the schema of the graph spec to ensure it's correct entra_group_graph_spec.show_schema()Criar o gráfico, incluindo preparar os dados e publicar o gráfico
# 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)Observação
Os gráficos criados durante sessões interativas do bloco de notas são removidos quando a sessão do bloco de notas é fechada. Para manter o gráfico para reutilização e partilha, consulte Manter o gráfico personalizado
Agora você criou um grafo no notebook.
Para mostrar uma representação visual do grafo, em uma nova célula cole e execute a consulta GQL (Linguagem de Consulta graph) de exemplo a seguir. Esta consulta percorre participações aninhadas em grupos do Microsoft Entra em até oito níveis de profundidade e exibe os relacionamentos resultantes:
# 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()
Este código executa uma consulta GQL (Graph Query Language) de exemplo para recuperar todas as participações em grupos aninhados em até 8 níveis de profundidade. O gráfico resultante é exibido na saída.
Manter o gráfico personalizado
Depois de criar o código do gráfico no bloco de notas, pode executar o bloco de notas numa sessão interativa ou agendar uma tarefa de gráfico. Os gráficos criados durante a sessão interativa do bloco de notas são temporários e só estão disponíveis no contexto da sessão do bloco de notas. Para guardar o seu gráfico e partilhar com a sua equipa, agende uma tarefa de gráfico para reconstruir o seu gráfico com frequência. Assim que o gráfico for guardado, é acessível a partir de: a experiência de gráfico no portal do Microsoft Defender em Sentinel, Visual Studio Code Notebooks e Graph query APIs.
No seu bloco de notas de gráficos, selecione Criar Tarefa Agendada e, em seguida, selecione Criar uma tarefa de gráfico.
No formulário Criar tarefa de grafo, insira o Nome do grafo e a Descrição e verifique se o notebook de grafo correto está incluído no campo Caminho.
Para criar o gráfico sem configurar uma agenda de atualização, selecione A pedido na secção Agenda e, em seguida, selecione Submeter para criar o gráfico.
Observação
Os gráficos criados com base na agenda a pedido têm uma retenção predefinida de 30 dias e são eliminados após a expiração.
Para criar o gráfico onde os dados do gráfico são atualizados regularmente, selecione Agendado na secção Agenda .
Selecione uma Frequência de repetição para a tarefa. Você pode escolher entre Por minuto, Por hora, Semanal, Diário ou Mensal.
São apresentadas mais opções para configurar a agenda, consoante a frequência que selecionar. Por exemplo, dia da semana, hora do dia ou dia do mês.
Selecione um horário de Iniciar em para que o agendamento comece a ser executado.
Selecione um horário de Terminar em para que o agendamento pare de ser executado. Se não quiser definir uma hora de fim para a agenda, selecione Definir tarefa para ser executada indefinidamente. As datas e horas estão no seu fuso horário.
Selecione Submeter para guardar a configuração da tarefa e publicar a tarefa. O processo de criação do grafo começa no seu locatário. Veja o gráfico recentemente criado e o respetivo status mais recente na extensão Sentinel.
Ver e gerir gráficos personalizados
Depois de criar uma tarefa de gráfico, pode ver e gerir o gráfico no seu inquilino a partir da extensão Microsoft Sentinel no Visual Studio Code.
Na lista de gráficos, selecione o gráfico materializado para ver os respetivos detalhes.
Selecione o separador Detalhes da Tarefa para ver o status da tarefa de gráfico, incluindo a hora da última execução, a hora da próxima execução e quaisquer erros encontrados durante o processo de compilação.
Selecione Executar Agora para acionar manualmente uma compilação de gráficos fora das horas agendadas. O Status muda para Na fila e, em seguida, "Em andamento" enquanto o gráfico está sendo criado.
Quando a compilação do gráfico estiver concluída, o Estado é atualizado para Pronto. Selecione o separador Detalhes do Graph para ver informações sobre o gráfico.
Agora você pode consultar e visualizar seu grafo na visualização de grafo do Microsoft Sentinel no portal do Microsoft Defender. Para obter mais informações, veja Visualizar gráficos no gráfico Microsoft Sentinel (pré-visualização).
Atualizar grafos personalizados
Depois de atualizar o código do grafo do notebook, execute o notebook localmente para validar suas alterações antes de atualizar um trabalho de grafo.
Editar detalhes do grafo personalizado existente
Use esse fluxo de trabalho para editar um trabalho de grafo existente.
No painel do Microsoft Sentinel Graph no Visual Studio Code, selecione Editar trabalho do grafo para o grafo que você deseja atualizar e, em seguida, acesse Nome do grafo>Detalhes do trabalho.
Atualize os campos que você deseja alterar:
- Nome do grafo (opcional). Ao atualizar o nome do grafo, um novo grafo é criado no seu tenant. O grafo existente permanece inalterado.
- Descrição (opcional). Ao atualizar a descrição, a descrição do grafo atual é substituída e o grafo é reconstruído.
- Configuração do cluster (opcional). Atualizar a configuração do cluster altera o tamanho da computação e recria o grafo.
- Frequência de trabalho (opcional). Atualizar a frequência do trabalho altera o agendamento recorrente e recria o grafo.
Sobrescrever um gráfico personalizado existente
Use esse fluxo de trabalho quando quiser recriar um grafo e substituir um grafo existente com o mesmo nome.
Abra o bloco de anotações atualizado.
Selecione Criar Trabalho Agendado na experiência do bloco de anotações do Sentinel e, em seguida, selecione Criar um trabalho de grafo.
No formulário Criar grafo , forneça um nome de grafo.
- Se você fornecer um novo nome de grafo, um novo grafo será criado no locatário, e o grafo existente permanecerá disponível.
- Se você reutilizar um nome de grafo existente para locatário, o grafo existente será substituído após a confirmação. Nomes de grafo são exclusivos, não há suporte para nomes de grafo duplicados.
Verifique se Caminho se refere ao notebook atualizado.
Atualize a Descrição do grafo.
Selecione a configuração do cluster e a frequência de trabalho, semelhante à criação de um novo grafo.
Atualize as informações de Agendamento , se necessário.
Atualize o campo Descrição novamente conforme necessário.
Selecione Enviar para recriar o grafo no seu tenant.