Aaron Jewitt

Automatizando solicitações de ajuste de detecção com casos do Kibana

Aprenda como automatizar solicitações de ajuste de regras de detecção no Elastic Security. Este guia mostra como adicionar campos personalizados aos casos, criar uma regra para detectar necessidades de ajuste e usar um webhook para criar um ciclo de feedback eficiente entre analistas e engenheiros de detecção.

20 min de leituraHabilitação
Automatizando solicitações de ajuste de detecção com casos do Kibana

Automatizando solicitações de ajuste de detecção com o Elastic Security.

Na Elastic, a equipe de segurança da informação é o "Cliente Zero". Utilizamos amplamente a versão mais recente dos produtos Elastic para proteger nossa organização, o que nos proporciona uma visão única de como solucionar desafios de segurança do mundo real. Uma das maneiras pelas quais aprimoramos a eficiência do Centro de Operações de Segurança (SOC) foi criando um fluxo de trabalho automatizado e integrado que permite aos nossos analistas abrir uma solicitação de ajuste de detecção diretamente do Kibana Cases com um único clique.

Em qualquer SOC, o ciclo de feedback entre analistas de segurança e engenheiros de detecção é crucial para manter uma postura de segurança saudável e eficaz. Os analistas que atuam na linha de frente são os primeiros a observar o desempenho das regras de detecção no mundo real. Eles sabem quais alertas são valiosos, quais são irrelevantes e quais poderiam ser melhorados com alguns ajustes. A fadiga de alertas causada por alertas ruidosos aumenta o risco de perder um alerta realmente positivo. A correção rápida de falsos positivos é crucial para a resposta aos verdadeiros positivos. Capturar esse feedback de alertas de forma eficiente pode ser um desafio – processos manuais, como o envio de e-mails, a abertura de chamados ou mensagens diretas, podem ser inconsistentes, demorados e difíceis de rastrear.

Com o Elastic Security, um analista pode anexar alertas a um caso novo ou existente no Kibana, conduzir sua investigação e, com alguma personalização e automação, iniciar uma solicitação de ajuste com um único clique diretamente do Kibana Cases. Este artigo irá guiá-lo através de como construímos essa automação e como você pode implementar um sistema semelhante para fechar o ciclo de feedback e otimizar seu programa de detecção e resposta.

Campos personalizados em casos do Kibana

Os campos personalizados são um componente essencial dessa automação nos casos do Kibana. Utilizando esses campos personalizados, podemos capturar as informações necessárias diretamente da ferramenta que os analistas já estão usando. Esses campos personalizados aparecerão em todos os casos, novos e existentes, proporcionando aos analistas uma maneira clara e consistente de sinalizar uma detecção para revisão.

Observação: A possibilidade de adicionar campos personalizados aos casos foi introduzida na versão 8.15. Para obter mais detalhes, consulte a documentação oficial dos casos.

Cada caso do Kibana é um documento armazenado em um índice Elasticsearch dedicado: .kibana_alerting_cases. Isso significa que todos os dados dos seus casos estão disponíveis para consulta, agregação e automação, assim como qualquer outra fonte de dados no Elastic. Cada documento de caso contém uma grande quantidade de informações, mas alguns campos são particularmente úteis para métricas e automação. O campo cases.status rastreia se um caso está aberto, em andamento ou fechado, enquanto cases.created_at e cases.updated_at fornecem registros de data e hora cruciais para calcular métricas como o Tempo Médio de Resolução (MTTR). Campos como cases.severity e cases.owner permitem segmentar e analisar suas métricas para ver como a equipe está se saindo. Mais importante para este blog, o objeto cases.custom_fields contém uma matriz dos campos personalizados que você configurou. Os campos de tempo de execução podem ser usados para analisar a matriz de campos personalizados, permitindo criar consultas, painéis, visualizações e regras de detecção que acionam fluxos de trabalho.

