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:
SELECT date_key, timestamp, tsEventType, syscall, connection, user, command, exe, args FROM compact.audit_v4 WHERE date_key >= '2020-02-05-00' AND date_key < '2020-02-14-00' AND organization_id = '5a8c4a54e11909bd290021ed' AND agent_id = 'b0f6bdb2-9904-11e9-b036-25972ec55a45' GROUP BY date_key, timestamp, tsEventType, syscall, connection, user, command, exe, args SELECT date_key, timestamp, tsEventType, syscall, connection, user, command, exe, args FROM compact.audit_v4 WHERE date_key >= '2020-02-14-00' AND date_key < '2020-02-17-00' AND organization_id = '5a8c4a54e11909bd290021ed' AND agent_id = 'b0f6bdb2-9904-11e9-b036-25972ec55a45' GROUP BY date_key, timestamp, tsEventType, syscall, connection, user, command, 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/EXCITED_WHILE /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):
exe args 80 /tmp/EXCITED_WHILE ./EXCITED_WHILE 162 /usr/bin/wget wget https://github.com/andrew-d/static-binari... 255 /tmp/EXCITED_WHILE ./EXCITED_WHILE 256 /tmp/FRONT_RUN ./FRONT_RUN 359 /tmp/UNUSUAL_COMB ./UNUSUAL_COMB 360 /tmp/SURROUNDING_LOCK ./SURROUNDING_LOCK 464 /tmp/nmap 494 /tmp/SURROUNDING_LOCK ./SURROUNDING_LOCK 533 /tmp/EXCITED_WHILE ./EXCITED_WHILE 589 /tmp/FRONT_RUN ./FRONT_RUN 603 /tmp/EXCITED_WHILE ./EXCITED_WHILE 658 /tmp/EXCITED_WHILE ./EXCITED_WHILE 660 /tmp/FRONT_RUN ./FRONT_RUN 671 /usr/bin/scp scp -t /tmp/ 699 /tmp/SURROUNDING_LOCK ./SURROUNDING_LOCK 738 /tmp/UNUSUAL_COMB ./UNUSUAL_COMB 762 /tmp/sliver ./sliver 816 /tmp/SURROUNDING_LOCK ./SURROUNDING_LOCK 834 /tmp/sliver2 ./sliver2 878 /tmp/nmap /tmp/nmap 909 /tmp/EXCITED_WHILE ./EXCITED_WHILE 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.
SELECT date_key, timestamp, tsEventType, syscall, connection, user, command, exe, args, agentId, tty, session, cwd FROM compact.audit_v4 WHERE date_key >= '2020-01-01' AND date_key <= '2020-02-29' AND organization_id = '5a8c4a54e11909bd290021ed' AND tsEventType = 'audit' AND syscall = 'execve' GROUP BY date_key, timestamp, tsEventType, syscall, connection, user, command, exe, args, agentId, tty, session, 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 .