Baixe o app para aproveitar ainda mais
Prévia do material em texto
Análise de Malwares Aula 9: Investigandp via Análise de Memória - Linux Apresentação Nessa nona aula revisaremos algumas técnicas utilizadas para análise de memória para busca de atividades maliciosas, porém o foco será em ambiente Linux. Como abordamos na última aula, é importante entender as peculiaridades entres os diferentes sistemas e saber como proceder em cada um deles. Algumas das técnicas podem ser semelhantes, mas o processo de aquisição e análise difere do Windows. Objetivo Identi�car técnicas de aquisição de memória; Construir pro�les do sistema operacional Linux; Reconhecer recursos internos do ambiente Linux. Linux O sistema operacional Linux, quando foi lançado, revolucionou o mundo. Linus Torvald, seu criador, sempre foi a favor do código aberto. Baseado no sistema UNIX, mesma origem do macOS, a proposta desse sistema operacional sempre foi a gratuidade e inclusão. Aquisição de memória A ideia é abordar os tópicos fundamentais para iniciar a análise da memória. Vamos abordar algumas técnicas de aquisição de memória no Linux e analisar suas vantagens e desvantagens. Comentário Você verá que a utilização do Volatility não é tão simples quanto do Windows; é preciso, primeiro, criar os per�s do sistema Linux utilizado. Um per�l é um arquivo que contém as informações necessárias para que o Volatility encontre e interprete adequadamente os dados dos dumps de memória do Linux. Primeiros métodos O Os primeiros métodos de aquisição de memória no Linux não exigiam qualquer outra aplicação para serem realizados. Havia as interfaces que eram integradas ao próprio sistema operacional que permitiam a leitura e a gravação da memória física, portanto, bastando a leitura do /dev/mem ou /dev/kmem e seu direcionamento para um arquivo. Sistemas modernos Em sistemas mais modernos, essas interfaces foram desativadas por questões de segurança para evitar abusos. Com as restrições impostas pela desativação das interfaces, os desenvolvedores da comunidade forense criaram ferramentas especializadas de aquisição de memória. Como discutido na aula anterior, apesar do uso de ferramenta de terceiros fornecer aos analistas uma maior �exibilidade e agilidade no processo de aquisição, exige a execução de um processo nos sistemas de destino para coletar as evidências, podendo alterar informações importantes. Com o lançamento dos sistemas de 64 bits, outro dispositivo foi criado e possibilitou a aquisição da memória física sem a necessidade de ferramentas externas: O /proc/kcore. Dados os problemas, já mencionados, da interface /dev/mem em sistemas de 32 bits, foi criado um projeto: fmem. fmem Trata-se de um driver de kernel que cria o dispositivo /dev/fmem, o qual exporta amemória física para outros programas acessarem. Vantagens e desvantagens do fmem Clique no botão acima. javascript:void(0); Vantagens Uma de suas vantagens é que ele veri�ca se as páginas físicas residem na memória principal antes de acessá-las, evitando que os analistas tentem ler acidentalmente áreas de memória de dispositivos ou endereços físicos não mapeados, o que poderia causar problemas de estabilidade no sistema. Outra vantagem do fmem é que ele pode acessar páginas físicas acima do limite de 896 MB, ao contrário de /dev/mem. Desvantagem A única desvantagem do fmem é que ele exige que o investigador inspecione o dispositivo /proc/iomem para determinar onde a RAM está mapeada. Isso é necessário para máquinas que não mapeiam toda a memória principal sem nenhum tipo de deslocamento físico. Pode parecer confuso em um primeiro momento, mas imagine o seguinte cenário: Em alguns sistemas, a memória RAM é dividida em diversos segmentos diferentes que são carregados na memória física. A Figura 1 a seguir mostra a saída inicial do dispositivo /proc/iomem em uma máquina virtual com 4096 MB de memória física. Fonte: Autor. Figura1: Mapeamento da memória física Como se pode notar, existem quatro intervalos de memória física que precisam ser adquiridos. Observe que o último intervalo (100000000-13fffffff) está acima do limite normal para sistemas de 32 bits, que é 0xffffffff. Portanto, caso seja utilizada a ferramenta dd para adquirir 4096 MB de RAM com fmem, não serão capturados os dados na última região. Atenção Parece um erro simples, porém esse tipo de problema é bastante comum e precisaria de um analista bastante experiente para identi�car, pois o arquivo teria o tamanho correto da RAM (4096 MB) e as ferramentas de análise de memória (incluindo o Volatility) funcionariam normalmente. No entanto, a amostra de memória estaria incompleta. Atenção! Aqui existe uma videoaula, acesso pelo conteúdo online Embora o fmem seja um ótimo complemento para a aquisição de memória, trata-se de uma ferramenta que necessita de bastante intervenção do analista, além de um conhecimento profundo do layout da memória física para usá-la adequadamente. Uma ferramenta bastante utilizada é o Linux MemoryExtractor, conhecido como LiME. Ressalta-se que LiME: 01 É a ferramenta de aquisição de memória Linux mais recente. Ela corrige os problemas e desa�os envolvidos com as ferramentas e técnicas discutidas anteriormente. 02 Opera carregando um driver do kernel e toda a aquisição é feita diretamente no kernel em contraste às soluções anteriores que criavam um dispositivo no modo de usuário. Isso aumenta signi�cativamente a precisão da amostra resultante pois não criam-se alternâncias de contexto entre o ambiente do usuário e o kernel necessários para transferir dados. 03 Tem uma grande vantagem em relação ao fmem ao determinar automaticamente os intervalos de endereços que contêm a memória principal. Para enumerar os intervalos, o LiME percorre a lista encadeada do kernel, que possui os descritores para cada segmento de memória física. Se o nome do segmento corresponder ao da RAM (System RAM), os membros inicial e �nal correspondentes determinam onde o segmento reside na memória física. Ao realizar a aquisição da memória com LiME, é possível escolher entre vários formatos. Ao selecionar o formato recomendado, um arquivo estruturado é produzido eliminando a necessidade de criar um arquivo preenchido com zeros para preencher os dados da área de memória vazios. Este formato estruturado contém metadados que descrevem de qual deslocamento físico cada seção veio, o que permite que a ferramenta de análise de memória reconstrua dinamicamente o layout de memória original. Para usar o LiME, você deve primeiro compilar o módulo do kernel para a versão do kernel que deseja analisar. Para mais informações, veja a documentação do projeto. Depois de compilar o módulo, você terá um arquivo chamado lime-.ko que pode ser carregado no sistema de destino. O LiME tem a capacidade de adquirir a memória diretamente no disco local ou via rede, e pode fazer isso nos seguintes formatos: javascript:void(0); 1 raw Todos os intervalos de memória são concatenados juntos. 2 padded Semelhante ao formato anterior, exceto que as lacunas entre os intervalos de memória são preenchidas com zeros. 3 lime Grava no formato LiME mencionado anteriormente (recomendado). Comentário Você pode controlar o destino do arquivo gerado da memória de�nindo o parâmetro de caminho para o módulo do kernel. Para descarregar o conteúdo da memória em um arquivo em um dispositivo de armazenamento, basta especi�car a variável path=/path/to/ mememoria.lime. Nesse caso, a memória é adquirida e gravada no local desejado assim que o módulo é carregado. Um exemplo de aquisição de memória para o disco no formato lime é o seguinte: #insmodlime.ko "path=/tmp/memoria.limeformat=lime” Para aquisição via rede, basta modi�car a variável como path=tcp:4444, sendo o número da porta escolhida pelo analista. Com isso, um soquete de escuta é criado no sistema de destino e na porta especi�cada. Basta se conectar ao soquete com uma ferramenta de rede e a aquisição começará assim que a conexão for estabelecida. Segue um exemplode aquisição de memória via rede com a ferramenta netcat, assumindo que o ip da máquina alvo seja 192.168.10.2: máq alvo: #insmodlime.ko "path=tcp:443 format=lime" máqdest: $ nc 192.168.10.2 443 >memoria.lime Linux Pro�les Antes de usar o Volatility para analisar sua amostra de memória adquirida, você deve primeiro criar um per�l para o sistema operacional de destino. Como vimos na aula anterior, o Volatility tem suporte integrado para todas as versões principais do Windows. No entanto, o Linux é diferente devido ao grande número de versões de kernel, versões de subkernel e kernels personalizados. Atenção! Aqui existe uma videoaula, acesso pelo conteúdo online Existem mais de 100 kernels básicos e milhares de sub-versões nessa faixa, cada uma exigindo um per�l separado. Além disso, dada a mobilidade do sistema operacional, quando um usuário compila um kernel do zero, cada opção de con�guração alterada pode alterar drasticamente o kernel resultante. Esse grande número de versões do kernel inviabiliza que o Volatility possua os per�s para todas as compilações possíveis do Linux. A solução adotada foi compilar per�s para os kernels mais comuns e possibilitar que o próprio analista crie per�s para o sistema a ser analisado. Existem projetos que visam uma compilação automatizada para o per�l desejado. Para a criação de um per�l são necessárias algumas ferramentas: dwarfdump , alguns compiladores e cabeçalhos do kernel. São necessários, também, os compiladores da linguagem C como, por exemplo, gcc e make, todos disponíveis no pacote build- essential. Por �m, é necessária a informação sobre os cabeçalhos do kernel, para que se descubra a exata versão do kernel. Para as distribuições do tipo Ubuntu/Debian, como na Figura 2 a seguir, a informação pode ser adquirida pelo comando ‘uname -r’. 1 Fonte: Autor. Figura 2: Exemplo de cabeçalho do kernel https://stecine.azureedge.net/webaula/estacio/go0682/aula9.html A criação de um per�l consiste em gerar um conjunto de de�nições de estrutura, conhecidos como VTypes e um arquivo System.map para uma determinada versão do kernel. O método atual para criá-los é compilar o arquivo module.c, disponibilizado na arquitetura do Volatility e dentro da pasta /tools/linux, contra o kernel que você deseja analisar. Esse módulo foi projetado para declarar os membros de todos os tipos de que a Volatility precisa, e, com isso, serão compiladas todas as informações necessárias para a depuração do módulo. Para compilá-lo, basta estar no diretório do arquivo modulo.c e digitar o comando make. Se for bem-sucedido, sua saída deve ser semelhante à Figura 3 a seguir. Fonte: Autor. Figura 3: Criando um Per�l para o Volatility Observe no �nal da compilação que a ferramenta dwarfdump é executada recebendo como parâmetro o arquivo module.ko, o módulo do kernel, produzindo o arquivo module.dwarf, que será utilizado mais tarde. Compilar o module.ko não é necessário se você pode usar o arquivo kernel Linux compilado vmlinux, porém o arquivo vmlinux não é fornecido com a maioria das distribuições Linux. Por �m, precisamos gerar os símbolos do sistema operacional, os quais estão contidos no arquivo System.map. É possível encontrá-lo em diversos lugares no sistema, usaremos aquele que está no diretório /boot da máquina em que o kernel está instalado. Se você tiver o arquivo ELF do kernelvmlinux, também pode gerar um arquivo System.map executando a ferramenta nm passando o arquivo como parâmetro. Tome o cuidado de copiar o arquivo correto, com o mesmo valor veri�cado do comando uname -r. O arquivo System.map contém os endereços de todos os símbolos do kernel que o Volatility usa para localizar as principais estruturas de dados na memória. Agora, basta colocar os arquivos module.dwarf e System.map em um arquivo zip diretório no diretório volatility/plugins/overlays/linux/. Você deve nomear o arquivo zip de acordo com a distribuição, arquitetura e versão do kernel que ele representa. Você pode cuidar de todas essas etapas com um único comando, conforme mostrado na Figura 4 a seguir. Para veri�car a e�cácia, basta realizar o comando volatility --infoe veri�car a existência do novo per�l. Fonte: Autor. Figura4: Finalizando a criação de um per�l Linux Atenção! Aqui existe uma videoaula, acesso pelo conteúdo online Memória e Processos Um ponto crucial durante uma análise da memória de qualquer sistema envolve enumerar processos em execução. Para identi�cá-los é necessário compreender as estruturas de um processo. Cada processo do Linux é representado por uma estrutura na memória do kernel. Comentário Essa estrutura contém todas as informações necessárias para vincular um processo com seus descritores de arquivo abertos, mapas de memória, credenciais de autenticação e todas suas informações. As instâncias das estruturas são alocadas do cache de memória do kernel e armazenadas em um cache denominado. O kernel usa a lista de processos ativos para manter um conjunto de processos que estejam em execução; ressalta-se que essa lista não está disponível ao usuário. Por esse motivo, a maioria das ferramentas não faz referência a essa lista para enumerar processos. Antigamente, alguns rootkits manipulavam essa estrutura de dados para se camu�arem, pois ferramentas forenses dependiam dessa lista para enumerar os processos ativos. O plugin do Volatility linux_pslist enumera processos percorrendo a lista de processos ativos apontada pela variável global init_task. A variável init_task é alocada estaticamente no kernel, tem um ID de processo (PID) de 0 e tem um nome de swapper. Devido a uma escolha de design do desenvolvedor, ele não aparece nas listas de processos geradas por meio do comando ps, como na Figura 5 a seguir. Fonte: Autor. Figura 5: Reconstrução da lista de processos Um analista deve ter como objetivo a classi�cação da memória do processo: Aprender a localizar e extrair o heap, a pilha ou código executável de um processo da memória. 1 Argumentos da linha de comando Determinar onde procurar para extrair a linha de comando completa usada para invocar um processo. 2 Variáveis de ambiente Descobrir onde as variáveis de um processo são armazenadas e como veri�car se as variáveis de ambiente foram modi�cadas. 3 Injeção de biblioteca compartilhada Analisar os caminhos completos para bibliotecas compartilhadas e executáveis de processo ajuda a detectar ataques de injeção de código. Artefatos de Redes Conforme já abordamos, quase todo artefato malicioso possui uma capacidade de rede, seja para comunicar-se com o atacante, seja para se espalhar pela rede infectada. Já abordamos nas aulas anteriores técnicas para identi�car pacotes enviados pelo artefato para comunicação e como forjar uma rede para identi�car e reproduzir requisitos necessários para a completa execução do malware. Mas, no caso da memória, o artefato já foi reproduzido, as peças complementares já foram carregadas e todo os processos já estão em execução ou foram executados. Qual sistema foi inicialmente infectado? Outras máquinas foram comprometidas por meio de movimento lateral? Quais sistemas remotos foram envolvidos na ex�ltração de dados ou comando e controle? A análise forense de memória é crítica para responder a essas perguntas porque poucos artefatos relacionados são gravados em disco. É preciso entender como esses dados são armazenados nas amostras colhidas da memória do Linux, como recuperá-los e como tirar conclusões com base no que encontrar. Antes de começar a analisar informações de rede na memória, você deve primeiro localizar os descritores de arquivo de soquete de rede, pois eles representam uma ampla variedade de itens, como, por exemplo, identi�cadores de arquivo aberto, recursos de entrada e saída, soquetes de rede e canais de comunicação entre processos. O Linux fornece uma interface de programação de aplicativo (API) comum para acessar os descritores e, conhecendo as estruturas de dados dessa API,é possível determinar com sucesso a �nalidade de um descritor de arquivo aberto na memória. Existe um plugin do Volatility chamado linux_netstat que possui a capacidade de recuperar os artefatos de rede. A saída replica a mesma saída do comando netstat em um sistema ativo, com a diferença da fonte utilizada pelo comando, consulta da memória RAM ao invés das APIs do sistema operacional, conforme pode ser visto na Figura 6 a seguir. Fonte: Autor. Figura 6: Reconstrução das conexões de rede através da memória Por �m, ressaltamos os seguintes objetivos que o analista deve ter em mente durante sua análise: Recuperar informações de conexão Ao encontrar o descritor de arquivo de socket, deve-se determinar qual protocolo ele representa e como encontrar as estruturas de conexão especí�cas do protocolo, permitindo a recuperação de endereços IP, portas, estados de conexão. Detectar conexões de rede maliciosas Das informações levantadas, deve- se buscar conexões que fujam do padrão normal. Isso inclui sinais de ex�ltração de dados, comunicação de comando e controle ou o uso do sistema suspeito para atacar outros recursos. Sistemas de Arquivos Assim como visto nas aulas anteriores, conforme os arquivos são abertos, criados, lidos e/ou gravados, o Linux armazena informações sobre essas ações em várias estruturas de dados. Os artefatos associados registram a estrutura de diretório, os metadados, como registros de data e hora e, até mesmo, o conteúdo de arquivos acessados recentemente. Particularmente no Linux, essas informações �cam armazenadas apenas na memória e são perdidas quando a máquina é desligada. Portanto, em muitos casos, preservar a memória é o melhor e, às vezes, o único método para determinar quais arquivos foram acessados, onde um rootkit se esconde ou qualquer outra informação valiosa. O Linux mantém uma lista dos sistemas de arquivos ativos e montados no kernel na memória. É fundamental: Localizar e relacionar todos os sistemas de arquivos que estavam acessíveis e ter uma noção da extensão dos possíveis danos. Veri�car se um determinado arquivo foi acessado no disco rígido local, em uma unidade remota do Network File System (NFS) ou via protocolo Server MessageBlock (SMB) ou, ainda, se existia um disco removível externo conectado na máquina. Como objetivo, um analista deve focar nos seguintes pontos, em relação ao sistema de arquivos: Clique nos botões para ver as informações. Muitas empresas têm servidores de arquivos internos que hospedam dados sensíveis. Qualquer invasor tentará encontrar e montar compartilhamentos de rede para pesquisar e ex�ltrar arquivos sensíveis. Se o compartilhamento estiver montado no momento da aquisição, todos os artefatos dessa atividade estarão presentes na memória. Identi�car reconhecimento e a espionagem Todos os arquivos acessados, discos removíveis externos e cópias realizadas �carão registrados na memória. Detectar vazamento de dados Ao contrário dos sistemas Windows, que geralmente instalam tudo na mesma partição, os sistemas Linux usam muitas partições para armazenar conjuntos de dados. O Linux também pode usar sistemas de arquivos temporários apenas com memória, o que tem implicações forenses interessantes. Entender as convenções de montagem do Linux O plugin linux_mount recupera cada sistema de arquivo e lista dos dispositivos, ponto de montagem, tipo de sistema de arquivo e opções de montagem. Conforme mostrado na Figura 7 a seguir, é possível veri�car todas essas informações válidas no momento da aquisição da memória. Fonte: Autor. Figura 7: Sistemas de arquivos montados Rootkit Ao projetar um rootkit, uma das primeiras decisões a serem tomadas é se o mesmo operará em modo do usuário ou no modo kernel. Os rootkits de modo kernel oferecem maior liberdade para o atacante, como recursos de Manipulação Direta de Objetos Kernel (DKOM), capacidade de executar certas operações privilegiadas e interação direta com dispositivos de hardware. Porém, tarefas comuns de rootkit, como ocultar processos, armazenar as teclas digitadas e espionar atividades de rede, podem ser realizadas no modo de usuário. Modo usuário Modo kernel Uma vantagem dos rootkits do modo de usuário é a portabilidade. A detecção de rootkit no espaço do usuário é pouco identi�cada pelas ferramentas, o que pode ser utilizado por um atacante. Os rootkits de modo kernel são mais difíceis de manter, pois o kernel é modi�cado com bastante frequência. Outro problema é em relação a detecção de rootkit em modo kernel por várias ferramentas de administração do sistema e de Sistema de Prevenção de Intrusão de Host (HIPS). Dentro desse assunto, um analista deve ter como objetivo os seguintes pontos: Clique nos botões para ver as informações. Os invasores podem injetar shellcode, instruções de assembly brutas, diretamente em processos para modi�car o �uxo e manipular e interceptar dados. Detectar injeção de shellcode A injeção de biblioteca compartilhada permite carregar binários ELF completos em um processo de destino. Esse método é conveniente para invasores de uma perspectiva de desenvolvimento, mas deixa mais rastros na memória do que a simples injeção de shellcode. Encontrar injeção de biblioteca compartilhada Enquanto os endereços dos símbolos são resolvidos em tempo de execução, eles são armazenados nas entradas da GOT do processo. Ao substituir esses ponteiros, o malware pode efetivamente se ligar a chamadas de função desse processo de uma maneira muito simples. Analisar sobrescrição da tabela de offset global (GOT) ou tabela de ligação de procedimento (PLT) Alguns artefatos maliciosos podem sobrescrever o código dentro de uma função legítima para que o controle seja transferido para outra função maliciosa armazenada na memória pelo próprio malware. Essa técnica permite que ele adicione, modi�que e exclua quaisquer dados processados ou retornados pela função interceptada. Rastreamento de ligações de funções ‘em linha’ Atividade 1. Qual dos dispositivos abaixo pode ser utilizado para aquisição de memória em ambiente Linux mais moderno de 64-bits? a) /dev/mem b) /dev/kmem c) /dev/fmem d) /proc/kcore e) /dev/null 2. Qual dos itens abaixo não é necessário para criação de um pro�le linux? a) dwarfdump b) Dumpit c) Cabeçalhos do kernel d) make e) gcc 3. Em relação à memória e processos, durante uma análise de memória, todos os itens abaixo devem ser analisados para uma busca e�caz por ações maliciosas, exceto: a) Injeção de biblioteca compartilhada b) Argumentos da linha de comando c) Senhas de usuário d) Variáveis de ambiente e) Classificação da memória do processo Notas dwarfdump1 É uma ferramenta que analisa as informações de depuração dos arquivos executáveis do Linux (ELF), basta instalá-lo via pacote de instalação do linux. Referências ANLEY, C. The shellcoder’sHandbook: discoveringandexploringsecurityholes. 2.ed. [S.1.]: WileyPublishing, Inc., 2007. LIGH, M.H. et al. The ArtofMemoryForensics: DetectingMalwareandThreats in Windows Linux and Mac Mamory, Indianapolis, Indiana:J. Wiley& Sons, 2014. SIKORSKI,M.;HONIG, A. PracticalMalwareAnalysis: The Hands-On GuidetoDissectingMalicious Software(1.ed.). No Starch Press, 2012. TANENBAUM, A.S. Organização Estruturada de Computadores. 5.ed. São Paulo: Pearson Prentice Hall, 2010. Próxima aula Revisão de assembly em ARM; Investigação de malwares em ambientes Android; Investigação de malwares em ambientes iOS. Explore mais Leia o texto Implementação original do LiME. javascript:void(0);
Compartilhar