O blog da AWS

Como usar a API do Amazon Detective para investigar as descobertas de segurança do GuardDuty e enriquecer os dados no Security Hub

Por Nicholas Jaeger, Principal Security Solutions Architect na AWS e Rima Tanash, Senior Security Engineer e pesquisadora da AWS.

Compreender o risco e identificar a causa raiz de um problema em tempo hábil é fundamental para as empresas. A Amazon Web Services (AWS) oferece vários serviços de segurança que você pode utilizar em conjunto para realizar investigações mais oportunas e melhorar o tempo médio de correção dos problemas. Nesta postagem, você aprenderá como integrar o Amazon Detective ao AWS Security Hub, oferecendo melhor visibilidade dos indicadores de ameaças e dos dados investigativos diretamente do Security Hub, que fornece uma visão centralizada da postura geral de segurança em todas as suas contas da AWS.

O Amazon GuardDuty é um serviço inteligente de detecção de ameaças que monitora continuamente suas contas, cargas de trabalho, atividades de tempo de execução e dados da AWS em busca de possíveis atividades maliciosas. Se as atividades suspeitas, como comportamento anômalo ou exfiltração de credenciais, forem detectadas, o GuardDuty gera as descobertas de segurança detalhadas para as ameaças detectadas. Quando você ativa o GuardDuty e o Security Hub na mesma conta e na mesma região da AWS, o GuardDuty envia as descobertas geradas para o Security Hub.

O AWS Security Hub é uma ferramenta de gerenciamento da postura de segurança na nuvem que detecta automaticamente quando suas contas e recursos da AWS desviam das melhores práticas de segurança, agrega alertas de segurança em um único local e formato e fornece informações sobre sua postura de segurança de todas as suas contas da AWS.

O Amazon Detective facilita a análise, a investigação e a identificação rápida da causa raiz de possíveis problemas de segurança ou atividades suspeitas. O Detective oferece suporte à capacidade de investigar automaticamente usuários e funçoes do AWS Identity and Access Management (IAM) em busca de indicadores de comprometimento (IoC). Esse recurso ajuda os analistas de segurança a determinar se os usuários e as funções do IAM foram potencialmente comprometidos ou envolvidos em alguma tática, técnica e procedimento (TTPs) conhecidos da estrutura MITRE ATT&CK. Nesta postagem, mostramos um exemplo de como usar programaticamente a API Detective Investigation para ajudar a investigar possíveis problemas de segurança.

O exemplo de arquitetura que fornecemos nesta publicação realiza o enriquecimento automaticamente para descobertas de severidade CRITICAL, HIGH e MEDIUM e oferece a flexibilidade de iniciar investigações adicionais e enriquecer sob demanda. Em seguida, você tem a opção de analisar essas descobertas aprimoradas diretamente no console do Security Hub ou pode habilitar uma integração para analisar as descobertas aprimoradas no serviço da AWS ou por uma solução de um AWS Partner Network (APN) de sua escolha. Esta postagem fornece uma visão geral do que você precisa fazer para criar a arquitetura de exemplo, mas se você preferir instruções passo a passo, confira a versão de workshop com o passo-a-passo.

Essa integração e o enriquecimento de descobertas são possíveis por meio do uso da API Detective Investigation. Você deve ter o GuardDuty, o Detective e o Security Hub habilitados para que isso funcione. Recomendamos que você crie essa arquitetura na conta que está usando como administrador delegado do GuardDuty, Detective e Security Hub e na região em que o Security Hub agrega as descobertas (se a agregação de descobertas estiver configurada).

Arquitetura da solução

O Security Hub consome automaticamente as descobertas do GuardDuty. Você pode integrar o Security Hub com o Detective usando as regras do EventBridge e uma função Lambda. Para tornar a solução mais gerenciável e personalizável, você pode configurar uma ação personalizada do Security Hub e uma regra de automação do Security Hub. A ação personalizada é usada para identificar as descobertas que você deseja selecionar manualmente para investigação. A regra de automação é configurada para identificar e sinalizar as descobertas para as quais você deseja iniciar automaticamente as investigações. As regras do EventBridge (duas delas) são usadas para iniciar a função Lambda para cada descoberta que você deseja investigar e enriquecer. A função Lambda processa a descoberta que recebe, faz chamadas de API para o Detective e, em seguida, faz uma chamada de API de volta ao Security Hub para atualizar e enriquecer a descoberta. A função Lambda é invocada uma vez para cada descoberta. A Figura 1 ilustra essa solução.

