Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. 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 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 seguintes elementos 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, veja Integrar no Microsoft Sentinel data lake.
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 necessárias |
|---|---|
| Modelar e criar um gráfico de bloco de notas | Utilize uma função RBAC unificada personalizada do Microsoft Defender XDR com permissões de dados (gerir) sobre a recolha de dados do Microsoft Sentinel. |
| Manter um gráfico no inquilino | Utilize 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, não pode estar sujeito a um âmbito do Sentinel. Um utilizador com permissões limitadas não pode criar um gráfico personalizado.
As funções do Microsoft Entra ID concedem acesso abrangente a todas as áreas de trabalho no lago de dados. Para obter mais informações, veja Funções e permissões no Microsoft Sentinel.
Instalar o 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 o 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 o seu notebook e ligue-o ao lago de dados
Use os passos seguintes para criar um caderno e ligar-se ao data lake do Microsoft Sentinel.
No 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 Spark.
Selecione Microsoft Sentinel e, em seguida, selecione qualquer um dos pools do Spark disponíveis.
Sugestão
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.
Para executar uma célula, selecione o ícone triangular 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.
Na primeira vez que executas uma célula, iniciar a sessão de Spark demora cerca de cinco minutos.
Criar um gráfico
O exemplo seguinte cria um grafo para percorrer as associações a grupos no Microsoft Entra e compreender as relações aninhadas entre grupos. O código de exemplo ajuda-o a dar os primeiros passos com um caso de utilização simples para aprender a funcionalidade de grafo personalizado e tirar partido do poder da travessia de grafos nas suas investigações. Pode criar um gráfico a partir de qualquer tabela disponível no Sentinel data lake.
Ligue-se ao seu espaço de trabalho e leia as tabelas de recursos 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")Preparar 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 grafo e associe-o aos DataFrames de nós e arestas que 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)Nota
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 criou um gráfico no caderno.
O exemplo seguinte de Python executa uma consulta Graph Query Language (GQL) contra o grafo que acabou de criar para explorar relações de grupos aninhados. Use consultas como esta após a criação do grafo para atravessar hierarquias de membros e descobrir caminhos de acesso indiretos. Para experimentar, cole o código numa nova célula de caderno e execute-o. Esta consulta de exemplo percorre membros de grupos Microsoft Entra aninhados até oito níveis de profundidade e apresenta as relações 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 de exemplo em Graph Query Language (GQL) para recuperar todas as pertenças a grupos aninhados até 8 níveis de profundidade. O grafo resultante é visualizado no resultado.
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, Blocos de Notas do Visual Studio Code e APIs de consulta do Graph.
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 gráfico , introduza o Nome do gráfico e a Descrição e verifique se o bloco de notas de grafos correto está incluído em 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.
Nota
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. Pode escolher entre Ao minuto, À hora, Semanalmente, Diariamente ou Mensalmente.
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 Início a tempo para que a agenda comece a ser executada.
Selecione uma hora de Terminar em para que o agendamento deixe 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 estado 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 estado 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, para "Em curso", enquanto o gráfico está a ser gerado.
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, pode consultar e visualizar o seu grafo na visualização de grafos no Microsoft Sentinel no portal do Defender. Para obter mais informações, veja Visualizar gráficos no gráfico Microsoft Sentinel (pré-visualização).
Atualizar grafos personalizados
Depois de atualizares o código do grafo do caderno, executa o caderno localmente para validar as tuas alterações antes de atualizares um trabalho no grafo.
Editar detalhes do grafo personalizado existente
Use este fluxo de trabalho para editar um trabalho de grafo existente.
No painel Gráfico do Microsoft Sentinel no Visual Studio Code, selecione Editar tarefa do gráfico para o gráfico que pretende atualizar e, em seguida, aceda a Nome do gráfico>Detalhes da tarefa.
Atualize os campos que quer alterar:
- Nome do grafo (opcional). Ao atualizar o nome do grafo, é criado um novo grafo no seu locatário. O gráfico existente mantém-se inalterado.
- Descrição (opcional). Atualizar a descrição substitui a descrição atual do grafo e reconstrói o grafo.
- Configuração do cluster (opcional). Atualizar a configuração do cluster altera o tamanho do cálculo e reconstrói o grafo.
- Frequência de trabalho (opcional). Atualizar a frequência do trabalho altera o cronograma recorrente e reconstrói o gráfico.
Sobrescrever um grafo personalizado existente
Use este fluxo de trabalho quando quiser recriar um grafo e sobrescrever um grafo existente com o mesmo nome.
Abre o caderno atualizado.
Selecione Criar Trabalho Agendado na experiência do caderno Sentinel, depois selecione Criar um trabalho de grafo.
No formulário Create graph , forneça o nome do grafo.
- Se indicar um novo nome de grafo, é criado um novo grafo no tenant e o grafo existente permanece disponível.
- Se reutilizar um nome de grafo existente para o inquilino, o grafo existente é sobrescrito após confirmação. Os nomes dos grafos são únicos, nomes duplicados de grafos não são suportados.
Verifica se Caminho aponta para o notebook atualizado.
Atualize a Descrição para o gráfico.
Selecione Configuração do cluster e Frequência de trabalho, semelhante a criar um novo grafo.
Atualize a informação do calendário , se necessário.
Atualize novamente o campo de Descrição conforme necessário.
Selecione Enviar para recriar o gráfico no seu inquilino.
Conteúdo relacionado
- Criação de grafos personalizados assistidos por IA no Microsoft Sentinel
- Referência da biblioteca do fornecedor de grafos do Microsoft Sentinel
- Referência da Linguagem de Consulta de Grafos (GQL) para gráfico personalizado do Sentinel
- Visualizar gráficos no gráfico Microsoft Sentinel (pré-visualização)