Introdução
Os sistemas Unix e Linux operam nos bastidores, sustentando silenciosamente uma parte significativa de nossa infraestrutura tecnológica. Com a crescente complexidade das ameaças direcionadas a esses sistemas, garantir sua segurança tornou-se mais importante do que nunca.
Uma das ferramentas fundamentais no arsenal dos engenheiros de detecção de segurança que trabalham em sistemas Unix e Linux é o Auditd. Esta poderosa ferramenta foi projetada para monitorar e registrar eventos do sistema, fornecendo um histórico de auditoria detalhado de quem fez o quê e quando. Ele atua como um cão de guarda, patrulhando e registrando informações detalhadas sobre chamadas de sistema, acessos a arquivos e alterações no sistema, que são cruciais para análises forenses e monitoramento em tempo real.
O objetivo deste artigo é multifacetado:
- Nosso objetivo é fornecer informações adicionais sobre o Auditd, demonstrando suas capacidades e o imenso poder que ele detém na engenharia de detecção de segurança.
- Iremos orientá-lo na configuração do Auditd em seus próprios sistemas, adaptando-o para atender às suas necessidades específicas de monitoramento. Ao entender como criar e modificar regras do Auditd, você aprenderá a capturar o comportamento exato que deseja monitorar e a interpretar os registros resultantes para criar suas próprias regras de detecção.
- Vamos apresentar o Auditd Manager, uma ferramenta de integração que aumenta a utilidade do Auditd, simplificando o gerenciamento do Auditd em diferentes sistemas.
Ao final deste artigo, você não só aprenderá como usar o Auditd Manager para incorporar algumas de nossas regras de detecção predefinidas à sua estratégia de segurança, como também obterá uma compreensão abrangente do Auditd e de como utilizá-lo para criar suas próprias regras de detecção.
Introdução ao Auditd
O Auditd é uma ferramenta Linux projetada para monitorar e registrar eventos do sistema, fornecendo um histórico completo das atividades do usuário, alterações no sistema e acessos de segurança. O Auditd funciona interagindo com o kernel do Linux, capturando informações detalhadas sobre chamadas de sistema e outros eventos do sistema à medida que ocorrem. Esses eventos são então registrados em um arquivo, fornecendo um registro com data e hora. Os administradores podem definir regras que especificam quais eventos devem ser registrados, oferecendo a flexibilidade de focar em áreas específicas de interesse ou preocupação. Os dados registados podem ser utilizados para uma variedade de fins, desde auditorias de conformidade até análises forenses detalhadas.
Configuração auditada
Para começar a usar o Auditd, a Elastic oferece diversas opções:
- Módulo Auditd do Auditbeat
- Módulo Auditd do Filebeat
- Integração de logs de auditoria do Elastic Agent
- Integração do Auditd Manager do Elastic Agent
Neste artigo, vamos nos concentrar nos dois últimos, aproveitando o Elastic Agent para ingerir logs no Elasticsearch com facilidade. Se você é novo no Elasticsearch, pode criar facilmente uma conta no Elastic Cloud com uma licença de avaliação de 30 dias ou, para testes locais, pode baixar o Elastic Container Project e definir o valor da licença como "trial" no arquivo .env. arquivo.
Fique à vontade para acompanhar usando o Auditbeat ou o Filebeat. Para obter instruções de configuração, consulte a documentação cujo link está acima. Como a integração do Auditd Logs funciona analisando o arquivo audit.log, é necessário instalar o Auditd no host Linux do qual você deseja coletar os logs. Dependendo da distribuição Linux e do gerenciador de pacotes escolhido, o pacote Auditd deve ser instalado, e o serviço Auditd deve ser iniciado e ativado. Para distribuições baseadas em Debian:
sudo apt update
sudo apt install auditd
sudo systemctl start auditd
sudo systemctl enable auditd
O arquivo /var/log/audit/audit.log agora deve estar preenchido com os registros do Auditd. Em seguida, você precisa instalar a integração do Auditd Logs, criar uma política de agente no Fleet com a integração recém-instalada e aplicar a integração a um Elastic Agent compatível com o Auditd instalado.
As configurações padrão devem ser suficientes para a maioria dos cenários. Em seguida, você precisa adicionar a integração a uma política de agente e adicionar a política de agente aos Elastic Agents dos quais deseja coletar dados. O Elastic Agent envia os logs para o arquivo logs-auditd.log-[namespace] fluxo de dados. Agora você pode criar uma nova visualização de dados que corresponda apenas aos nossos registros de auditoria (Auditd) recebidos.
Agora você pode explorar os registros do Auditd que foram ingeridos. Mas, como você perceberá rapidamente, o Auditd não registra muitos dados por padrão – você precisa usar regras do Auditd para desbloquear todo o seu potencial.
Auditd rules
As regras do Auditd são diretivas usadas para especificar quais atividades do sistema devem ser monitoradas e registradas, permitindo um controle granular sobre o processo de auditoria de segurança. Essas regras são normalmente configuradas no arquivo /etc/audit/audit.rules . As regras Auditd vêm em 3 variedades: control, file e syscall. Mais informações podem ser encontradas aqui.
Regras do tipo de controle
O tipo de controle é, na maioria dos casos, usado para configurar o Auditd em vez de especificar os eventos a serem monitorados. Por padrão, o arquivo de regras de auditoria contém as seguintes configurações de tipo de controle:
-D
-b 8192
-f 1
--backlog_wait_time 60000
-D: excluir todas as regras na inicialização (o Auditd analisa as regras no arquivo de cima para baixo). Remover todas as regras na inicialização garante uma configuração limpa.-b 8192: define a quantidade máxima de buffers de auditoria existentes no kernel.-f 1: Defina o modo de falha do Auditd para registrar logs.--backlog_wait_time 60000: especifique a quantidade de tempo (em ms) que o sistema de auditoria aguardará caso o limite de registros de auditoria pendentes seja atingido, antes de descartar os registros de auditoria.
Regras do sistema de arquivos
Com base nessas configurações padrão de tipo de controle, você pode criar regras do sistema de arquivos, às vezes chamadas de "monitores". Essas regras nos permitem monitorar arquivos de interesse quanto a ações de leitura, gravação, alteração e execução. Uma regra típica do sistema de arquivos seria semelhante à seguinte:
-w [path-to-file] -p [permissions] -k [keyname]
-w: o caminho para o arquivo ou diretório a ser monitorado.-p: qualquer uma das permissões de leitura (r), escrita (w), execução (e) ou alteração (a).-k: o nome de um identificador de chave que pode ser usado para pesquisar mais facilmente nos registros do auditd.
Caso você queira monitorar o arquivo /etc/shadow em busca de leituras, gravações e alterações, e salvar esses eventos com uma chave chamada shadow_access, você pode configurar a seguinte regra:
-w /etc/shadow -p rwa -k shadow_access
Regras de chamada do sistema
O verdadeiro poder do Auditd se revela quando se trabalha com suas regras de chamadas de sistema. As regras de chamadas de sistema do Auditd são configurações que especificam quais chamadas de sistema (syscalls) devem ser monitoradas e registradas, permitindo o rastreamento detalhado da atividade do sistema e das interações com o kernel do sistema operacional. Como cada chamada de sistema é interceptada e comparada à regra, é importante usar essa funcionalidade com cuidado, capturando apenas as chamadas de sistema de interesse e, quando possível, capturando várias dessas chamadas de sistema em uma única regra. Uma regra típica de chamada de sistema seria assim:
-a [action],[filter] -S [syscall] -F [field=value] -k [keyname]
Você pode usar o sinalizador -a seguido por action,filter para escolher quando um evento é registrado, onde action pode ser always (sempre criar um evento) ou never (nunca criar um evento).
O filtro pode ser qualquer um dos seguintes:
task: registra eventos de criação de tarefas.entry: registra os pontos de entrada das chamadas de sistema.exit: registra as saídas/resultados das chamadas de sistema.user: registra eventos do espaço do usuário.exclude: exclui eventos do registro.
Em seguida, você tem:
-S: a chamada de sistema que lhe interessa (nome ou número da chamada de sistema).-F: um ou mais filtros para escolher com o que comparar.-k: o identificador principal.
Com as informações fornecidas acima, você deverá ser capaz de compreender os conceitos básicos da maioria das regras do Auditd. Para obter mais informações e exemplos de valores que podem ser adicionados a essas regras, fique à vontade para ler mais aqui.
Começar a criar e testar um arquivo de regras Auditd abrangente e dedicado para sua organização pode parecer uma tarefa assustadora. Felizmente, existem alguns bons exemplos de arquivos de regras públicos disponíveis no GitHub. Um dos meus modelos favoritos para desenvolver é o do Neo23x0, que oferece um bom equilíbrio entre visibilidade e desempenho.
Uma desvantagem de usar a integração de logs do Auditd é que você precisa instalar o Auditd manualmente em cada host que deseja monitorar e aplicar o arquivo de regras manualmente a cada instância do Auditd em execução. Isso significa que, sempre que você quiser atualizar o arquivo de regras, terá que atualizá-lo em todos os hosts. Atualmente, muitas organizações utilizam ferramentas de gestão que podem tornar esse processo menos demorado. No entanto, a Elastic também oferece outra maneira de ingerir logs do Auditd por meio da integração com o Auditd Manager, o que alivia a carga de gerenciamento.
Introdução ao Auditd Manager e configuração
A integração do Auditd Manager recebe eventos de auditoria do Linux Audit Framework , que faz parte do kernel do Linux. Essa integração estabelece uma assinatura do kernel para receber os eventos à medida que ocorrem. A estrutura de auditoria do Linux pode enviar várias mensagens para um único evento auditável. Por exemplo, uma chamada de sistema rename() faz com que o kernel envie oito mensagens separadas. Cada mensagem descreve um aspecto diferente da atividade que está ocorrendo (a própria chamada de sistema, caminhos de arquivos, diretório de trabalho atual, título do processo). Essa integração combinará todos os dados de cada uma das mensagens em um único evento. Você pode encontrar mais informações sobre o Auditd Manager aqui.
Além disso, o Auditd Manager resolve o problema da sobrecarga de gerenciamento, pois permite o gerenciamento centralizado por meio do Fleet. Uma atualização da integração será aplicada automaticamente a todos os agentes Elastic que fazem parte da política de agentes alterada.
Configurar a integração com o Auditd Manager é simples. Você precisa garantir que o Auditd não esteja mais em execução em nossos servidores, interrompendo e desativando o serviço.
sudo systemctl stop auditd
sudo systemctl disable auditd
Agora você pode remover a integração do Auditd Logs da nossa política de agente e, em vez disso, instalar/adicionar a integração do Auditd Manager.
Existem diversas opções disponíveis para configurar a integração. O Auditd Manager oferece a opção de definir a configuração de auditoria como imutável (semelhante à configuração da regra de tipo de controle -e 2 na configuração do Auditd), proporcionando segurança adicional, na qual usuários não autorizados não podem alterar o sistema de auditoria, tornando mais difícil ocultar atividades maliciosas.
Você pode aproveitar a funcionalidade Resolver IDs para habilitar a resolução de UIDs e GIDs para seus respectivos nomes.
Para o gerenciamento de regras do Auditd, você pode fornecer as regras na seção Regras de auditoria ou utilizar um arquivo de regras e especificar o caminho do arquivo para leitura. O formato da regra é semelhante ao formato da regra para a integração dos logs do Auditd. No entanto, em vez de fornecer sinalizadores de controle em nosso arquivo de regras, você pode definir essas opções nas configurações de integração.
O Auditd Manager remove automaticamente todas as regras existentes antes de adicionar quaisquer novas regras fornecidas na configuração, tornando desnecessário especificar o sinalizador -D no arquivo de regras. Além disso, você pode definir nosso modo de falha para silent nas configurações e, portanto, não precisa fornecer o sinalizador -f também.
Você também pode definir o limite de pendências, o que seria semelhante a definir a flag -b .
Existe também uma opção para definir a estratégia de contrapressão, equivalente à configuração --backlog_wait_time .
Por fim, marque a opção para preservar o evento original, pois isso permitirá que você o analise com mais facilidade no futuro.
Agora você pode salvar a integração e aplicá-la à política do agente para os hosts dos quais deseja receber logs do Auditd.
Solução de problemas com arquivos de regras do Auditd
O arquivo de regras fornecido pelo Neo23x0 não funciona com o Auditd Manager por padrão. Para que funcione, você precisará fazer alguns ajustes menores, como remover os sinalizadores do tipo de controle, uma conversão de UID para usuário para um usuário que não está presente nos sistemas padrão ou uma entrada de regra redundante. As mudanças que precisam ser feitas serão, em última análise, específicas para o seu ambiente.
Você tem duas maneiras de identificar os erros que serão gerados ao copiar e colar um arquivo incompatível na integração do Auditd Manager. Você pode navegar até o agente que recebeu a política e verificar o erro de entrada da integração. Você pode analisar os erros um por um e alterar ou remover a linha conflitante.
Você também pode usar a guia Descobrir , selecionar nossa visualização de dados do Auditd Manager e filtrar os eventos onde o campo auditd.warnings existe e analisar os avisos um por um.
Por exemplo, você pode ver que o erro indica "tipo de regra desconhecido", o que está relacionado ao fato do Auditd não suportar regras de controle. A mensagem "falha ao converter o usuário 'x' em um ID numérico" está relacionada ao fato de o usuário não existir no sistema. E, por fim, “a regra 'x' é uma duplicata de 'x'” está relacionada a regras duplicadas. Agora que você removeu as entradas conflitantes e o status do nosso agente está saudável, você pode começar a analisar alguns dados do Auditd!
Analisando eventos do Auditd Manager
Agora que você tem os dados do Auditd Manager disponíveis em nosso cluster Elasticsearch, assim como você fez antes, você pode criar uma visualização de dados para o índice logs-auditd_manager.auditd* para filtrar especificamente esses dados. Nosso arquivo de regras implementado contém a seguinte entrada:
-w /etc/sudoers -p rw -k priv_esc
Isso captura ações de leitura e gravação para o arquivo /etc/sudoers e grava esses eventos em um log com a chave priv_esc . Vamos executar o comando cat /etc/sudoers e analisar o evento. Vamos primeiro analisar alguns dos campos que contêm informações gerais.
Você pode ver que o arquivo /etc/sudoers foi acessado pelo binário /usr/bin/cat através da chamada de sistema openat() . Como o proprietário e o grupo do arquivo são root e o usuário que solicita acesso a este arquivo não é UID 0 (root), a chamada de sistema openat() falhou, o que é representado no log. Por fim, você pode ver a etiqueta que foi vinculada a essa atividade específica.
Investigando um pouco mais a fundo, é possível identificar informações adicionais sobre o evento.
Você pode ver a linha de comando do processo que foi executada, bem como o ID do processo e o ID do processo pai que iniciaram a atividade. Além disso, você pode ver de qual arquitetura o evento se originou e através de qual tty (terminal conectado à entrada padrão) o comando foi executado.
Para entender os valores a0-3, você precisa se aprofundar nas chamadas de sistema Unix. A esta altura, você já deve saber o que é uma chamada de sistema (syscall), mas, para sermos completos, uma chamada de sistema Unix (ou syscall) é uma interface fundamental que permite a um programa solicitar um serviço do kernel do sistema operacional, como operações de arquivo, controle de processos ou comunicações de rede.
Vamos dar uma olhada na chamada de sistema openat() . Consultando a página de manual open(2) (fonte), você verá as seguintes informações.
openat() é uma versão evoluída da chamada de sistema open() , permitindo o acesso a arquivos relativos a um descritor de arquivo de diretório (dirfd). Essa chamada de sistema permite que um programa abra um arquivo ou diretório — uma operação crucial para muitas tarefas do sistema. Você pode ver que a chamada de sistema faz parte da biblioteca padrão C e está disponível no cabeçalho fcntl.h através da instrução include #include <fcntl.h> .
Consultando o manual, você pode ver que a sintaxe da chamada de sistema openat() é a seguinte:
int openat(int dirfd, const char *pathname, int flags, /* mode_t mode */);
dirfdEspecifica o descritor de arquivo do diretório.*pathnameé um ponteiro para o nome do arquivo/diretório a ser aberto.flagsDeterminar o modo de operação (ex.: leitura, escrita, criação, etc.).
Voltando ao nosso evento original, você agora está pronto para entender os campos auditd.data.a0-a3 . Os valores a0 a a3 em um log auditd representam os argumentos passados para uma chamada de sistema. Esses argumentos são cruciais para a compreensão do contexto e dos detalhes da execução da chamada de sistema. Vamos analisar como esses valores se relacionam com openat() e o que eles nos dizem sobre a operação tentada com base em nossa exploração anterior.
auditd.data.a0(dirfd): O valor a0,ffffff9c, indica uma diretiva especial,AT_FDCWD, sugerindo que a operação é relativa ao diretório de trabalho atual.auditd.data.a1(pathname): O valora1,7ffd0f81871d, representa um endereço de memória hexadecimal apontando para a string do caminho do arquivo ou diretório de destino. Neste caso, refere-se a uma tentativa de acesso ao arquivo/etc/sudoers.auditd.data.a2(flags): Refletido pelo valora2de0, o argumento flags especifica o modo no qual o arquivo deve ser acessado. Com0indicando que nenhum sinalizador especial foi usado, isso implica uma operação padrão – muito provavelmente acesso somente leitura.auditd.data.a3(mode): O valora3, também 0, torna-se relevante em contextos onde o arquivo está sendo criado, ditando as permissões definidas no novo arquivo.
Com base na análise acima, você agora tem uma compreensão bastante boa de como interpretar os eventos do Auditd Manager.
Uma forma diferente de obter rapidamente uma ideia do que significa um evento do Auditd Manager é usando o Assistente de IA integrado da Elastic. Vamos executar o comando whoami e dar uma olhada no campo auditd.messages dentro do evento.
Você pode pedir ao Elastic AI Assistant para fazer o trabalho pesado e analisar o evento, após o que você só precisa consultar o manual de chamadas de sistema para garantir que tudo estava correto. Vamos primeiro criar um novo prompt do sistema, focado na análise dos logs do Auditd, semelhante a este:
Agora você pode usar o novo prompt do sistema, colar sua mensagem do Auditd sem nenhuma formatação adicional e receber a seguinte resposta:
As ferramentas de IA generativa são muito úteis para obter uma explicação rápida de um evento. Mas a IA generativa pode cometer erros, por isso você deve sempre estar ciente dos riscos ao usar ferramentas de IA para esse tipo de análise e verificar cuidadosamente os resultados gerados. Principalmente ao utilizar os resultados dessas ferramentas para o desenvolvimento de regras de detecção, pois um pequeno erro pode levar a uma lógica falha.
Exemplos de regras de detecção do Auditd Manager
Após a leitura da seção anterior, você já deve ter conhecimento suficiente para começar a analisar os logs do Auditd Manager. O conjunto atual de regras de detecção do Elastic aproveita principalmente a integração com o Elastic Defend, mas o número de regras que utilizam o Auditd está aumentando significativamente. Esta seção irá explorar diversas regras de detecção que utilizam o Auditd, explicar o porquê e tentar ensinar algumas técnicas pouco utilizadas para escrever consultas de regras de detecção.
Possível shell reverso via UDP
A regra "Potencial Reverse Shell via UDP" tem como objetivo identificar shells reversos baseados em UDP. Como o Elastic Defend atualmente não captura tráfego UDP, você pode usar o Auditd para preencher essa lacuna de visibilidade. A regra utiliza a seguinte lógica:
sample by host.id, process.pid, process.parent.pid
[process where host.os.type == "linux" and event.type == "start" and event.action == "executed" and process.name : (
"bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "perl", "python*", "nc", "ncat", "netcat", "php*",
"ruby", "openssl", "awk", "telnet", "lua*", "socat"
)]
[process where host.os.type == "linux" and auditd.data.syscall == "socket" and process.name : (
"bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "perl", "python*", "nc", "ncat", "netcat", "php*",
"ruby", "openssl", "awk", "telnet", "lua*", "socat"
) and auditd.data.a1 == "2"]
[network where host.os.type == "linux" and event.type == "start" and event.action == "connected-to" and
process.name : (
"bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "perl", "python*", "nc", "ncat", "netcat", "php*",
"ruby", "openssl", "awk", "telnet", "lua*", "socat"
) and network.direction == "egress" and destination.ip != null and
not cidrmatch(destination.ip, "127.0.0.0/8", "169.254.0.0/16", "224.0.0.0/4", "::1")]
A regra utiliza a funcionalidade de amostra , que descreve e corresponde a uma série de eventos cronologicamente não ordenados. Isso garantirá que a sequência também seja acionada se os eventos ocorrerem no mesmo milissegundo. Além disso, utilizamos uma abordagem de lista branca para especificar binários suspeitos que são capazes de gerar uma conexão reversa, permitindo uma taxa minimizada de falsos positivos.
Garantimos a captura de conexões UDP aproveitando os dados Auditd relacionados à chamada de sistema socket() .
Vemos que o valor a0 representa o domínio, a1 representa o tipo e a2 representa o protocolo usado. Nossa regra aproveita a sintaxe auditd.data.a1 == "2" , que se traduz no tipo SOCK_DGRAM , que é UDP.
Finalmente, garantimos que capturamos apenas conexões de rede de saída do host e garantimos a exclusão de endereços de loopback IPv4 e IPv6, endereços IPv4 link-local e multicast, e sequenciamos a consulta por process.pid e process.parent.pid para garantir que os eventos se originem do mesmo processo (pai).
Se quisermos procurar processos suspeitos que abrem sockets UDP, podemos consultar todas as chamadas de sistema socket() com auditd.data.a1 == "2", contar o número de ocorrências de processos distintos e classificá-las em ordem crescente para encontrar anomalias. Para isso, podemos utilizar esta consulta ES|QL:
FROM logs-*, auditbeat-*
| EVAL protocol = CASE(
auditd.data.a1 == "1", "TCP",
auditd.data.a1 == "2", "UDP"
)
| WHERE host.os.type == "linux" and auditd.data.syscall == "socket" and protocol == "UDP"
| STATS process_count = COUNT(process.name), host_count = COUNT(host.name) by process.name, protocol
| SORT process_count asc
| LIMIT 100
Ao analisarmos os resultados, podemos observar o surgimento de vários processos interessantes, que podem ser um bom ponto de partida para a busca de ameaças.
Potencial Meterpreter reverso
Outro tipo interessante de conexão reversa para a qual utilizamos o Auditd é a detecção do shell Meterpreter, um shell reverso popular usado no Metasploit Framework. A regra "Potencialmente um Shell Reverso do Meterpreter" aproveita o comportamento padrão de enumeração de hosts do Meterpreter para detectar sua presença.
sample by host.id, process.pid, user.id
[file where host.os.type == "linux" and auditd.data.syscall == "open" and auditd.data.a2 == "1b6" and file.path == "/etc/machine-id"]
[file where host.os.type == "linux" and auditd.data.syscall == "open" and auditd.data.a2 == "1b6" and file.path == "/etc/passwd"]
[file where host.os.type == "linux" and auditd.data.syscall == "open" and auditd.data.a2 == "1b6" and file.path == "/proc/net/route"]
[file where host.os.type == "linux" and auditd.data.syscall == "open" and auditd.data.a2 == "1b6" and file.path == "/proc/net/ipv6_route"]
[file where host.os.type == "linux" and auditd.data.syscall == "open" and auditd.data.a2 == "1b6" and file.path == "/proc/net/if_inet6"]
Quando o Meterpreter é iniciado, ele coleta informações padrão do sistema, como a máquina, o usuário e as informações de roteamento IP, lendo arquivos de sistema específicos. Podemos observar esse comportamento ao descompilar o payload do Meterpreter, pois os caminhos estão codificados diretamente no binário.
Nossa lógica de detecção utiliza auditd.data.a2 == “1b6”, pois isso é consistente com o comportamento do Meterpreter. Podemos observar como o Meterpreter utiliza essa combinação específica de chamadas de sistema para ler arquivos, analisando a forma como ele abre os manipuladores de arquivos.
Apenas para fins informativos, alguns outros caminhos que o Meterpreter lê podem ser encontrados na captura de tela abaixo.
Podemos usar o ES|QL para analisar um conjunto de shells reversos do Meterpreter e descobrir facilmente quais caminhos de arquivo estão sendo acessados por todos eles.
FROM logs-*, auditbeat-*
| WHERE host.os.type == "linux" and event.action == "opened-file" and process.name in ("shell-x64.elf", "JBNhk", "reverse.elf", "shell.elf", "elf") and auditd.data.a2 == "1b6"
| STATS file_access = COUNT_DISTINCT(process.name) by file.path
| SORT file_access desc
| LIMIT 100
Neste exemplo, estamos analisando apenas 5 shells Meterpreter, mas usando ES|QL podemos facilmente escalar essa análise para números maiores. Com base nas informações acima, podemos ver que os caminhos selecionados para a regra de detecção estão presentes em todas as cinco amostras.
Combinando a lógica acima, podemos potencialmente descobrir payloads do Meterpreter no Linux.
Detectado ataque de força bruta FTP/RDP no Linux
Dado que existem muitos clientes FTP/RDP diferentes disponíveis para Linux, e os registros de autenticação não são implementados de forma totalmente semelhante, você pode aproveitar o campo auditd.data.terminal do Auditd para detectar diferentes implementações de FTP/RDP. Nossa lógica de detecção de FTP funciona da seguinte maneira:
sequence by host.id, auditd.data.addr, related.user with maxspan=3s
[authentication where host.os.type == "linux" and event.action == "authenticated" and
auditd.data.terminal == "ftp" and event.outcome == "failure" and auditd.data.addr != null and
auditd.data.addr != "0.0.0.0" and auditd.data.addr != "::"] with runs=5
[authentication where host.os.type == "linux" and event.action == "authenticated" and
auditd.data.terminal == "ftp" and event.outcome == "success" and auditd.data.addr != null and
auditd.data.addr != "0.0.0.0" and auditd.data.addr != "::"] | tail 1
Aqui, sequenciamos 5 tentativas de login falhas com 1 tentativa de login bem-sucedida no mesmo host, do mesmo IP e para o mesmo usuário. Aproveitamos o recurso "tail" , que funciona de forma semelhante ao comando "tail" do Unix, selecionando os últimos X alertas em vez de selecionar todos os alertas dentro do período de tempo. Isso não afeta a interface das regras de detecção do SIEM; serve apenas para facilitar a leitura, já que ataques de força bruta podem gerar muitos alertas rapidamente.
Embora estejamos utilizando diferentes ferramentas FTP, como vsftpd, a entrada auditd.data.terminal permanece semelhante em todas as ferramentas, permitindo-nos capturar uma gama mais ampla de ataques de força bruta FTP. Nossa regra de detecção de RDP utiliza uma lógica semelhante:
sequence by host.id, related.user with maxspan=5s
[authentication where host.os.type == "linux" and event.action == "authenticated" and
auditd.data.terminal : "*rdp*" and event.outcome == "failure"] with runs=10
[authentication where host.os.type == "linux" and event.action == "authenticated" and
auditd.data.terminal : "*rdp*" and event.outcome == "success"] | tail 1
Dado que os campos auditd.data.terminal de diferentes clientes RDP são inconsistentes, podemos usar curingas para capturar seus eventos de autenticação.
Conexão de rede a partir de um binário com região de memória RWX
A chamada de sistema mprotect() é usada para alterar as proteções de acesso em uma região de memória que já foi alocada. Essa chamada de sistema permite que um processo modifique as permissões de páginas em seu espaço de endereço virtual, habilitando ou desabilitando permissões como leitura, gravação e execução para essas páginas. Nosso objetivo com essa regra de detecção é identificar conexões de rede provenientes de binários que possuem permissões de leitura, gravação e execução em regiões da memória. Vamos dar uma olhada na chamada de sistema.
Para a nossa lógica de regras de detecção, o valor prot é o mais importante. Você pode ver que prot pode ter os seguintes sinalizadores de acesso:
Conforme mencionado, prot é um OR bit a bit dos valores na lista. Portanto, para permissões de leitura, gravação e execução, estamos procurando um número inteiro de:
int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
Isso se traduz em um valor de 0x7 após a operação bit a bit e, portanto, estaremos olhando para um auditd.data.a2 == “7”. Criamos duas regras de detecção que aproveitam essa lógica: Execução desconhecida de binário com região de memória RWX e Conexão de rede a partir de binário com região de memória RWX. As regras de detecção que utilizam configurações específicas do Auditd para funcionar terão uma observação sobre qual regra adicionar em seu guia de configuração:
O método anterior utiliza o tipo de regra new_terms , que nos permite detectar termos previamente desconhecidos dentro de um intervalo de tempo especificado. Isso nos permite detectar binários com permissões RWX que estão sendo vistos em um host específico pela primeira vez, ao mesmo tempo que reduzimos os falsos positivos para binários que são excessivamente permissivos, mas usados regularmente.
Este último utiliza a seguinte lógica de detecção:
sample by host.id, process.pid, process.name
[process where host.os.type == "linux" and auditd.data.syscall == "mprotect" and auditd.data.a2 == "7"]
[network where host.os.type == "linux" and event.type == "start" and event.action == "connection_attempted" and
not cidrmatch(destination.ip, "127.0.0.0/8", "169.254.0.0/16", "224.0.0.0/4", "::1")
]
Analisamos um processo sendo executado com essas permissões RWX, após o qual uma conexão de rede (excluindo endereços de loopback, multicast e link-local) é iniciada.
Curiosamente, o Metasploit costuma atribuir essas permissões RWX a regiões específicas de seus payloads gerados. Por exemplo, um dos eventos que acionam essa lógica de detecção em uma pilha de testes está relacionado à execução do Payload Postgres do Metasploit para Linux. Ao analisar o código-fonte desta carga útil, você pode ver que a função payload_so define os sinalizadores PROT_READ, PROT_WRITE e PROT_EXEC .
Em seguida, uma região de memória específica, com um tamanho de página específico de 0x1000 recebe os sinalizadores de acesso RWX de maneira semelhante à descrita anteriormente.
Após executar o payload e consultar o rastreamento de pilha, você poderá ver vários resultados retornados, todos relacionados a payloads do Metasploit Meterpreter.
Com foco na carga útil do Postgres que estávamos analisando anteriormente, você pode ver o caminho exato de execução da carga útil por meio do nosso analisador visual de eventos. O Elastic Security permite que qualquer evento detectado pelo Elastic Endpoint seja analisado usando um analisador visual baseado em processos, que exibe uma linha do tempo gráfica dos processos que levaram ao alerta e dos eventos que ocorreram imediatamente depois. Analisar os eventos no analisador visual de eventos é útil para determinar a origem de atividades potencialmente maliciosas e outras áreas do seu ambiente que possam estar comprometidas. Isso também permite que os analistas de segurança examinem detalhadamente todos os hosts, processos e outros eventos relacionados para auxiliar em suas investigações.
No analisador, você pode ver o Perl sendo usado para criar e preencher o payload jBNhk no diretório /tmp (com permissões RWX) e para gerar um shell Meterpreter reverso.
Conclusão
Neste post, mergulhamos no mundo do Auditd, explicando o que é e qual a sua finalidade. Mostramos como configurar e executar o Auditd, como direcionar esses logs para o Elasticsearch para aumentar a visibilidade do Unix/Linux e permitir que você aprimore suas habilidades de engenharia de detecção em Linux. Discutimos como criar regras no Auditd para monitorar atividades específicas e como interpretar os eventos que ele gera. Para facilitar a sua vida, apresentamos o Auditd Manager, uma integração criada pela Elastic para aliviar parte da sua carga de gestão. Por fim, concluímos explorando várias regras de detecção e algumas das pesquisas que levaram à sua criação, permitindo que você aproveite ao máximo essa fonte de dados.
Esperamos que este guia tenha sido útil! Incorporar o Auditd em seus sistemas Unix é uma jogada inteligente para obter maior visibilidade da segurança. Quer você opte por usar nossas regras de detecção predefinidas ou criar as suas próprias, o Auditd pode realmente fortalecer sua estratégia de segurança Unix.