Figura 1: A arquitetura da solução, incluindo GuardDuty, Security Hub, EventBridge, Lambda e Detective

O fluxo de trabalho será:

  1. O Security Hub consome automaticamente as descobertas do GuardDuty. À medida que o Security Hub consome as descobertas, ele aplica uma ou mais regras de automação habilitadas para modificar as descobertas. Você pode usar regras para adicionar um campo definido pelo usuário para marcar quais descobertas você deseja processar automaticamente, como aquelas de severidade CRITICAL, HIGH e MEDIUM.
  2. A. O Security Hub emite um evento para cada novo e atualizado finding importado depois de aplicar as regras de automação que estão habilitadas. O evento emitido inclui uma descoberta (após a aplicação das regras de automação).
    B. O Security Hub emite um evento para cada execução de uma ação personalizada. O evento emitido inclui as descobertas que são selecionadas quando a ação personalizada é iniciada.
  3. A. Uma regra do EventBridge avalia eventos que correspondem às descobertas do Security Hub — Imported e envia os eventos para uma função Lambda de destino para processamento. Você pode ajustar ainda mais o padrão do evento para enviar somente descobertas que contenham um campo definido pelo usuário.
    B. Uma segunda regra do EventBridge avalia eventos que correspondem às descobertas do Security Hub — Ação personalizada (a ação personalizada específica) e envia os eventos para a mesma função Lambda de destino para processamento.
  4. A função Lambda de destino processa a descoberta no evento, faz chamadas de API para o Detective para iniciar uma investigação para o usuário do IAM relacionado ou a função do IAM (se houver) e busca os resultados. Em seguida, faz uma chamada de API para o Security Hub para atualizar a descoberta. A função adiciona uma nota com um resumo da investigação, um link para o resultado completo da investigação e um campo definido pelo usuário que pode ser usado para filtrar as descobertas que foram investigadas.

Nas seções a seguir desta postagem, forneceremos mais detalhes sobre os componentes e a configuração da arquitetura. Como pré-requisito, você deve ter o GuardDuty, o Detective e o Security Hub habilitados.

Realize investigações com o Detective usando o Lambda

Você pode iniciar investigações no Detective e recuperar os resultados por meio da API. O AWS Lambda oferece suporte a várias linguagens de programação, mas você usará JavaScript (Node.js 20.x) neste exemplo. Para iniciar uma investigação, forneça o Amazon Resource Name (ARN) de uma função ou usuário do IAM, a hora de início, a hora de término e o ARN do gráfico de comportamento do detective. A API do Detective buscará os resultados da investigação, incluindo IOCs, TTPs e uma pontuação categórica de gravidade. A pontuação de gravidade retornada é calculada usando duas dimensões, confiança e impacto, em que a confiança representa a probabilidade de que os eventos sejam anômalos e não sejam um comportamento normal do usuário, enquanto o impacto quantifica os danos que podem ocorrer a partir dos eventos como uma medida do efeito dos TTPs.

Você pode usar o exemplo da função Lambda no exemplo de código 1 como destino da regra do EventBridge na arquitetura descrita anteriormente. A função obtém o ARN de uma descoberta de segurança do GuardDuty que foi agregada pelo Security Hub e invoca a API Investigation. Quando o resultado é retornado, a função formata os dados no AWS Security Finding Format (ASFF) usado pelo Security Hub e invoca a API BatchUpdateFindings para enviar a descoberta enriquecida e atualizada de volta ao Security Hub. Certifique-se de ler e revisar a função para entender detalhadamente como ela funciona.

Exemplo de código 1: Exemplo de função Lambda em JavaScript usando Node.js 20.x

"use strict";
import {
  DetectiveClient,
  GetInvestigationCommand,
  ListGraphsCommand,
  StartInvestigationCommand,
} from "@aws-sdk/client-detective";
import { BatchUpdateFindingsCommand, SecurityHubClient } from "@aws-sdk/client-securityhub";

const SHClient = new SecurityHubClient();
const detectiveClient = new DetectiveClient();

