Escreva de Volta: Aplicando uma Transformação de Senha no Sentido Direto
O desafio
A biblioteca de Aldermoor ainda roda o sistema de associados que comprou em 2011. Um teste de intrusão encontrou um ponto de injeção capaz de escrever na tabela members, e o manual do fornecedor explica o que a coluna pw_enc guarda: pw_enc = base64_encode(strrev(password)). Não é hash. Não tem sal. Uma inversão e uma codificação, ambas reversíveis. A conta de demonstração prova isso: demo.reader tem a senha demo1234 e pw_enc NDMyMW9tZWQ=. Você quer que a conta do bibliotecário aceite a senha Kestrel-88 no próximo login. Produza a string exata para escrever em pw_enc.
O que você vai aprender
- Aplicar uma cadeia de codificação no sentido direto, em vez de desfazê-la ao contrário
- Ler uma transformação aninhada e descobrir qual operação roda primeiro
- Explicar a diferença prática entre um hash e uma transformação reversível
- Descrever o valor do acesso de escrita a uma coluna de senha quando o armazenamento é reversível
Habilidades testadas
Pré-requisitos
- O que é base64
- Ler uma chamada de função de dentro para fora
Como funciona
O armazenamento de senha tem exatamente uma função: dado o valor armazenado, ninguém deve conseguir descobrir uma entrada que corresponda a ele. Um hash de senha moderno consegue isso sendo unidirecional e deliberadamente lento, de modo que a única rota de um banco de dados roubado até um login funcional é a tentativa e erro, a um custo por tentativa escolhido pelo defensor.
O que esse sistema de biblioteca faz não é isso. base64_encode(strrev(password)) são duas etapas reversíveis. O acesso de leitura à coluna entrega todas as senhas em texto puro, e o acesso de escrita é ainda mais forte: você não precisa saber a senha atual, porque pode calcular a forma armazenada de qualquer senha que quiser e colocá-la lá.
A direção é a habilidade em jogo aqui. Chamadas aninhadas se leem de dentro para fora, então strrev roda primeiro e base64_encode envolve o que ela retornar. Troque a ordem das duas e você ainda obtém uma string base64 bem formada, e é por isso que essa classe de erro sobrevive a uma revisão superficial: a saída parece igualmente convincente quando está errada.
Erros comuns
- Codificar antes de inverter. As duas ordens produzem base64 válido. Só uma delas decodifica para a senha escrita ao contrário.
- Enviar a senha invertida.
88-lertseKé o valor intermediário, não o que a coluna guarda. - Remover ou adicionar padding manualmente. Deixe a ferramenta gerar isso. O
==no final é parte da codificação, não decoração. - Recorrer a uma operação de decodificação. Nada aqui está codificado ainda. A entrada é texto puro.
Como se proteger
Armazene um verificador, nunca um valor recuperável.
- Use um hash de senha projetado para essa função, como argon2id ou bcrypt, com um sal por usuário. Codificação e inversão não são um hashing fraco, não são hashing nenhum.
- Migre no próximo login: valide contra a coluna legada uma vez, grave um hash adequado, apague o antigo. Um sistema que não pode ser reescrito ainda pode ter seus valores reversíveis drenados um login de cada vez.
- Trate a coluna de senha como uma superfície somente de escrita para a aplicação. Se uma injeção consegue alcançá-la, a tomada de conta não precisa de credencial nenhuma.
- Corrija a injeção como o defeito principal. O armazenamento reversível é o que torna isso catastrófico, mas consultas parametrizadas são o que impede o ataque.