Além de permitir ajustes, os campos personalizados são incrivelmente versáteis para rastrear métricas e enriquecer casos. Por exemplo, temos um campo personalizado "Caso Complexo" para sinalizar casos que levam mais de uma hora para serem resolvidos, ajudando-nos a identificar regras que podem precisar de melhores guias de investigação ou automação para ajudar a reduzir o tempo de investigação. Também utilizamos campos personalizados como "Regra de detecção válida" e "Alerta de verdadeiro positivo" para coletar feedback detalhado sobre o desempenho e a fidelidade das regras, o que nos permite criar painéis robustos no Kibana para visualizar a eficácia operacional do nosso SOC.

Se você ainda não criou uma visualização de dados para as informações dos casos, precisará fazê-lo se quiser usar campos em tempo de execução e visualizações de dados com seus casos.

Navegue até Padrões de Índice: No Kibana, acesse Gerenciamento de Pilha > Visualizações de Dados e clique em 'criar nova visualização de dados'.

Configure a visualização de dados para mapear o índice do sistema .kibana_alerting_cases . Você precisará clicar no botão "Permitir índices ocultos e do sistema" para permitir isso. Para o campo de carimbo de data/hora, recomendo usar o campo cases.updated_at para que os casos sejam exibidos pela atividade mais recente.

Criação de campos personalizados

Existem dois tipos de campos personalizados; campos Text para entrada de texto livre ou campos Toggle para feedback simples de sim/não. Para nossa automação de Solicitação de Ajuste, usamos um de cada. O campo de texto é opcional e serve para registrar qualquer feedback adicional do analista, enquanto o campo de alternância é usado para acionar a automação.

No Kibana, acesse Segurança > Casos e clique em Configurações no canto superior direito. Na página de configurações, você encontrará uma seção de Campos Personalizados onde poderá adicionar os novos campos que desejar. Os campos são exibidos na interface do usuário dos casos em ordem alfabética, então prefixamos nossos campos com números para mantê-los na ordem desejada.

Você pode criar novos campos personalizados. Os rótulos adicionados na interface do usuário são apenas para os analistas e não são armazenados no índice de casos. Esses valores podem ser quaisquer que você desejar.

Adicionar campos personalizados: Precisamos de dois campos para este fluxo de trabalho.

  • Campo 1: Alternar ajuste necessário
    • Este será o botão que os analistas clicarão para iniciar uma solicitação de ajuste.

      • Rótulo: Open tuning request?
      • Tipo: Alternar
      • Valor padrão: Desativado
    • Campo 2: Detalhes da solicitação de ajuste

      • Este campo permite ao analista fornecer detalhes específicos sobre o que precisa ser alterado, como adicionar uma exceção, diminuir a gravidade ou ajustar a lógica da consulta.
      • Name: Tuning request detail
      • Tipo: Texto
    • Valor padrão: Desativado

Utilizando campos de tempo de execução para mapear os campos personalizados.

Um desafio ao trabalhar com campos personalizados em casos do Kibana é que o campo cases.custom_fields é mapeado como uma matriz de objetos, onde cada objeto representa um campo personalizado com seu nome e valor. Essa estrutura dificulta a consulta direta de campos personalizados específicos em KQL. Por exemplo, você não pode simplesmente usar uma consulta como cases.custom_fields.open_tuning_request : "true". Para contornar isso, podemos usar campos de tempo de execução para analisar e consultar os campos personalizados.

Os campos de tempo de execução são campos que são avaliados no momento da consulta. Elas permitem que você crie novos campos instantaneamente, sem precisar reindexar seus dados. Podemos definir campos de tempo de execução no índice .kibana_alerting_cases para usar um script simples para analisar a matriz cases.custom_fields e extrair os valores que precisamos em novos campos facilmente consultáveis.

Para este fluxo de trabalho, criaremos dois campos de tempo de execução que serão mapeados para os campos personalizados criados acima:
* TuningRequired: Um campo booleano que será true se a opção "Abrir solicitação de ajuste" estiver ativada.
* TuningDetail: Um campo de texto que conterá os comentários do analista do campo "Detalhes da solicitação de ajuste".