export const handler = async (event) => {
  try {
    // Handle only one (the first) finding per function call
    const finding = event.detail.findings[0];

    if (finding.ProductName != "GuardDuty") {
      // Handle only GuardDuty findings
      throw new Error("This is not a GuardDuty finding!");
    }

    const listgraphs = new ListGraphsCommand({});
    const graphs = await detectiveClient.send(listgraphs);
    const graphArn = graphs.GraphList[0].Arn;

    const IAMResourceARNs = finding.Resources.filter((resource) => {
      return (
        resource.Type == "AwsIamAccessKey" ||
        resource.Type == "AwsIamRole" ||
        resource.Type == "AwsIamUser"
      );
    }).map((resource) => {
      if (resource.Type == "AwsIamRole" || resource.Type == "AwsIamUser") {
        return {
          arn: resource.Id,
          type: resource.Type == "AwsIamRole" ? "role" : "user",
        };
      } else if (resource.Type == "AwsIamAccessKey") {
        return {
          arn: `arn:aws:iam::${finding.AwsAccountId}:role/${resource.Details.AwsIamAccessKey.PrincipalName}`,
          type: "role",
        };
      }
    });

    if (IAMResourceARNs.length == 0) {
      throw new Error("No IAM resource!");
    }

    // Investigate the first IAM role or user identified in the finding
    const investigationTarget = IAMResourceARNs[0].arn;
    const investigationTargetType = IAMResourceARNs[0].type;

    const investigationEndTime = new Date(Date.now());

    let investigationStartTime;
    if (finding.FirstObservedAt) {
      investigationStartTime = new Date(finding.FirstObservedAt);
    } else if (finding.CreatedAt) {
      investigationStartTime = new Date(finding.CreatedAt);
    } else if (finding.ProcessedAt) {
      investigationStartTime = new Date(finding.ProcessedAt);
    } else {
      throw new Error("Investigation start time invalid!");
    }
    investigationStartTime.setHours(investigationStartTime.getHours() - 24);

    const totalInvestigationTime = Math.round(
      (investigationEndTime.getTime() - investigationStartTime.getTime()) / (1000 * 60 * 60),
    ); // Hours

    const startInvestigationRequest = {
      GraphArn: graphArn,
      EntityArn: investigationTarget,
      ScopeStartTime: investigationStartTime,
      ScopeEndTime: investigationEndTime,
    };

    const startinvestigation = new StartInvestigationCommand(startInvestigationRequest);
    const investigation = await detectiveClient.send(startinvestigation);
    const investigationId = investigation.InvestigationId;

    const getInvestigationRequest = {
      GraphArn: graphArn,
      InvestigationId: investigationId,
    };

    let investigationResult = { Status: "RUNNING" };
    while (investigationResult.Status == "RUNNING") {
      await new Promise((r) => setTimeout(r, 30000));
      const getinvestigation = new GetInvestigationCommand(getInvestigationRequest);
      investigationResult = await detectiveClient.send(getinvestigation);
      if (investigationResult.Status == "FAILED") {
        throw new Error("Investigation failed!");
      }
    }

    let investigationSummary = "";
    switch (investigationResult.Severity) {
      case "INFORMATIONAL":
      case "LOW":
        investigationSummary += `We did not observe uncommon behavior for the associated ${investigationTargetType} during the ${totalInvestigationTime} hour investigation window.`;
        break;
      case "MEDIUM":
        investigationSummary += `We observed anomalous behavior for the associated ${investigationTargetType} during the ${totalInvestigationTime} hour investigation window which might be indicative of compromise.`;
        break;
      case "HIGH":
      case "CRITICAL":
        investigationSummary += `We observed anomalous behavior for the associated ${investigationTargetType} during the ${totalInvestigationTime} hour investigation window indicating potential compromise.`;
        break;
      default:
        throw new Error("Severity information not found!");
    }

    investigationSummary += " For more information, visit ";
    investigationSummary += `https://${process.env.AWS_REGION}.console.aws.amazon.com/detective/home?region=${process.env.AWS_REGION}#investigationReport/${investigationResult.InvestigationId}`;

    const findingUpdateInput = {
      FindingIdentifiers: [
        {
          Id: finding.Id,
          ProductArn: finding.ProductArn,
        },
      ],
      Note: {
        Text: investigationSummary.substring(0, 512),
        UpdatedBy: "Detective Investigation Lambda function.",
      },
      UserDefinedFields: {
        investigate: "complete",
      },
    };

    const batchUpdateCommand = new BatchUpdateFindingsCommand(findingUpdateInput);
    const updatedFinding = await SHClient.send(batchUpdateCommand);

    return updatedFinding;
  } catch (error) {
    console.error("Error:", error);
    throw error;
  }
};

Para que essa função funcione conforme desejado, você precisa alterar as permissões e o tempo limite da função Lambda. As permissões devem incluir as ações necessárias que você está realizando com o Detective e o Security Hub na função. Anexe a política mostrada no exemplo de código 2 à regra usada pela função. Em seguida, defina o tempo limite da função para 15 minutos para permitir que o detective conclua a investigação. Observe que você pode alterar “resource”:” *” para restringir as permissões conforme necessário.

