BLOG

Exportando dados do Threat Stack para análise personalizada

Miniatura F5
F5
Atualizado em 10 de agosto de 2020

O Threat Stack agora é F5 Distributed Cloud App Infrastructure Protection (AIP). Comece a usar o Distributed Cloud AIP com sua equipe hoje mesmo .

Este host foi comprometido? Este anfitrião sempre fez isso?

Todos que trabalharam em operações/engenharia/segurança já tiveram, em algum momento, um servidor ou servidores que estavam exibindo comportamento inesperado. Pode estar executando processos estranhos, consumindo mais memória do que o esperado, aceitando solicitações, fazendo conexões com o GitHub, seja o que for.

O primeiro passo para triar um evento é saber que você tem um. Há uma série de fontes de dados que podem potencialmente indicar um servidor host específico:

  • Ferramentas de monitoramento que medem coisas como espaço em disco e memória
  • Sistemas de detecção de intrusão de segurança gerando alertas
  • Logs de aplicativos mostrando falhas ao atingir hosts específicos

Neste ponto, há um servidor que queremos acessar e obter mais informações. Supondo que cada pedaço de dados do sistema não necessariamente se encaixe em nosso SIEM, o próximo passo lógico é conectar-se ao host e começar a consultar o sistema operacional diretamente para saber o que ele está fazendo. Dependendo do seu nível de familiaridade com o ambiente, isso pode incluir desde ferramentas como uname e vmstat até itens mais específicos como ps e lsof. Em ambos os casos, será mostrado o que o host está fazendo no momento. Aqui está o problema com esse processo: Na verdade, você não se importa com o estado atual; você quer saber o que mudou. Assim como receber uma solicitação de pull no git, você não quer revisar toda a base de código — apenas as partes que foram modificadas.

Portabilidade de dados para Amazon S3

Aqui no Threat Stack Cloud SecOps Program℠, os analistas de segurança em nosso SOC desenvolveram uma solução para nos ajudar a responder a esses tipos de perguntas para nossos clientes. A Threat Stack Cloud Security Platform® tem esse recurso bacana que chamamos de portabilidade de dados. Em um nível mais alto, isso nos permite pegar a telemetria que coletamos dos hosts, incluindo coisas como executáveis em execução, usuários, argumentos de linha de comando, conexões, etc., e armazená-los em buckets do S3.

O que é ótimo sobre os blobs S3 é que eles são uma maneira barata de armazenar muitos e muitos dados. O problema é aproveitar grandes quantidades de dados não indexados. Para isso, acabamos usando o Amazon EMR para criar notebooks Jupyter PySpark para usar Apache Spark DataFrames e Python Pandas DataFrames para criar uma ferramenta poderosa para comparar o estado atual de uma máquina com qualquer estado anterior que tenhamos em retenção.

ETL (o favorito de todos)

Aqui estão algumas notas antes de analisar nossos exemplos de código. As tabelas e referências de esquema são mantidas no AWS Glue e correspondem ao formato de evento bruto do Threat Stack para sistemas Linux . Você pode anexar esses dados ao seu data lake existente. Depois, há uma configuração definida para o cluster Spark que informa para ele ler do Glue para saber quais tabelas e colunas estão disponíveis. Então, quando um cluster é criado, você pode referenciar a tabela no notebook JupyterLab.

Observação: O código a seguir é totalmente real; a situação é artificial. Um analista de segurança foi solicitado a comprometer um host com nosso agente em execução em algum momento do Dia dos Namorados. O objetivo era descobrir o que foi feito.

Vamos entrar no código

As primeiras coisas que precisamos criar são SparkSession e SparkContext. Felizmente, ao usar um notebook PySpark, eles são instanciados automaticamente quando executamos nossa primeira célula.

 

Configurando nosso notebook PySpark.

Temos um objeto spark que referenciaremos mais tarde, e também temos sc, que é nosso contexto spark. Podemos então usar isso para carregar no pandas e no Matplotlib .

Instalando pacotes.

Na próxima etapa, confirmarei os nomes das colunas criando um spark.table() com base nas tabelas do Glue e, em seguida, exibirei meu esquema herdado.

Lendo a estrutura de nossas colunas carregadas do AWS Glue.

