Antes de responder diretamente à pergunta, vale a pena notar que, mesmo que tudo o que um invasor possa fazer seja ler dados que ele não deveria conseguir, isso geralmente ainda muito ruim. Considere isso usando
JOIN
s e SELECT
a partir de tabelas do sistema (como mysql.innodb_table_stats
), um invasor que começa com um SELECT
injeção e nenhum outro conhecimento de seu banco de dados pode mapear seu esquema e então exfiltrar a totalidade dos dados que você tem no MySQL. Para a grande maioria dos bancos de dados e aplicativos, isso já representa uma falha de segurança catastrófica. Mas para responder à pergunta diretamente:existem algumas maneiras que eu conheço pelas quais a injeção em um MySQL
SELECT
pode ser usado para modificar dados. Felizmente, todos eles exigem razoavelmente circunstâncias incomuns sejam possíveis. Todas as injeções de exemplo abaixo são fornecidas em relação à consulta injetável de exemplo da pergunta:SELECT id, name, message FROM messages WHERE id = $_GET['q']
1. Consultas "empilhadas" ou "em lote".
A técnica clássica de injeção de apenas colocar uma outra declaração inteira após a que está sendo injetada. Conforme sugerido em outra resposta aqui , você pode definir
$_GET['q']
para 1; DELETE FROM users; --
para que a consulta forme duas instruções que são executadas consecutivamente, a segunda das quais exclui tudo no users
tabela. Em mitigação
A maioria dos conectores MySQL - notavelmente incluindo PHP (obsoleto)
mysql_*
e (não obsoleto) mysqli_*
funções - não suporta consultas empilhadas ou em lote, então esse tipo de ataque simplesmente não funciona. No entanto, alguns fazem - incluindo o conector PDO do PHP (embora o suporte pode ser desativado para aumentar a segurança
). 2. Explorando funções definidas pelo usuário
As funções podem ser chamadas de um
SELECT
, e pode alterar os dados. Se uma função de alteração de dados foi criada no banco de dados, você pode fazer o SELECT
chame-o, por exemplo, passando 0 OR SOME_FUNCTION_NAME()
como o valor de $_GET['q']
. Em mitigação
A maioria dos bancos de dados não contém nenhuma função definida pelo usuário - muito menos alterações de dados - e, portanto, não oferece nenhuma oportunidade para executar esse tipo de exploração.
3. Gravando em arquivos
Conforme descrito no artigo de Muhaimin Dzulfakar (um nome um tanto presunçoso) Exploração avançada do MySQL , você pode usar
INTO OUTFILE
ou INTO DUMPFILE
cláusulas em um MySQL selecionam para despejar o resultado em um arquivo. Uma vez que, usando um UNION
, qualquer resultado arbitrário pode ser SELECT
ed, isso permite escrever novos arquivos com conteúdo arbitrário em qualquer local que o usuário estiver executando o mysqld
pode acessar. É concebível que isso possa ser explorado não apenas para modificar dados no banco de dados MySQL, mas para obter acesso shell ao servidor no qual ele está sendo executado - por exemplo, escrevendo um script PHP no webroot e fazendo uma solicitação a ele, se o O servidor MySQL é co-hospedado com um servidor PHP. Em mitigação
Muitos fatores reduzem a possibilidade de exploração prática desse ataque que parece impressionante:
- O MySQL nunca permite que você use
INTO OUTFILE
ouINTO DUMPFILE
para substituir um arquivo existente, nem gravar em uma pasta que não existe. Isso evita ataques como a criação de um.ssh
pasta com uma chave privada nomysql
diretório inicial do usuário e, em seguida, usando SSH ou sobrescrevendo omysqld
binário com uma versão maliciosa e aguardando a reinicialização do servidor. - Qualquer pacote de instalação decente irá configurar um usuário especial (normalmente chamado
mysql
) para executarmysqld
, e dê a esse usuário apenas permissões muito limitadas. Como tal, ele não deve ser capaz de gravar na maioria dos locais no sistema de arquivos - e certamente não deve ser capaz de fazer coisas como gravar na raiz da web de um aplicativo da Web. - As instalações modernas do MySQL vêm com
--secure-file-priv
definido por padrão, impedindo o MySQL de gravar em qualquer lugar que não seja um diretório de importação/exportação de dados designado e, portanto, tornando este ataque quase completamente impotente... a menos que o proprietário do servidor o tenha desativado deliberadamente. Felizmente, ninguém jamais desabilitaria completamente um recurso de segurança como esse, pois obviamente seria - oh espere não importa .
4. Chamando o sys_exec()
função de lib_mysqludf_sys
para executar comandos shell arbitrários
Existe uma extensão MySQL chamada
lib_mysqludf_sys
isso - a julgar por suas estrelas no GitHub
e uma pesquisa rápida do Stack Overflow
- tem pelo menos algumas centenas de usuários. Ele adiciona uma função chamada sys_exec
que executa comandos do shell. Conforme observado em #2, as funções podem ser chamadas de dentro de um SELECT
; espera-se que as implicações sejam óbvias. Para citar a fonte
, esta função "pode ser um risco de segurança" . Em mitigação
A maioria dos sistemas não tem esta extensão instalada.