Exemplo de código 2: permissões exigidas pela função Lambda

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"detective:ListGraphs",
				"detective:searchGraph",
				"detective:StartInvestigation",
				"detective:UpdateInvestigationState",
                "detective:GetInvestigation",
				"detective:ListInvestigations",
				"detective:ListIndicators",
				"securityhub:BatchUpdateFindings",
                "securityhub:UpdateFindings"
			],
			"Resource": "*"
		}
	]
}

Inicie investigações automatizadas e encontre oportunidades

Agora que você configurou a função Lambda, está pronto para configurar os dois métodos de iniciar as investigações. A primeira abordagem envolve investigar e enriquecer automaticamente as descobertas do GuardDuty de severidade CRITICAL, HIGH e MEDIUM. Isso pode acelerar as investigações para constatações de maior gravidade, porque você não precisa acessar o Security Hub ou o Detective e selecionar manualmente as descobertas para investigação.

Nessa abordagem, a função Lambda de investigação que você criou anteriormente é invocada automaticamente usando as automações do Security Hub e uma regra do EventBridge. O uso das automações do Security Hub permite que você configure e atualize quais descobertas são automaticamente investigadas e enriquecidas sem alterações contínuas no código. (As regras de automação usam uma interface de usuário com opções suspensas para critérios.)

Configure uma regra de automação na página Automações no Security Hub. Use estes critérios para a regra:

  • O ProductName é igual a GuardDuty
  • SeverityLabel é igual a CRITICAL, HIGH ou MEDIUM
  • ResourceType é igual a AwsIamUser ou AwsIamRole (conforme Figura 2)

No futuro, se você quiser modificar quais descobertas serão investigadas automaticamente, poderá revisitar a regra e selecionar novos critérios para especificar quais descobertas receberão o campo definido pelo usuário.

Figura 2: Exemplo de critérios para regra de automação no Security Hub

Para as ações automatizadas da regra, adicione um campo definido pelo usuário da seguinte forma:

  • Key: investigate, Value: true (conforme Figura 3)

Figura 3: Definir o campo definido pelo usuário para a regra de automação no Security Hub

Em seguida, defina uma regra do EventBridge para determinar quais eventos do Security Hub Findings — Imported são investigados com base no campo definido pelo usuário, investigate. Cada evento Security Hub Findings — Imported contém uma única descoberta. Use o padrão JSON conforme exemplo de código 3 para combinar as descobertas na regra. Você precisa definir a meta dessa regra para a função Lambda que você configurou anteriormente.

Exemplo de código 3: O padrão usado em sua regra do EventBridge

{
  "source": ["aws.securityhub"],
  "detail": {
    "findings": {
      "UserDefinedFields": {
        "investigate": ["true"]
      }
    }
  }
}

À medida que as novas descobertas são agregadas no Security Hub, elas são avaliadas e atualizadas pela regra de automação. As descobertas que receberem o campo definido pelo usuário iniciarão a função Lambda. Depois que a função Lambda for iniciada, pode levar alguns minutos para que a execução seja concluída e apareça no Security Hub. Quando isso acontecer, você notará um novo campo Notes, conforme Figura 4, e dados adicionais na descoberta do JSON.

Figura 4: Veja se a descoberta aprimorada agora inclui uma seção de notas

Você também pode ver quais atualizações foram feitas na descoberta na guia Histórico da descoberta, conforme Figura 5.

Figura 5: Veja os campos que foram atualizados para a descoberta na guia Histórico

Se você quiser modificar quais descobertas iniciam esse fluxo, você pode modificar a regra de automação no console do Security Hub. Por exemplo, talvez você também queira investigar descobertas de outros serviços ou com outros rótulos de gravidade. Lembre-se de que o Detective só oferece suporte a usuários e funções do IAM.

Talvez você queira adicionar outros critérios para ajudar a evitar a repetição de investigações sobre as mesmas descobertas. Por exemplo, talvez você não queira que o fluxo de investigação seja iniciado toda vez que uma descoberta recebe uma atualização. Para ajudar a evitar esse comportamento, você pode adicionar critérios à regra de automação em que o campo definido pelo usuário, investigate, não seja igual a COMPLETE.

Pesquisa, investigação e enriquecimento sob demanda

