1
resposta

String SQL na Senha

Boa tarde, fiquei com dúvida com relação as strings utilizadas nos campos Login e Senha. Vi o vídeo e li o texto e não consigo entender a lógica utilizada para o ataque. Poderia me explicar melhor a questão das strings?

Obrigado.

1 resposta

Olá Kramer, tudo bom? A questão é a seguinte:

Imagine que para fazer o login, ao receber o usuário e senha do formulário o sistema precise buscar no banco de dados por um usuário com as credenciais.

O ataque se baseia em suposições:

Será que existe um usuário com nome de usuário admin?

Ao tentar fazer login com admin e uma senha qualquer, a mensagem de erro retornada foi Senha incorreta, diferente da mensagem anterior Conta inexistente. A partir disso, é possível supor que exista um usuário com nome de usuário admin.

Será que conseguimos injetar código SQL no sistema?

Ao fazer queries em um banco SQL, o código segue um padrão. Uma query que busca por um usuário com nome admin em geral se assemelha a algo assim:

  SELECT * FROM usuarios WHERE nome_de_usuario = 'admin' AND senha = 'hash da senha';

Se o programador fez uma simples concatenação de strings no servidor, é possível injetar código. Por exemplo, se o código do servidor for algo assim.

  usuarioValidoCom(nome, senha) {
    usuario = fazQuery("SELECT * FROM usuarios WHERE nome_de_usuario = '" + nome + "' AND senha = '" + senha + "';");
  return usuario != null;
  }

Repare que podemos interferir diretamente no meio da query com um nome adequado.

Será que o sistema trata os erros de modo correto, ou posso conseguir informação através deles?

Se eu preencher o formulário com um nome de usuario inválido, podemos causar um erro. Se o erro não for tratado, podemos obter informações sobre o banco de dados. Ao inserir a senha ', causamos um erro de sintaxe no banco SQL, pois a query inteira fica algo que supomos ser semelhante à seguinte:

  SELECT * FROM usuarios WHERE nome_de_usuario = 'admin' AND senha = ''';

Repare que ao filtrar o campo senha existem agora 3 aspas, ou seja: as primeiras duas abrem e fecham uma string vazia, enquanto a segunda abre uma nova string que não é esperada. Ao encontrar essa nova abertura de string, o banco lança um erro pois o código SQL da consulta é inválido. No caso, o erro é mostrado diretamente na tela de login, dando acesso a informações sigilosas como o nome da tabela e dos campos de nome de usuário e senha reais, como na imagem da transcrição do vídeo mostra:

  SELECT username FROM accounts WHERE username = 'admin' AND password = ''';

Será que, com todas essas informações que temos, conseguimos fazer login com o usuário admin?

Para isso, basta fazer com que a query retorne o username do usuário admin. Como já sabemos qual a query está sendo feita e conseguimos injetar o código que desejarmos, podemos manipular essa query para retornar o que queremos.

Para isso, precisamos de uma consulta que ignore a condição de senha e retorne qualquer coisa. A query que desejamos executar é a seguinte:

SELECT username FROM accounts WHERE username = 'admin' AND password = 'qualquer coisa'  OR '1' = '1';

Se conseguirmos executar essa query, provavelmente conseguiremos fazer login com o usuário de admin. Para isso, basta inserir a seguinte senha no campo de senha:

qualquer coisa' OR '1' = '1

Por causa do modo como a query foi montada, conseguimos executar o código malicioso que queremos:

fazQuery("SELECT username FROM accounts WHERE username = '" + "admin" + "' AND password = '" + "qualquer coisa' OR '1' = '1" + "'");
// traduz para 
SELECT username FROM accounts WHERE username = 'admin' AND password = 'qualquer coisa' OR '1' = '1'

Deu pra entender a sequencia de suposições, testes e como foi executado o código?