O Threat Stack agora é F5 Distributed Cloud App Infrastructure Protection (AIP). Comece a usar o Distributed Cloud AIP com sua equipe hoje mesmo .
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:
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.
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.
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.
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.
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:
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 .