# Encontrar e remover chaves SSH desconhecidas

> Verificar authorized_keys: onde estão as chaves SSH no servidor, como reconhecer entradas estranhas, removê-las em segurança e reforçar depois o acesso SSH.

Fonte: https://phpsos.de/pt/blog/ssh-schluessel-pruefen/  
Atualizado em: 25/10/2026  
Prestador: PHP SOS, Assistência de emergência PHP e segurança de servidores. Ajuda imediata por WhatsApp: https://wa.me/491736494914?text=Ol%C3%A1%2C%20PHP%20SOS%2C%20precisamos%20de%20ajuda%20com%20o%20nosso%20servidor%20PHP.%20Empresa%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**Em resumo:** Para encontrar chaves SSH desconhecidas, tem de verificar todos os ficheiros authorized_keys do servidor, não só o de root. Apure com `sshd -T` que ficheiros o seu serviço SSH lê, liste as impressões digitais de cada chave e compare-as com as chaves conhecidas. Primeiro guardar as entradas estranhas, depois removê-las e a seguir reforçar o acesso.

## A chave que sobrevive a qualquer mudança de palavra-passe

Depois de um incidente, muitos operadores alteram primeiro todas as palavras-passe. Contra uma das portas dos fundos mais discretas isso não ajuda: uma chave pública adicional num ficheiro `authorized_keys`. Quem possui a chave privada correspondente autentica-se sem palavra-passe, até alguém encontrar a linha.