Ótimo, agora posso ver quais colunas e tipos tenho disponíveis para começar a executar minhas consultas SQL. Agora posso pegar qualquer servidor e qualquer intervalo de tempo que eu quiser e compará-los. Aqui, estou criando dois Spark DataFrames, reunindo os dados que preciso para fazer a investigação pré-incidente e a perícia forense pós-incidente:

SELECIONE chave_de_data, registro de data e hora, tsEventType, chamada_de_sistema, conexão, usuário, comando, exe, argumentos DE compact.audit_v4 ONDE chave_de_data >= '2020-02-05-00' E chave_de_data < '2020-02-14-00' E id_da_organização = '5a8c4a54e11909bd290021ed' E id_do_agente = 'b0f6bdb2-9904-11e9-b036-25972ec55a45' AGRUPAR POR chave_de_data, registro de data e hora, tsEventType, chamada_de_sistema, conexão, usuário, comando, exe, argumentos SELECIONE chave_de_data, registro de data e hora, tsEventType, chamada_de_sistema, conexão, usuário, comando, exe, argumentos DE compact.audit_v4 ONDE chave_de_data >= '2020-02-14-00' E date_key < '2020-02-17-00' E organization_id = '5a8c4a54e11909bd290021ed' E agent_id = 'b0f6bdb2-9904-11e9-b036-25972ec55a45' AGRUPAR POR date_key, timestamp, tsEventType, syscall, conexão, usuário, comando, exe, args

Agrupando os dados em torno da nossa data de compromisso de 14 de fevereiro. (Algumas células do notebook são exibidas aqui como GitHub Gists para facilitar a leitura.)

Agora, uma rápida verificação de quantos dados coletei:

Contando o número de registros em ambos os Spark DataFrames para garantir uma quantidade razoável para investigação.

Isso parece certo. Tenho um intervalo de tempo muito maior para meu preCompromiseDf em comparação ao meu postCompromiseDf . (O “Df” é para me ajudar a lembrar que esses são objetos Spark DataFrame — simplesmente uma convenção de nomenclatura.)

Os Apache Spark DataFrames são bons porque armazenam o DataFrame inteiro no cluster. Isso é ótimo para grandes conjuntos de dados, mas, neste caso, tenho um número relativamente pequeno de registros que quero comparar. Para isso, executo toPandas() para mover esses dados para a memória do meu notebook, o que permitirá uma computação mais rápida.

Como não estamos lidando com “big data”, neste caso é mais rápido executar o restante da nossa análise localmente.

Iniciando nossa análise

Agora posso começar a fazer coisas poderosas, como verificar quais são os novos executáveis em execução neste servidor desde meia-noite de 14 de fevereiro.

/tmp/EXCITADO_ENQUANTO
/usr/bin/wget
/tmp/FRONT_RUN
/tmp/UNUSUAL_COMB
/tmp/SURROUNDING_LOCK
/tmp/nmap
/usr/bin/scp
/tmp/sliver
/tmp/sliver2
/tmp/PROUD_THUMB

Uma lista de executáveis em execução no servidor durante a noite em questão.

Olá, alguns nomes aleatórios de executáveis em letras maiúsculas: nmap, scp, wget e algo chamado sliver. Uma pequena pesquisa no Google revela que o sliver provavelmente está associado a https://github.com/BishopFox/sliver e é uma estrutura de implante que oferece suporte a comando e controle sobre vários protocolos.

Tenho a prova necessária de que meu servidor foi comprometido, mas quero fazer minha devida diligência e ver o que realmente foi feito com esses executáveis. Usando minha lista como um filtro para o mesmo DataFrame, posso extrair outros detalhes e indicadores de comprometimento (IoC):

