Durante uma auditoria operacional no ambiente de desenvolvimento de um projeto, identifiquei comportamento compatível com exploração RCE em dependência legada (React2Shell). O incidente não ficou na camada de aplicação: houve indícios de persistência em shell startup e tentativa de execução recorrente em tmp, com padrão típico de dropper para escalada posterior.
Este artigo documenta exatamente o que executei, em ordem cronológica, comandos incluídos, critérios de decisão e validações de saída. O objetivo foi restaurar disponibilidade com rastreabilidade técnica e reduzir risco residual para nível aceitável de produção.
1) Detecção inicial, triagem e ativação do protocolo#
O primeiro alerta não veio de dashboard bonito: veio de comportamento anômalo de processos de diagnóstico e ruído incomum em sessão shell.
Sinais observados na triagem inicial:
- interrupções intermitentes durante inspeção com
psetop. - artefatos executáveis e ocultos em
tmp. - entradas suspeitas em inicialização de shell em
profile. - conexões de saída sem vínculo com o fluxo normal da aplicação.
Comandos executados na triagem quente:
ps auxf
ps -eo pid,ppid,user,cmd --sort=-%cpu | head -n 40
top -b -n 1 | head -n 60
ss -lntup
ss -plant
journalctl -xe --no-pager | tail -n 200
last -a | head -n 30
Com base nesses indicadores, ativei resposta a incidente em modo contenção.
1.1) Varredura sistêmica de outras compromissões#
Após constatar os primeiros indicadores, é fundamental expandir a triagem técnica de maneira a abranger outras superfícies do sistema operacional para mapear a profundidade da invasão:
- Processos Suspeitos: Filtrar executáveis estranhos ativos e processos que rodam em background associados a usuários de serviços web (como
nginxouwww-data) sem terminais associados:
ps auxf | grep -v "\[" | awk '{print $11}' | sort | uniq -c | sort -rn | head -20
- Conexões de Saída Ativas: Listar soquetes que não realizam binds em interfaces locais e apontam para a Internet:
ss -plant | grep -v "127.0.0.1"
- Modificação Recente de Arquivos: Investigar arquivos criados ou modificados nas últimas 24 horas em todo o sistema (limitando para evitar sobrecarga de I/O):
find / -mtime -1 -type f 2>/dev/null | head -50
- Agendamentos de Tarefas (Cron): Auditar as tabelas crontab dos usuários e o diretório de tarefas globais do sistema em
cron.d:
crontab -l
ls -la /etc/cron.d/
ls -la /etc/cron.daily/
cat /var/log/cron | tail -n 100
2) Contenção imediata (janela de impacto)#
A contenção teve três objetivos: parar propagação, preservar evidência e evitar perda de disponibilidade em sistemas adjacentes.
Ações executadas:
- congelamento de mudanças (deploy e automações de CI/CD do projeto afetado).
- bloqueio de tráfego externo não essencial no host comprometido.
- isolamento de credenciais de operação usadas naquele host.
- preservação de artefatos para análise posterior.
Exemplo de bloqueio emergencial aplicado no host:
# Política restritiva temporária
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# Exceções mínimas para administração segura durante resposta
iptables -A INPUT -p tcp --dport 22 -s <SEU_IP_ADMIN>/32 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -d <SEU_IP_ADMIN>/32 -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
Nota operacional: em resposta a incidente, eu privilegio isolamento primeiro, limpeza depois. Sem isolamento, qualquer correção vira corrida contra processo ativo do atacante.
2.1) Análise de movimentação lateral e exfiltração de dados#
Com a contenção ativa, o próximo passo consiste em investigar se houve tentativa do atacante de atingir outros servidores da sub-rede local ou exfiltrar dados sensíveis:
- Movimentação Lateral por SSH: Consultar os registros de logins bem-sucedidos a partir de IPs da rede interna em
auth.logousecure:
grep "Accepted" /var/log/auth.log | awk '{print $11}' | sort | uniq -c
# Em sistemas Rocky Linux ou RedHat:
grep "Accepted" /var/log/secure | awk '{print $11}' | sort | uniq -c
- Conexões de Rede Suspeitas: Analisar a tabela de conexões ativas direcionadas a sub-redes corporativas:
ss -plant | grep -v "127.0.0.1" | awk '{print $5}' | cut -d: -f1 | sort | uniq -c
- Identificação de Exfiltração de Dados: Auditar o consumo de largura de banda e identificar transferências massivas incomuns no tráfego de saída:
# Visualização rápida com socket status estabelecido
ss -plant state established | awk '{print $5}' | sort | uniq -c
# Monitorar tráfego ativo de I/O na interface de rede
iftop -i eth0 -t -s 10
# Investigar diretórios temporários em busca de arquivos compactados grandes
du -sh /tmp/
find /tmp -size +10M -type f 2>/dev/null
3) Coleta forense mínima viável (antes de tocar no disco)#
Antes de remover qualquer arquivo, executei coleta de evidências para manter cronologia dos eventos e sustentar análise técnica posterior em ir-evidence.
Itens coletados:
- processos e árvores de execução (
ps,top,pstree). - sockets e conexões (
ss -plant,ss -lntup). - logs críticos (
journalctl, auth logs, logs de aplicação). - hashes de arquivos suspeitos em
tmpe startup scripts.
Exemplo de coleta aplicada:
mkdir -p /root/ir-evidence/{logs,proc,net,fs}
date -u > /root/ir-evidence/timestamp_utc.txt
ps auxf > /root/ir-evidence/proc/ps_auxf.txt
ss -plant > /root/ir-evidence/net/ss_plant.txt
ss -lntup > /root/ir-evidence/net/ss_lntup.txt
journalctl -b --no-pager > /root/ir-evidence/logs/journal_current_boot.log
find /tmp -maxdepth 2 -type f -printf "%TY-%Tm-%Td %TT %p\n" \
> /root/ir-evidence/fs/tmp_file_timeline.txt
find /etc/profile* -maxdepth 1 -type f -exec sha256sum {} \; \
> /root/ir-evidence/fs/profile_hashes.txt
Compactei evidências para retenção offline:
tar -czf /root/ir-evidence-$(date +%F-%H%M).tar.gz /root/ir-evidence
sha256sum /root/ir-evidence-*.tar.gz > /root/ir-evidence.sha256
4) Recuperação forense em rescue mode (sem SO comprometido em execução)#
Para eliminar qualquer interferência do ambiente contaminado, migrei o host para Rescue Mode e trabalhei com montagem passiva.
Fluxo executado:
- reboot em modo rescue via painel do provedor.
- identificação de partições e montagem em leitura.
- extração seletiva de dados confiáveis.
- revisão de persistência SSH e shell startup fora do runtime comprometido.
Sequência base utilizada:
lsblk
blkid
mount /dev/vda2 /mnt/sysroot
mount -o remount,ro /mnt/sysroot
4.1) Backup cirúrgico (somente o que é confiável)#
Copiei apenas o que era necessário para continuidade de negócio:
- código-fonte versionado do projeto.
- dumps de banco e arquivos de configuração essenciais.
- artefatos de deploy reconstruíveis por pipeline foram descartados.
Itens explicitamente excluídos:
node_modules, caches de pacote e binários transitórios.- qualquer executável fora da cadeia conhecida do projeto.
Exemplo de extração seletiva:
rsync -aHAX --numeric-ids \
--exclude='node_modules' \
--exclude='.cache' \
--exclude='tmp' \
/mnt/sysroot/home/domain_user/app/ /mnt/backup/app/
4.2) Auditoria de chaves e persistência#
Revisei e saneei todos os pontos de acesso persistente:
cat /mnt/sysroot/root/.ssh/authorized_keys
cat /mnt/sysroot/home/*/.ssh/authorized_keys
grep -R "ssh-rsa\|ssh-ed25519" /mnt/sysroot/home -n
find /mnt/sysroot/etc -type f -name "*profile*" -o -name "*rc" | sort
Entradas não reconhecidas foram removidas, registradas e correlacionadas com o horário dos eventos no relatório de incidente.
5) Decisão técnica: rebuild completo (clean slate)#
Com evidência de tentativa de persistência e vetor com potencial de escalada, optei por rebuild completo do host.
Critério usado para descartar "limpeza parcial":
- confiança comprometida em integridade de bibliotecas e binários.
- alto custo de validar 100% de um sistema possivelmente adulterado.
- risco residual inaceitável para retorno de carga em produção.
Resultado: formatação e reinstalação completa do SO como única opção com rastreabilidade e compliance defensável.
6) Hardening pós-reinstalação (Rocky Linux baseline)#
Após reinstalar Rocky Linux, apliquei uma baseline prática de endurecimento em camadas.
6.1) Backups preventivos pré-hardening#
Antes de realizar modificações nas configurações de segurança pós-reinstalação, é mandatório estabelecer cópias de segurança locais e datar as versões de fábrica dos arquivos de configuração críticos:
- Backup da Configuração SSH em
sshd_config:
cp /etc/ssh/sshd_config /root/sshd_config.bak.$(date +%Y%m%d)
- Backup das Configurações Globais de Rede em
sysctl.conf:
cp /etc/sysctl.conf /root/sysctl.conf.bak.$(date +%Y%m%d)
- Backup das Regras Básicas do Firewall:
iptables-save > /root/iptables-backup-$(date +%Y%m%d).rules
6.2) Segregação de privilégios e runtime sem root#
Criei usuário de sistema dedicado em domain_user para execução da aplicação, sem shell de administração para tarefas comuns.
sudo adduser --system --group --home /home/domain_user domain_user
id domain_user
Ajustei ownership da aplicação para o usuário de runtime e removi permissões excessivas de escrita em diretórios sensíveis.
6.3) Endurecimento de filesystem temporário#
Configurei tmp com noexec,nosuid,nodev em fstab para reduzir vetor de execução de payload em diretório temporário.
echo "tmpfs /tmp tmpfs defaults,noexec,nosuid,nodev 0 0" >> /etc/fstab
mount -o remount /tmp
findmnt /tmp
6.4) Hardening de SSH#
No arquivo sshd_config, apliquei:
PasswordAuthentication noPermitRootLogin no- porta administrativa customizada
- allowlist de usuários autorizados
Validação e aplicação:
sshd -t
systemctl restart sshd
systemctl status sshd --no-pager
6.5) Perímetro com firewalld (deny by default)#
Substituí regra aberta por política de menor privilégio:
firewall-cmd --permanent --set-default-zone=drop
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --reload
firewall-cmd --list-all
6.6) Isolamento lógico de dados#
Mantive dados operacionais em domain_user e isolei caminho de aplicação do core do SO para simplificar backup, restore e governança de permissões.
mkdir -p /home/www
ln -s /home/www /www
ls -la /
6.7) Regras de kernel e higiene básica#
Apliquei parâmetros de rede conservadores em sysctl.conf para reduzir superfícies conhecidas:
cat >/etc/sysctl.d/99-hardening.conf <<'SYSCTL'
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.tcp_syncookies = 1
SYSCTL
sysctl --system
6.8) Validação pós-hardening#
Concluídas as configurações de segurança, validei fisicamente a aplicação de cada política no sistema para evitar desvios:
- Validação da Sintaxe do SSH:
sshd -t
systemctl status sshd
- Validação do Estado do Firewall:
firewall-cmd --list-all
- Validação das Variáveis do Sysctl em Memória:
sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.tcp_syncookies
- Validação de Montagem Segura de
tmp:
mount | grep tmp
findmnt /tmp
- Validação do Usuário Dedicado e Permissões:
id domain_user
7) Restauração de aplicação e deploy controlado#
Com host endurecido, executei restauração com foco em previsibilidade:
- restauração de código limpo e configuração auditada.
- reinstalação de dependências a partir de lockfile.
- subida com gerência de processo e observabilidade mínima.
Stack operacional aplicada:
- Bun para build e execução.
- PM2 para supervisão, restart automático e controle de processo.
Validações de pós-deploy:
pm2 status
pm2 logs --lines 100
ss -lntup | grep -E ':80|:443|:3000'
systemctl status sshd firewalld --no-pager
Critério de saída do incidente:
- serviço estável por janela contínua sem IOC novo.
- logs sem tentativa de reexecução do vetor anterior.
- acesso administrativo restrito e auditável.
7.1) Monitoramento de integridade pós-rebuild#
Para certificar que o novo ambiente permanece íntegro e imune a novas tentativas de invasão, implemente a rotina de monitoramento ativo:
- Checar Processos Novos em Execução:
ps auxf | head -30
- Auditar Novas Conexões Ativas:
ss -plant | head -20
- Inspecionar logs por falhas ou erros em tempo real:
journalctl --since "1 hour ago" | grep -iE "error|fail|deny|block"
- Configuração de Alertas: Integrar métricas operacionais com ferramentas como Prometheus e Grafana, configurando alertas para gatilhos de conexões incomuns no tráfego de saída.
7.2) Backup completo pós-reconstrução#
Concluída a reconstrução e validação do ambiente de produção, é essencial consolidar backups limpos de baseline para recuperação de desastres ágil caso o incidente ocorra novamente:
- Backup da Configuração Endurecida do Sistema:
tar czf /root/system-backup-$(date +%Y%m%d).tar.gz \
/etc/ssh/sshd_config \
/etc/sysctl.conf \
/etc/sysctl.d/99-hardening.conf \
/etc/firewalld/
- Backup Limpo dos Arquivos da Aplicação:
tar czf /root/app-backup-$(date +%Y%m%d).tar.gz /home/domain_user/app/
- Exportação das Regras de Baseline Ativas:
iptables-save > /root/iptables-$(date +%Y%m%d).rules
sysctl -a > /root/sysctl-$(date +%Y%m%d).conf
8) Plano de comunicação e notificação de stakeholders#
Um processo maduro de resposta a incidentes exige a notificação tempestiva das equipes de governança e stakeholders afetados para conter danos reputacionais e cumprir requisitos contratuais.
Checklist de notificação e janelas temporárias#
Imediato (janela de 0 a 1 hora)#
- [ ] Notificar a equipe interna de segurança da informação (SecOps) e o DPO (Data Protection Officer).
- [ ] Comunicar a liderança de engenharia e diretoria operacional.
- [ ] Documentar o início do incidente e criar a linha do tempo (timeline) preliminar.
Curto prazo (janela de 1 a 24 horas)#
- [ ] Elaborar o relatório preliminar de contenção e análise técnica inicial.
- [ ] Fornecer status sobre isolamento das credenciais e mitigação periférica.
- [ ] Planejar os próximos passos de rebuild e validações de integridade.
Médio prazo (janela de 1 a 7 dias)#
- [ ] Redigir e publicar o relatório completo pós-incidente.
- [ ] Compartilhar lições aprendidas e atualizações necessárias nos playbooks de resposta.
- [ ] Validar a eficácia dos novos controles e notificar clientes se houver impacto contratual.
9) Post-incident review (PIR) e lições aprendidas#
O encerramento de qualquer incidente de segurança deve ser documentado formalmente através de uma revisão retrospectiva detalhada (Post-Mortem):
# Relatório de Post-Incident Review (PIR)
## O que aconteceu?
- **Timeline Detalhada:** Registro exato das horas em UTC da detecção inicial, isolamento e rebuild.
- **Vetor de Ataque:** Exploração RCE na dependência vulnerável `React2Shell`.
- **Impacto Estimado:** Indisponibilidade do host e suspensão temporária das pipelines de CI/CD.
## O que fizemos?
- **Ações de Contenção:** Bloqueios de tráfego via iptables e isolamento total das chaves operacionais.
- **Evidências Coletadas:** Empacotamento criptográfico de logs e arquivos modificados sob `/root/ir-evidence`.
- **Decisões Tomadas:** Rebuild completo do sistema operacional para recuperação total de integridade.
## O que podemos melhorar?
- **Controles Ausentes:** Ausência de varredura automatizada contínua de dependências no pipeline.
- **Processos Aprimorados:** Implementação de baseline rígida de hardening de filesystem já no bootstrap de hosts.
- **Treinamento Necessário:** Treinar o time operacional de SecOps para auditorias preventivas de sockets e crontabs.
## Próximos passos
- Implementar análise estática de composição de software (SCA).
- Revisar a automação de logs centralizados e alertas preventivos de rede.
10) Conformidade e compliance regulatório (LGPD/GDPR/pci-dss)#
A resposta a incidentes deve estar alinhada com as obrigações regulatórias vigentes do mercado de proteção de dados pessoais:
Tabela de relação regulatória e obrigações#
| Legislação / Framework | Exigência e Prazos | Ação Prática no Incidente |
|---|---|---|
| LGPD (Art. 48) | Notificação de incidentes à ANPD e aos titulares que possam acarretar risco relevante em tempo razoável (recomendado 72h). | Elaborar documentação formal com impacto estimado, mitigação aplicada e medidas tomadas de segurança. |
| GDPR (Art. 33) | Notificação obrigatória à autoridade supervisora em até 72 horas após detecção inicial. | Envio de formulário de violação detalhado indicando o vetor de ataque e categorias de dados afetadas. |
| PCI-DSS (v4.0) | Registro imutável de logs de auditoria de acessos e monitoramento ativo do perímetro do ambiente de dados de portadores de cartões. | Manutenção dos arquivos comprimidos em local isolado seguro e integridade de assinaturas. |
| ISO 27001 (A.12.6) | Gestão de vulnerabilidades técnicas e controle operacional documentado de incidentes. | Atualização do inventário de riscos, logs de incidentes e playbooks de recuperação ativa. |
11) Checklist operacional de resposta a incidentes e matriz de riscos#
Checklist operacional do ciclo de resposta#
- [ ] Fase 1: Detecção e Triagem
- [ ] Executar comandos de diagnóstico rápido (
ps,ss,journalctl). - [ ] Identificar indicadores de compromisso (IOCs).
- [ ] Ativar formalmente o protocolo de crise.
- [ ] Fase 2: Contenção de Segurança
- [ ] Aplicar políticas restritivas temporárias de firewall.
- [ ] Congelar pipelines de deploy do projeto.
- [ ] Rotacionar chaves e credenciais de acesso operacionais.
- [ ] Fase 3: Coleta Forense
- [ ] Criar diretório seguro com controle de hashes sha256.
- [ ] Extrair logs, conexões e timelines de arquivos modificados.
- [ ] Compactar e exportar evidências para repositório offline.
- [ ] Fase 4: Recuperação em Rescue Mode
- [ ] Efetuar boot passivo de rescue mode.
- [ ] Montar filesystem comprometido sob a flag
ro(read-only). - [ ] Sincronizar dados cirurgicamente com rsync isolado.
- [ ] Fase 5: Rebuild e Hardening
- [ ] Formatar o volume e realizar instalação limpa do Rocky Linux.
- [ ] Aplicar baseline de hardening (SSH, firewall, kernel sysctl e tmpfs).
- [ ] Validar integridade e sintaxe das políticas de segurança aplicadas.
- [ ] Fase 6: Pós-Incidente e Notificações
- [ ] Configurar monitoramento contínuo de portas e logs pós-redeploy.
- [ ] Emitir notificações regulatórias à ANPD/GDPR se aplicável.
- [ ] Elaborar relatório de Post-Incident Review (PIR).
Matriz de riscos de segurança operacional#
| Ameaça / Vulnerabilidade | Severidade | Impacto Estimado | Ação de Mitigação Implementada |
|---|---|---|---|
| Execução Arbitrária (RCE) | Crítica | Compromisso total de integridade e confidencialidade do host. | Reinstalação integral do SO (clean slate) e atualização rigorosa de pacotes. |
| Persistência por SSH / Shell | Alta | Acesso persistente do atacante persistindo a reinstalações de pacotes. | Auditoria estrita em Rescue Mode das chaves autorizadas e shell profiles globais. |
| Movimentação Lateral | Alta | Contaminação de servidores adjacentes e infraestrutura de banco de dados. | Isolamento imediato via regras restritivas do firewall e auditoria de tráfego. |
| Exfiltração de Dados | Alta | Vazamento de credenciais corporativas e dados sensíveis de clientes. | Bloqueio de tráfego de saída incomum e monitoramento em tempo real do volume de I/O. |
| Downtime da Aplicação | Média | Perda de disponibilidade temporária dos serviços em produção. | Automação PM2 e monitoramento contínuo de status de processos. |
A principal lição operacional foi objetiva: em cenário com tentativa de escalada, rapidez sem método aumenta risco. O protocolo que funcionou foi sequencial e disciplinado: detectar, conter, preservar evidência, reconstruir, endurecer e só então restaurar carga. Esse tipo de resposta não é teoria. É execução técnica orientada a continuidade, auditoria e redução real de superfície de ataque em ambiente Linux.
Este artigo foi útil?
Deixe uma reação rápida para apoiar o conteúdo:
Este post está licenciado sob CC BY-NC.



Comentários
Participe da discussão abaixo.
0 comentários