As chaves SSH desconhecidas pertencem por isso aos indícios que depois de uma execução de código devem ser sempre verificados. Para o PHP2Shell não existem Indicators of Compromise publicados e confirmados; a deteção assenta na análise de comportamento. Uma chave estranha não é uma prova específica do PHP2Shell, mas é um sinal claro de que alguém queria um acesso duradouro. Outros indícios descreve-os [Já fui comprometido?](https://phpsos.de/pt/php2shell/bin-ich-gehackt-anzeichen/).

## Onde estão as chaves SSH no servidor

O OpenSSH lê, segundo a documentação, por defeito dois ficheiros no diretório pessoal de cada utilizador: `.ssh/authorized_keys` e `.ssh/authorized_keys2`. O segundo é muitas vezes esquecido. A definição pode ser alterada e, com `AuthorizedKeysCommand`, o servidor pode até obter chaves de um programa externo. Verifique por isso primeiro o que realmente vale no seu servidor:

```bash
# Mostrar a configuração SSH efetiva (apenas leitura)
sudo sshd -T | grep -iE '^(authorizedkeysfile|authorizedkeyscommand|permitrootlogin|passwordauthentication|pubkeyauthentication)'

# Ficheiros de configuração adicionais e blocos Match
ls -la /etc/ssh/sshd_config.d/ 2>/dev/null
sudo grep -rn -iE '^\s*(Match|AuthorizedKeys)' /etc/ssh/
```

Um local especial é o diretório pessoal do utilizador do servidor web. No Debian e no Ubuntu, para o `www-data` é muitas vezes `/var/www`. Se este diretório for gravável pelo PHP, código introduzido pode criar aí um `.ssh/authorized_keys`. Se a autenticação então resulta depende da shell de login e das definições SSH, mas o próprio ficheiro já é um sinal de alarme.

Nem toda a entrada desconhecida é maliciosa. Ferramentas de deployment, serviços de cópia de segurança ou prestadores anteriores depositam chaves próprias. Essas entradas devem, porém, ter um proprietário e uma finalidade conhecidos.

## Verificar authorized_keys: passo a passo

Os comandos seguintes não alteram nada. Listam todos os ficheiros de chaves dos utilizadores e mostram a impressão digital de cada chave:

```bash
# Todos os ficheiros authorized_keys nos diretórios pessoais de todos os utilizadores
getent passwd | cut -d: -f1,6 | while IFS=: read -r user home; do
  for f in "$home/.ssh/authorized_keys" "$home/.ssh/authorized_keys2"; do
    [ -f "$f" ] && echo "== $user: $f" && sudo ls -la --time-style=full-iso "$f"
  done
done

# Mostrar impressões digitais e comentários de um ficheiro
sudo ssh-keygen -lf /root/.ssh/authorized_keys

# Outros ficheiros de chaves fora dos locais habituais
sudo find / -xdev -name 'authorized_keys*' 2>/dev/null
```

Percorra o resultado com esta lista de verificação:

1. **Cada chave pertence a uma pessoa ou serviço conhecido?** Compare as impressões digitais, não apenas o comentário.
2. **Algum utilizador tem chaves que não devia ter?** Por exemplo o utilizador do servidor web, da base de dados ou contas de serviço.
3. **Há opções antes da chave?** As entradas com `command=` executam um comando fixo em cada autenticação. É legítimo para cópias de segurança, mas também um esconderijo.
4. **Quando foi alterado o ficheiro pela última vez?** Uma data de alteração depois de 17/10/2026, a primeira tentativa de ataque do PHP2Shell observada segundo relatos dos meios de comunicação, merece especial atenção. Os carimbos de data/hora podem, porém, ser falsificados.
5. **Proprietário e permissões coincidem?** Um ficheiro que pertence a um utilizador diferente do do diretório pessoal chama a atenção.

## Remover chaves estranhas em segurança

Antes de apagar uma linha, guarde o ficheiro com carimbo de data/hora e soma de verificação fora do servidor. Anote a impressão digital da chave estranha. Ajuda mais tarde na questão de saber se a mesma chave aparece também noutros servidores, por exemplo numa agência com muitos sistemas de clientes.

Verifique além disso os registos de autenticação. Em `/var/log/auth.log` (Debian, Ubuntu) ou `/var/log/secure` (família RHEL), o serviço SSH regista as autenticações bem-sucedidas com a impressão digital da chave usada. Assim vê se a chave estranha já foi usada e a partir de que endereço.

Pense também no sentido inverso. Se no servidor houver chaves privadas, por exemplo em `~/.ssh/id_*` para deployments ou cópias de segurança, um atacante pode tê-las copiado. Com elas alcança talvez outros servidores, repositórios Git ou destinos de cópia de segurança. Tais chaves consideram-se esgotadas depois de uma intrusão: criar chaves novas e remover as antigas em todos os sistemas de destino.

Uma chave estranha raramente é o único vestígio. Quem a depositou tinha direitos de escrita e talvez tenha montado outros caminhos, como cronjobs ou contas adicionais. Verifique por isso também os [cronjobs escondidos](https://phpsos.de/pt/blog/cronjobs-als-hintertuer/) e as [contas de administrador estranhas](https://phpsos.de/pt/blog/fremde-admin-konten-finden/). Se o atacante teve direitos de root, uma reconstrução do servidor é muitas vezes mais fiável do que uma limpeza.

> **Importante:**
> Só remova chaves estranhas quando o PHP estiver num estado corrigido (8.5.12, 8.4.27, 8.3.36, 8.2.35 ou backport confirmado) e todos os workers tiverem sido reiniciados. Caso contrário, o atacante pode voltar a inscrever a chave imediatamente através da mesma vulnerabilidade.

## Reforçar depois o acesso SSH

Depois da limpeza, vale a pena um reforço rápido. A maioria dos pontos aplica-se depressa, mas deve ser sempre testada com uma segunda sessão aberta, para que não fique bloqueado.

| Medida | Definição ou procedimento |
|---|---|
| Autenticação apenas por chave | `PasswordAuthentication no` |
| Não permitir autenticação direta de root | `PermitRootLogin no`, trabalhar através de contas pessoais com sudo |
| Desativar o segundo ficheiro de chaves | `AuthorizedKeysFile .ssh/authorized_keys` |
| Limitar a chave à origem | opção `from=` antes da chave, por exemplo para servidores de cópia de segurança |
| Restringir chaves de serviço | opção `restrict` e `command=` fixo para automatização |
| Utilizador do servidor web sem login | shell de login `nologin`, sem `.ssh` no diretório pessoal |

Mantenha além disso uma lista de todas as chaves autorizadas com proprietário e finalidade. Quando um colaborador ou prestador sai, a sua chave é removida em todos os servidores. Sem esta lista, a próxima verificação volta a ser trabalho de detetive. Diretrizes de reforço reconhecidas para SSH constam também dos CIS Benchmarks.

## Como ajuda concretamente a PHP SOS?

- Apuramos que ficheiros de chaves o seu serviço SSH realmente lê e verificamos cada entrada face aos proprietários conhecidos.
- Guardamos os achados e analisamos os registos de autenticação, para esclarecer se uma chave estranha foi usada.
- Limpamos chaves, contas e cronjobs pela ordem certa e fechamos antes a vulnerabilidade.
- No âmbito do [hardening de servidores](https://phpsos.de/pt/leistungen/server-haertung/), aplicamos as definições SSH e configuramos uma gestão de chaves com lista de proprietários.


## Perguntas frequentes

**Como reconheço que uma chave SSH é estranha?**  
Cada chave tem uma impressão digital e, em geral, um comentário no fim da linha. Compare as impressões digitais com as chaves dos seus colaboradores e prestadores. O comentário por si só não prova nada, porque é de livre escolha e pode ser falsificado.

**Ajuda alterar a palavra-passe de root?**  
Contra uma chave introduzida, não. A autenticação por chave não precisa de palavra-passe. Por isso, os próprios ficheiros authorized_keys têm de ser verificados e limpos.

**Porque é que o utilizador do servidor web pode ter uma chave SSH?**  
O utilizador do servidor web tem um diretório pessoal próprio, no Debian e no Ubuntu muitas vezes /var/www. Se aí existir um .ssh/authorized_keys e a conta tiver uma shell de login, é possível autenticar-se como esse utilizador. Com um diretório web gravável, código PHP introduzido pode criar um ficheiro destes.

**O que é authorized_keys2?**  
Um segundo ficheiro mais antigo que o OpenSSH também lê, segundo a configuração padrão. Muitos guias de verificação ignoram-no. Controle com sshd -T que ficheiros o seu servidor realmente avalia.

## Fontes

- [BSI: indicações sobre incidentes de segurança informática](https://www.bsi.bund.de/)
- [php.net: avisos de segurança](https://www.php.net/)
- [CIS Benchmarks](https://www.cisecurity.org/cis-benchmarks)