Antes de podermos criar os campos de tempo de execução, primeiro precisamos identificar o ID exclusivo (key) que o Kibana atribui a cada campo personalizado. Atualmente, não existe uma maneira simples de visualizar esse ID na interface do usuário. Para encontrá-lo, usamos a seguinte solução alternativa:

  1. Crie os campos. Se você estiver usando outros campos personalizados, crie-os um de cada vez para facilitar a identificação das novas chaves de campo. Se você tiver apenas os dois campos mencionados acima, poderá diferenciá-los usando o valor type , que pode ser texto ou alternar.
  2. Criar um novo caso. Após adicionar o campo, criamos um caso de teste no Kibana, adicionamos alguns dados ao campo de descrição e ativamos o campo "ajuste necessário" (tuning required) como verdadeiro, mantendo todos os outros campos personalizados como falsos ou em branco.
  3. Analise o documento do caso. Em seguida, navegamos até o Discover e consultamos o índice .kibana_alerting_cases para encontrar o documento do novo caso. Ao inspecionar a matriz cases.customFields no código-fonte do documento, pudemos encontrar o key associado ao nosso novo campo personalizado. Salve os valores dos campos key para serem usados nos scripts de tempo de execução.

Os dados cases.customFields estão formatados da seguinte maneira:

  [
    {
      "key": "4537b921-3ca4-4ff0-aa39-02dd6a3177bd",
      "type": "text",
      "value": "This alert is too noisy"
    },
    {
      "key": "cdf28896-c793-43d2-9384-99562e23a646",
      "type": "toggle",
      "value": true
    }
  ]

Criando os campos de tempo de execução

Você pode adicionar campos de tempo de execução por meio da interface do usuário do Kibana ou usando a API do Elasticsearch no console das Ferramentas de Desenvolvimento. Se você ainda não criou uma visualização de dados para as informações de Casos, precisará fazer isso primeiro.

Ao visualizar a nova visualização de dados de casos do Kibana, clique no botão "Adicionar campo" para abrir o menu suspenso e criar um novo campo de tempo de execução.

Insira o nome do campo; neste exemplo, estamos configurando TuningRequired como um novo tipo de campo booleano. Clique na opção 'Definir valor' para configurar isso como um novo campo de tempo de execução configurado por meio de um script Painless. Atualize este script Painless para substituir TUNING_REQUIRED_FIELD_KEY_UUID pelo valor key do campo personalizado Tuning Required, cole-o no campo de valor e salve o novo campo de tempo de execução.

...
    if (params._source.containsKey('cases') &&
    params._source.cases != null &&
    params._source.cases.containsKey('customFields') &&
    params._source.cases.customFields != null) 
{
  for (def cf : params._source.cases.customFields) {
    if (cf != null &&
        cf.containsKey('key') &&
        cf.key != null &&
        cf.key.contains('TUNING_REQUIRED_FIELD_KEY_UUID') &&
        cf.containsKey('value') &&
        cf.value != null) {
      emit(cf.value);
      break;
    }
  }
}

Repita este processo para o campo TuningDetail , lembre-se de usar o valor key do campo de texto no script painless deste campo. Se você tiver campos personalizados adicionais em seus casos que deseja usar para painéis ou métricas, também poderá mapeá-los com esse mesmo processo.

Se você controla as configurações do cluster e as visualizações de dados "como código", também pode adicionar campos de tempo de execução a um mapeamento de índice usando a API "Atualizar mapeamento" no console do Kibana Dev Tools.

Automatizar a criação de pedidos de ajuste

Podemos acionar essa automação de duas maneiras: por meio de uma regra de detecção personalizada (que criará um novo alerta e o enviará a um conector quando um caso for atualizado com uma solicitação de ajuste) ou por meio de uma automação externa agendada que consulta a API.

Essa automação pode ser criada usando qualquer plataforma de automação, como Tines, Github Actions ou scripts personalizados. Esta é a lógica que usamos para nossa automação:

Passo 1: Encontre quaisquer casos recentemente marcados como TuningRequired

Você pode usar esta consulta do Elasticsearch para encontrar quaisquer casos que tenham sido atualizados na última hora onde o campo TuningRequired foi definido como true. Esta consulta usa o campo cases.updated_at como intervalo de tempo. Os mapeamentos de campos em tempo de execução devem ser incluídos na solicitação da API para consultar os campos personalizados.

Esta consulta retornará todos os documentos de caso do índice .kibana_alerting_cases que foram atualizados na última hora e cujo campo TuningRequired foi definido como true

POST /.kibana_alerting_cases/_search  
{  
  "query": {  
    "bool": {  
      "must": [],  
      "filter": [  
        {  
          "bool": {  
            "should": [  
              {  
                "match": {  
                  "TuningRequired": true  
                }  
              }  
            ],  
            "minimum_should_match": 1  
          }  
        },  
        {  
          "range": {  
            "cases.updated_at": {  
              "format": "strict_date_optional_time",  
              "gte": "now-1h",  
              "lte": "now"  
            }  
          }  
        }  
      ],  
      "should": [],  
      "must_not": []  
    }  
  },  
 "runtime_mappings": {  
   "TuningDetail": {  
     "type": "keyword",  
     "script": {  
       "source": "if (\nparams._source.containsKey('cases') &&\nparams._source.cases != null &&\nparams._source.cases.containsKey('customFields') &&\nparams._source.cases.customFields != null\n) {\nfor (def cf : params._source.cases.customFields) {\nif (\ncf != null &&\ncf.containsKey('key') &&\ncf.key != null &&\ncf.key.contains('6cadc70a-7d68-4531-9861-7d5bc24c4c1c') &&\ncf.containsKey('value') &&\ncf.value != null\n) {\nemit(cf.value);\nbreak;\n}\n}\n}"  
     }  
   },  
   "TuningRequired": {  
     "type": "boolean",  
     "script": {  
       "source": "if (\nparams._source.containsKey('cases') &&\nparams._source.cases != null &&\nparams._source.cases.containsKey('customFields') &&\nparams._source.cases.customFields != null\n) {\nfor (def cf : params._source.cases.customFields) {\nif (\ncf != null &&\ncf.containsKey('key') &&\ncf.key != null &&\ncf.key.contains('496e71f2-2bce-47a2-93a8-00db0de2d1b4') &&\ncf.containsKey('value') &&\ncf.value != null\n) {\nemit(cf.value);\nbreak;\n}\n}\n}"  
     }  
   }  
 },  
  "fields": [  
    "TuningDetail",  
    "TuningRequired"  
  ]  
}

Sempre que um campo for alterado ou um comentário for feito em um caso, o campo updated_at será atualizado para a hora atual. Como qualquer atualização ou comentário adicionado a um caso atualizará esse registro de data e hora, é possível que um único caso seja retornado várias vezes por essa automação se ela for executada regularmente enquanto o caso estiver sendo atualizado. Qualquer processo de automação utilizado para isso deve incluir um mecanismo de desduplicação para evitar o processamento do mesmo caso várias vezes nesse cenário.

Etapa 2: Analisando cada caso

Percorra cada um dos casos retornados pela consulta anterior para processá-los um de cada vez. Cada documento retornado conterá a matriz fields com os valores dos campos personalizados, bem como outros campos úteis. Analise cada um dos seguintes campos e armazene-os para uso futuro:

  • O campo _id terá um formato como cases:{{case_ID}}. O ID do caso é usado para futuras solicitações de API na automação, seja para adicionar comentários ao caso ou recuperar todos os alertas associados a ele.
  • cases.title é o título do caso
  • cases.assignees é a quem o caso foi atribuído
  • cases.updated_by É a última pessoa a atualizar o caso; geralmente é a pessoa que submete o pedido de ajuste e pode ser útil para saber quem contatar para obter mais informações.
  • cases.tags Pode ser útil se você estiver usando tags para classificar ou identificar seus casos.