argumentos exe
80 /tmp/EXCITED_WHILE ./EXCITED_WHILE
162 /usr/bin/wget wget https://github.com/andrew-d/static-binari...
255 /tmp/EXCITADO_ENQUANTO ./EXCITADO_ENQUANTO
256 /tmp/EXECUÇÃO_FRONTAL ./EXECUÇÃO_FRONTAL
359 /tmp/PENTE_INCOMUM ./PENTE_INCOMUM
360 /tmp/BLOQUEIO_ENQUANTO ./BLOQUEIO_ENQUANTO
464 /tmp/nmap
494 /tmp/BLOQUEIO_ENQUANTO ./BLOQUEIO_ENQUANTO
533 /tmp/EXCITADO_ENQUANTO ./EXCITADO_ENQUANTO
589 /tmp/EXECUÇÃO_FRONTAL ./EXECUÇÃO_FRONTAL
603 /tmp/EXCITADO_ENQUANTO ./EXCITADO_ENQUANTO
658 /tmp/EXCITADO_ENQUANTO ./EXCITADO_ENQUANTO
660 /tmp/EXECUÇÃO_FRONTAL ./FRONT_RUN
671 /usr/bin/scp scp -t /tmp/
699 /tmp/BLOQUEIO_ENVOLVENTE ./BLOQUEIO_ENVOLVENTE
738 /tmp/PENTE_INCOMUM ./PENTE_INCOMUM
762 /tmp/sliver ./sliver
816 /tmp/BLOQUEIO_ENVOLVENTE ./BLOQUEIO_ENVOLVENTE
834 /tmp/sliver2 ./sliver2
878 /tmp/nmap /tmp/nmap
909 /tmp/EXCITADO_ENQUANTO ./EXCITADO_ENQUANTO
937 /tmp/FRONT_RUN ./FRONT_RUN
992 /tmp/FRONT_RUN ./FRONT_RUN
1023 /tmp/FRONT_RUN
1040 /usr/bin/scp scp -t /tmp/
...

Extraindo quaisquer argumentos relacionados associados à minha lista de executáveis suspeitos.

Então, o scp foi usado para mover arquivos, o wget obteve algum código do GitHub (ao acessar essa linha, vejo que foi assim que o nmap entrou no sistema) e os detalhes da execução desses outros arquivos estão contidos no próprio arquivo, pois não receberam argumentos de linha de comando. Neste ponto, faz sentido tirar um instantâneo do host como evidência e encerrar a instância.

A etapa final é confirmar que nenhum outro host no ambiente foi comprometido. Para isso, pegaremos alguns itens da nossa lista de IoC anterior e verificaremos em todos os servidores.

SELECIONE date_key, timestamp, tsEventType, syscall, conexão, usuário, comando, exe, args, agentId, tty, sessão, cwd DE compact.audit_v4 ONDE date_key >= '2020-01-01' E date_key <= '2020-02-29' E organization_id = '5a8c4a54e11909bd290021ed' E tsEventType = 'audit' E syscall = 'execve' AGRUPAR POR date_key, timestamp, tsEventType, syscall, conexão, usuário, comando, exe, args, agentId, tty, sessão, cwd
52

Essa consulta retorna 52 resultados em todo o ambiente para atividades suspeitas de nmap e sliver. Podemos restringir ainda mais essa visualização indo para um DataFrame do pandas e agrupando os resultados por cada servidor:

Introdução à análise do seu próprio Threat Stack

Obrigado por permanecer comigo neste post. Estou muito animado com as possibilidades que esses dados oferecem e em encontrar novas maneiras de explorá-los. Se você atualmente utiliza a plataforma Threat Stack, pode configurar sua própria portabilidade de dados usando esta documentação como guia. A vantagem é que você pode decidir o nível certo de dados a serem retidos para atender às necessidades do seu negócio.

Para pessoas que aproveitam nosso serviço Threat Stack Oversight℠, temos 30 dias de dados de eventos e ficaremos felizes em trabalhar com você para fornecer análises forenses mais profundas em seu ambiente, aproveitando este conjunto de ferramentas caso você não tenha um data lake.

O próximo passo para a equipe de Operações de Segurança do Threat Stack é começar a incorporar mais gráficos e tabelas para ajudar a analisar os dados visualmente como parte de nossa próxima análise usando cadernos de ciência de dados. Mais sobre isso virá, mas aqui está uma primeira análise de alguns IPs geolocalizados (a densidade de cada círculo indica o número de conexões).

Mais visualizações analíticas em breve da equipe de segurança do Threat Stack!

O Threat Stack agora é F5 Distributed Cloud App Infrastructure Protection (AIP). Comece a usar o Distributed Cloud AIP com sua equipe hoje mesmo .