A segunda abordagem envolve investigar e enriquecer as descobertas sob demanda. Talvez você queira usar as duas abordagens caso haja descobertas que não atendam aos critérios de sua automação anterior que você ainda queira investigar.

Nessa abordagem, inicie a função Lambda por meio do uso de um recurso no Security Hub chamado custom action. Para usar uma ação personalizada do Security Hub para enviar descobertas para o EventBridge, primeiro crie a custom action no Security Hub. Chame-o de investigate. Em seguida, defina uma regra no EventBridge que se aplique à sua ação personalizada (usando o ARN da custom action) e que utilize a mesma função do Lambda como destino para orquestrar a automação. O padrão da sua regra do EventBridge será semelhante à Figura 6, mas utilizando o ARN da custom action que você criou no Security Hub.

Figura 6: A regra do EventBridge para a segunda abordagem

Depois de configurar a ação personalizada e a regra do EventBridge, você pode selecionar uma descoberta e escolher investigate na lista suspensa Actions para iniciar o processamento, conforme Figura 7.

Figura 7: Inicie o enriquecimento de busca sob demanda

Como as duas abordagens para iniciar a investigação usam a mesma função Lambda, a descoberta enriquecida resultante no Security Hub será a mesma.

Limitações e personalização adicional

Recomendamos que você experimente, teste e personalize a arquitetura e o código de exemplo. Para simplificar o exemplo, há algumas limitações codificadas na função Lambda. Por exemplo, a função Lambda processa somente a primeira descoberta que recebe (por execução) e prossegue somente se a descoberta for originada do GuardDuty. A função também só inicia uma investigação sobre o primeiro usuário do IAM ou função do IAM que ela identifica e que está associada à descoberta. Se você tiver um caso de uso que exija que a função Lambda trate várias descobertas ao mesmo tempo, descobertas de outros serviços ou outros problemas, você precisará fazer alterações no código ou na arquitetura para acomodar esses requisitos (como incorporar o uso do AWS Step Functions ou do Amazon Simple Queue Service (Amazon SQS)) e realizar os testes relevantes.

Conclusão

Use o código de exemplo fornecido aqui ou a versão do workshop com o passo-a-passo para testar a API Detective e enriquecer as descobertas no Security Hub com dados investigativos. Isso pode ajudá-lo a reduzir o tempo médio de resposta investigando automaticamente as entidades do IAM, fornecendo detalhes da investigação dentro das descobertas e fornecendo um link direto para os detalhes da investigação do detective. Visite Conceitos básicos do AWS Security Hub, Introdução ao Amazon Detective e Introdução ao Amazon GuardDuty para saber mais.

Se você tiver comentários sobre esta postagem, envie-os na seção comentários abaixo. Se você tiver dúvidas sobre esta publicação, entre em contato com o AWS Support.

Biografia dos Autores

Nicholas Jaeger é Principal Security Solutions Architect na AWS, oferencendo orientação a clientes focados em operar seus negócios da forma mais segura possível. Sua experiência inclui engenharia de software, ensino, arquitetura de soluções e segurança da AWS. O Nicholas também organiza o AWS Security Activation Days para fornecer aos clientes orientação prescritiva sobre o uso dos serviços de segurança da AWS.

https://awsactivationdays.splashthat.com/

Rima Tanash é Senior Security Engineer e pesquisadora da AWS, é especializada no desenvolvimento de recursos inovadores de segurança na nuvem que usam aprendizado de máquina e raciocínio automatizado. Seu trabalho abrange modelagem, automação da identificação de riscos, sequências de API da AWS, criação de manuais investigativos e análise gráfica para modelagem de ameaças. Ela tem um PhD pela Rice University e um mestrado pela Johns Hopkins University.

Biografia do tradutor

Alexandre Carlim é Enterprise Support Lead na AWS, com mais de 23 anos de experiencia, com amplo conhecimento em arquitetura, segurança e operação em cloud. Atualmente está habilitando empresas parceiras da AWS, simplificando a operação na nuvem, otimizando os custos e implementando boas práticas em cloud. 

https://www.linkedin.com/in/alexandre-carlim

Biografia do Revisor

Nicolas Tarzia é Senior Technical Account Manager na AWS, com mais de 13 anos de experiencia, com ampla experiencia em arquitetura cloud, engenharia e design de software. Atualmente está habilitando empresas do ramo de ISV (Independent Software Vendors) simplificando a operação na nuvem e otimizando os custos em cloud. Sua area de interesse são tecnologias serverless.

https://www.linkedin.com/in/nicolastarzia