Etapa 3: Recuperando os alertas associados ao caso

Para cada caso, você precisará saber quais alertas estão associados a ele para identificar quais precisam ser ajustados. Isso pode ser feito usando a API de casos com o campo _id para o caso.

/api/cases/{caseId}/alerts

Esta consulta retornará uma matriz de todos os valores de alerta id que estão associados ao caso. Usando este valor de ID você pode consultar o índice .siem-signals* do Elasticsearch para encontrar as informações completas sobre cada alerta associado ao caso que precisa de ajuste.

POST /.siem-signals-*/_search  
{  
 "size": 1,  
 "query": {  
   "bool": {  
     "must": [],  
     "filter": [  
       {  
         "bool": {  
           "should": [  
             {  
               "match": {  
                 "_id": "{{alert_id}}"  
               }  
             }  
           ],  
           "minimum_should_match": 1  
         }  
       },  
       {  
         "range": {  
           "@timestamp": {  
             "format": "strict_date_optional_time",  
             "gte": "now-30d",  
             "lte": "now"  
           }  
         }  
       }  
     ],  
     "should": [],  
     "must_not": []  
   }  
 }  
}

A partir dos resultados desta consulta, você pode extrair informações sobre o alerta, como o nome e a data de criação, juntamente com quaisquer outras informações que possam ajudar no ajuste, como os campos user.name ou process.name . Como um caso pode ter muitos alertas associados a ele, você desejará remover os alertas duplicados pelo valor signal.rule.name .

Passo 4: Abrir um pedido de ajuste.

Esta etapa depende do sistema de emissão de tickets que você utiliza em seu ambiente. Nossa equipe usa o GitHub Issues para acompanhar solicitações de ajustes e o Slack para notificações, mas isso também poderia ser feito com qualquer sistema de emissão de tickets ou gerenciamento de projetos que suporte automação.

Este é o fluxo lógico que usamos para nossa automação, utilizando tanto o Github quanto o Slack para acompanhar as solicitações de ajuste:

  • Utilizando o nome do alerta, procuramos por quaisquer solicitações de ajuste em aberto já existentes.
    • Se já existir uma solicitação de ajuste, atualizaremos essa solicitação com os detalhes do caso e da nova solicitação.
    • Caso não exista uma solicitação existente, abriremos uma nova solicitação de ajuste e anexaremos as informações.
  • Em seguida, enviamos uma notificação para o canal do Slack da equipe de engenharia de Detecção, contendo um link para a solicitação de ajuste, um link para o caso e detalhes sobre a solicitação e o alerta.
  • Em seguida, usamos a API de Casos para adicionar um comentário ao caso original com um link para a solicitação de ajuste.
  • Agente de IA opcional: Estamos começando a experimentar o uso de agentes de IA para analisar os alertas e as informações dos casos e, em seguida, fornecer um contexto ainda melhor com a solicitação de ajuste, podendo até mesmo recomendar alterações nas regras de detecção.

O resultado final dessa automação é que nossos analistas do SOC podem criar um ticket de solicitação de ajuste de detecção detalhado com um único clique a partir do caso. Graças a essa automação, observamos um aumento drástico na redução de falsos positivos e na eficiência geral de nossas regras de detecção.

Conclusão

Ao usar o Kibana Cases com campos personalizados e integrá-lo a plataformas de automação, você pode otimizar muitos dos seus processos manuais. Esse fluxo de trabalho automatizado reduz o trabalho manual associado à coleta de feedback dos analistas, garantindo que as valiosas percepções dos analistas sejam rapidamente traduzidas em melhorias práticas nas regras de detecção. O resultado é um SOC mais eficiente, preciso e resiliente, capaz de se adaptar rapidamente a ameaças emergentes e reduzir a fadiga de alertas.

Pronto para otimizar a eficiência do seu SOC e melhorar sua capacidade de detecção? Explore o Elastic Security e comece a criar seus próprios fluxos de trabalho automatizados para solicitações de ajuste hoje mesmo!

Compartilhe este artigo