Encontrando uma Senha de Banco de Dados Fixa no Arquivo de Config de uma Aplicação Web
O desafio
Você abriu um shell num servidor web como www-data. A aplicação lê a senha do banco de um arquivo na raiz web. Explore o shell, leia o arquivo certo e envie a senha.
O que você vai aprender
- Reconhecer onde aplicações PHP e outras aplicações web armazenam as configurações de conexão com o banco de dados
- Usar reconhecimento básico via shell para listar a raiz web e ler um arquivo de config
- Procurar no código-fonte e na config por chaves de credencial como db_pass e password
- Explicar como uma config legível transforma acesso web em acesso ao banco de dados
- Aplicar a correção padrão: variáveis de ambiente e um gerenciador de segredos
Habilidades testadas
Pré-requisitos
- Familiaridade com comandos básicos de shell (ls, cat, grep)
- Capacidade de ler um arquivo de configuração PHP simples
Como funciona
Toda aplicação web que se comunica com um banco de dados precisa de um usuário e uma senha para abrir essa conexão. Em projetos PHP, essas configurações quase sempre ficam em um pequeno arquivo de configuração, tipicamente config.php, que fica bem ao lado de index.php na raiz web e é carregado com require ou include. O mesmo padrão aparece em todo lugar com nomes diferentes: settings.py no Django, application.properties no Spring, .env no Node e no Laravel, e docker-compose.yml em stacks containerizadas.
Guardar a credencial em um arquivo que é distribuído junto com a aplicação é conveniente, mas é justamente essa a fraqueza que este desafio explora. Assim que você tem qualquer acesso de leitura a esse arquivo - um shell de baixo privilégio como o usuário do servidor web, um bug de path traversal, um diretório .git exposto, ou simplesmente um colega clonando o repositório - a senha do banco de dados fica à vista. Diferente de uma sessão roubada, que expira, uma credencial de banco de dados vazada costuma dar acesso direto e persistente a todas as linhas que a aplicação enxerga.
Encontrar o segredo é basicamente saber onde procurar. A partir de um shell, o caminho mais rápido é listar o diretório web, identificar o arquivo de config e lê-lo; um grep recursivo por palavras-chave como password, passwd ou db_pass revela o mesmo valor caso o nome do arquivo não seja óbvio. A credencial é armazenada para que a aplicação possa enviá-la ao banco de dados, por isso fica em texto puro, não como hash - e é exatamente por isso que ler o arquivo é suficiente.
Erros comuns
- Procurar a senha no lugar errado. A credencial não está em
/etc/passwd(esse arquivo guarda contas de usuário do sistema, não segredos da aplicação) - ela fica na própria config da aplicação, ao lado do front controller. - Verificar apenas o arquivo óbvio. Credenciais costumam estar duplicadas em uma config de exemplo, em um backup como
config.php.bak, ou em uma linha comentada deixada de um teste. - Ignorar o histórico do controle de versão. Uma senha removida do arquivo atual ainda pode estar em um commit anterior, recuperável com o git log.
- Assumir que um valor com cara de aleatório está com hash. Uma string de conexão com o banco mantém a senha em texto puro para que a aplicação possa se autenticar - não é um hash de mão única.
Como se proteger
A correção durável é manter os segredos fora dos arquivos que são distribuídos junto com o código, de modo que ler a raiz web nunca os revele:
- Carregue a credencial do banco de dados a partir de uma variável de ambiente em tempo de execução, em vez de fixá-la em
config.php. - Armazene e rotacione-a em um gerenciador de segredos - um serviço de vault ou o serviço de segredos do seu provedor de nuvem - em vez de deixá-la em disco na raiz web.
- Adicione qualquer arquivo que contenha segredos ao
.gitignoree faça commit apenas de um.env.examplecom valores de exemplo. - Rode uma ferramenta de secret-scanning na CI para que uma credencial seja detectada antes de chegar ao repositório remoto.
Se uma credencial já foi commitada ou exposta, trate-a como queimada e rotacione-a imediatamente. Apagar a linha não é suficiente, porque o valor antigo continua no histórico do git e em eventuais backups - troque a senha do banco de dados e atualize a aplicação em execução para usar o novo segredo.
Solução completa
Estatísticas da comunidade
Vá mais fundo
Hacks de hoje relacionados
Colaboradores creditados
Estes hackers relataram problemas, melhoraram o conteúdo e ajudaram a fortalecer esta página.